Handed to triage by the os-dev patch round on #18301 (report comment 5707574628), which measured it while re-deriving a PM assumption it was told to falsify rather than inherit. ⛔ The dev does not POST issues; the seat is filing it verbatim in substance. The fix lands in packages/spec/src/**, outside #18301's fence — ⛔ do not fold it into that card.
The trap
ServerRateLimitConfigSchema is declared as
strictObject({ ... guidance: { keyBy, store } }, RateLimitConfigSchema.shape)
— built from the open schema's shape object. So one declaration answers for two emitted defs:
| def |
shape |
parse of an undeclared keyBy |
system/ServerRateLimitConfig |
closed (strictObject) |
refused, loudly, with the prescription |
shared/RateLimitConfig |
plain open z.object |
succeeds, and the key is dropped in silence |
⇒ the guidance entries for keyBy and store prescribe to nobody on the open twin. An author writing keyBy on an API endpoint's rateLimit gets no error, no warning, and no effect — the write is discarded.
⚠️ Both defs emit additionalProperties: false, and both match the same declaration by per-entry instance identity. So neither of the two cheap instruments distinguishes them.
Why this is class (c) and not a nit
This is precisely 「AI 写元数据会被运行时拒收或静默丢弃的陷阱」 on a live authorable surface: the key is declared, the guidance text exists to teach it, the schema accepts the document, and the platform hands back a different one. It is #4001's own failure mode, and it is the shape this project treats as the most dangerous — a declaration the runtime does not honour, failing silently rather than loudly.
⭐ Why the earlier sweep missed it, which is the part worth keeping
A CONTRACT_REVIEW_TIER review of PR #18529 swept for exactly this class and found nothing, with live controls: 5 .strip() sites (all extending with new keys), 0 z.object(XSchema.shape…), 0 z.object(bareIdentifier), and the single strictObjectError( site module-private. That sweep was not sloppy — the sharing runs the other way round. It looked for an open clone built from a strict schema's shape; here the strict schema is built from the open one's shape. Every grep shape in that sweep is blind to that direction by construction.
⇒ ⛔ Do not re-derive this population by grep. The dev found it with the gate's own instrument — a census pass over all 1525 emitted defs that runs the declaration match and then asks each def what it actually does with the key. Measured: 258 defs resolve to exactly one declaration naming an undeclared key, promising 779 keys; 770 are delivered, 9 are not. Two of the 9 are this live member on a root-reachable def. The other 7 are union defs the probe cannot drive to a single door.
Scope for whoever takes it
The two named keys are the measured instance; the census method is the deliverable, because the same shape-sharing pattern can recur anywhere a strictObject(..., Open.shape) exists. Decide per key whether the guidance belongs on the open twin (then close it, or move the key into the shape) or whether the open twin should not carry the prescription at all.
⚠️ Re-run the census on the then-current main before acting: the 258 / 779 / 770 / 9 figures were measured at 9e0324f807 on a branch, and the 7 union defs are a boundary the probe explicitly cannot resolve, ⛔ not a clean zero.
Dedupe words: RateLimitConfig guidance keyBy, silent strip open z.object shared shape, strictObject built from open shape, one declaration two emitted defs, guidance prescribes to nobody.
Generated by Claude Code
Handed to triage by the
os-devpatch round on #18301 (report comment5707574628), which measured it while re-deriving a PM assumption it was told to falsify rather than inherit. ⛔ The dev does not POST issues; the seat is filing it verbatim in substance. The fix lands inpackages/spec/src/**, outside #18301's fence — ⛔ do not fold it into that card.The trap
ServerRateLimitConfigSchemais declared as— built from the open schema's shape object. So one declaration answers for two emitted defs:
keyBysystem/ServerRateLimitConfigstrictObject)shared/RateLimitConfigz.object⇒ the
guidanceentries forkeyByandstoreprescribe to nobody on the open twin. An author writingkeyByon an API endpoint'srateLimitgets no error, no warning, and no effect — the write is discarded.additionalProperties: false, and both match the same declaration by per-entry instance identity. So neither of the two cheap instruments distinguishes them.Why this is class (c) and not a nit
This is precisely 「AI 写元数据会被运行时拒收或静默丢弃的陷阱」 on a live authorable surface: the key is declared, the guidance text exists to teach it, the schema accepts the document, and the platform hands back a different one. It is #4001's own failure mode, and it is the shape this project treats as the most dangerous — a declaration the runtime does not honour, failing silently rather than loudly.
⭐ Why the earlier sweep missed it, which is the part worth keeping
A
CONTRACT_REVIEW_TIERreview of PR #18529 swept for exactly this class and found nothing, with live controls: 5.strip()sites (all extending with new keys), 0z.object(XSchema.shape…), 0z.object(bareIdentifier), and the singlestrictObjectError(site module-private. That sweep was not sloppy — the sharing runs the other way round. It looked for an open clone built from a strict schema's shape; here the strict schema is built from the open one's shape. Every grep shape in that sweep is blind to that direction by construction.⇒ ⛔ Do not re-derive this population by grep. The dev found it with the gate's own instrument — a census pass over all 1525 emitted defs that runs the declaration match and then asks each def what it actually does with the key. Measured: 258 defs resolve to exactly one declaration naming an undeclared key, promising 779 keys; 770 are delivered, 9 are not. Two of the 9 are this live member on a root-reachable def. The other 7 are union defs the probe cannot drive to a single door.
Scope for whoever takes it
The two named keys are the measured instance; the census method is the deliverable, because the same shape-sharing pattern can recur anywhere a
strictObject(..., Open.shape)exists. Decide per key whether the guidance belongs on the open twin (then close it, or move the key into the shape) or whether the open twin should not carry the prescription at all.mainbefore acting: the 258 / 779 / 770 / 9 figures were measured at9e0324f807on a branch, and the 7 union defs are a boundary the probe explicitly cannot resolve, ⛔ not a clean zero.Dedupe words:
RateLimitConfig guidance keyBy,silent strip open z.object shared shape,strictObject built from open shape,one declaration two emitted defs,guidance prescribes to nobody.Generated by Claude Code