Repository navigation
error-code provenance: the Hono doors and the runtime dispatcher stamp UNIQUE_VIOLATION as a literal inside a ternary that check:error-code-provenance cannot see, and the ledger has no row for either package #23714
Description
Filing gate ①, a follow-up owed by landed work (PR #23682 and PR #23700, both this seat's). reach: named real producers: the two stamp sites below. Each one's wire answer was measured at a public door by its own PR (POST /api/v1/data/:object on both Hono doors; POST /api/v1/actions/:object/:action on the dispatcher).
Filed by domain:cli seat 1 (#6024) · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG, from #23701's os-dev-report 6199848483 (out-of-scope finding 1). ⛔ Not a claim. Grade and lane are triage's.
Governing text
ERROR_CODE_LEDGER(packages/spec/src/api/error-code-ledger.zod.ts): "a code emitted by several packages is listed once per emitting package".UNIQUE_VIOLATIONis listed under@objectstack/types,driver-memoryanddriver-sqlonly.check:error-code-provenance(packages/spec/scripts/check-error-code-provenance.ts): every stamp site of a registered code inpackages/**non-test source must be listed under the stamping package's own owner key, or carry a recordedPROVENANCE_WAIVERSentry. Its own bounds line (:326) says it is "blind to helper/shorthand/ternary indirections".
The two sites, on origin/main
packages/plugins/plugin-hono-server/src/adapter.ts:362:isEngineDuplicateRecordEnvelope(thrown) ? 'UNIQUE_VIOLATION' : resolved.code(PR fix(plugin-hono-server): a Hono door answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23587) #23682, hono: a 409 DELETE_RESTRICTED answered by createHonoApp carries no developerMessage, dependentObject, dependentCount or object, which RestServer's structuredCodeAnswer arm carries (the #23531 family beyond CONCURRENT_UPDATE) #23587).packages/runtime/src/http-dispatcher.ts:1235:engineDuplicate ? 'UNIQUE_VIOLATION' : thrown.code(PR fix(runtime): the dispatcher answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23686) #23700, runtime: the dispatcher's own catch arms answer the engine's DuplicateRecordError as409 DUPLICATE_RECORD, not the ruled wire spellingUNIQUE_VIOLATION(measured atPOST /api/v1/actions/:object/:action) #23686). The same file'sduplicateArmContextcompares against the literal at:406, which is a read and not a stamp.- Both sit inside a ternary, so the gate stays green. The same gate went RED on PR fix(mcp): an MCP tool call repeating a unique value answers UNIQUE_VIOLATION, not the engine's DUPLICATE_RECORD (#23701) #23713's (mcp: a tool call that repeats a unique value answers the engine's in-process
DUPLICATE_RECORDin its error result, not the ruled wire spellingUNIQUE_VIOLATION(create_record,run_action,resume_run) #23701) first spelling, a module constant in@objectstack/mcp. That PR now reads the code offstructuredCodeAnswer's arm (@objectstack/types), so@objectstack/mcpspells no copy of the code.
Reader who acts
Triage grades it and routes it. Two remedies, both small. The second is the one PR #23713 already took, so the family would read one way:
domain:spec: two ledger rows,@objectstack/plugin-hono-serverand@objectstack/runtimeunderUNIQUE_VIOLATION.domain:cli: re-spell both sites to relay the shared arm's code, as@objectstack/mcpdoes (wireCodeOfin PR fix(mcp): an MCP tool call repeating a unique value answers UNIQUE_VIOLATION, not the engine's DUPLICATE_RECORD (#23701) #23713). Then neither package stamps the code and no ledger row is owed. Nopackages/specedit.
Either way, pin it so the site's wire answer is unchanged (UNIQUE_VIOLATION). The gate's ternary blind spot is declared, not a defect of its own.
Dedupe
MCP search_issues on objectstack-ai/objectstack, closed included: error-code-provenance ternary stamp blind spot UNIQUE_VIOLATION ledger row runtime plugin-hono-server gave 38 hits, top 8 read.
- The nearest are error-code provenance:
@objectstack/mcp's stdio data bridge stampsOBJECT_API_DISABLEDthrough a constant outsidecheck:error-code-provenance's declared patterns, and the ledger has no@objectstack/mcprow for it #22664 (closed;@objectstack/mcpstampingOBJECT_API_DISABLEDthrough a constant outside the gate's patterns) and [finding] error-code ledger: five more packages stamp a registered code with no provenance row — the #13254 class, swept #13353 (closed; five packages stamping without a row, swept). Both are the same class, for other codes and packages. - None names these two sites.
Dedupe words: error-code-provenance UNIQUE_VIOLATION ledger row runtime plugin-hono-server ternary stamp blind.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 15, 2026
Triage: first grade ·
bug·priority:p3·domain:cli·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-15T19:54ZRead fresh. Two stamp sites of
UNIQUE_VIOLATIONsit inside a ternary thatcheck:error-code-provenancecannot see (its own bounds line,:326):plugin-hono-server/src/adapter.ts:362(PR fix(plugin-hono-server): a Hono door answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23587) #23682);runtime/src/http-dispatcher.ts:1235(PR fix(runtime): the dispatcher answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23686) #23700).ERROR_CODE_LEDGERlists no row for either package.Grade p3: a ledger and source-shape gap. The wire answers are right and measured.
Direction (triage routes it): the
domain:cliremedy, the one PR #23713 (#23701, merged 19:32Z) already took for@objectstack/mcp.structuredCodeAnswer's arm (@objectstack/types) and spells no copy of it. The family then reads one way, and the ledger needs no new owner rows.Lane
domain:cli(plugin-hono-server,packages/runtime).Pins: the existing wire pins of PR #23682 and PR #23700 stay green, and
check:error-code-provenancestays green.findingleaves on grading.objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 4, batch 3 (the maintainer's 「并发恢复3」 in this seat's chat, about 22:35Z on 2026-10-15; recorded in seat post #6024 §1). Label order: the next unclaimed
bugatpriority:p3indomain:cli's open queue, after #23633. #23714: the Hono doors and the runtime dispatcher readUNIQUE_VIOLATIONoffstructuredCodeAnswer's arm, as@objectstack/mcpdoes, and stamp no copy of the literal · 2026-10-15T23:08ZSession:
session_01FLwgbTSmGMrqsXkBDsiwfGAccount:
os-bill(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23714-unique-violation-arm-relayWorktree:
objectstack-issue-23714Domain:
domain:cliSeat:
domain:cli#1(seat post #6024)File surface (read on
origin/main9bb93706fb; stop on a breach and explain it in the report):packages/plugins/plugin-hono-server/src/adapter.ts: the stamp at:362;packages/runtime/src/http-dispatcher.ts: the stamp at:1235, andduplicateArmContext's literal comparison at:406only if the relay makes it redundant;src/**, and one changeset.packages/spec(error-code-ledger.zod.tsandscripts/check-error-code-provenance.tsare read, not edited: triage's direction is the relay, and no ledger row is owed after it), and notpackages/types(structuredCodeAnswerandisEngineDuplicateRecordEnvelopeare read).Container & model:
M(two re-spelled sites, each re-measured at its public door and against the provenance gate),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier --repo objectstack-ai/objectstackover the two paths at9bb93706fb: "no path-derived mandate … The tier stays the PM's per-card judgment call")Clause-②: no
Basis for the Clause-② line: a source-shape change. The wire answer stays
UNIQUE_VIOLATIONat both doors (ruling65846bc46), and the status, message and envelope keys are unchanged. No export, accepted input or ledger row moves, and there is nopackages/specedit.Responsibility:
@objectstack/plugin-hono-serverand@objectstack/runtime's duplicate-record arms, platform code in this lane | the wire answers are already right and measured (PR fix(plugin-hono-server): a Hono door answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23587) #23682, PR fix(runtime): the dispatcher answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23686) #23700) | the provenance ledger's reader:check:error-code-provenanceis blind to a ternary (its bounds line,:326), so each package stamps a code the ledger does not list under itThread-read: 6201012432
Serial constraints cleared, and the landing order:
adapter.tsorhttp-dispatcher.ts(every open PR's file list was read in this act), and nopm:dispatchedclaim names them. Both have been free since PR fix(plugin-hono-server): a Hono door answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23587) #23682 and PR fix(runtime): the dispatcher answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23686) #23700 landed.Restart-touch:line on an openpm:on-holdcard names these files.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{ "issue": 23714, "status": "done", "branch": "claude/issue-23714-unique-violation-arm-relay", "pr": "https://github.com/objectstack-ai/objectstack/pull/23760", "session": "session_01FLwgbTSmGMrqsXkBDsiwfG", "premise_still_valid": true, "summary": "Both stamps of the literal 'UNIQUE_VIOLATION' now read the code off structuredCodeAnswer's arm (@objectstack/types), shaped as @objectstack/mcp's wireCodeOf: for a throw isEngineDuplicateRecordEnvelope accepts, code = the arm's body.code when it is a string, else the thrown or resolved code. Sites: plugin-hono-server declaredEnvelopeForThrow (was adapter.ts:362) and runtime HttpDispatcher.errorFromThrown (was http-dispatcher.ts:1235). The dispatcher's duplicateArmContext comparison against the literal (was :406) was made redundant by the relay, so it now compares with the envelope's decided {status, code}, the Hono declaredArmContext rule. Neither package's non-test source spells the literal now, as a stamp or as a read. The wire answer is byte-identical at every door (measured). No packages/spec or packages/types edit. One patch changeset says there is no behaviour change. H1, H2 and H3 were all confirmed (see literal_census, before_after, provenance_gate). The arm-answers-undefined fallback is unreachable for any value with stable code/name reads (9 accepted shapes all answered 409 UNIQUE_VIOLATION). Only a contrived unstable code getter reaches it. origin/main 2906cd8d2 was merged before opening (no conflict, disjoint files), and everything below was re-run at the final head ea8db26da.", "tests": "Final head ea8db26da, after the merge and a full rebuild (pnpm turbo run build --filter='!@objectstack/docs' --concurrency=2: 75 successful, 32 cached), all under os-verify-lock, each part's exit recorded: pnpm --filter @objectstack/plugin-hono-server test = Test Files 29 passed (29), Tests 366 passed (366) [exit 0]; plugin-hono-server typecheck exit 0 (check:test-typecheck: OK, 0 debt); pnpm --filter @objectstack/runtime test = Test Files 395 passed (395), Tests 5918 passed | 19 skipped (5937) [exit 0]; runtime test:repo = Test Files 3 passed (3), Tests 808 passed (808) [exit 0]; runtime typecheck exit 0 (check:test-typecheck: OK, ledger unchanged). The same counts were read at 20fb7e3d9 on base 3b46855fb. Landed pins, unchanged and green (verbose re-run): handler-throw-declared-envelope.test.ts 49/49, including all 12 rows of the [#23587] 'a repeated unique value answers 409 UNIQUE_VIOLATION on a Hono door' block (route, raw mount, declaredEnvelopeForThrow x engine class with and without field, plus 2 controls). dispatcher-unique-violation-wire-code.test.ts 7/7. sandbox-relay-unique-violation-wire-code + error-envelope.conformance also green (3 files, 66 tests). eslint --no-inline-config over packages/plugins/plugin-hono-server and packages/runtime: exit 0, empty output. A JSON-format run over the two changed files shows both linted, 0 errors, 0 warnings. Ablation: none, because no tested behaviour changed (the diff is source-shape only). The discrimination is the landed pins, each measured red against untranslated doors by its own PR. Rebuild proof for the rig's after leg: node scripts/ablation-dist-preflight.mjs found the new identifier duplicateArmCode in 2 built files each of @objectstack/plugin-hono-server and @objectstack/runtime, and a quoted UNIQUE_VIOLATION occurs 0 times in their dist index files. Consumer suites (@objectstack/hono and others) were not run: no export, signature or wire byte moved, and createHonoApp's dist was measured end to end in the rig.", "gates": "Local, at the final head ea8db26da (merge base 2906cd8d2): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths, derived 60 commands from 3 paths. All 60 ran, each exit captured before any pipe ('cmd :: exit N'), and all 60 exited 0. --ran: '60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero), exit 0. First pass at 20fb7e3d9: 59 exit 0, and pnpm check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET, no workspace dist). After the full build it exited 0, as did post-build re-runs of check:dts-closure, check:lean-entry-closure, check:published-files and check:sourcemap-no-sources-content. The 5 artifact-roster families whose roster is in a touched directory, all exit 0 at the final head: check-changeset-fixed.mjs, check:authz-resolver, check:error-code-casing, check:filter-alias-parity, check:route-ledger-census. Also pnpm --filter @objectstack/spec check:error-code-provenance exit 0 (see provenance_gate). NUL and control-byte self-scan of the 3 changed files and the PR body: no hit. CI check-runs at ea8db26da when this report was written (37): success = Dogfood Regression Gate, Governed Surface Queue Guard, Check PR Size, Check Documentation Links, Auto Label, filter, Lint · scoped · tooling self-tests, 'No other open PR may claim the same single-writer path', 'No other open PR may claim the same issue', 'The card this PR closes must claim this branch', 'Part-of PR must not also close its card', 'Flag docs affected by code changes'. in_progress = Check Changeset, Build Core, Test Core (1/6..6/6), Type Check · workspace / source gates / consumer gates / debt ledger, Lint · ESLint / PM dispatch-gates / CI, release & engine gates / repo & tooling gates / docs & code guards / scoped · query-options erasure / scoped · slot lookup & corpus. skipped = full-battery jobs (Temporal Conformance, Console Pin Gate, Dogfood Verify CLI, Dogfood Regression Gate matrix, Build Docs, Packed-tarball smoke). CI convergence is the PM's.", "line_budget": "n/a", "files_changed": [ "packages/plugins/plugin-hono-server/src/adapter.ts (+16 -6)", "packages/runtime/src/http-dispatcher.ts (+24 -8)", ".changeset/23714-unique-violation-arm-relay.md (+12, new: patch for @objectstack/plugin-hono-server and @objectstack/runtime, no behaviour change stated, Clause-②: no)" ], "before_after": "Rig (scratch, not committed): real ObjectQL + SqlDriver better-sqlite3 :memory: + real ObjectStackProtocolImplementation, driving the BUILT dist of @objectstack/hono (createHonoApp, app.request), @objectstack/runtime and @objectstack/plugin-hono-server (HonoHttpServer route via wrap() and raw mount via onError). The identity step (HttpDispatcher.prototype.timedResolveExecutionContext, answering a member) is the only stub. udoc.email is unique and r1 holds it. Before = dist at base 3b46855fb (32/32 turbo cache hits for that source). After = dist rebuilt at e5ffc8248, and again at the merged final head ea8db26da. Rows (status | code | details keys): createHonoApp POST /api/v1/data/udoc 409 | UNIQUE_VIOLATION | developerMessage,object; HonoHttpServer route engine.insert 409 | UNIQUE_VIOLATION | developerMessage,object; HonoHttpServer route engine class with field 409 | UNIQUE_VIOLATION | developerMessage,field,object; HonoHttpServer raw mount 409 | UNIQUE_VIOLATION | developerMessage,object; createHonoApp POST /api/v1/actions/udoc/add_duplicate 409 | UNIQUE_VIOLATION (+httpStatus 409) | developerMessage,object; .../take_email/r2 (declarative update) 409 | same; .../throw_named_duplicate 409 | UNIQUE_VIOLATION | developerMessage,field,object; CONTROLS: a producer speaking DUPLICATE_RECORD keeps DUPLICATE_RECORD (route; actions door), and DELETE_RESTRICTED keeps its body; store: 1 row holds the value, r2 unchanged. Example body (identical before/after): 409 {\"success\":false,\"error\":{\"code\":\"UNIQUE_VIOLATION\",\"message\":\"Duplicate record refused on 'udoc': a unique constraint already holds these values. No record was written.\",\"details\":{\"developerMessage\":\"Duplicate record refused on 'udoc': a unique constraint already holds these values. No record was written.\",\"object\":\"udoc\"}}}. Byte compare: before.tsv vs after.tsv cmp exit 0, and before vs after-merged cmp exit 0. sha256 3694fa2b2f02... on all three 12-line records.", "literal_census": "git grep for the quoted literal in non-test source, packages/plugins/plugin-hono-server/src and packages/runtime/src, comment lines dropped. BEFORE (3b46855fb): adapter.ts:362 STAMP (isEngineDuplicateRecordEnvelope(thrown) ? 'UNIQUE_VIOLATION' : resolved.code); http-dispatcher.ts:406 READ (duplicateArmContext: arm.body.code !== 'UNIQUE_VIOLATION'); http-dispatcher.ts:1235 STAMP (engineDuplicate ? 'UNIQUE_VIOLATION' : thrown.code). No third stamp (H1 holds). AFTER (ea8db26da): zero occurrences, stamp or read. Remaining mentions are docblock prose only (adapter.ts, http-dispatcher.ts, sandbox/quickjs-runner.ts:1463). Built dist index files of both packages: 0 quoted occurrences.", "provenance_gate": "pnpm --filter @objectstack/spec check:error-code-provenance. BEFORE at 3b46855fb: exit 0, 'scanned 2985 files; 379 registered-code stamp site(s): 360 listed, 19 waived', 'OK — every registered-code stamp site is listed under its own owner key or carries a recorded waiver (10 waiver(s), all live)'. AFTER at e5ffc8248 (same base): exit 0, identical two lines. --report before vs after: the same four UNIQUE_VIOLATION sites (driver-memory memory-unique-constraint.ts:210, driver-sql sql-driver.ts:2400, types data-error-classification.ts:1150 and :1751). The only report delta is runtime PROJECT_MEMBERSHIP_REQUIRED moving from http-dispatcher.ts:1759 to :1775 (added comment lines). At the merged final head ea8db26da: exit 0, 'scanned 2986 files; 380 registered-code stamp site(s): 361 listed, 19 waived', same OK line (the +1 file and +1 site come from main's incoming driver-sql change, not this diff). H3 holds. The gate's ternary blindness is untouched.", "mcp_calls": "0 — no MCP GitHub tool was called", "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches via scripts/pm/fleet-write/dispatch.mjs), executing 3 REST writes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft #23760), POST /repos/objectstack-ai/objectstack/issues/23760/assignees (os-bill), POST /repos/objectstack-ai/objectstack/issues/23714/comments (this report). Plus git push (not REST): the empty branch, then 3 commits. No label write, no PR-body PATCH. Reads were REST GETs only (card and comments, PRs 23713/23682/23700, PR 23760 read-back, check-runs).", "pr_body_changes": [], "deviations": [ "Commit trailers: the harness attribution reminder asked for a model-named Co-Authored-By and a robot-emoji PR footer. Per AGENTS.md and the dispatch, every commit carries the model-free pair the model-free 'Co-Authored-By: Claude' trailer (no model name) + Claude-Session, and the PR body ends with the session-URL footer. The merge commit's default message was amended before its first push to add that pair, so no pushed history was rewritten.", "Changeset: the dispatch left the call to Check Changeset. With no skip-changeset label (this dispatch writes none), that gate needs an added changeset, and check-empty-changeset refuses an empty one. The repo's own rule also points away from skip-changeset: both packages' files[] ship dist, and the rebuilt dist bytes changed. So one patch changeset was written, stating no behaviour change. If the seat prefers skip-changeset plus no changeset, the seat must apply the label and drop the file.", "Docblock lines next to the edits were re-wrapped (adapter.ts One-wire-spelling paragraph, errorFromThrown's docblock), as part of inserting one sentence each. There are no other text changes.", "Worktree cleanup (rm -rf node_modules, git worktree remove) runs right after this comment posts, because this comment is posted with the worktree's relay script. The final handback states the measured outcome." ], "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Landed: PR #23760 →
7428da02a2(#23714). The card is closedcompleted, andpm:dispatchedis strippeddomain:cliseat 1 (#6024) ·os-bill· sessionsession_01FLwgbTSmGMrqsXkBDsiwfG· 2026-10-16T01:28Z · holder of claim6204167058, released by this landing.origin/main7428da02a2: one parent (a queue squash), an ancestor oforigin/main, 3 files +52 / −14, identical to the reviewed headea8db26da; no queue branch leftcompletedby the PR'sFixes #23714;pm:dispatchedremoved by targeted delete6205306126on a true-green head. No contract review was owed.@objectstack/plugin-hono-server'sdeclaredEnvelopeForThrowand@objectstack/runtime'sHttpDispatcher.errorFromThrownread the engine duplicate's wire code offstructuredCodeAnswer's arm, as@objectstack/mcpdoes. Neither package's non-test source spells'UNIQUE_VIOLATION'now.check:error-code-provenancelists the same fourUNIQUE_VIOLATIONsites, and the ledger needs no new owner row.mainnow: every door answersUNIQUE_VIOLATION, and every one reads the code off the one classification in@objectstack/types.packages/plugins/plugin-hono-server/src/adapter.tsandpackages/runtime/src/http-dispatcher.ts.Generated by Claude Code