Skip to content

refactor(plugin-hono-server,runtime): the Hono doors and the dispatcher read UNIQUE_VIOLATION off the shared arm instead of stamping the literal (#23714) - #23760

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-23714-unique-violation-arm-relay
Oct 16, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-23714-unique-violation-arm-relay

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #23714
Clause-②: no

The two doors that translate the engine's DuplicateRecordError into the ruled wire spelling now read that code off the shared classification's arm (structuredCodeAnswer, @objectstack/types), as @objectstack/mcp's wireCodeOf already does. Neither package's non-test source spells 'UNIQUE_VIOLATION' any more, as a stamp or as a comparison. The wire answer does not move. It was compared byte for byte at every door, before and after.

Governing text

Triage's grade on the card (6201012432):

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 ruling it serves (recorded in commit 65846bc46): one wire spelling on every route, UNIQUE_VIOLATION.

What changed

  • packages/plugins/plugin-hono-server/src/adapter.ts, declaredEnvelopeForThrow. For the engine's class (the unchanged key isEngineDuplicateRecordEnvelope), the envelope's code is now structuredCodeAnswer(thrown)?.body.code when that is a string, and the thrown code otherwise. It was the literal 'UNIQUE_VIOLATION'. declaredArmContext is unchanged.
  • packages/runtime/src/http-dispatcher.ts, HttpDispatcher.errorFromThrown: the same read. duplicateArmContext's agreement check compared the arm's code with the literal. It now compares it with the envelope's decided code, which is the Hono doors' declaredArmContext rule. Once the code is read off the same arm, the literal comparison is redundant, so it goes too. The status half of the check is unchanged.
  • One patch changeset (see "Changeset" below).
  • No packages/spec edit (no ledger row, no gate change), no packages/types edit, no export added or changed, and no test file added. Two call sites in two packages, each three lines, so no shared helper.

Literal census (non-test source, both packages)

Read at origin/main 3b46855fb (this branch's base) and at this head, with git grep for the quoted literal and comment lines dropped.

Site Before After
plugin-hono-server/src/adapter.ts:362, declaredEnvelopeForThrow stamp: isEngineDuplicateRecordEnvelope(thrown) ? 'UNIQUE_VIOLATION' : resolved.code gone (relay)
runtime/src/http-dispatcher.ts:406, duplicateArmContext read: arm.body.code !== 'UNIQUE_VIOLATION' gone (compares with the envelope's code)
runtime/src/http-dispatcher.ts:1235, errorFromThrown stamp: engineDuplicate ? 'UNIQUE_VIOLATION' : thrown.code gone (relay)

H1 holds: those are the only two stamps, and there is no third. After the change both packages' non-test source has zero quoted occurrences outside comments. The remaining mentions are prose in docblocks (adapter.ts, http-dispatcher.ts, sandbox/quickjs-runner.ts:1463). The rebuilt dist/ of both packages has zero quoted UNIQUE_VIOLATION too (index.mjs and index.js of plugin-hono-server, index.js and index.cjs of runtime).

The fallback branch (H2): measured unreachable

The seat asked whether structuredCodeAnswer can answer undefined for a throw isEngineDuplicateRecordEnvelope accepts. By reading: the predicate requires code === 'DUPLICATE_RECORD' and name === 'DuplicateRecordError'. The three arms ahead of the duplicate arm key on DELETE_RESTRICTED, on CONCURRENT_UPDATE or the ConcurrentUpdateError name, and on METADATA_CONFLICT, so none of them fires. The duplicate arm keys on the same two-part predicate inline and answers the literal UNIQUE_VIOLATION at 409.

Measured with a scratch probe over the built @objectstack/types (not committed). The arm answered 409 / "UNIQUE_VIOLATION" for all 9 accepted shapes: the engine's class with and without field, a plain object, a null-prototype object, a frozen Error declaring status: 400, and shapes also carrying currentVersion (string and null), dependentObject / dependentCount, or a non-string field with an empty message and object. The one shape that reaches the fallback is contrived: a code getter that answers DUPLICATE_RECORD to the predicate's read and something else to the arm's reads. So the thrown-code fallback (as in wireCodeOf) is unreachable for any value whose code and name are stable.

Measured before and after: each door's duplicate-record answer

Rig (scratch, not committed): a real ObjectQL over SqlDriver (better-sqlite3 :memory:), a real ObjectStackProtocolImplementation, and the BUILT dist/ of @objectstack/hono, @objectstack/runtime and @objectstack/plugin-hono-server. The doors are the real createHonoApp (app.request) and a real HonoHttpServer (a route through wrap(), and a raw mount through onError). The identity step (HttpDispatcher.prototype.timedResolveExecutionContext, answering a member) is the one stubbed seam. The object udoc declares email unique, and r1 holds the value.

  • Before: dist/ built at the base 3b46855fb (pnpm turbo run build --filter=@objectstack/hono..., all 32 tasks cache hits for that source).
  • After: dist/ rebuilt at e5ffc8248 (26 of 32 cached; the hono, plugin-hono-server and runtime builds re-ran). node scripts/ablation-dist-preflight.mjs found the new identifier duplicateArmCode in 2 built files of each package.
Door (site) Status Code error keys details keys Bytes
createHonoApp POST /api/v1/data/udoc repeating email (adapter) 409 UNIQUE_VIOLATION code, message, details developerMessage, object identical
HonoHttpServer route, engine.insert repeating email (adapter) 409 UNIQUE_VIOLATION code, message, details developerMessage, object identical
HonoHttpServer route, the engine's class with field: 'email' (adapter) 409 UNIQUE_VIOLATION code, message, details developerMessage, field, object identical
HonoHttpServer raw mount, engine.insert repeating email (adapter) 409 UNIQUE_VIOLATION code, message, details developerMessage, object identical
createHonoApp POST /api/v1/actions/udoc/add_duplicate, a handler write (dispatcher) 409 UNIQUE_VIOLATION code, message, httpStatus, details developerMessage, object identical
createHonoApp POST /api/v1/actions/udoc/take_email/r2, a declarative update (dispatcher) 409 UNIQUE_VIOLATION code, message, httpStatus, details developerMessage, object identical
createHonoApp POST /api/v1/actions/udoc/throw_named_duplicate, the class with field (dispatcher) 409 UNIQUE_VIOLATION code, message, httpStatus, details developerMessage, field, object identical
CONTROL: HonoHttpServer route, a producer speaking DUPLICATE_RECORD 409 DUPLICATE_RECORD code, message none identical
CONTROL: createHonoApp actions door, a producer speaking DUPLICATE_RECORD 409 DUPLICATE_RECORD code, message, httpStatus none identical
CONTROL: createHonoApp actions door, DELETE_RESTRICTED 409 DELETE_RESTRICTED code, message, httpStatus none identical

Two of the bodies, verbatim (the same bytes before and after):

  • createHonoApp POST /api/v1/data/udoc: 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"}}}
  • createHonoApp POST /api/v1/actions/udoc/add_duplicate: 409 {"success":false,"error":{"code":"UNIQUE_VIOLATION","message":"Duplicate record refused on 'udoc': a unique constraint already holds these values. No record was written.","httpStatus":409,"details":{"developerMessage":"Duplicate record refused on 'udoc': a unique constraint already holds these values. No record was written.","object":"udoc"}}}

The whole 12-line record (the 10 rows above plus two store checks: one row holds the value, and r2 keeps its own) is byte-identical before and after: cmp exit 0, sha256 3694fa2b2f02 on both files. No ablation was run, because no tested behaviour changed. The landed pins below, which were each measured red against the untranslated doors by their own PRs, are the discrimination.

Provenance gate (H3)

pnpm --filter @objectstack/spec check:error-code-provenance:

  • Before (base 3b46855fb): exit 0. scanned 2985 files; 379 registered-code stamp site(s): 360 listed, 19 waived and OK — every registered-code stamp site is listed under its own owner key or carries a recorded waiver (10 waiver(s), all live).
  • After (this head): exit 0, the same two lines.
  • --report, before and after: the UNIQUE_VIOLATION sites are the same four listed ones (@objectstack/driver-memory, @objectstack/driver-sql, and @objectstack/types twice). The only difference in the whole report is one @objectstack/runtime → PROJECT_MEMBERSHIP_REQUIRED site, whose line moved from http-dispatcher.ts:1759 to :1775 because of the added comment lines.

The gate could not see the two ternaries before, and there is nothing for it to see after. Its blindness is not changed here.

Tests

At the final head ea8db26da. Before opening, origin/main 2906cd8d2 was merged in (no conflict). Its three commits touch cli, driver-sql and metadata-protocol and none of the changed files here. Then the workspace was rebuilt (pnpm turbo run build --filter='!@objectstack/docs' --concurrency=2: 75 successful, 32 cached), packages/runtime/.objectstack was removed, and every line below was re-run there. The first pass at 20fb7e3d9 (on the base 3b46855fb) read the same counts.

  • pnpm --filter @objectstack/plugin-hono-server test: Test Files 29 passed (29), Tests 366 passed (366). This includes PR fix(plugin-hono-server): a Hono door answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23587) #23682's pins in handler-throw-declared-envelope.test.ts (Tests 49 passed (49) in a verbose re-run). All 12 rows of its [#23587] a repeated unique value answers 409 UNIQUE_VIOLATION on a Hono door block are green, unchanged: three doors, each with the engine's class with and without field and the two controls.
  • pnpm --filter @objectstack/plugin-hono-server typecheck: exit 0 (tsc twice and check:test-typecheck: OK, 0 debt).
  • pnpm --filter @objectstack/runtime test: Test Files 395 passed (395), Tests 5918 passed | 19 skipped (5937). That includes PR fix(runtime): the dispatcher answers the engine's DuplicateRecordError as 409 UNIQUE_VIOLATION, with the arm's fields (#23686) #23700's dispatcher-unique-violation-wire-code.test.ts, whose 7 rows are green, unchanged (Tests 7 passed (7) in a verbose re-run).
  • pnpm --filter @objectstack/runtime test:repo: Test Files 3 passed (3), Tests 808 passed (808).
  • pnpm --filter @objectstack/runtime typecheck: exit 0 (tsc --noEmit and check:test-typecheck: OK, the debt ledger unchanged).
  • pnpm exec eslint --no-inline-config packages/plugins/plugin-hono-server packages/runtime: exit 0, no output. A JSON-format run over the two changed files shows both linted, with 0 errors and 0 warnings. Repo-wide pnpm lint is CI's.

Both pin files import the door under test from source (./adapter, ./http-dispatcher.js), so they ran against this change without a rebuild.

Gates

At the final head ea8db26da:

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths: 60 commands derived from the 3 changed paths (merge base 2906cd8d2). All 60 ran, each exit code was recorded before any pipe, and all 60 exited 0.
  • --ran reconciliation: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero: all 60 recorded an exit code and none is 3).
  • Among them, all exit 0: pnpm check:dispatcher-error-vocabulary, pnpm check:route-envelope, pnpm check:error-status-conformance, pnpm check:test-source-alias, pnpm check:cross-package-test-inputs, pnpm check:nul-bytes, pnpm check:issue-citations, pnpm check:doc-authoring, pnpm check:published-files, pnpm check:dual-build-cjs-loads, check-adr-0087-registration, check-empty-changeset and check-changeset-no-major.
  • On the first pass at 20fb7e3d9, pnpm check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET, no workspace dist/). After a cache-backed full build under the verify lock it exited 0, and so did the four other dist/-reading gates re-run beside it. At the final head all 60 exited 0 on the first pass.
  • The five artifact-roster gates whose roster sits in a directory this diff touches, all exit 0 at the final head: node scripts/check-changeset-fixed.mjs, pnpm check:authz-resolver, pnpm check:error-code-casing, pnpm check:filter-alias-parity, pnpm check:route-ledger-census.
  • pnpm --filter @objectstack/spec check:error-code-provenance at the final head: exit 0, scanned 2986 files; 380 registered-code stamp site(s): 361 listed, 19 waived and the same OK line. The counts moved by one file and one site from the base reading above because of main's incoming driver-sql change. The UNIQUE_VIOLATION sites are still the same four listed ones.
  • Consumer suites: not owed and not run. No export, signature or wire byte changed, and the end-to-end doors above (createHonoApp over the rebuilt dist/) were measured directly.
  • Every family CI runs on this PR is reported on its check-runs.

Changeset

.changeset/23714-unique-violation-arm-relay.md, patch for @objectstack/plugin-hono-server and @objectstack/runtime. It says there is no behaviour change and describes the source-shape change. The dispatch left the call to the Check Changeset gate, and under this repo's rules the gate needs one:

  • Both packages' files[] ship dist/, and the rebuilt dist/ changed (the new identifier is in the built files, and the literal is gone). So this PR publishes changed bytes from two released packages, and skip-changeset (for a diff that publishes nothing) does not apply.
  • check-empty-changeset refuses an added empty-frontmatter changeset, so an empty one is not an option.
  • This dispatch writes no labels.

The changeset describes no behaviour change, because none happened.

Acceptance notes

  • At each site structuredCodeAnswer is now asked twice for the engine's class: once for the code, and once by the context helper. It is a pure function on an error path only. Passing the arm between them would change declaredArmContext's signature, which is out of this card's surface.
  • declaredArmContext (Hono) and duplicateArmContext (dispatcher) now carry the same agreement rule, status and code against the decided envelope. They stay two module-local functions, one per package, as the dispatch directed.
  • content/docs/releases/ is untouched. No docs edit: no published sentence names the literal at these sites.

Generated by Claude Code

…code off the shared arm instead of stamping the literal

Both doors that translate the engine's DuplicateRecordError to the ruled
wire spelling now read that code off structuredCodeAnswer's arm
(@objectstack/types), as @objectstack/mcp's wireCodeOf does, so neither
package spells a copy of UNIQUE_VIOLATION. The dispatcher's arm-agreement
check compares against the envelope's decided code, as the Hono doors'
does. The wire answer is unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FLwgbTSmGMrqsXkBDsiwfG
…ique-violation-arm-relay

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FLwgbTSmGMrqsXkBDsiwfG
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Oct 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/plugin-hono-server, @objectstack/runtime, touching 5 documentable anchor(s).

8 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/api/environment-routing.mdx (via HttpDispatcher (symbol, a top-level class))
  • content/docs/api/error-catalog.mdx (via UNIQUE_VIOLATION (literal, a string literal in declaredEnvelopeForThrow; a string literal in duplicateArmContext; a string literal in errorFromThrown))
  • content/docs/automation/webhooks.mdx (via HttpDispatcher (symbol, a top-level class))
  • content/docs/data-modeling/drivers.mdx (via UNIQUE_VIOLATION (literal, a string literal in declaredEnvelopeForThrow; a string literal in duplicateArmContext; a string literal in errorFromThrown))
  • content/docs/kernel/cluster.mdx (via HttpDispatcher (symbol, a top-level class))
  • content/docs/plugins/packages.mdx (via HttpDispatcher (symbol, a top-level class))
  • content/docs/protocol/kernel/error-handling.mdx (via declaredEnvelopeForThrow (symbol, a top-level function), UNIQUE_VIOLATION (literal, a string literal in declaredEnvelopeForThrow; a string literal in duplicateArmContext; a string literal in errorFromThrown))
  • content/docs/protocol/kernel/http-protocol.mdx (via UNIQUE_VIOLATION (literal, a string literal in declaredEnvelopeForThrow; a string literal in duplicateArmContext; a string literal in errorFromThrown))

⛔ 4 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v17/17-3.mdx (via UNIQUE_VIOLATION (literal, a string literal in declaredEnvelopeForThrow; a string literal in duplicateArmContext; a string literal in errorFromThrown))
  • content/docs/releases/v17/17-4.mdx (via UNIQUE_VIOLATION (literal, a string literal in declaredEnvelopeForThrow; a string literal in duplicateArmContext; a string literal in errorFromThrown))
  • content/docs/releases/v17/17-5.mdx (via HttpDispatcher (symbol, a top-level class), UNIQUE_VIOLATION (literal, a string literal in declaredEnvelopeForThrow; a string literal in duplicateArmContext; a string literal in errorFromThrown))
  • content/docs/releases/v17/17-6.mdx (via UNIQUE_VIOLATION (literal, a string literal in declaredEnvelopeForThrow; a string literal in duplicateArmContext; a string literal in errorFromThrown))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 27 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 140238a47b892ef9234052e44267ec3739fa79c2 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 47c6fce64718d82f4fd9a733e0ff586bf9fa49bb — the merge of head ea8db26da26920af1f10f43f6f154ee9a25951d4 into base 140238a47b892ef9234052e44267ec3739fa79c2, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 47c6fce64718d82f4fd9a733e0ff586bf9fa49bb && git checkout 47c6fce64718d82f4fd9a733e0ff586bf9fa49bb
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 140238a47b892ef9234052e44267ec3739fa79c2 ea8db26da26920af1f10f43f6f154ee9a25951d4 && git checkout -B drift-repro 140238a47b892ef9234052e44267ec3739fa79c2 && git merge --no-ff ea8db26da26920af1f10f43f6f154ee9a25951d4

node scripts/docs-audit/affected-docs.mjs --json 140238a47b892ef9234052e44267ec3739fa79c2

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 140238a47b892ef9234052e44267ec3739fa79c2 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

✅ ACCEPT: PR #23760 at ea8db26da (#23714, Fixes #23714). It queues once its head is true-green; no contract review is owed

domain:cli seat 1 (#6024) · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG · 2026-10-16T00:36Z · holder of claim 6204167058. Report: os-dev-report 6205271840.

席位核对

  1. Shape, read on GitHub:
    • Draft against main, head ea8db26da. Line 1 is Fixes #23714, the only closing keyword. Line 2 is a bare Clause-②: no. Assignee os-bill.
    • Files: 3, +52 / −14. check-governed-merges --pr 23760: NOT governed (0 of 3 paths). No content/docs/releases/ change. All three commits, the merge of main (2906cd8d2) included, carry the model-free trailer pair.
    • git merge-tree against origin/main 140238a47b is clean.
  2. The change, read against the diff:
    • declaredEnvelopeForThrow (plugin-hono-server) and HttpDispatcher.errorFromThrown (runtime) take the code for the engine's duplicate class off structuredCodeAnswer(thrown)?.body.code, falling back to the resolved code only when the arm answers no string. That is wireCodeOf's shape in @objectstack/mcp.
    • duplicateArmContext now requires the arm to agree with the envelope's own { status, code }, the rule declaredArmContext states at the Hono doors. Because the code is the arm's, the comparison holds exactly when the old literal comparison did.
    • Census, re-run by the seat at the head: no 'UNIQUE_VIOLATION' literal remains in either package's non-test source, stamp or read.
    • ⛔ No packages/spec and no packages/types edit, as ruled.
  3. Measured, not read: the dev drove the built dists of @objectstack/hono, @objectstack/runtime and @objectstack/plugin-hono-server over a real SqlDriver. The twelve-row record (both Hono doors, the raw mount, three action-door shapes, and three controls that keep DUPLICATE_RECORD or DELETE_RESTRICTED) is byte-identical before, after, and after the merge (cmp exit 0). check:error-code-provenance is exit 0 before and after, with the same four UNIQUE_VIOLATION sites listed.
  4. The fallback branch: unreachable for any value whose code and name reads are stable (nine accepted shapes all answered 409 UNIQUE_VIOLATION). Accepted as the same defensive branch wireCodeOf carries.
  5. Deviations, each accepted:
    • A patch changeset that states no behaviour change. Check Changeset needs an added changeset without a skip label, check-empty-changeset refuses an empty one, and both packages ship dist, whose bytes changed. Checked sentence by sentence: the "No behaviour change" paragraph matches the byte-compared record, and the "What changed" paragraph matches the diff, including that DuplicateRecordError.code is still DUPLICATE_RECORD.
    • The trailer pair, and the re-wrapped docblock lines beside the two edits, are in order.
  6. Clause-②: no holds: a source-shape change with the wire answer byte-identical. No contract-review face is touched: under contract-review.md, CI plus this seat's reading.
  7. Out of scope: none reported.
  8. CI on ea8db26da, read in this act: every completed run is success or an expected skip, Check Changeset included. Lint & Repo Gates, both Type Check workspace and consumer gates, and Test Core 1 to 6 of 6 are in_progress, with no failure.

Landing: once every check on ea8db26da is green, the seat marks the PR ready and arms auto-merge. Fixes #23714 closes the card when it merges.


Generated by Claude Code

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

Labels

documentation Improvements or additions to documentation size/s tooling

Projects

None yet

2 participants