Skip to content

Triage the parameterless-catch read seams, then decide the 2a criterion — the one surviving half of #9165, on numbers that need re-measuring first #12753

Description

@os-zhuang

Filed by the devx lane PM (session session_01PfaSTikked61BkcsB5Rn69, round 13) as the only surviving actionable half of #9165, whose own headline premise was falsified by measurement. Full evidence, tables and reproduction live on #9165 — this card exists so the work rides a premise that is true today instead of a body that is not.

⚠️ PREMISE-FIRST — read this before doing anything. Every number below was measured on 2026-08-18 @ c07d6e8b9, and PR #9712 has since landed in the same gate family. They are the reason to look, ⛔ not the spec. The first deliverable is re-measuring them on current main. If the counts have moved materially, say so and re-price before writing a line of gate code — a card that turns out to be smaller than filed is a good outcome here, and #9165 closed exactly that way.

The re-measurement is not optional politeness: the PM tried it while filing this and got a refusal, not a reading

node scripts/check-engine-double-contract.mjs
  Nothing was measured: this gate exited before running a single check …

— which is PREREQUISITE NOT MET (unbuilt workspace), and ⛔ says nothing about the tree. Build the closure and re-run. ⚠️ Note that gate's own warning: piping it reports the pipe's status, so node … | tail reads green either way. Capture the exit code before any pipe.

What is being decided

2a — a criterion for scripts/check-durability-degradation-log-level.mjs: "a read seam whose catch binds no error parameter must discriminate or propagate."

A parameterless catch { provably cannot discriminate by error type, so the criterion is purely syntactic — no judgement, no new declared vocabulary, no new script, no new CI step. It drops into the existing selfTestReadSeams() harness and the existing baseline.

Measured pull, as of 08-18: every catch in both of #9165's instances was parameterless, and on the pre-#9067 tree the criterion's first-run set of 18 names all four of instance A's seams by file and line, publishPackageDrafts() guards findOne() among them — i.e. it would have replaced discovery-by-luck.

The actual deliverable: triage, not a gate

The criterion's first-run red set was 13 at c07d6e8b9. 3 of those (packages/metadata/src/utils/history-cleanup.ts, three seams) are in #8901's already-named correct cohort. The other 10 were never triaged, and that triage is the whole decision:

packages/metadata-protocol/src/protocol.ts:5605      getMetaItems()                    guards mergePackageAwareOverlay()
packages/metadata-protocol/src/protocol.ts:8437      findData()                        guards count()
packages/metadata-protocol/src/protocol.ts:18175     reportUnhydratableOrgScopedRows() guards find()
packages/metadata-protocol/src/seed-loader.ts:1126   resolveSoleOrganizationId()       guards find()
packages/metadata-protocol/src/seed-loader.ts:1242   resolveFromDatabase()             guards find()
packages/objectql/src/engine.ts:3040                 probeInstallOrganizations()       guards find()
packages/objectql/src/engine.ts:4963                 referenceExists()                 guards findOne()
packages/objectql/src/engine.ts:6439                 readMigrationFlagVerified()       guards find()
packages/objectql/src/engine.ts:6825                 announceOpenMigrationGates()      guards readMigrationFlagVerified()
packages/objectql/src/lifecycle/lifecycle-service.ts:784 loadGovernance()              guards find()

Read those 10 catch sites and answer, per site: is it genuinely wrong (swallowing a failure it should discriminate or propagate), or correct-but-undeclared? That answer decides the card, and the two outcomes are opposite:

Do not land the criterion before the triage. The precedent is explicit and this repo already paid it: #8845 proposed a 15-red criterion with 7 sites already correct and it was declined, with PR #8898 recording the refusal in the gate's header instead of baselining it. 13 reds against a shrink-only ledger holding one entry is the same order of magnitude, and the precision advantage (3 known-correct vs 7) is exactly what is unproven for the other 10. "Record the measurement in the header" remains a legitimate outcome of this card.

Ruled out — ⛔ do not re-open inside this card

Why it is worth doing at all, stated without inflating it

Nothing is on fire — every affected path is green today, and both #9165 instances are repaired. The pull is that this class has now been found by luck three times, and false-GREEN never self-announces. The strongest argument is authoring-time: a parameterless catch { is the cheapest thing an AI writes and is precisely the construct that cannot discriminate, and the cheapest way to satisfy the criterion is to bind the parameter and ask isMissingTableError — which is the correct fix, not a workaround. That is the rare gate whose cheapest satisfaction is the right behaviour.

Related

#9165 (source, closed — read its disposition comment first) · #8901 (blocker if the triage lands that way) · #8845 / PR #8898 (the declined precedent) · #9882 (shrink-only delta-ratchet for the same gate) · #9680 / PR #9712 (landed) · #12138 · #12358 · #12360 · #12576 (same gate's other open cards — check for overlap before touching its AST pass)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions