Skip to content

check-durability-degradation-log-level: the read-seam invention rule keys on return, so a catch that degrades by FALLING THROUGH into an empty accumulator is structurally invisible #8845

Description

@hotlong

Filed by the triage seat (whole-repo Routine, fire 08:47Z), split out of #8833 so that card can be ruled on its own terms. Unassigned. Not a claim.

#8833's 06:36Z comment recommended this be its own card with its own measurement, and its 07:07Z comment repeated that it is worth filing regardless of how #8833 is ruled. This is that card. ⛔ It is deliberately not a rider on #8833: the gate extension is what stops the class recurring, and it must not be hostage to a response-contract decision on one endpoint.

The blind spot

scripts/check-durability-degradation-log-level.mjs carries the read-seam invention rule (#5186, extended by #6451): a read seam must not invent an unreported answer. packages/metadata-protocol/src is in its scan roots, and it is green on main.

The rule classifies a catch by what it returns. Verified on origin/main @ 6b6b606 — the analysis keys on ts.isReturnStatement at :863 and :893.

So a catch of this shape is invisible to it:

} catch {
// history table unavailable — fall through with empty list
}

There is no return statement to classify. The accumulator declared above the try stays at its initial [], and the invention happens later, when code below reads that never-filled accumulator as though it were a real answer. The seam is neither baselined nor exempted — the rule simply cannot see it.

The live instance is diffMetaItem in packages/metadata-protocol/src/protocol.ts, which answers 200 with an empty diff when sys_metadata_history is unreadable (#8833). Measured there with a stub engine whose find throws; no log line is emitted either, so the outage leaves no trace on any surface.

Why it is worth a card rather than a note

This is the third recorded instance of the same meta-shape, which is what makes it a pattern rather than a one-off:

Each time, a rule written for exactly this harm was green over a live instance of it. The rule is good; its classification surface keeps turning out to be narrower than the harm.

Scope — measurement first, extension only if the red set is controllable

⚠️The extension is NOT the first step.scripts/check-durability-degradation-log-level.mjs's own header documents the 收窄先行 discipline that #6451 followed, and that header is the authority on it — read it before writing anything.

  1. Measure. Across the three scan roots, count catch blocks that are (a) empty-bodied or contain no return, and (b) sit above a read accumulator that is subsequently read as an answer. Report the set and how many are already-correct.
  2. Decide from the measurement. If the set is small and mostly-correct, extend the criterion in the finding(devx): #5186 读接缝规则的「编造空答案」词表看不见「原样返回入参」这一形状 —— #6116 是实证样本 #6451 style. If it is large or noisy, ⛔ do not extend — report the false-positive surface and stop. A gate that goes red across dozens of benign seams gets baselined into uselessness, which is worse than the current blind spot.
  3. Only if step 2 says extend: add the criterion, with the new red set enumerated in the PR body.

premise_still_valid: false or "measured, extension not advisable" with pr: null is a valid and valuable outcome here. This card is a measurement, not a promised diff.

Explicitly out of scope

⛔ Do not fix diffMetaItem in this card. That seam's disposition is #8833 and is with the maintainer — it has three candidate response contracts and one of them changes a published shape. If the gate extension you build would go red on diffMetaItem, that is the correct outcome and should be reported, not resolved by editing the seam.

Related

Metadata

Metadata

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions