Found while implementing #15633 (which teaches check:error-status-conformance to read the assignment form err.code = ...; err.status = ...). Not fixed there — out of that card's scope, and it moves a ratchet.
What the run prints
With #15633's R6 in place, the gate's live run reports:
unresolved: 50 declaration(s) the deriver could not read —
packages/drivers/driver-sql/src/sql-driver.ts:885: assignment: code=StandardErrorCode.enum.DATABASE_ERROR status=500
packages/drivers/driver-mongodb/src/mongodb-aggregation.ts:319: assignment: code=StandardErrorCode.enum.NOT_IMPLEMENTED status=501
packages/objectql/src/filter-comparand-shape.ts:247: assignment: code=StandardErrorCode.enum.INVALID_FIELD status=400
...
36 of those 50 are one mechanical shape: StandardErrorCode.enum.SOME_CODE. They are genuine producers — the status beside them is already a literal, and the code half is a Zod enum member whose value equals its own name by construction (packages/spec/src/api/errors.zod.ts:52, export const StandardErrorCode = z.enum([...])).
Why the deriver cannot read them
lookup() in scripts/check-error-status-conformance.mjs resolves an identifier of at most ONE dot (NAME or OBJ.key, plus the MAP[OBJ.key] subscript form). StandardErrorCode.enum.INVALID_FILTER has two, and buildConstantIndex records nothing for a z.enum([...]) declaration in any case, so the whole family resolves to undefined.
Reporting them is the gate behaving correctly — its header's rule is that an unresolvable declaration is REPORTED, never silently dropped, and that is exactly what happens. The gap is that this is a shape the gate could resolve mechanically and does not, so 36 real producers stay outside the derivation.
Suggested disposition
Index z.enum([...]) declarations as NAME.enum.MEMBER -> 'MEMBER' (each literal in the array is its own value), and let lookup() walk the extra segment. Add a --self-test case for the shape in the same edit, as that file's header requires.
⚠️ This moves a ratchet, and that is the real cost to plan for. Several codes currently listed in scripts/error-status-unpinned-baseline.json as "no derivable producer" would gain one, so the gate reds with nowPinned findings until those rows are removed. Whoever takes this should expect the baseline shrink to be part of the change, and should say so in the PR.
Where the numbers come from
Branch claude/issue-15633-error-status-deriver at cd26dd16b, node scripts/check-error-status-conformance.mjs on packages/** (2243 source files scanned, 279 producer sites derived).
Generated by Claude Code
Found while implementing #15633 (which teaches
check:error-status-conformanceto read the assignment formerr.code = ...; err.status = ...). Not fixed there — out of that card's scope, and it moves a ratchet.What the run prints
With #15633's R6 in place, the gate's live run reports:
36 of those 50 are one mechanical shape:
StandardErrorCode.enum.SOME_CODE. They are genuine producers — the status beside them is already a literal, and the code half is a Zod enum member whose value equals its own name by construction (packages/spec/src/api/errors.zod.ts:52,export const StandardErrorCode = z.enum([...])).Why the deriver cannot read them
lookup()inscripts/check-error-status-conformance.mjsresolves an identifier of at most ONE dot (NAMEorOBJ.key, plus theMAP[OBJ.key]subscript form).StandardErrorCode.enum.INVALID_FILTERhas two, andbuildConstantIndexrecords nothing for az.enum([...])declaration in any case, so the whole family resolves toundefined.Reporting them is the gate behaving correctly — its header's rule is that an unresolvable declaration is REPORTED, never silently dropped, and that is exactly what happens. The gap is that this is a shape the gate could resolve mechanically and does not, so 36 real producers stay outside the derivation.
Suggested disposition
Index
z.enum([...])declarations asNAME.enum.MEMBER -> 'MEMBER'(each literal in the array is its own value), and letlookup()walk the extra segment. Add a--self-testcase for the shape in the same edit, as that file's header requires.scripts/error-status-unpinned-baseline.jsonas "no derivable producer" would gain one, so the gate reds withnowPinnedfindings until those rows are removed. Whoever takes this should expect the baseline shrink to be part of the change, and should say so in the PR.Where the numbers come from
Branch
claude/issue-15633-error-status-deriveratcd26dd16b,node scripts/check-error-status-conformance.mjsonpackages/**(2243 source files scanned, 279 producer sites derived).Generated by Claude Code