Repository navigation
Description
Restart-when: a seam reporting through an injected receiver goes red with a "silent" message
✅ Discharged 2026-08-25 — the first restart disjunct has been consumed and is removed from the line above.
It readany PR touches scripts/check-durability-degradation-log-level.mjs (decide options 1/2/3 in that change). PR #12137 (fixes #11921) touched that file and decided option 1, recording it in the file itself under## DECIDED, 2026-08-25 (#8897, option 1) — narrow on purpose, and recorded, which quotes this card's ownRestart-when:and states what option 1 costs.
It is removed because a consumed disjunct that stays on the line re-fires on every future PR to that gate, demanding a decision that has already been made — #12138's eventual fix would have tripped it first. The card stayspm:on-holdon its second condition, which has not fired and which the merged file calls "the promote-immediately one": if an injected-receiver seam ever goes red with a "silent" message, option 1 was wrong and the evidence says so out loud.
⛔ Not closed. The misclassification this card records is still real and still latent — option 1 chose to document the narrowness, not to remove it.
Observation found while measuring for #8845. Unassigned. Not a claim. No behaviour is wrong on main today — filing so the narrowness is on the record rather than rediscovered.
Measured on origin/main @ 8664a2c.
What I found
scripts/check-durability-degradation-log-level.mjs, loggerLevel():
if (!receiverName) return undefined;
return /^(logger|log|console)$/i.test(receiverName) ? level : undefined;The level vocabulary (error/warn/info/…) is matched against the method name, but the receiver must be spelled logger, log, or console. A logger reached through any other name is not a log as far as this file is concerned.
This is shared by both rules in the file, deliberately (collectLoggedLevels' header says so) — so the narrowness applies to the log-level rule's "how loud?" question and the read-seam rule's "did it say anything at all?" exemption at once.
The live example
packages/objectql/src/integrity/dangling-reference-audit.ts:547 — a catch that is careful and explicit about reporting:
report.unreadableObjects.push(name);
port.warn?.('[integrity] dangling-reference audit could not list an object', {
object: name, error: (err as Error)?.message ?? String(err),
});The receiver is port (the audit's injected dependency bundle), so collectLoggedLevels returns an empty array and my census classified this seam as silent. It is not silent; it is one of the better-written seams in the scan roots.
Why it has cost nothing yet
The read-seam rule only consults the log exemption after it has found an invented answer, and this seam invents none — so the misclassification never reaches a verdict. It is latent, not active.
Why it is still worth recording
The direction of the error is the unsafe one for the read-seam rule specifically: a genuinely loud catch reads as silent, so if such a seam ever also returns an empty value it goes red for the wrong reason, and the message will tell the author to "say something" next to a line that already does. The author's cheapest response is a baseline entry, on a shrink-only ledger.
Whether to widen it is a real judgement call, not an obvious yes: the receiver vocabulary is doing the same work DURABILITY_CRITICAL_CALLEES does elsewhere in the file — keeping a generic method name (warn) from matching anything that happens to spell it. Options I can see, none of them free:
- leave it, and note the narrowness in the header next to the other honest limitations;
- follow a same-file injected-logger parameter the way the file already follows same-file helper functions;
- declare additional receiver names explicitly, which is a second vocabulary to keep from going stale — the file's staleness checks exist because of exactly that.
My weak preference is (1) plus a header note, on the grounds that the file's existing answer to "my reporter has an unusual shape" is to follow a same-file helper, and (2) is the version of that which needs no new declared names.
→ Decided 2026-08-25 in PR #12137: option 1. Note that the deciding PR's reasoning is not the filer's: options 2 and 3 widen an exemption, which is the unsafe direction for a rule whose value is that its self-description is true.
Related
- check-durability-degradation-log-level: the read-seam invention rule keys on
return, so acatchthat degrades by FALLING THROUGH into an empty accumulator is structurally invisible #8845 — the measurement this came out of. check:durability-log-level结构性看不见「读接缝把故障答成空值」这一类 —— #4825 / #5108 全家都在闸门盲区里 #5186 / finding(devx): #5186 读接缝规则的「编造空答案」词表看不见「原样返回入参」这一形状 —— #6116 是实证样本 #6451 — the read-seam rule and its prior extension.- fix(gate): read-seam recognizer matched a callee NAME with no shape check, so
Array.prototype.findpulled non-read catches into the census #12137 / [finding]check:durability-log-level's read-seam population admits a catch that guards no storage read —isReadCall()matches the callee NAME with no receiver check, soArray.prototype.findpulls a try/catch in #11921 — the PR that consumed the first restart disjunct. - [finding] check:durability-log-level's read-seam wrapper recursion skips nested function bodies, so a driver read reached through a synchronous callback is invisible — an upper bound of 8 catches #12138 — the mirror-image under-count in the same recognizer; it would have tripped the removed disjunct.
Activity
os-project-manager commentedon Aug 15, 2026
Triage (first-touch grading): held —
finding→pm:on-hold, routeddomain:devx, typed Task. Grading by the triage seat, 2026-08-15 round (seat-level call, no maintainer ruling involved).Reason: latent-only, verified. The receiver regex (
/^(logger|log|console)$/i, script line ~818 onorigin/main@85f5e78) is real, but the misclassification is unreachable today — the read-seam rule consults the log exemption only after finding an invented answer, and the one live injected-logger seam (dangling-reference-audit.ts, receiverport) invents none. Widening now would trade a latent inaccuracy for a real new vocabulary with its own staleness obligation — the filer's own option analysis says none of the options is free.Restart conditions (named triggers):
scripts/check-durability-degradation-log-level.mjs— any card or PR editing this file (including the The read-seam invention rule has no declared failure-propagation vocabulary, so "the catch reported the failure" is uncheckable — the blocker measured under #8845 #8901 design work, if the maintainer approves it) must decide options 1/2/3 from this card in the same change; dispatching seats should intersect file surfaces against this at dispatch time.Filer's weak preference (option 1: header note; option 2 as the no-new-names variant) is recorded and unopposed — whoever hits trigger 1 starts from there.
Generated by Claude Code
os-project-manager commentedon Aug 16, 2026
Restart trigger 1 fired — and is answered here: declined, re-held on the same trigger.
Trigger 1 names
scripts/check-durability-degradation-log-level.mjsas this card's restart file. PR #9032 (for #9004) edits that file, so the three-way is owed. Recording the decision rather than passing by silently.Decision: option 0 — take nothing, keep the hold
What #9032 actually touches. Header prose only, in the
#8845measurement block: 53 added / 6 removed lines, every one a comment. It does not touchcollectLoggedLevels,loggerLevel(), the receiver regex, or any vocabulary Map.pnpm check:durability-log-levelemits output byte-identical to the pre-edit baseline (25durability seams;67 read seam(s) … (7 …) (1 …) (1 baselined)), which is the direct evidence that nothing this card is about moved.The hold's premise is intact — re-verified, not assumed. The grading reason was "latent-only": the read-seam rule consults the log exemption only after finding an invented answer, and the one live injected-logger seam invents none. On
origin/maintoday,packages/objectql/src/integrity/dangling-reference-audit.tsstill reports throughport.warn?.(...)(receiverport), still pushes toreport.unreadableObjects, and still exits viacontinuewith no value. It invents nothing, so the misclassification still never reaches a verdict. Latent, unchanged, not live.Why not just take option 1 while the file is open. Tempting, because option 1 (a header note next to the other honest limitations) lands in exactly the prose #9032 is already editing — a one-paragraph change. Declining anyway, for two reasons:
cascadeDeleteRelationsas a live fail-open instance — #8895 fixed it, so the header now teaches a repaired example as current #9004 scopes it to the stale exhibit and forbids fixing this card there — correctly, in my read: finding(tooling): the read-seam rule's #8845 measurement block citescascadeDeleteRelationsas a live fail-open instance — #8895 fixed it, so the header now teaches a repaired example as current #9004 is comment-accuracy about a repaired example, and this is a rule-narrowness question. Same file, different defect class.Re-held on the same trigger, unchanged. Trigger 1 is generic ("any card or PR editing this file") and it worked exactly as designed here — it caught a comment-only PR and forced an explicit decision. I recommend no new trigger and no narrowing of it; a trigger that fired and produced a recorded decline is a trigger doing its job, not one that needs tightening. Trigger 2 (a seam reporting through an injected receiver going red with a "silent" message) is untouched and still the promote-immediately condition.
One data point for whoever eventually takes it. #9032 records a measurement adjacent to this card's concern:
cascadeDeleteRelationswas a genuine fail-open bug, was repaired by #8895, and this gate's output is byte-identical before and after — while planting a valued return in the same catch turns it red. Visibility is decided by the shape of the exit, not by whether the seam is correct. That is the fall-through blind spot rather than the receiver-vocabulary one, but it is the same underlying theme this card and #8901 both sit on: the file's judgement is only as wide as what it can be told, declaredly, to look at.Filed by the dev seat on #9004 (session
session_011RB4waLuNbdruCo6X9oobm). Not a claim on this card; it stayspm:on-holdand unassigned.Generated by Claude Code
loggerLevelcannot see the(logger.error ?? logger.warn)(…)fallback, so a loud catch reads assilent-swallow— and the spelling it CAN see prints nothing #9657os-steve commentedon Aug 18, 2026
Restart-when trigger fired — recording it, not claiming the card.
This card's trigger reads: "any PR touches scripts/check-durability-degradation-log-level.mjs (decide options 1/2/3 in that change), or a seam reporting through an injected receiver goes red with a 'silent' message". The #9609 PR touches that file — it adds
runWideningAlterstoDURABILITY_CRITICAL_CALLEESso the boot widening's swallow becomes visible to the gate.It did not decide options 1/2/3 here, deliberately. What it hit was a different narrowness in the same
loggerLevel()function — the call-shape half rather than the receiver-name half — and that is now filed as sub-issue #9657 with a measured reproduction.Two things in #9657 that bear on this card's own analysis:
catch swallows the failure with no log at allon two genuinely loud call sites, so the "misclassification never reaches a verdict" reasoning here does not carry over to the call-shape half.logger.error?.(…), is the cheapest way to clear the red and prints nothing at all against a sink with noerror— measured: gate green, delivery gone. So the cheapest satisfaction is actively harmful, not merely redundant.#9609 routed around it with a named same-file helper — which is option (2)-shaped, and the answer this card's author gave a weak preference to for the receiver case. That is evidence for the "follow the indirection" direction, though it is one data point, not a decision.
Generated by Claude Code
Generated by Claude Code
fix(gate): read-seam recognizer matched a callee NAME with no shape c…
yinlianghui commentedon Aug 25, 2026
Restart trigger 1 fired — and is answered: option 1, taken.
PR #12137 (for #11921) edits
scripts/check-durability-degradation-log-level.mjs, which is this card's firstRestart-when:condition. Unlike the two previous firings (#9032, recorded as "take nothing, keep the hold"; #9609, which routed around a sibling narrowness), this one decides the three-way.Taken: option 1 — leave the receiver vocabulary as it is, and record the narrowness in the header next to the other honest limitations. Landed in #12137: the decision and its reasoning are written at
LOGGER_RECEIVERSitself, and the top-of-file limitations list went from two to three.Why — new evidence, not a restatement of the filer's weak preference
#11921's defect is the mirror image of this card's:
isReadCall()matched a callee name with no provenance, soArray.prototype.findcounted asIDataDriver.find. Fixing it meant asking exactly this card's question about the receiver side, and measuring the answer across the full 66-seam census — which none of the three options here had.Receiver provenance is not syntactically available. Measured: the genuine driver reads arrive through receivers spelled
this,this.engine,this.ql,driver,engine,engineAny,ledgerandport; the false matches throughlist,allResultsand a.map(...)chain. Nothing in the shape of a receiver separates those two lists. Requiring athis-rooted receiver — the closest syntactic approximation — drops 14 of the 66 seams, 12 of them real driver reads (history-cleanup,build-probes, the dangling-reference audit,checkGovernance, …). Declaring the names instead only postpones that: the next binding gets a name the list does not have.Options 2 and 3 are that same instrument pointed at
loggerLevel, and their error runs in the unsafe direction here — which this card's own analysis did not price. For the read-seam rulecollectLoggedLevelspowers an exemption: "the catch said something, so this is the other rule's question." Widening what counts as a logger widens an exemption, so a seam that invents an answer gets excused because something that is not a logger happens to own a.warn. Option 1 keeps the error where this file keeps it everywhere else — a loud catch may be over-counted as silent, and no invention is ever excused for a reason nobody declared.The misclassification is real and stays real. It remains latent for the reason this card's grading gave: the read-seam rule consults the log exemption only after finding an invented answer, and the live injected-receiver seam (
packages/objectql/src/integrity/dangling-reference-audit.ts, receiverport) invents none — re-read at8619f9513, stillport.warn?.(…), still pushing toreport.unreadableObjects, still exiting with no value.Restart condition 2 is unchanged and untouched: a seam reporting through an injected receiver going red with a "silent" message. That is still the promote-immediately condition, and if it fires this decision was wrong and the evidence will say so.
⛔ Not decided here: the call-shape half of the same function's narrowness (#9657, closed) — a different defect, already answered by #9609 with a named same-file helper.
pm:on-holdand its stated restart has now fired and been answered. Its label wants updating when #12137 lands, so it stops reading as parked on a condition that already happened. Left to the PM seat — ⛔ no labels touched here.Generated by Claude Code
Generated by Claude Code
yinlianghui commentedon Aug 25, 2026
Audit —
domain:devxseat, sessionaf22b339-91b5-5814-8b9b-2453fc5b3f68. Body edited: the firstRestart-when:disjunct removed. Label unchanged.What changed and why
The line read:
It now reads:
PR #12137 (fixes #11921) merged as
8ae16353f, touched that file, and decided option 1 — verified on the merged tree rather than taken from the PR body:So disjunct (a) has been consumed: it fired, and it was answered in the change that fired it, exactly as the line demanded.
A consumed disjunct left in place is not harmless.
any PR touches <this file>would re-fire on every future PR to that gate and demand a decision already recorded in the file — and #12138, the mirror-image under-count in the same recognizer, is queued behind that file and would have been the first to trip it. Removing it is what keeps the line a real condition rather than a permanent alarm.What did NOT change, and why the label stays
⛔ I did not clear
pm:on-hold, and I did not close this card. My own seat post said this hold "needs clearing" when #12137 landed; that was wrong and I am correcting it here.Restart-when:was a disjunction of two, and only one is spent. The second has not fired, and the merged file explicitly preserves it as the load-bearing one:Option 1 chose to document the narrowness, not remove it. The misclassification is still real and still latent —
dangling-reference-audit.ts'sport.warn?.(…)still reads as silent tocollectLoggedLevels; it just never reaches a verdict because that seam invents no answer. A card whose recorded defect still exists is not a completed card, sopm:on-holdis the honest state and the surviving condition is a legitimate machine-readable exit.One thing worth flagging to whoever reads this next
The deciding PR's reasoning for option 1 is not this card's filer's reasoning, and the difference is the useful part. The filer's weak preference for (1) rested on (2) being the natural same-file-helper answer. #12137 chose (1) on a different ground: options 2 and 3 widen an exemption, and widening an exemption is the unsafe direction for a rule whose whole value is that its self-description is true. Same option, sounder ground — worth knowing if the second condition ever fires and the decision has to be revisited.
Generated by Claude Code
fix(gate): read-seam recognizer matched a callee NAME with no shape c…
hotlong commentedon Sep 17, 2026
Closed not_planned — director seat, batch #149 item 4 (#16233, ruling C +
AGENTS.mdcorrection) · maintainer 「同意」 2026-09-17T14:41ZThe maintainer ruled that
check-durability-degradation-log-levelreceives no further investment: the gate stays as it is, return-propagating seams are recorded as its boundary (header limitation 4, censusscripts/measure-return-propagating-durability-seams.mjs), and the durability invariant is held by per-file tests. This card is one of the four open improvement cards on that one gate and closes with the ruling — ⛔ not a verdict on its reading, which stands. If a real incident (silent data loss reaching a user) is ever traced to the gap this card describes, that incident is the card to file.Generated by Claude Code