Uh oh!
There was an error while loading. Please reload this page.
feat(spec): register driver-memory as a UNIQUE_VIOLATION emitter in the error-code ledger - #13354
Conversation
…he error-code ledger ERROR_CODE_LEDGER lists a code once per emitting package -- provenance, not identity. driver-memory refuses a colliding write with code UNIQUE_VIOLATION / status 409 (conflictRefusal, memory-unique-constraint.ts), stamped in one place for both the field-level and the declared-index surface, and had no owner key. Pure append: one new owner key naming one already-registered code. No shape, mechanism, or other package's rows touched; the deduped union is unchanged, so no generated reference product moves. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KX8wnyjStaZcuMyAMNsy3N
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KX8wnyjStaZcuMyAMNsy3N
📓 Docs Drift CheckThis PR changes 1 package(s): 4 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 126 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 880a405fc553cdd3f6e30a3338b7ce0ae6385944 && git checkout 880a405fc553cdd3f6e30a3338b7ce0ae6385944
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 2331b1ed8779b8abbda1494cdd249bbf43352a49 659abf7782a362360a2196f8370292b149bdf2ff && git checkout -B drift-repro 2331b1ed8779b8abbda1494cdd249bbf43352a49 && git merge --no-ff 659abf7782a362360a2196f8370292b149bdf2ff
node scripts/docs-audit/affected-docs.mjs --json 2331b1ed8779b8abbda1494cdd249bbf43352a49
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#13254
Adds the one provenance row the ledger was missing:
@objectstack/driver-memoryas an emitter ofUNIQUE_VIOLATION. Pure append — a new owner key naming one already-registered code.The premise, re-verified on the base rather than recalled
Branched from
origin/mainat881f8d8e, which contains both ordering edges the card required:git merge-base --is-ancestor 56c093c HEADexits 0 — PR fix(driver-memory): enforce field-leveluniqueso a colliding write is refused, not landed #13249 (card [finding] driver-memory enforces no uniqueness, so an out-of-process duplicate autonumber lands SILENTLY and the write succeeds — the #5499 freeze that deferred the fix dissolved 2026-08-11 #13197), the change that makes the claim true, is present.5b3ff63c(PR feat(spec,rest): register READ_BACK_FAILED as a named wire row mapped in handleApprovalError #13296, card ShouldREAD_BACK_FAILEDget a named wire row, asRESUME_FAILEDhas? The #12769 refusal currently rides an unmapped 500 #13182) is the most recent commit touchingpackages/spec/src/api/error-code-ledger.zod.ts, so the other open writer of this single-writer file has landed.Both halves of the card's premise then measured on that base:
grep -n 'driver-memory\|UNIQUE_VIOLATION' packages/spec/src/api/error-code-ledger.zod.tsreturns exactly one line —250: 'UNIQUE_VIOLATION',, the@objectstack/restregistration. There is no@objectstack/driver-memoryowner key anywhere in the file. (The R+37 unlock comment deliberately declined to assert this, having grepped a guessed path; this is the re-verification it asked for, against the real file.)packages/drivers/driver-memory/src/memory-unique-constraint.ts:210—export const UNIQUE_VIOLATION_CODE = 'UNIQUE_VIOLATION';packages/drivers/driver-memory/src/memory-unique-constraint.ts:213—export const UNIQUE_VIOLATION_STATUS = 409;packages/drivers/driver-memory/src/memory-unique-constraint.ts:500-506—conflictRefusal(), the single place both declaration surfaces are stamped:err.code = UNIQUE_VIOLATION_CODE; err.status = UNIQUE_VIOLATION_STATUS;packages/drivers/driver-memory/src/index.ts:31-32— both constants re-exported from the package entry.memory-unique-constraint.test.ts:63-65andmemory-declared-index-unique.test.ts:85-87each assertcodeandstatus, and then the literal'UNIQUE_VIOLATION'.So the row's fields are copied from landed reality: package
@objectstack/driver-memory, codeUNIQUE_VIOLATION, status 409.What changed
packages/spec/src/api/error-code-ledger.zod.ts— one new owner key placed beside@objectstack/driver-sql, grouping the two drivers, with a comment in the form the file's existing rows use: the producer and its stamping function, the second-emitter note the header's "provenance, not identity" rule calls for, and the wire-reachability argument in the shape@objectstack/driver-sql's own row makes (an ordinary create/update on an object with auniquefield reachesInMemoryDriver.createon a server already serving HTTP, andresolveThrownHttpErrorputs the driver'scode/statuson the envelope — the same test #8035 applied when it unregisteredMONGODB_MULTI_TENANT_UNSUPPORTEDfor failing it).Nothing else moves. No code's identity, status, casing or union membership changes; no other package's rows are touched; the ledger's shape and admission mechanism are untouched.
No generated product moves, and that is measured, not assumed
pnpm --filter @objectstack/spec check:generated(after a realbuild, per the stale-dist caveat) prints "All 14 generated artifacts are up to date", every one of the 14 individually green. That is the expected result rather than a missing step: the generated reference pages enumerate the deduped union, andUNIQUE_VIOLATIONwas already in it. Confirmed from the other side too —content/docs/references/api/error-code-ledger.mdxcontains no owner key at all (grepfordriver-sql,@objectstack/rest,ERROR_CODE_LEDGERreturns nothing), so per-package rows have no rendered surface to drift.Contrast the precedent commit
5b3ff63c, which registered a genuinely new code and therefore did moveerror-code-ledger.mdxandcontract.mdxby one line each.Verification
All of the following ran on the final head
659abf77, heavy runs serialised throughscripts/pm/os-verify-lock.sh. Verdict lines are the gates' own, not a captured$?:pnpm --filter '@objectstack/spec...' build— exit 0;check-dts-emitted: @objectstack/spec - 34/34 declared declaration file(s) present.pnpm --filter @objectstack/spec check:generated—All 14 generated artifacts are up to date.pnpm check:dispatcher-error-vocabulary—OK — 22 unregistered code-stamping site(s), all classified; 1 awaiting a ledger entry (#8846).(that pending entry is pre-existing and unrelated; scope line: 2103 non-test sources, 298 registered codes)pnpm check:error-code-casing—no unlisted lowercase error codes in 5010 scanned file(s) (ADR-0112).pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/api/error-code-ledger.test.ts src/api/errors.test.ts src/api/contract.test.ts src/api/error-catalog-docs.test.ts—Test Files 4 passed (4) / Tests 102 passed (102). These are the admission-rule pins: SCREAMING_SNAKE, per-package duplication, standard-catalog shadowing, owner-key shape, the deduped-sorted-union identity, and the [finding]@objectstack/restregisters four generic synonyms the standard catalog already covers (CONFLICT,NOT_FOUND,FORBIDDEN,INTERNAL) — contract call, not a cleanup #8211 synonym gate.pnpm --filter @objectstack/driver-memory test—Test Files 31 passed (31) / Tests 905 passed (905). The consumer check the dispatch asked for: the row agrees with the emitter's readings and nothing in the producing package turned red.pnpm --filter @objectstack/spec run typecheck— exit 0;check:test-typecheck: OK.pnpm lint(eslint . --no-inline-config, repo-wide, not narrowed) — exit 0.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(which reads its own change set from the merge base — 2 paths). Its 34 derived families were run: all green except three that measured nothing and say so in their own words —check-dev-prereqsandcheck-doc-formula-expressionsreportedPREREQUISITE NOT METon an unbuilt workspace (the latter re-run green after building@objectstack/formulaand@objectstack/lint), andcheck-test-completenessexited 3 withPREREQUISITE NOT MET — this gate grades a saved turbo run test log, which its own text records as NOT MEASURED locally and not a finding.pnpm check:nul-bytes—OK (scanned 7401 text file(s) ... no raw ASCII control bytes).Changeset
patchon@objectstack/spec, notminor: the exportedERROR_CODE_LEDGERvalue gains a key, butRegisteredErrorCode,REGISTERED_ERROR_CODESand theErrorCodeunion are byte-for-byte unchanged — no new vocabulary reaches any client. (The5b3ff63cprecedent tookminorbecause it added a code.)Clause-② and review posture
The PATH limb fires — the diff touches
packages/spec/src/**— so this PR stays DRAFT and carriesneeds:contract-reviewon both carriers. This seat does not flip it ready, does not enqueue it, and does not clear the label; the review chain owns that. The card's own text ruled the same, and the content limb is the narrow one: a provenance row registers an already-landed refusal and changes no accept/reject behaviour.The sweep the card asked for — reported, not widened
The card asked whether any other emitter is missing a row, and to report rather than widen. A read-only literal scan over the 71 workspace packages under
packages/**found five further packages stamping a registered code their own owner key does not list (four of them literal HTTP envelopes), plus one SDK-side sub-class. None of it is in this diff. Filed separately as #13353, with the per-site table, the triage that discarded the ledger's already-explained "door, not producer" cases, and the note that the recurring fix is a gate nobody has.Generated by Claude Code