Skip to content

docs(rest): qualify the three residual ADR-0112 citations to the code axis - #12700

Merged
os-litant merged 1 commit into
mainfrom
claude/issue-12454-adr-0112-citation-qualifiers
Aug 27, 2026
Merged

docs(rest): qualify the three residual ADR-0112 citations to the code axis#12700
os-litant merged 1 commit into
mainfrom
claude/issue-12454-adr-0112-citation-qualifiers

Conversation

@os-litant

@os-litantos-litant commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Fixes#12454

PR #12453 qualified nine ADR-0112 citation sites to the code axis. Three still carried the
unqualified attribution — one was fenced by an in-flight PR when it was measured, two sat
outside that card's declared file surface. This is the other half, and all three land together.

Each site now echoes the form error-response.ts's resolveThrownHttpError docblock states
once in full: ADR-0112 D4 governs the semantic-CODE channel — the producer names the
condition on the CODE axis, and the ADR rules no HTTP status for an undeclared throw
— with a
pointer to that docblock for why the phrase is that file's own prose and not an ADR quotation.
No fourth wording is introduced. Amending ADR-0112 itself stays out of scope (governed
docs/adr/** maintainer path), and the qualification holds under either outcome of that open
question.

The census: the wrap-tolerant grep is a candidate pool, not a worklist

Measured on my own ref — origin/main @ 2805e5299, branch head d2f8ef944. No line numbers
were reused from the card or from triage; both sets had drifted.

# pool (the card's wrap-tolerant form — the contiguous form cannot see a wrapped comment)
git grep -n -iE "producer names|names the condition" -- '*.ts'
verdicthitswhat they are
already QUALIFIED9left untouched — includes rest-hook-refusal-message-parity.test.ts:630, the canonical form from #12280
NOT A CITATION2the regex matching other prose: package-door-declared-code.test.ts:337 describes a producer shape; service-analytics/.../objectql-strategy.ts:693 uses "names" in an unrelated sense ("a key no older producer names")
UNQUALIFIED3the residue — the only lines this PR touches
pool total14across 13 files (9 + 2 + 3 = 14)

The three sites changed, at the ref above:

  • packages/rest/src/rest-sandbox-declared-status.test.ts:130
  • packages/rest/src/rest-server.ts:9651
  • packages/rest/src/rest.test.ts:2486

For contrast at the same ref, the contiguous form the card marks as under-counting returns 6
lines in 6 files — it sees neither rest-sandbox-declared-status.test.ts nor rest.test.ts,
both of which wrap the phrase across a comment line boundary.

How the verdicts are recomputable

Each pool hit is judged over a +/-8 line window: no ADR-0112 in the window ⇒ NOT A CITATION;
otherwise a window naming the axis (CODE axis, semantic-CODE channel, own prose,
rules no HTTP status, ruled the status axis) ⇒ QUALIFIED; else UNQUALIFIED. The classifier
is calibrated in both directions: forcing the qualifier marker absent drives all 12
citations to UNQUALIFIED, forcing it always-present drives all 12 to QUALIFIED — so neither
verdict is an artifact of a dead branch.

After the fix, the same grep and the same classifier: pool still 14 hits / 13 files
(nothing added, nothing deleted), NOT A CITATION still 2, UNQUALIFIED 0, QUALIFIED 12.
Positive control for that zero: with the marker forced absent the same post-fix run still
reports 12 UNQUALIFIED, so the branch that would report a miss is still live.

The pool is complete, and the out-of-scope idiom never enters it

A fully multiline regex (producer[\s*/#]*names[\s*/#]*the[\s*/#]*condition, slurped per file,
so the phrase is caught under any wrapping) hits 11 files, every one already inside the
13-file pool, and no file outside it. Positive control: the same harness with a term known
present (ADR-0112) returns 509 files.

The "ADR-0112 envelope (code + status)" idiom is explicitly a different usage and was not
swept: it measures 314 lines across 223 files, and its intersection with the pool is 0 lines
— it is disjoint from the pool's regex, not merely excluded by judgement. Positive control for
that zero: pool intersected with itself returns 14.

Comment-only, proven

removeComments transpile (typescript 6.0.3) of each file before and after, sha256 over the
emitted JS:

EMIT-IDENTICAL packages/rest/src/rest-sandbox-declared-status.test.ts 76af7bef73763965
EMIT-IDENTICAL packages/rest/src/rest-server.ts 774981d9210f4c00
EMIT-IDENTICAL packages/rest/src/rest.test.ts b7d27ac160f34d8a

Instrument calibrated per file, both directions: appending a comment token leaves the hash
unmoved; appending const __calibration_token = 1; moves it. All three edits are // comment
text — none is a string literal or a test title.

Verification

19 gate families run at d2f8ef944, each exit code captured before any pipe, all green:
check:nul-bytes, check-comment-mask-adoption.mjs, check:route-envelope,
check:dispatcher-error-vocabulary, check:engine-double-contract, check:where-matcher,
check:test-source-alias, check:cross-package-test-inputs, check:objectql-double-limit,
check:authz-resolver, check:page-declaration-shape, check:published-files,
check:slot-lookup, check:type-source-resolution, check:query-options-erasure,
check:type-check-coverage, check-ci-filter-parity.mjs, check-plugin-teardown-shape.mjs,
docs-audit/check-affected-docs.mjs. Family list derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled. Every
heavy run went through scripts/pm/os-verify-lock.sh.

Declared narrowing — the suite and the repo-wide lint.packages/rest's suite and
check:type-check-debt need a 25-package build closure, and on this diff they can only
re-measure origin/main: the emitted JS is byte-identical (above), and the diff adds or removes
0 compiler/lint directive comments (@ts-expect-error, @ts-ignore, @ts-nocheck,
triple-slash reference directives, eslint-disable, prettier-ignore, …) — positive
controls: the same regex matches 136 files in the tree and matches a synthetic planted line.
pnpm lint (eslint . --no-inline-config) was narrowed to the three files: eslint's own config
linted all 3 (none ignored), 0 errors / 0 warnings, and this repo's single eslint.config.mjs
never enables type-aware linting for any file (its own comment at line 328 records the
measurement), so a comment-only diff cannot move the verdict of a file it does not touch. CI
runs both farms in full regardless.

No changeset: comment text only, nothing released — skip-changeset applies.

Generated by Claude Code

… axis
PR #12453 qualified nine sites; three carried the unqualified attribution
still — one because it was fenced by an in-flight PR at the time, two
because they sat outside that card's declared file surface.
Each now echoes the form `error-response.ts`'s docblock states in full:
ADR-0112 D4 governs the semantic-CODE channel, the producer names the
condition on the CODE axis, and the ADR rules no HTTP status for an
undeclared throw. Comment text only — the emitted JS is byte-identical
under a `removeComments` transpile.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️1 changed file(s) yielded no anchor (packages/rest/src/rest-server.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/rest/src/rest-server.ts) — pages documenting those are invisible to this run
  • 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.

Coarse fallback — 13 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 3e8f5b05d671e6e55d3ea51656affd4b80877bd9packageMentionDocs.

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

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

2 participants

@os-litant@claude