Uh oh!
There was an error while loading. Please reload this page.
feat(spec): register the 9 unregistered REST wire codes the #8885 sweep found; pin the ADR-0106 D6 tier-3 emission - #9177
Conversation
…ep found; pin the ADR-0106 D6 tier-3 emission - ERROR_CODE_LEDGER (@objectstack/rest): +THROTTLED (429, approvals remind cool-down, contract-documented) and the 8 template-generated APPROVAL_<ACTION>_FAILED terminal 500 codes whose literal-spelled siblings were already registered. - rest-field-visibility-fault-envelope.test.ts: the tier-3 pin the card owed (sendFieldVisibilityFault: code FIELD_VISIBILITY_UNRESOLVED + 503 + closed- union membership), plus the RECORD_NOT_ACCESSIBLE characterization baseline and the premise-falsifying pin (it is a StandardErrorCode member). - rest-approvals-wire-codes.test.ts: live 429/500 emissions through the real routes + a derived class pin over every POST /approvals/requests/:id/<action> route's generated terminal code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01225pUjnCKWqxcc1PeqKFUq
… codes (gen:docs) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01225pUjnCKWqxcc1PeqKFUq
📓 Docs Drift CheckThis PR changes 1 package(s): 106 hand-written doc(s) reference the affected code — list omitted above 15 rows. Re-derive: ⛔ 7 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.
|
Uh oh!
There was an error while loading. Please reload this page.
os-zhuang
commented
Aug 16, 2026
条款②追溯审计 — 结论:通过,无缺陷性质:本 PR 向 审计席:skills 席 session_017TNzEetykdh7ceZGwuAPLq(契约复审档位,非派发席)。 结论:9 码均有活产源(模板生成臂 + remind 冷却 429); 制度化修复(入队闸门,防再穿):#9185。 Generated by Claude Code |
Fixes#8885
Premise re-verified before implementing (rule: the issue body is a lead, not a spec)
The card's table had two rows; both moved:
FIELD_VISIBILITY_UNRESOLVED— registered by PR feat(spec): register the dispatcher conformance gate's reported error codes in ERROR_CODE_LEDGER #9170 (merged 19:08Z) under@objectstack/rest. What remained was the card's second half: the tier-3 pin, delivered here.RECORD_NOT_ACCESSIBLE— the card's row was a measurement error. The code has been aStandardErrorCodemember (Authorization block, "Sharing rule restriction",errors.zod.tsline 81) since before the card's own measured commitcc5c07b80— verified withgit show cc5c07b80:packages/spec/src/api/errors.zod.ts. Thesys_commenthas no record-level authorization: any org member reads and writes comments on records they cannot see #4630 emitter comment ("uses the STANDARD catalog code") is correct as written. The register-or-collapse fork the card and the dispatch priced as a maintainer decision dissolves: there is nothing to register (the admission gate refuses codes that shadow the standard catalog) and nothing to collapse (it already IS the catalog code, so no wire change is on the table). A pin now records the membership so the premise cannot be re-reported.Population sweep (the card's warning was right — the population was larger than two)
Swept every non-test source under
packages/rest/srcfor codes reaching an error envelope, across four spellings:code: 'LITERAL'sites, helper-call literals (respondError(...),sendEnvelopeError(...), mapping tables), ternaries, and template literals. Result: 9 codes on the wire in neitherStandardErrorCodenorERROR_CODE_LEDGER, all in the approvals family, all with live emitters:THROTTLEDhandleApprovalErrormapping table; producer: plugin-approvalsremind()cool-down, documented in the spec contract (contracts/approval-service.ts)APPROVAL_APPROVE_FAILED,APPROVAL_REJECT_FAILEDdecisionRouteterminal catch (template literal)APPROVAL_REVISE_FAILED,APPROVAL_RESUBMIT_FAILEDflowMoveRouteterminal catch (template literal)APPROVAL_REASSIGN_FAILED,APPROVAL_REMIND_FAILED,APPROVAL_REQUEST_INFO_FAILED,APPROVAL_COMMENT_FAILEDthreadRouteterminal catch (template literal)Root cause of the gap: the route factories spell the terminal code as a template (backtick
APPROVAL_${action}_FAILED), so the literal-grep pass that registered the family's literal-spelled siblings (APPROVAL_RECALL_FAILED,APPROVAL_ACTIONS_FAILED,APPROVAL_REQUEST_GET_FAILED,APPROVAL_REQUEST_LIST_FAILED) could not see these eight;THROTTLEDis a single word, which the multi-token sweep shape missed.All 9 are registered, not renamed — no wire behavior changes; the accepted set widens to match what the wire already carries, the same shape as #9170/#8846. None trips the #8211 synonym detector (
APPROVAL_carries a token no standard member has;THROTTLEDis neither an HTTP reason phrase nor a token-subset of any member — deliberately kept: a per-action business cool-down, not an API quota, and the value is spec-contract vocabulary). Provenance comments follow #9170's rows.Pins
rest-field-visibility-fault-envelope.test.ts— the tier-3 pin the deployment docs' advertised signal never had:sendFieldVisibilityFaultanswers503+code: FIELD_VISIBILITY_UNRESOLVED, the pair parses throughApiErrorSchema's closed union, and a control case proves the union is closed (an invented spelling fails parse). The pin also records the ruled sendError 的显式状态直通覆盖 400–599,5xx 的原始驱动报错绕过全部泄漏启发式直达客户端(metadata-protocol 有活体产出方) #5437 behavior that the emitter's prose is withheld from the wire (client readsINTERNAL_ERROR_MESSAGE; the text goes to the operator log). Plus theRECORD_NOT_ACCESSIBLEcharacterization baseline (403 + code +error.objectpreference throughmapDataError'ssys_commenthas no record-level authorization: any org member reads and writes comments on records they cannot see #4630 branch) and the premise-falsifying membership pin.rest-approvals-wire-codes.test.ts— live emissions through the real routes (remindcool-down 429THROTTLED; unmapped fault onapprove500APPROVAL_APPROVE_FAILED), and a class pin: it enumerates the registeredPOST /approvals/requests/:id/{action}routes and asserts the code each catch arm would generate — derived with exactly the production template, single-occurrence dash replace included — parses against the closed union. A tenth action route whose generated code nobody registers goes red here mechanically; the same gap cannot reopen.The vocabulary parses map the data-door's flat
{code, error}dialect intoApiErrorSchema's{code, message}slots: envelope POSITION is #7035's ratcheted debt and #9098's typing question is the cli lane's — this card owes the VOCABULARY, and both cards remain open (out of scope here: #9098, #7035).Reverse verification (direction: red, as expected)
Fix committed first, then the ledger ablated back to
origin/main's version, spec rebuilt from the ablated source, pins re-run: all 3 approvals cases red (union membership fails forTHROTTLEDand the generated codes). Restored from the commit, rebuilt, re-run: green. This proves the pins read the rebuiltdistvocabulary, not a cached one. TheFIELD_VISIBILITY_UNRESOLVEDcase is independent of this PR's ledger rows (registered by #9170) and stays green through the ablation, as expected.Verification at head
ed8e77e1dpnpm --filter @objectstack/spec test— 406 files / 10817 passed (includes the ledger admission gate accepting all nine rows)pnpm --filter @objectstack/rest test— 122 files / 2011 passed; the two new pin files re-run at head: 2 files / 7 passedpnpm --filter @objectstack/spec typecheck,pnpm --filter @objectstack/rest typecheck— greenpnpm --filter @objectstack/spec check:generated— all 13 up to date aftergen:docsregeneratedcontent/docs/references/**(the nine codes ripple into the generated API references; committed as its own commit)node scripts/check-dispatcher-error-vocabulary.mjs— OK (7 classified sites, 0 awaiting a ledger entry)node scripts/pm/dispatch-gates.mjsunion over the changed paths — all matched gates green, includingcheck:error-code-casing,check:adr-0087-registration,check:merge-driver,check:cross-package-test-inputs,check:type-check-coverage,check:type-check-debt --re-measure(33 entries, none above recorded),check:engine-double-contract,check:where-matcher,check:query-options-erasure,check:nul-bytes,check:dev-prereqs(after full workspace build)Changeset:
@objectstack/specpatch (matching #9170/#8212 precedent); non-breaking, so no ADR-0087 marker is required andcheck:adr-0087-registrationis green.Generated by Claude Code