Skip to content

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

Closed

Description

@objectstack-fleet

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_VIOLATION is listed under @objectstack/types, driver-memory and driver-sql only.
  • check:error-code-provenance (packages/spec/scripts/check-error-code-provenance.ts): every stamp site of a registered code in packages/** non-test source must be listed under the stamping package's own owner key, or carry a recorded PROVENANCE_WAIVERS entry. Its own bounds line (:326) says it is "blind to helper/shorthand/ternary indirections".

The two sites, on origin/main

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:

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.

Dedupe words: error-code-provenance UNIQUE_VIOLATION ledger row runtime plugin-hono-server ternary stamp blind.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade · bug · priority:p3 · domain:cli · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T19:54Z

    Read fresh. Two stamp sites of UNIQUE_VIOLATION sit inside a ternary that check:error-code-provenance cannot see (its own bounds line, :326):

    ERROR_CODE_LEDGER lists 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:cli remedy, the one PR #23713 (#23701, merged 19:32Z) already took for @objectstack/mcp.

    • Each site reads the code off 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.
    • ⛔ The gate's ternary blindness is not tightened here: that would be a gate strengthening, and the maintainer's 「新增门禁默认否」 applies.

    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-provenance stays green.

    finding leaves on grading.

  2. added
    bugSomething isn't working
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    and removed on Oct 15, 2026
  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    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 bug at priority:p3 in domain:cli's open queue, after #23633. #23714: the Hono doors and the runtime dispatcher read UNIQUE_VIOLATION off structuredCodeAnswer's arm, as @objectstack/mcp does, and stamp no copy of the literal · 2026-10-15T23:08Z
    Session: session_01FLwgbTSmGMrqsXkBDsiwfG
    Account: os-bill (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23714-unique-violation-arm-relay
    Worktree: objectstack-issue-23714
    Domain: domain:cli
    Seat: domain:cli#1 (seat post #6024)
    File surface (read on origin/main 9bb93706fb; stop on a breach and explain it in the report):


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #23760 → 7428da02a2 (#23714). The card is closed completed, and pm:dispatched is stripped

    domain:cli seat 1 (#6024) · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG · 2026-10-16T01:28Z · holder of claim 6204167058, released by this landing.

    reading value
    queue ready and auto-merge armed 00:56Z, enqueued 00:58Z, merged 01:28Z
    origin/main 7428da02a2: one parent (a queue squash), an ancestor of origin/main, 3 files +52 / −14, identical to the reviewed head ea8db26da; no queue branch left
    card closed completed by the PR's Fixes #23714; pm:dispatched removed by targeted delete
    • Review chain: ACCEPT 6205306126 on a true-green head. No contract review was owed.
    • What landed:
      • @objectstack/plugin-hono-server's declaredEnvelopeForThrow and @objectstack/runtime's HttpDispatcher.errorFromThrown read the engine duplicate's wire code off structuredCodeAnswer's arm, as @objectstack/mcp does. Neither package's non-test source spells 'UNIQUE_VIOLATION' now.
      • The wire answer is byte-identical at every door, as measured on the built dists.
      • check:error-code-provenance lists the same four UNIQUE_VIOLATION sites, and the ledger needs no new owner row.
    • The family on main now: every door answers UNIQUE_VIOLATION, and every one reads the code off the one classification in @objectstack/types.
    • Holds released: packages/plugins/plugin-hono-server/src/adapter.ts and packages/runtime/src/http-dispatcher.ts.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they landpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions