feat(devx): reach the INLINE literal expression at an object-literal code: - #14625

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape
Sep 2, 2026
Merged

feat(devx): reach the INLINE literal expression at an object-literal code:#14625
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape

Conversation

@claude

@claudeclaudeBot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes#13790

scripts/check-dispatcher-error-vocabulary.mjs reached no INLINE literal expression at an object-literal code: — a ternary, or a ||/?? chain, written at the stamp itself with every branch already a literal. That is no site AND no unresolved, the one way the gate's own "REPORTED as unresolved, never dropped" bound cannot notice itself failing, in a third stamp position after #9223's code: CONST and #13233's { code } helper.

This adds the fifth object-literal shape, objlitexpr. Per the triage's ⭐ it needs no resolver: literalCodeValues already reduces the expression, so the shape is the reduction of the value text between code: and the property's terminating top-level comma.

The precision measurement, first

The triage refused to authorise the widening until the precision cost was measured (objlithelper reaches 65 type annotations per value stamp). It was measured over the gate's own population — packages/** non-test source, 2186 files — with the gate's own primitives, before the shape was written. The finding: the ALL-OR-NOTHING reduction is the guard. A type annotation reduces to nothing for the same reason a runtime expression does, so it costs a continue and no verdict row.

code: tokens in the population902
reached by the shape's regex (a bare quoted literal is refused — see below)346
① rejected: enclosing bracket is not { (41 parameter lists, 33 inside a string)74
② rejected: already objlit's (4), objlitconst's (40), objlittemplate's (3)47
② rejected: a bare identifier (objlithelper's candidate / #13478's remainder)9
③ rejected: a CONDITIONAL type (code: T extends X ? 'A' : 'B')0
reaching the reduction216
declined by ALL-OR-NOTHING (~150 of them type annotations, ~64 runtime)214
true positions2
type-annotation positions surviving every guard0
distinct values behind the true positions5
verdict rows owed2
unregistered WIRE codes hiding0

⇒ preventive, not a live defect — the same disposition and evidence standard #13478 and #13233 were closed on. Every figure is frozen in INLINE_LITERAL_EXPRESSION_CENSUS, printed on every run in the bounds line, and its arithmetic is pinned by --self-test.

Every position reached, with its classification

  • packages/rest/src/error-response.ts:1250code: isProvisioning ? 'PROJECT_PROVISIONING' : isFailed ? 'PROJECT_PROVISIONING_FAILED' : 'PROJECT_NOT_FOUND'. All three are in ERROR_CODE_LEDGER, so the scan derives no site and owes no row. This is the REST door file, stamped straight into an HTTP error envelope's body.code — registered today, and now no longer invisible to the gate tomorrow.
  • packages/runtime/src/domains/automation.ts:1125code: body.name === undefined ? 'required' : 'invalid_type'. An ADR-0112 D6 field-addressed validation catalog reaching details.fields[].code, never error.code. Two rows, foreign-vocabulary / door: 'none'.
  • The other 214 candidates all decline at the reduction: type annotations (code: string | undefined, code: FieldErrorCode, code?: 'a' | 'b') and runtime expressions (code: typeof issue.code === 'string' ? issue.code : 'unknown').

Where the lowercase catalog is reported, and why — measured, not assumed

The shape carries lowercase: 'here'. Every pattern check:error-code-casing has needs a quoted literal beside the token code; at an inline ternary there is none. Measured: findViolations() returns 0 findings for domains/automation.ts, while the literally-spelled code: 'invalid_type' a few lines up it does see and correctly skips as D6. That gate's own verdict text says the same thing from its side — "a code value with NO literal at the position — a constant, a template, a ternary, a helper parameter — is out of reach for every pattern here by construction; that half belongs to check:dispatcher-error-vocabulary". So a casing-gate delegation here would be the seam the gate's header describes, not a hand-off. --self-test pins this against that gate's real detector rather than against this paragraph. ⛔ check-error-code-casing.mjs is untouched.

Two deliberate boundaries, declared rather than discovered later

  • The anchor is the strict code:, not objlithelper's code\s*:\s*. Measured: the loose spelling matches the colon of a ternary, so typeof issue.code === 'string' ? issue.code : 'unknown' reads as a code : stamp of 'unknown' — a false position with no structural tell. objlithelper can afford the loose anchor because its parameter guard rejects that; this shape's guard is the reduction, which accepts it.
  • The regex refuses a bare quoted literal ((?!\s*'[^']*'\s*[,;}\n])). [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 pins the kebab-diagnostic declaration by counting recognizer matches, not findings; a bare code: anchor matchescode: 'unknown-component' even though every guard then declines it, and that reds the kebab pin. A bare literal is objlit's anyway. The cost is one declared remainder: a chain whose first operand is a bare quoted literal (code: 'A' || 'B') is handed to objlit, which reports 'A' and not 'B' — partial reporting rather than silence, zero live instances, counted as chainWhoseFirstOperandIsABareLiteral and pinned.

Ablation — every guard proved to fail

Run from a committed tree; each leg proved on disk by blob hash before/after, restored to the HEAD blob and verified equal, with a trap on EXIT/INT/TERM.

ablated--self-testwhat it said
the objlitexpr SHAPES entryexit 1SHAPE 'objlitexpr' matched nothing in its own sample + the nested-ternary pin
the sibling OWNERSHIP guardexit 1one stamp reported under two shape names
the CONDITIONAL-TYPE guardexit 1a CONDITIONAL type at a code: derived ["INLINE_A","INLINE_B"]
the enclosing-BRACKET testexit 1a code: in a function PARAMETER LIST derived ["INLINE_PARAM_A","INLINE_PARAM_B"]

⚠️ Two of these are only honest because the first attempt was not. The bracket-guard ablation initially sat green: the pin used (code: number | null, signal), whose value text the reduction declines anyway — a pin measuring nothing. It now uses a parameter default (code: string = down ? 'A' : 'B'), a value expression only the bracket rejects. And the bare-identifier partition is documented as what it is: with no resolver it changes no output today, so it is declared as a reader-facing statement of the partition rather than as a guard an ablation can see.

What is NOT here

Known limitation found on the way (filed, not fixed here)

The gate's shared textual scanners (enclosingOpeners, sliceBalanced, scanTopLevel) skip a string by seeking its closing quote, so a nested template literal `a ${xs.map((k) => `\`${k}\).join(', ')} b`` — closes the outer template at the first inner backtick and desynchronises everycode:position after it in that file.domains/automation.tscarries one at line 1285, and **two further instances of the identical catalog ternary** (the clone door'snameandlabelchecks,:1384and:1399) sit behind it, invisible to guard ①. Same values, same verdict, so the zero for hidden wire codes is unaffected — but the position count is a floor, not a total. Pre-existing and shared with objlithelper, recorded in the census and in the invalid_type` row rather than repaired inside a shape widening.

Verification

git diff --stat origin/main..HEAD — 2 files, exactly the declared surface:

 packages/runtime/src/dispatcher-error-vocabulary.ts | 83 ++-
scripts/check-dispatcher-error-vocabulary.mjs | 675 +++++++++++++++++++-
2 files changed, 753 insertions(+), 5 deletions(-)

Changeset

skip-changeset. The diff is one gate script plus packages/runtime/src/dispatcher-error-vocabulary.ts, which is a declaration table read textually by the gate and by tests: nothing in packages/runtime/src imports it, it is not re-exported from src/index.ts, and the package publishes only . — so no published bytes change. If a reviewer reads that differently, a changeset is cheap to add.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV


Generated by Claude Code

…`code:`
The vocabulary gate reached a `code:` whose value is a quoted literal
(`objlit`), a SCREAMING_SNAKE constant (`objlitconst`), a template
(`objlittemplate`) or a helper parameter (`objlithelper`), but not an INLINE
literal EXPRESSION — a ternary or a `||`/`??` chain written at the stamp with
every branch already a literal. That is no site AND no unresolved: the one way
the gate's "REPORTED as unresolved, never dropped" bound cannot notice itself
failing, in a third stamp position.
Adds the fifth object-literal shape, `objlitexpr`. It needs no resolver —
`literalCodeValues` reduces the value text between `code:` and the property's
terminating top-level comma directly, and `resolveIdent` is left at its default
so an identifier limb keeps the expression unreducible, which is what keeps this
shape out of the lower-case-LOCAL position that stays censused and open.
Precision measured BEFORE implementing, over the gate's own population: of 902
`code:` tokens the shape reaches 346, three guards reject 130, 216 reach the
reduction and 214 decline — including every type annotation — leaving 2 live
positions, 5 values, 2 verdict rows and 0 unregistered wire codes hiding. The
ALL-OR-NOTHING reduction IS the guard against the type-annotation noise the
helper position pays per value stamp. Frozen in
INLINE_LITERAL_EXPRESSION_CENSUS, printed in the bounds line, arithmetic pinned.
The two rows the widening owes land in the same commit, after the widening,
because the reconciliation runs in both directions: the ADR-0112 D6
field-addressed validation catalog in `domains/automation.ts`. They are reported
here rather than delegated to check:error-code-casing because that gate needs a
quoted literal beside the token `code` and an inline ternary has none —
measured, and pinned against its real detector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/runtime, touching 5 documentable anchor(s).

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

  • content/docs/api/error-catalog.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/api/error-handling-server.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/deployment/cli.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/protocol/objectui/concept.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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

  • content/docs/releases/v17.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 24 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21fpackageMentionDocs.

Which tree this was computed on

This run read content/docs from fe7200da54d381d2c79d8544c2737f8478bc7139 — the merge of head 8a10049e48beaa67589d72c742355f2a55bc29ae into base 87ad30c103bb4e8c5d7b8a399634b59716f3c21f, 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 fe7200da54d381d2c79d8544c2737f8478bc7139 && git checkout fe7200da54d381d2c79d8544c2737f8478bc7139
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87ad30c103bb4e8c5d7b8a399634b59716f3c21f 8a10049e48beaa67589d72c742355f2a55bc29ae && git checkout -B drift-repro 87ad30c103bb4e8c5d7b8a399634b59716f3c21f && git merge --no-ff 8a10049e48beaa67589d72c742355f2a55bc29ae
node scripts/docs-audit/affected-docs.mjs --json 87ad30c103bb4e8c5d7b8a399634b59716f3c21f

⚠️ 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

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

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] An INLINE literal ternary at an object-literal code: is reached by no vocabulary shape — the third stamp position, censused at zero

2 participants

@baozhoutao@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(devx): reach the INLINE literal expression at an object-literal code: - #14625

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape
Sep 2, 2026
Merged

feat(devx): reach the INLINE literal expression at an object-literal code:#14625
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape

Conversation

@claude

@claudeclaudeBot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes#13790

scripts/check-dispatcher-error-vocabulary.mjs reached no INLINE literal expression at an object-literal code: — a ternary, or a ||/?? chain, written at the stamp itself with every branch already a literal. That is no site AND no unresolved, the one way the gate's own "REPORTED as unresolved, never dropped" bound cannot notice itself failing, in a third stamp position after #9223's code: CONST and #13233's { code } helper.

This adds the fifth object-literal shape, objlitexpr. Per the triage's ⭐ it needs no resolver: literalCodeValues already reduces the expression, so the shape is the reduction of the value text between code: and the property's terminating top-level comma.

The precision measurement, first

The triage refused to authorise the widening until the precision cost was measured (objlithelper reaches 65 type annotations per value stamp). It was measured over the gate's own population — packages/** non-test source, 2186 files — with the gate's own primitives, before the shape was written. The finding: the ALL-OR-NOTHING reduction is the guard. A type annotation reduces to nothing for the same reason a runtime expression does, so it costs a continue and no verdict row.

code: tokens in the population902
reached by the shape's regex (a bare quoted literal is refused — see below)346
① rejected: enclosing bracket is not { (41 parameter lists, 33 inside a string)74
② rejected: already objlit's (4), objlitconst's (40), objlittemplate's (3)47
② rejected: a bare identifier (objlithelper's candidate / #13478's remainder)9
③ rejected: a CONDITIONAL type (code: T extends X ? 'A' : 'B')0
reaching the reduction216
declined by ALL-OR-NOTHING (~150 of them type annotations, ~64 runtime)214
true positions2
type-annotation positions surviving every guard0
distinct values behind the true positions5
verdict rows owed2
unregistered WIRE codes hiding0

⇒ preventive, not a live defect — the same disposition and evidence standard #13478 and #13233 were closed on. Every figure is frozen in INLINE_LITERAL_EXPRESSION_CENSUS, printed on every run in the bounds line, and its arithmetic is pinned by --self-test.

Every position reached, with its classification

  • packages/rest/src/error-response.ts:1250code: isProvisioning ? 'PROJECT_PROVISIONING' : isFailed ? 'PROJECT_PROVISIONING_FAILED' : 'PROJECT_NOT_FOUND'. All three are in ERROR_CODE_LEDGER, so the scan derives no site and owes no row. This is the REST door file, stamped straight into an HTTP error envelope's body.code — registered today, and now no longer invisible to the gate tomorrow.
  • packages/runtime/src/domains/automation.ts:1125code: body.name === undefined ? 'required' : 'invalid_type'. An ADR-0112 D6 field-addressed validation catalog reaching details.fields[].code, never error.code. Two rows, foreign-vocabulary / door: 'none'.
  • The other 214 candidates all decline at the reduction: type annotations (code: string | undefined, code: FieldErrorCode, code?: 'a' | 'b') and runtime expressions (code: typeof issue.code === 'string' ? issue.code : 'unknown').

Where the lowercase catalog is reported, and why — measured, not assumed

The shape carries lowercase: 'here'. Every pattern check:error-code-casing has needs a quoted literal beside the token code; at an inline ternary there is none. Measured: findViolations() returns 0 findings for domains/automation.ts, while the literally-spelled code: 'invalid_type' a few lines up it does see and correctly skips as D6. That gate's own verdict text says the same thing from its side — "a code value with NO literal at the position — a constant, a template, a ternary, a helper parameter — is out of reach for every pattern here by construction; that half belongs to check:dispatcher-error-vocabulary". So a casing-gate delegation here would be the seam the gate's header describes, not a hand-off. --self-test pins this against that gate's real detector rather than against this paragraph. ⛔ check-error-code-casing.mjs is untouched.

Two deliberate boundaries, declared rather than discovered later

  • The anchor is the strict code:, not objlithelper's code\s*:\s*. Measured: the loose spelling matches the colon of a ternary, so typeof issue.code === 'string' ? issue.code : 'unknown' reads as a code : stamp of 'unknown' — a false position with no structural tell. objlithelper can afford the loose anchor because its parameter guard rejects that; this shape's guard is the reduction, which accepts it.
  • The regex refuses a bare quoted literal ((?!\s*'[^']*'\s*[,;}\n])). [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 pins the kebab-diagnostic declaration by counting recognizer matches, not findings; a bare code: anchor matchescode: 'unknown-component' even though every guard then declines it, and that reds the kebab pin. A bare literal is objlit's anyway. The cost is one declared remainder: a chain whose first operand is a bare quoted literal (code: 'A' || 'B') is handed to objlit, which reports 'A' and not 'B' — partial reporting rather than silence, zero live instances, counted as chainWhoseFirstOperandIsABareLiteral and pinned.

Ablation — every guard proved to fail

Run from a committed tree; each leg proved on disk by blob hash before/after, restored to the HEAD blob and verified equal, with a trap on EXIT/INT/TERM.

ablated--self-testwhat it said
the objlitexpr SHAPES entryexit 1SHAPE 'objlitexpr' matched nothing in its own sample + the nested-ternary pin
the sibling OWNERSHIP guardexit 1one stamp reported under two shape names
the CONDITIONAL-TYPE guardexit 1a CONDITIONAL type at a code: derived ["INLINE_A","INLINE_B"]
the enclosing-BRACKET testexit 1a code: in a function PARAMETER LIST derived ["INLINE_PARAM_A","INLINE_PARAM_B"]

⚠️ Two of these are only honest because the first attempt was not. The bracket-guard ablation initially sat green: the pin used (code: number | null, signal), whose value text the reduction declines anyway — a pin measuring nothing. It now uses a parameter default (code: string = down ? 'A' : 'B'), a value expression only the bracket rejects. And the bare-identifier partition is documented as what it is: with no resolver it changes no output today, so it is declared as a reader-facing statement of the partition rather than as a guard an ablation can see.

What is NOT here

Known limitation found on the way (filed, not fixed here)

The gate's shared textual scanners (enclosingOpeners, sliceBalanced, scanTopLevel) skip a string by seeking its closing quote, so a nested template literal `a ${xs.map((k) => `\`${k}\).join(', ')} b`` — closes the outer template at the first inner backtick and desynchronises everycode:position after it in that file.domains/automation.tscarries one at line 1285, and **two further instances of the identical catalog ternary** (the clone door'snameandlabelchecks,:1384and:1399) sit behind it, invisible to guard ①. Same values, same verdict, so the zero for hidden wire codes is unaffected — but the position count is a floor, not a total. Pre-existing and shared with objlithelper, recorded in the census and in the invalid_type` row rather than repaired inside a shape widening.

Verification

git diff --stat origin/main..HEAD — 2 files, exactly the declared surface:

 packages/runtime/src/dispatcher-error-vocabulary.ts | 83 ++-
scripts/check-dispatcher-error-vocabulary.mjs | 675 +++++++++++++++++++-
2 files changed, 753 insertions(+), 5 deletions(-)

Changeset

skip-changeset. The diff is one gate script plus packages/runtime/src/dispatcher-error-vocabulary.ts, which is a declaration table read textually by the gate and by tests: nothing in packages/runtime/src imports it, it is not re-exported from src/index.ts, and the package publishes only . — so no published bytes change. If a reviewer reads that differently, a changeset is cheap to add.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV


Generated by Claude Code

…`code:`
The vocabulary gate reached a `code:` whose value is a quoted literal
(`objlit`), a SCREAMING_SNAKE constant (`objlitconst`), a template
(`objlittemplate`) or a helper parameter (`objlithelper`), but not an INLINE
literal EXPRESSION — a ternary or a `||`/`??` chain written at the stamp with
every branch already a literal. That is no site AND no unresolved: the one way
the gate's "REPORTED as unresolved, never dropped" bound cannot notice itself
failing, in a third stamp position.
Adds the fifth object-literal shape, `objlitexpr`. It needs no resolver —
`literalCodeValues` reduces the value text between `code:` and the property's
terminating top-level comma directly, and `resolveIdent` is left at its default
so an identifier limb keeps the expression unreducible, which is what keeps this
shape out of the lower-case-LOCAL position that stays censused and open.
Precision measured BEFORE implementing, over the gate's own population: of 902
`code:` tokens the shape reaches 346, three guards reject 130, 216 reach the
reduction and 214 decline — including every type annotation — leaving 2 live
positions, 5 values, 2 verdict rows and 0 unregistered wire codes hiding. The
ALL-OR-NOTHING reduction IS the guard against the type-annotation noise the
helper position pays per value stamp. Frozen in
INLINE_LITERAL_EXPRESSION_CENSUS, printed in the bounds line, arithmetic pinned.
The two rows the widening owes land in the same commit, after the widening,
because the reconciliation runs in both directions: the ADR-0112 D6
field-addressed validation catalog in `domains/automation.ts`. They are reported
here rather than delegated to check:error-code-casing because that gate needs a
quoted literal beside the token `code` and an inline ternary has none —
measured, and pinned against its real detector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/runtime, touching 5 documentable anchor(s).

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

  • content/docs/api/error-catalog.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/api/error-handling-server.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/deployment/cli.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/protocol/objectui/concept.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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

  • content/docs/releases/v17.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 24 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21fpackageMentionDocs.

Which tree this was computed on

This run read content/docs from fe7200da54d381d2c79d8544c2737f8478bc7139 — the merge of head 8a10049e48beaa67589d72c742355f2a55bc29ae into base 87ad30c103bb4e8c5d7b8a399634b59716f3c21f, 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 fe7200da54d381d2c79d8544c2737f8478bc7139 && git checkout fe7200da54d381d2c79d8544c2737f8478bc7139
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87ad30c103bb4e8c5d7b8a399634b59716f3c21f 8a10049e48beaa67589d72c742355f2a55bc29ae && git checkout -B drift-repro 87ad30c103bb4e8c5d7b8a399634b59716f3c21f && git merge --no-ff 8a10049e48beaa67589d72c742355f2a55bc29ae
node scripts/docs-audit/affected-docs.mjs --json 87ad30c103bb4e8c5d7b8a399634b59716f3c21f

⚠️ 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

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

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] An INLINE literal ternary at an object-literal code: is reached by no vocabulary shape — the third stamp position, censused at zero

2 participants

@baozhoutao@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(devx): reach the INLINE literal expression at an object-literal code: - #14625

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape
Sep 2, 2026
Merged

feat(devx): reach the INLINE literal expression at an object-literal code:#14625
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape

Conversation

@claude

@claudeclaudeBot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes#13790

scripts/check-dispatcher-error-vocabulary.mjs reached no INLINE literal expression at an object-literal code: — a ternary, or a ||/?? chain, written at the stamp itself with every branch already a literal. That is no site AND no unresolved, the one way the gate's own "REPORTED as unresolved, never dropped" bound cannot notice itself failing, in a third stamp position after #9223's code: CONST and #13233's { code } helper.

This adds the fifth object-literal shape, objlitexpr. Per the triage's ⭐ it needs no resolver: literalCodeValues already reduces the expression, so the shape is the reduction of the value text between code: and the property's terminating top-level comma.

The precision measurement, first

The triage refused to authorise the widening until the precision cost was measured (objlithelper reaches 65 type annotations per value stamp). It was measured over the gate's own population — packages/** non-test source, 2186 files — with the gate's own primitives, before the shape was written. The finding: the ALL-OR-NOTHING reduction is the guard. A type annotation reduces to nothing for the same reason a runtime expression does, so it costs a continue and no verdict row.

code: tokens in the population902
reached by the shape's regex (a bare quoted literal is refused — see below)346
① rejected: enclosing bracket is not { (41 parameter lists, 33 inside a string)74
② rejected: already objlit's (4), objlitconst's (40), objlittemplate's (3)47
② rejected: a bare identifier (objlithelper's candidate / #13478's remainder)9
③ rejected: a CONDITIONAL type (code: T extends X ? 'A' : 'B')0
reaching the reduction216
declined by ALL-OR-NOTHING (~150 of them type annotations, ~64 runtime)214
true positions2
type-annotation positions surviving every guard0
distinct values behind the true positions5
verdict rows owed2
unregistered WIRE codes hiding0

⇒ preventive, not a live defect — the same disposition and evidence standard #13478 and #13233 were closed on. Every figure is frozen in INLINE_LITERAL_EXPRESSION_CENSUS, printed on every run in the bounds line, and its arithmetic is pinned by --self-test.

Every position reached, with its classification

  • packages/rest/src/error-response.ts:1250code: isProvisioning ? 'PROJECT_PROVISIONING' : isFailed ? 'PROJECT_PROVISIONING_FAILED' : 'PROJECT_NOT_FOUND'. All three are in ERROR_CODE_LEDGER, so the scan derives no site and owes no row. This is the REST door file, stamped straight into an HTTP error envelope's body.code — registered today, and now no longer invisible to the gate tomorrow.
  • packages/runtime/src/domains/automation.ts:1125code: body.name === undefined ? 'required' : 'invalid_type'. An ADR-0112 D6 field-addressed validation catalog reaching details.fields[].code, never error.code. Two rows, foreign-vocabulary / door: 'none'.
  • The other 214 candidates all decline at the reduction: type annotations (code: string | undefined, code: FieldErrorCode, code?: 'a' | 'b') and runtime expressions (code: typeof issue.code === 'string' ? issue.code : 'unknown').

Where the lowercase catalog is reported, and why — measured, not assumed

The shape carries lowercase: 'here'. Every pattern check:error-code-casing has needs a quoted literal beside the token code; at an inline ternary there is none. Measured: findViolations() returns 0 findings for domains/automation.ts, while the literally-spelled code: 'invalid_type' a few lines up it does see and correctly skips as D6. That gate's own verdict text says the same thing from its side — "a code value with NO literal at the position — a constant, a template, a ternary, a helper parameter — is out of reach for every pattern here by construction; that half belongs to check:dispatcher-error-vocabulary". So a casing-gate delegation here would be the seam the gate's header describes, not a hand-off. --self-test pins this against that gate's real detector rather than against this paragraph. ⛔ check-error-code-casing.mjs is untouched.

Two deliberate boundaries, declared rather than discovered later

  • The anchor is the strict code:, not objlithelper's code\s*:\s*. Measured: the loose spelling matches the colon of a ternary, so typeof issue.code === 'string' ? issue.code : 'unknown' reads as a code : stamp of 'unknown' — a false position with no structural tell. objlithelper can afford the loose anchor because its parameter guard rejects that; this shape's guard is the reduction, which accepts it.
  • The regex refuses a bare quoted literal ((?!\s*'[^']*'\s*[,;}\n])). [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 pins the kebab-diagnostic declaration by counting recognizer matches, not findings; a bare code: anchor matchescode: 'unknown-component' even though every guard then declines it, and that reds the kebab pin. A bare literal is objlit's anyway. The cost is one declared remainder: a chain whose first operand is a bare quoted literal (code: 'A' || 'B') is handed to objlit, which reports 'A' and not 'B' — partial reporting rather than silence, zero live instances, counted as chainWhoseFirstOperandIsABareLiteral and pinned.

Ablation — every guard proved to fail

Run from a committed tree; each leg proved on disk by blob hash before/after, restored to the HEAD blob and verified equal, with a trap on EXIT/INT/TERM.

ablated--self-testwhat it said
the objlitexpr SHAPES entryexit 1SHAPE 'objlitexpr' matched nothing in its own sample + the nested-ternary pin
the sibling OWNERSHIP guardexit 1one stamp reported under two shape names
the CONDITIONAL-TYPE guardexit 1a CONDITIONAL type at a code: derived ["INLINE_A","INLINE_B"]
the enclosing-BRACKET testexit 1a code: in a function PARAMETER LIST derived ["INLINE_PARAM_A","INLINE_PARAM_B"]

⚠️ Two of these are only honest because the first attempt was not. The bracket-guard ablation initially sat green: the pin used (code: number | null, signal), whose value text the reduction declines anyway — a pin measuring nothing. It now uses a parameter default (code: string = down ? 'A' : 'B'), a value expression only the bracket rejects. And the bare-identifier partition is documented as what it is: with no resolver it changes no output today, so it is declared as a reader-facing statement of the partition rather than as a guard an ablation can see.

What is NOT here

Known limitation found on the way (filed, not fixed here)

The gate's shared textual scanners (enclosingOpeners, sliceBalanced, scanTopLevel) skip a string by seeking its closing quote, so a nested template literal `a ${xs.map((k) => `\`${k}\).join(', ')} b`` — closes the outer template at the first inner backtick and desynchronises everycode:position after it in that file.domains/automation.tscarries one at line 1285, and **two further instances of the identical catalog ternary** (the clone door'snameandlabelchecks,:1384and:1399) sit behind it, invisible to guard ①. Same values, same verdict, so the zero for hidden wire codes is unaffected — but the position count is a floor, not a total. Pre-existing and shared with objlithelper, recorded in the census and in the invalid_type` row rather than repaired inside a shape widening.

Verification

git diff --stat origin/main..HEAD — 2 files, exactly the declared surface:

 packages/runtime/src/dispatcher-error-vocabulary.ts | 83 ++-
scripts/check-dispatcher-error-vocabulary.mjs | 675 +++++++++++++++++++-
2 files changed, 753 insertions(+), 5 deletions(-)

Changeset

skip-changeset. The diff is one gate script plus packages/runtime/src/dispatcher-error-vocabulary.ts, which is a declaration table read textually by the gate and by tests: nothing in packages/runtime/src imports it, it is not re-exported from src/index.ts, and the package publishes only . — so no published bytes change. If a reviewer reads that differently, a changeset is cheap to add.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV


Generated by Claude Code

…`code:`
The vocabulary gate reached a `code:` whose value is a quoted literal
(`objlit`), a SCREAMING_SNAKE constant (`objlitconst`), a template
(`objlittemplate`) or a helper parameter (`objlithelper`), but not an INLINE
literal EXPRESSION — a ternary or a `||`/`??` chain written at the stamp with
every branch already a literal. That is no site AND no unresolved: the one way
the gate's "REPORTED as unresolved, never dropped" bound cannot notice itself
failing, in a third stamp position.
Adds the fifth object-literal shape, `objlitexpr`. It needs no resolver —
`literalCodeValues` reduces the value text between `code:` and the property's
terminating top-level comma directly, and `resolveIdent` is left at its default
so an identifier limb keeps the expression unreducible, which is what keeps this
shape out of the lower-case-LOCAL position that stays censused and open.
Precision measured BEFORE implementing, over the gate's own population: of 902
`code:` tokens the shape reaches 346, three guards reject 130, 216 reach the
reduction and 214 decline — including every type annotation — leaving 2 live
positions, 5 values, 2 verdict rows and 0 unregistered wire codes hiding. The
ALL-OR-NOTHING reduction IS the guard against the type-annotation noise the
helper position pays per value stamp. Frozen in
INLINE_LITERAL_EXPRESSION_CENSUS, printed in the bounds line, arithmetic pinned.
The two rows the widening owes land in the same commit, after the widening,
because the reconciliation runs in both directions: the ADR-0112 D6
field-addressed validation catalog in `domains/automation.ts`. They are reported
here rather than delegated to check:error-code-casing because that gate needs a
quoted literal beside the token `code` and an inline ternary has none —
measured, and pinned against its real detector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/runtime, touching 5 documentable anchor(s).

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

  • content/docs/api/error-catalog.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/api/error-handling-server.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/deployment/cli.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/protocol/objectui/concept.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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

  • content/docs/releases/v17.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 24 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21fpackageMentionDocs.

Which tree this was computed on

This run read content/docs from fe7200da54d381d2c79d8544c2737f8478bc7139 — the merge of head 8a10049e48beaa67589d72c742355f2a55bc29ae into base 87ad30c103bb4e8c5d7b8a399634b59716f3c21f, 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 fe7200da54d381d2c79d8544c2737f8478bc7139 && git checkout fe7200da54d381d2c79d8544c2737f8478bc7139
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87ad30c103bb4e8c5d7b8a399634b59716f3c21f 8a10049e48beaa67589d72c742355f2a55bc29ae && git checkout -B drift-repro 87ad30c103bb4e8c5d7b8a399634b59716f3c21f && git merge --no-ff 8a10049e48beaa67589d72c742355f2a55bc29ae
node scripts/docs-audit/affected-docs.mjs --json 87ad30c103bb4e8c5d7b8a399634b59716f3c21f

⚠️ 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

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

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] An INLINE literal ternary at an object-literal code: is reached by no vocabulary shape — the third stamp position, censused at zero

2 participants

@baozhoutao@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(devx): reach the INLINE literal expression at an object-literal code: - #14625

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape
Sep 2, 2026
Merged

feat(devx): reach the INLINE literal expression at an object-literal code:#14625
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape

Conversation

@claude

@claudeclaudeBot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes#13790

scripts/check-dispatcher-error-vocabulary.mjs reached no INLINE literal expression at an object-literal code: — a ternary, or a ||/?? chain, written at the stamp itself with every branch already a literal. That is no site AND no unresolved, the one way the gate's own "REPORTED as unresolved, never dropped" bound cannot notice itself failing, in a third stamp position after #9223's code: CONST and #13233's { code } helper.

This adds the fifth object-literal shape, objlitexpr. Per the triage's ⭐ it needs no resolver: literalCodeValues already reduces the expression, so the shape is the reduction of the value text between code: and the property's terminating top-level comma.

The precision measurement, first

The triage refused to authorise the widening until the precision cost was measured (objlithelper reaches 65 type annotations per value stamp). It was measured over the gate's own population — packages/** non-test source, 2186 files — with the gate's own primitives, before the shape was written. The finding: the ALL-OR-NOTHING reduction is the guard. A type annotation reduces to nothing for the same reason a runtime expression does, so it costs a continue and no verdict row.

code: tokens in the population902
reached by the shape's regex (a bare quoted literal is refused — see below)346
① rejected: enclosing bracket is not { (41 parameter lists, 33 inside a string)74
② rejected: already objlit's (4), objlitconst's (40), objlittemplate's (3)47
② rejected: a bare identifier (objlithelper's candidate / #13478's remainder)9
③ rejected: a CONDITIONAL type (code: T extends X ? 'A' : 'B')0
reaching the reduction216
declined by ALL-OR-NOTHING (~150 of them type annotations, ~64 runtime)214
true positions2
type-annotation positions surviving every guard0
distinct values behind the true positions5
verdict rows owed2
unregistered WIRE codes hiding0

⇒ preventive, not a live defect — the same disposition and evidence standard #13478 and #13233 were closed on. Every figure is frozen in INLINE_LITERAL_EXPRESSION_CENSUS, printed on every run in the bounds line, and its arithmetic is pinned by --self-test.

Every position reached, with its classification

  • packages/rest/src/error-response.ts:1250code: isProvisioning ? 'PROJECT_PROVISIONING' : isFailed ? 'PROJECT_PROVISIONING_FAILED' : 'PROJECT_NOT_FOUND'. All three are in ERROR_CODE_LEDGER, so the scan derives no site and owes no row. This is the REST door file, stamped straight into an HTTP error envelope's body.code — registered today, and now no longer invisible to the gate tomorrow.
  • packages/runtime/src/domains/automation.ts:1125code: body.name === undefined ? 'required' : 'invalid_type'. An ADR-0112 D6 field-addressed validation catalog reaching details.fields[].code, never error.code. Two rows, foreign-vocabulary / door: 'none'.
  • The other 214 candidates all decline at the reduction: type annotations (code: string | undefined, code: FieldErrorCode, code?: 'a' | 'b') and runtime expressions (code: typeof issue.code === 'string' ? issue.code : 'unknown').

Where the lowercase catalog is reported, and why — measured, not assumed

The shape carries lowercase: 'here'. Every pattern check:error-code-casing has needs a quoted literal beside the token code; at an inline ternary there is none. Measured: findViolations() returns 0 findings for domains/automation.ts, while the literally-spelled code: 'invalid_type' a few lines up it does see and correctly skips as D6. That gate's own verdict text says the same thing from its side — "a code value with NO literal at the position — a constant, a template, a ternary, a helper parameter — is out of reach for every pattern here by construction; that half belongs to check:dispatcher-error-vocabulary". So a casing-gate delegation here would be the seam the gate's header describes, not a hand-off. --self-test pins this against that gate's real detector rather than against this paragraph. ⛔ check-error-code-casing.mjs is untouched.

Two deliberate boundaries, declared rather than discovered later

  • The anchor is the strict code:, not objlithelper's code\s*:\s*. Measured: the loose spelling matches the colon of a ternary, so typeof issue.code === 'string' ? issue.code : 'unknown' reads as a code : stamp of 'unknown' — a false position with no structural tell. objlithelper can afford the loose anchor because its parameter guard rejects that; this shape's guard is the reduction, which accepts it.
  • The regex refuses a bare quoted literal ((?!\s*'[^']*'\s*[,;}\n])). [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 pins the kebab-diagnostic declaration by counting recognizer matches, not findings; a bare code: anchor matchescode: 'unknown-component' even though every guard then declines it, and that reds the kebab pin. A bare literal is objlit's anyway. The cost is one declared remainder: a chain whose first operand is a bare quoted literal (code: 'A' || 'B') is handed to objlit, which reports 'A' and not 'B' — partial reporting rather than silence, zero live instances, counted as chainWhoseFirstOperandIsABareLiteral and pinned.

Ablation — every guard proved to fail

Run from a committed tree; each leg proved on disk by blob hash before/after, restored to the HEAD blob and verified equal, with a trap on EXIT/INT/TERM.

ablated--self-testwhat it said
the objlitexpr SHAPES entryexit 1SHAPE 'objlitexpr' matched nothing in its own sample + the nested-ternary pin
the sibling OWNERSHIP guardexit 1one stamp reported under two shape names
the CONDITIONAL-TYPE guardexit 1a CONDITIONAL type at a code: derived ["INLINE_A","INLINE_B"]
the enclosing-BRACKET testexit 1a code: in a function PARAMETER LIST derived ["INLINE_PARAM_A","INLINE_PARAM_B"]

⚠️ Two of these are only honest because the first attempt was not. The bracket-guard ablation initially sat green: the pin used (code: number | null, signal), whose value text the reduction declines anyway — a pin measuring nothing. It now uses a parameter default (code: string = down ? 'A' : 'B'), a value expression only the bracket rejects. And the bare-identifier partition is documented as what it is: with no resolver it changes no output today, so it is declared as a reader-facing statement of the partition rather than as a guard an ablation can see.

What is NOT here

Known limitation found on the way (filed, not fixed here)

The gate's shared textual scanners (enclosingOpeners, sliceBalanced, scanTopLevel) skip a string by seeking its closing quote, so a nested template literal `a ${xs.map((k) => `\`${k}\).join(', ')} b`` — closes the outer template at the first inner backtick and desynchronises everycode:position after it in that file.domains/automation.tscarries one at line 1285, and **two further instances of the identical catalog ternary** (the clone door'snameandlabelchecks,:1384and:1399) sit behind it, invisible to guard ①. Same values, same verdict, so the zero for hidden wire codes is unaffected — but the position count is a floor, not a total. Pre-existing and shared with objlithelper, recorded in the census and in the invalid_type` row rather than repaired inside a shape widening.

Verification

git diff --stat origin/main..HEAD — 2 files, exactly the declared surface:

 packages/runtime/src/dispatcher-error-vocabulary.ts | 83 ++-
scripts/check-dispatcher-error-vocabulary.mjs | 675 +++++++++++++++++++-
2 files changed, 753 insertions(+), 5 deletions(-)

Changeset

skip-changeset. The diff is one gate script plus packages/runtime/src/dispatcher-error-vocabulary.ts, which is a declaration table read textually by the gate and by tests: nothing in packages/runtime/src imports it, it is not re-exported from src/index.ts, and the package publishes only . — so no published bytes change. If a reviewer reads that differently, a changeset is cheap to add.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV


Generated by Claude Code

…`code:`
The vocabulary gate reached a `code:` whose value is a quoted literal
(`objlit`), a SCREAMING_SNAKE constant (`objlitconst`), a template
(`objlittemplate`) or a helper parameter (`objlithelper`), but not an INLINE
literal EXPRESSION — a ternary or a `||`/`??` chain written at the stamp with
every branch already a literal. That is no site AND no unresolved: the one way
the gate's "REPORTED as unresolved, never dropped" bound cannot notice itself
failing, in a third stamp position.
Adds the fifth object-literal shape, `objlitexpr`. It needs no resolver —
`literalCodeValues` reduces the value text between `code:` and the property's
terminating top-level comma directly, and `resolveIdent` is left at its default
so an identifier limb keeps the expression unreducible, which is what keeps this
shape out of the lower-case-LOCAL position that stays censused and open.
Precision measured BEFORE implementing, over the gate's own population: of 902
`code:` tokens the shape reaches 346, three guards reject 130, 216 reach the
reduction and 214 decline — including every type annotation — leaving 2 live
positions, 5 values, 2 verdict rows and 0 unregistered wire codes hiding. The
ALL-OR-NOTHING reduction IS the guard against the type-annotation noise the
helper position pays per value stamp. Frozen in
INLINE_LITERAL_EXPRESSION_CENSUS, printed in the bounds line, arithmetic pinned.
The two rows the widening owes land in the same commit, after the widening,
because the reconciliation runs in both directions: the ADR-0112 D6
field-addressed validation catalog in `domains/automation.ts`. They are reported
here rather than delegated to check:error-code-casing because that gate needs a
quoted literal beside the token `code` and an inline ternary has none —
measured, and pinned against its real detector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/runtime, touching 5 documentable anchor(s).

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

  • content/docs/api/error-catalog.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/api/error-handling-server.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/deployment/cli.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/protocol/objectui/concept.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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

  • content/docs/releases/v17.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 24 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21fpackageMentionDocs.

Which tree this was computed on

This run read content/docs from fe7200da54d381d2c79d8544c2737f8478bc7139 — the merge of head 8a10049e48beaa67589d72c742355f2a55bc29ae into base 87ad30c103bb4e8c5d7b8a399634b59716f3c21f, 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 fe7200da54d381d2c79d8544c2737f8478bc7139 && git checkout fe7200da54d381d2c79d8544c2737f8478bc7139
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87ad30c103bb4e8c5d7b8a399634b59716f3c21f 8a10049e48beaa67589d72c742355f2a55bc29ae && git checkout -B drift-repro 87ad30c103bb4e8c5d7b8a399634b59716f3c21f && git merge --no-ff 8a10049e48beaa67589d72c742355f2a55bc29ae
node scripts/docs-audit/affected-docs.mjs --json 87ad30c103bb4e8c5d7b8a399634b59716f3c21f

⚠️ 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

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

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] An INLINE literal ternary at an object-literal code: is reached by no vocabulary shape — the third stamp position, censused at zero

2 participants

@baozhoutao@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(devx): reach the INLINE literal expression at an object-literal code: - #14625

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape
Sep 2, 2026
Merged

feat(devx): reach the INLINE literal expression at an object-literal code:#14625
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape

Conversation

@claude

@claudeclaudeBot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes#13790

scripts/check-dispatcher-error-vocabulary.mjs reached no INLINE literal expression at an object-literal code: — a ternary, or a ||/?? chain, written at the stamp itself with every branch already a literal. That is no site AND no unresolved, the one way the gate's own "REPORTED as unresolved, never dropped" bound cannot notice itself failing, in a third stamp position after #9223's code: CONST and #13233's { code } helper.

This adds the fifth object-literal shape, objlitexpr. Per the triage's ⭐ it needs no resolver: literalCodeValues already reduces the expression, so the shape is the reduction of the value text between code: and the property's terminating top-level comma.

The precision measurement, first

The triage refused to authorise the widening until the precision cost was measured (objlithelper reaches 65 type annotations per value stamp). It was measured over the gate's own population — packages/** non-test source, 2186 files — with the gate's own primitives, before the shape was written. The finding: the ALL-OR-NOTHING reduction is the guard. A type annotation reduces to nothing for the same reason a runtime expression does, so it costs a continue and no verdict row.

code: tokens in the population902
reached by the shape's regex (a bare quoted literal is refused — see below)346
① rejected: enclosing bracket is not { (41 parameter lists, 33 inside a string)74
② rejected: already objlit's (4), objlitconst's (40), objlittemplate's (3)47
② rejected: a bare identifier (objlithelper's candidate / #13478's remainder)9
③ rejected: a CONDITIONAL type (code: T extends X ? 'A' : 'B')0
reaching the reduction216
declined by ALL-OR-NOTHING (~150 of them type annotations, ~64 runtime)214
true positions2
type-annotation positions surviving every guard0
distinct values behind the true positions5
verdict rows owed2
unregistered WIRE codes hiding0

⇒ preventive, not a live defect — the same disposition and evidence standard #13478 and #13233 were closed on. Every figure is frozen in INLINE_LITERAL_EXPRESSION_CENSUS, printed on every run in the bounds line, and its arithmetic is pinned by --self-test.

Every position reached, with its classification

  • packages/rest/src/error-response.ts:1250code: isProvisioning ? 'PROJECT_PROVISIONING' : isFailed ? 'PROJECT_PROVISIONING_FAILED' : 'PROJECT_NOT_FOUND'. All three are in ERROR_CODE_LEDGER, so the scan derives no site and owes no row. This is the REST door file, stamped straight into an HTTP error envelope's body.code — registered today, and now no longer invisible to the gate tomorrow.
  • packages/runtime/src/domains/automation.ts:1125code: body.name === undefined ? 'required' : 'invalid_type'. An ADR-0112 D6 field-addressed validation catalog reaching details.fields[].code, never error.code. Two rows, foreign-vocabulary / door: 'none'.
  • The other 214 candidates all decline at the reduction: type annotations (code: string | undefined, code: FieldErrorCode, code?: 'a' | 'b') and runtime expressions (code: typeof issue.code === 'string' ? issue.code : 'unknown').

Where the lowercase catalog is reported, and why — measured, not assumed

The shape carries lowercase: 'here'. Every pattern check:error-code-casing has needs a quoted literal beside the token code; at an inline ternary there is none. Measured: findViolations() returns 0 findings for domains/automation.ts, while the literally-spelled code: 'invalid_type' a few lines up it does see and correctly skips as D6. That gate's own verdict text says the same thing from its side — "a code value with NO literal at the position — a constant, a template, a ternary, a helper parameter — is out of reach for every pattern here by construction; that half belongs to check:dispatcher-error-vocabulary". So a casing-gate delegation here would be the seam the gate's header describes, not a hand-off. --self-test pins this against that gate's real detector rather than against this paragraph. ⛔ check-error-code-casing.mjs is untouched.

Two deliberate boundaries, declared rather than discovered later

  • The anchor is the strict code:, not objlithelper's code\s*:\s*. Measured: the loose spelling matches the colon of a ternary, so typeof issue.code === 'string' ? issue.code : 'unknown' reads as a code : stamp of 'unknown' — a false position with no structural tell. objlithelper can afford the loose anchor because its parameter guard rejects that; this shape's guard is the reduction, which accepts it.
  • The regex refuses a bare quoted literal ((?!\s*'[^']*'\s*[,;}\n])). [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 pins the kebab-diagnostic declaration by counting recognizer matches, not findings; a bare code: anchor matchescode: 'unknown-component' even though every guard then declines it, and that reds the kebab pin. A bare literal is objlit's anyway. The cost is one declared remainder: a chain whose first operand is a bare quoted literal (code: 'A' || 'B') is handed to objlit, which reports 'A' and not 'B' — partial reporting rather than silence, zero live instances, counted as chainWhoseFirstOperandIsABareLiteral and pinned.

Ablation — every guard proved to fail

Run from a committed tree; each leg proved on disk by blob hash before/after, restored to the HEAD blob and verified equal, with a trap on EXIT/INT/TERM.

ablated--self-testwhat it said
the objlitexpr SHAPES entryexit 1SHAPE 'objlitexpr' matched nothing in its own sample + the nested-ternary pin
the sibling OWNERSHIP guardexit 1one stamp reported under two shape names
the CONDITIONAL-TYPE guardexit 1a CONDITIONAL type at a code: derived ["INLINE_A","INLINE_B"]
the enclosing-BRACKET testexit 1a code: in a function PARAMETER LIST derived ["INLINE_PARAM_A","INLINE_PARAM_B"]

⚠️ Two of these are only honest because the first attempt was not. The bracket-guard ablation initially sat green: the pin used (code: number | null, signal), whose value text the reduction declines anyway — a pin measuring nothing. It now uses a parameter default (code: string = down ? 'A' : 'B'), a value expression only the bracket rejects. And the bare-identifier partition is documented as what it is: with no resolver it changes no output today, so it is declared as a reader-facing statement of the partition rather than as a guard an ablation can see.

What is NOT here

Known limitation found on the way (filed, not fixed here)

The gate's shared textual scanners (enclosingOpeners, sliceBalanced, scanTopLevel) skip a string by seeking its closing quote, so a nested template literal `a ${xs.map((k) => `\`${k}\).join(', ')} b`` — closes the outer template at the first inner backtick and desynchronises everycode:position after it in that file.domains/automation.tscarries one at line 1285, and **two further instances of the identical catalog ternary** (the clone door'snameandlabelchecks,:1384and:1399) sit behind it, invisible to guard ①. Same values, same verdict, so the zero for hidden wire codes is unaffected — but the position count is a floor, not a total. Pre-existing and shared with objlithelper, recorded in the census and in the invalid_type` row rather than repaired inside a shape widening.

Verification

git diff --stat origin/main..HEAD — 2 files, exactly the declared surface:

 packages/runtime/src/dispatcher-error-vocabulary.ts | 83 ++-
scripts/check-dispatcher-error-vocabulary.mjs | 675 +++++++++++++++++++-
2 files changed, 753 insertions(+), 5 deletions(-)

Changeset

skip-changeset. The diff is one gate script plus packages/runtime/src/dispatcher-error-vocabulary.ts, which is a declaration table read textually by the gate and by tests: nothing in packages/runtime/src imports it, it is not re-exported from src/index.ts, and the package publishes only . — so no published bytes change. If a reviewer reads that differently, a changeset is cheap to add.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV


Generated by Claude Code

…`code:`
The vocabulary gate reached a `code:` whose value is a quoted literal
(`objlit`), a SCREAMING_SNAKE constant (`objlitconst`), a template
(`objlittemplate`) or a helper parameter (`objlithelper`), but not an INLINE
literal EXPRESSION — a ternary or a `||`/`??` chain written at the stamp with
every branch already a literal. That is no site AND no unresolved: the one way
the gate's "REPORTED as unresolved, never dropped" bound cannot notice itself
failing, in a third stamp position.
Adds the fifth object-literal shape, `objlitexpr`. It needs no resolver —
`literalCodeValues` reduces the value text between `code:` and the property's
terminating top-level comma directly, and `resolveIdent` is left at its default
so an identifier limb keeps the expression unreducible, which is what keeps this
shape out of the lower-case-LOCAL position that stays censused and open.
Precision measured BEFORE implementing, over the gate's own population: of 902
`code:` tokens the shape reaches 346, three guards reject 130, 216 reach the
reduction and 214 decline — including every type annotation — leaving 2 live
positions, 5 values, 2 verdict rows and 0 unregistered wire codes hiding. The
ALL-OR-NOTHING reduction IS the guard against the type-annotation noise the
helper position pays per value stamp. Frozen in
INLINE_LITERAL_EXPRESSION_CENSUS, printed in the bounds line, arithmetic pinned.
The two rows the widening owes land in the same commit, after the widening,
because the reconciliation runs in both directions: the ADR-0112 D6
field-addressed validation catalog in `domains/automation.ts`. They are reported
here rather than delegated to check:error-code-casing because that gate needs a
quoted literal beside the token `code` and an inline ternary has none —
measured, and pinned against its real detector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/runtime, touching 5 documentable anchor(s).

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

  • content/docs/api/error-catalog.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/api/error-handling-server.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/deployment/cli.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/protocol/objectui/concept.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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

  • content/docs/releases/v17.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 24 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21fpackageMentionDocs.

Which tree this was computed on

This run read content/docs from fe7200da54d381d2c79d8544c2737f8478bc7139 — the merge of head 8a10049e48beaa67589d72c742355f2a55bc29ae into base 87ad30c103bb4e8c5d7b8a399634b59716f3c21f, 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 fe7200da54d381d2c79d8544c2737f8478bc7139 && git checkout fe7200da54d381d2c79d8544c2737f8478bc7139
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87ad30c103bb4e8c5d7b8a399634b59716f3c21f 8a10049e48beaa67589d72c742355f2a55bc29ae && git checkout -B drift-repro 87ad30c103bb4e8c5d7b8a399634b59716f3c21f && git merge --no-ff 8a10049e48beaa67589d72c742355f2a55bc29ae
node scripts/docs-audit/affected-docs.mjs --json 87ad30c103bb4e8c5d7b8a399634b59716f3c21f

⚠️ 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

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

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] An INLINE literal ternary at an object-literal code: is reached by no vocabulary shape — the third stamp position, censused at zero

2 participants

@baozhoutao@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(devx): reach the INLINE literal expression at an object-literal code: - #14625

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape
Sep 2, 2026
Merged

feat(devx): reach the INLINE literal expression at an object-literal code:#14625
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape

Conversation

@claude

@claudeclaudeBot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes#13790

scripts/check-dispatcher-error-vocabulary.mjs reached no INLINE literal expression at an object-literal code: — a ternary, or a ||/?? chain, written at the stamp itself with every branch already a literal. That is no site AND no unresolved, the one way the gate's own "REPORTED as unresolved, never dropped" bound cannot notice itself failing, in a third stamp position after #9223's code: CONST and #13233's { code } helper.

This adds the fifth object-literal shape, objlitexpr. Per the triage's ⭐ it needs no resolver: literalCodeValues already reduces the expression, so the shape is the reduction of the value text between code: and the property's terminating top-level comma.

The precision measurement, first

The triage refused to authorise the widening until the precision cost was measured (objlithelper reaches 65 type annotations per value stamp). It was measured over the gate's own population — packages/** non-test source, 2186 files — with the gate's own primitives, before the shape was written. The finding: the ALL-OR-NOTHING reduction is the guard. A type annotation reduces to nothing for the same reason a runtime expression does, so it costs a continue and no verdict row.

code: tokens in the population902
reached by the shape's regex (a bare quoted literal is refused — see below)346
① rejected: enclosing bracket is not { (41 parameter lists, 33 inside a string)74
② rejected: already objlit's (4), objlitconst's (40), objlittemplate's (3)47
② rejected: a bare identifier (objlithelper's candidate / #13478's remainder)9
③ rejected: a CONDITIONAL type (code: T extends X ? 'A' : 'B')0
reaching the reduction216
declined by ALL-OR-NOTHING (~150 of them type annotations, ~64 runtime)214
true positions2
type-annotation positions surviving every guard0
distinct values behind the true positions5
verdict rows owed2
unregistered WIRE codes hiding0

⇒ preventive, not a live defect — the same disposition and evidence standard #13478 and #13233 were closed on. Every figure is frozen in INLINE_LITERAL_EXPRESSION_CENSUS, printed on every run in the bounds line, and its arithmetic is pinned by --self-test.

Every position reached, with its classification

  • packages/rest/src/error-response.ts:1250code: isProvisioning ? 'PROJECT_PROVISIONING' : isFailed ? 'PROJECT_PROVISIONING_FAILED' : 'PROJECT_NOT_FOUND'. All three are in ERROR_CODE_LEDGER, so the scan derives no site and owes no row. This is the REST door file, stamped straight into an HTTP error envelope's body.code — registered today, and now no longer invisible to the gate tomorrow.
  • packages/runtime/src/domains/automation.ts:1125code: body.name === undefined ? 'required' : 'invalid_type'. An ADR-0112 D6 field-addressed validation catalog reaching details.fields[].code, never error.code. Two rows, foreign-vocabulary / door: 'none'.
  • The other 214 candidates all decline at the reduction: type annotations (code: string | undefined, code: FieldErrorCode, code?: 'a' | 'b') and runtime expressions (code: typeof issue.code === 'string' ? issue.code : 'unknown').

Where the lowercase catalog is reported, and why — measured, not assumed

The shape carries lowercase: 'here'. Every pattern check:error-code-casing has needs a quoted literal beside the token code; at an inline ternary there is none. Measured: findViolations() returns 0 findings for domains/automation.ts, while the literally-spelled code: 'invalid_type' a few lines up it does see and correctly skips as D6. That gate's own verdict text says the same thing from its side — "a code value with NO literal at the position — a constant, a template, a ternary, a helper parameter — is out of reach for every pattern here by construction; that half belongs to check:dispatcher-error-vocabulary". So a casing-gate delegation here would be the seam the gate's header describes, not a hand-off. --self-test pins this against that gate's real detector rather than against this paragraph. ⛔ check-error-code-casing.mjs is untouched.

Two deliberate boundaries, declared rather than discovered later

  • The anchor is the strict code:, not objlithelper's code\s*:\s*. Measured: the loose spelling matches the colon of a ternary, so typeof issue.code === 'string' ? issue.code : 'unknown' reads as a code : stamp of 'unknown' — a false position with no structural tell. objlithelper can afford the loose anchor because its parameter guard rejects that; this shape's guard is the reduction, which accepts it.
  • The regex refuses a bare quoted literal ((?!\s*'[^']*'\s*[,;}\n])). [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 pins the kebab-diagnostic declaration by counting recognizer matches, not findings; a bare code: anchor matchescode: 'unknown-component' even though every guard then declines it, and that reds the kebab pin. A bare literal is objlit's anyway. The cost is one declared remainder: a chain whose first operand is a bare quoted literal (code: 'A' || 'B') is handed to objlit, which reports 'A' and not 'B' — partial reporting rather than silence, zero live instances, counted as chainWhoseFirstOperandIsABareLiteral and pinned.

Ablation — every guard proved to fail

Run from a committed tree; each leg proved on disk by blob hash before/after, restored to the HEAD blob and verified equal, with a trap on EXIT/INT/TERM.

ablated--self-testwhat it said
the objlitexpr SHAPES entryexit 1SHAPE 'objlitexpr' matched nothing in its own sample + the nested-ternary pin
the sibling OWNERSHIP guardexit 1one stamp reported under two shape names
the CONDITIONAL-TYPE guardexit 1a CONDITIONAL type at a code: derived ["INLINE_A","INLINE_B"]
the enclosing-BRACKET testexit 1a code: in a function PARAMETER LIST derived ["INLINE_PARAM_A","INLINE_PARAM_B"]

⚠️ Two of these are only honest because the first attempt was not. The bracket-guard ablation initially sat green: the pin used (code: number | null, signal), whose value text the reduction declines anyway — a pin measuring nothing. It now uses a parameter default (code: string = down ? 'A' : 'B'), a value expression only the bracket rejects. And the bare-identifier partition is documented as what it is: with no resolver it changes no output today, so it is declared as a reader-facing statement of the partition rather than as a guard an ablation can see.

What is NOT here

Known limitation found on the way (filed, not fixed here)

The gate's shared textual scanners (enclosingOpeners, sliceBalanced, scanTopLevel) skip a string by seeking its closing quote, so a nested template literal `a ${xs.map((k) => `\`${k}\).join(', ')} b`` — closes the outer template at the first inner backtick and desynchronises everycode:position after it in that file.domains/automation.tscarries one at line 1285, and **two further instances of the identical catalog ternary** (the clone door'snameandlabelchecks,:1384and:1399) sit behind it, invisible to guard ①. Same values, same verdict, so the zero for hidden wire codes is unaffected — but the position count is a floor, not a total. Pre-existing and shared with objlithelper, recorded in the census and in the invalid_type` row rather than repaired inside a shape widening.

Verification

git diff --stat origin/main..HEAD — 2 files, exactly the declared surface:

 packages/runtime/src/dispatcher-error-vocabulary.ts | 83 ++-
scripts/check-dispatcher-error-vocabulary.mjs | 675 +++++++++++++++++++-
2 files changed, 753 insertions(+), 5 deletions(-)

Changeset

skip-changeset. The diff is one gate script plus packages/runtime/src/dispatcher-error-vocabulary.ts, which is a declaration table read textually by the gate and by tests: nothing in packages/runtime/src imports it, it is not re-exported from src/index.ts, and the package publishes only . — so no published bytes change. If a reviewer reads that differently, a changeset is cheap to add.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV


Generated by Claude Code

…`code:`
The vocabulary gate reached a `code:` whose value is a quoted literal
(`objlit`), a SCREAMING_SNAKE constant (`objlitconst`), a template
(`objlittemplate`) or a helper parameter (`objlithelper`), but not an INLINE
literal EXPRESSION — a ternary or a `||`/`??` chain written at the stamp with
every branch already a literal. That is no site AND no unresolved: the one way
the gate's "REPORTED as unresolved, never dropped" bound cannot notice itself
failing, in a third stamp position.
Adds the fifth object-literal shape, `objlitexpr`. It needs no resolver —
`literalCodeValues` reduces the value text between `code:` and the property's
terminating top-level comma directly, and `resolveIdent` is left at its default
so an identifier limb keeps the expression unreducible, which is what keeps this
shape out of the lower-case-LOCAL position that stays censused and open.
Precision measured BEFORE implementing, over the gate's own population: of 902
`code:` tokens the shape reaches 346, three guards reject 130, 216 reach the
reduction and 214 decline — including every type annotation — leaving 2 live
positions, 5 values, 2 verdict rows and 0 unregistered wire codes hiding. The
ALL-OR-NOTHING reduction IS the guard against the type-annotation noise the
helper position pays per value stamp. Frozen in
INLINE_LITERAL_EXPRESSION_CENSUS, printed in the bounds line, arithmetic pinned.
The two rows the widening owes land in the same commit, after the widening,
because the reconciliation runs in both directions: the ADR-0112 D6
field-addressed validation catalog in `domains/automation.ts`. They are reported
here rather than delegated to check:error-code-casing because that gate needs a
quoted literal beside the token `code` and an inline ternary has none —
measured, and pinned against its real detector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/runtime, touching 5 documentable anchor(s).

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

  • content/docs/api/error-catalog.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/api/error-handling-server.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/deployment/cli.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/protocol/objectui/concept.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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

  • content/docs/releases/v17.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 24 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21fpackageMentionDocs.

Which tree this was computed on

This run read content/docs from fe7200da54d381d2c79d8544c2737f8478bc7139 — the merge of head 8a10049e48beaa67589d72c742355f2a55bc29ae into base 87ad30c103bb4e8c5d7b8a399634b59716f3c21f, 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 fe7200da54d381d2c79d8544c2737f8478bc7139 && git checkout fe7200da54d381d2c79d8544c2737f8478bc7139
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87ad30c103bb4e8c5d7b8a399634b59716f3c21f 8a10049e48beaa67589d72c742355f2a55bc29ae && git checkout -B drift-repro 87ad30c103bb4e8c5d7b8a399634b59716f3c21f && git merge --no-ff 8a10049e48beaa67589d72c742355f2a55bc29ae
node scripts/docs-audit/affected-docs.mjs --json 87ad30c103bb4e8c5d7b8a399634b59716f3c21f

⚠️ 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

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

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] An INLINE literal ternary at an object-literal code: is reached by no vocabulary shape — the third stamp position, censused at zero

2 participants

@baozhoutao@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(devx): reach the INLINE literal expression at an object-literal code: - #14625

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape
Sep 2, 2026
Merged

feat(devx): reach the INLINE literal expression at an object-literal code:#14625
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape

Conversation

@claude

@claudeclaudeBot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes#13790

scripts/check-dispatcher-error-vocabulary.mjs reached no INLINE literal expression at an object-literal code: — a ternary, or a ||/?? chain, written at the stamp itself with every branch already a literal. That is no site AND no unresolved, the one way the gate's own "REPORTED as unresolved, never dropped" bound cannot notice itself failing, in a third stamp position after #9223's code: CONST and #13233's { code } helper.

This adds the fifth object-literal shape, objlitexpr. Per the triage's ⭐ it needs no resolver: literalCodeValues already reduces the expression, so the shape is the reduction of the value text between code: and the property's terminating top-level comma.

The precision measurement, first

The triage refused to authorise the widening until the precision cost was measured (objlithelper reaches 65 type annotations per value stamp). It was measured over the gate's own population — packages/** non-test source, 2186 files — with the gate's own primitives, before the shape was written. The finding: the ALL-OR-NOTHING reduction is the guard. A type annotation reduces to nothing for the same reason a runtime expression does, so it costs a continue and no verdict row.

code: tokens in the population902
reached by the shape's regex (a bare quoted literal is refused — see below)346
① rejected: enclosing bracket is not { (41 parameter lists, 33 inside a string)74
② rejected: already objlit's (4), objlitconst's (40), objlittemplate's (3)47
② rejected: a bare identifier (objlithelper's candidate / #13478's remainder)9
③ rejected: a CONDITIONAL type (code: T extends X ? 'A' : 'B')0
reaching the reduction216
declined by ALL-OR-NOTHING (~150 of them type annotations, ~64 runtime)214
true positions2
type-annotation positions surviving every guard0
distinct values behind the true positions5
verdict rows owed2
unregistered WIRE codes hiding0

⇒ preventive, not a live defect — the same disposition and evidence standard #13478 and #13233 were closed on. Every figure is frozen in INLINE_LITERAL_EXPRESSION_CENSUS, printed on every run in the bounds line, and its arithmetic is pinned by --self-test.

Every position reached, with its classification

  • packages/rest/src/error-response.ts:1250code: isProvisioning ? 'PROJECT_PROVISIONING' : isFailed ? 'PROJECT_PROVISIONING_FAILED' : 'PROJECT_NOT_FOUND'. All three are in ERROR_CODE_LEDGER, so the scan derives no site and owes no row. This is the REST door file, stamped straight into an HTTP error envelope's body.code — registered today, and now no longer invisible to the gate tomorrow.
  • packages/runtime/src/domains/automation.ts:1125code: body.name === undefined ? 'required' : 'invalid_type'. An ADR-0112 D6 field-addressed validation catalog reaching details.fields[].code, never error.code. Two rows, foreign-vocabulary / door: 'none'.
  • The other 214 candidates all decline at the reduction: type annotations (code: string | undefined, code: FieldErrorCode, code?: 'a' | 'b') and runtime expressions (code: typeof issue.code === 'string' ? issue.code : 'unknown').

Where the lowercase catalog is reported, and why — measured, not assumed

The shape carries lowercase: 'here'. Every pattern check:error-code-casing has needs a quoted literal beside the token code; at an inline ternary there is none. Measured: findViolations() returns 0 findings for domains/automation.ts, while the literally-spelled code: 'invalid_type' a few lines up it does see and correctly skips as D6. That gate's own verdict text says the same thing from its side — "a code value with NO literal at the position — a constant, a template, a ternary, a helper parameter — is out of reach for every pattern here by construction; that half belongs to check:dispatcher-error-vocabulary". So a casing-gate delegation here would be the seam the gate's header describes, not a hand-off. --self-test pins this against that gate's real detector rather than against this paragraph. ⛔ check-error-code-casing.mjs is untouched.

Two deliberate boundaries, declared rather than discovered later

  • The anchor is the strict code:, not objlithelper's code\s*:\s*. Measured: the loose spelling matches the colon of a ternary, so typeof issue.code === 'string' ? issue.code : 'unknown' reads as a code : stamp of 'unknown' — a false position with no structural tell. objlithelper can afford the loose anchor because its parameter guard rejects that; this shape's guard is the reduction, which accepts it.
  • The regex refuses a bare quoted literal ((?!\s*'[^']*'\s*[,;}\n])). [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 pins the kebab-diagnostic declaration by counting recognizer matches, not findings; a bare code: anchor matchescode: 'unknown-component' even though every guard then declines it, and that reds the kebab pin. A bare literal is objlit's anyway. The cost is one declared remainder: a chain whose first operand is a bare quoted literal (code: 'A' || 'B') is handed to objlit, which reports 'A' and not 'B' — partial reporting rather than silence, zero live instances, counted as chainWhoseFirstOperandIsABareLiteral and pinned.

Ablation — every guard proved to fail

Run from a committed tree; each leg proved on disk by blob hash before/after, restored to the HEAD blob and verified equal, with a trap on EXIT/INT/TERM.

ablated--self-testwhat it said
the objlitexpr SHAPES entryexit 1SHAPE 'objlitexpr' matched nothing in its own sample + the nested-ternary pin
the sibling OWNERSHIP guardexit 1one stamp reported under two shape names
the CONDITIONAL-TYPE guardexit 1a CONDITIONAL type at a code: derived ["INLINE_A","INLINE_B"]
the enclosing-BRACKET testexit 1a code: in a function PARAMETER LIST derived ["INLINE_PARAM_A","INLINE_PARAM_B"]

⚠️ Two of these are only honest because the first attempt was not. The bracket-guard ablation initially sat green: the pin used (code: number | null, signal), whose value text the reduction declines anyway — a pin measuring nothing. It now uses a parameter default (code: string = down ? 'A' : 'B'), a value expression only the bracket rejects. And the bare-identifier partition is documented as what it is: with no resolver it changes no output today, so it is declared as a reader-facing statement of the partition rather than as a guard an ablation can see.

What is NOT here

Known limitation found on the way (filed, not fixed here)

The gate's shared textual scanners (enclosingOpeners, sliceBalanced, scanTopLevel) skip a string by seeking its closing quote, so a nested template literal `a ${xs.map((k) => `\`${k}\).join(', ')} b`` — closes the outer template at the first inner backtick and desynchronises everycode:position after it in that file.domains/automation.tscarries one at line 1285, and **two further instances of the identical catalog ternary** (the clone door'snameandlabelchecks,:1384and:1399) sit behind it, invisible to guard ①. Same values, same verdict, so the zero for hidden wire codes is unaffected — but the position count is a floor, not a total. Pre-existing and shared with objlithelper, recorded in the census and in the invalid_type` row rather than repaired inside a shape widening.

Verification

git diff --stat origin/main..HEAD — 2 files, exactly the declared surface:

 packages/runtime/src/dispatcher-error-vocabulary.ts | 83 ++-
scripts/check-dispatcher-error-vocabulary.mjs | 675 +++++++++++++++++++-
2 files changed, 753 insertions(+), 5 deletions(-)

Changeset

skip-changeset. The diff is one gate script plus packages/runtime/src/dispatcher-error-vocabulary.ts, which is a declaration table read textually by the gate and by tests: nothing in packages/runtime/src imports it, it is not re-exported from src/index.ts, and the package publishes only . — so no published bytes change. If a reviewer reads that differently, a changeset is cheap to add.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV


Generated by Claude Code

…`code:`
The vocabulary gate reached a `code:` whose value is a quoted literal
(`objlit`), a SCREAMING_SNAKE constant (`objlitconst`), a template
(`objlittemplate`) or a helper parameter (`objlithelper`), but not an INLINE
literal EXPRESSION — a ternary or a `||`/`??` chain written at the stamp with
every branch already a literal. That is no site AND no unresolved: the one way
the gate's "REPORTED as unresolved, never dropped" bound cannot notice itself
failing, in a third stamp position.
Adds the fifth object-literal shape, `objlitexpr`. It needs no resolver —
`literalCodeValues` reduces the value text between `code:` and the property's
terminating top-level comma directly, and `resolveIdent` is left at its default
so an identifier limb keeps the expression unreducible, which is what keeps this
shape out of the lower-case-LOCAL position that stays censused and open.
Precision measured BEFORE implementing, over the gate's own population: of 902
`code:` tokens the shape reaches 346, three guards reject 130, 216 reach the
reduction and 214 decline — including every type annotation — leaving 2 live
positions, 5 values, 2 verdict rows and 0 unregistered wire codes hiding. The
ALL-OR-NOTHING reduction IS the guard against the type-annotation noise the
helper position pays per value stamp. Frozen in
INLINE_LITERAL_EXPRESSION_CENSUS, printed in the bounds line, arithmetic pinned.
The two rows the widening owes land in the same commit, after the widening,
because the reconciliation runs in both directions: the ADR-0112 D6
field-addressed validation catalog in `domains/automation.ts`. They are reported
here rather than delegated to check:error-code-casing because that gate needs a
quoted literal beside the token `code` and an inline ternary has none —
measured, and pinned against its real detector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/runtime, touching 5 documentable anchor(s).

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

  • content/docs/api/error-catalog.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/api/error-handling-server.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/deployment/cli.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/protocol/objectui/concept.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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

  • content/docs/releases/v17.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 24 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21fpackageMentionDocs.

Which tree this was computed on

This run read content/docs from fe7200da54d381d2c79d8544c2737f8478bc7139 — the merge of head 8a10049e48beaa67589d72c742355f2a55bc29ae into base 87ad30c103bb4e8c5d7b8a399634b59716f3c21f, 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 fe7200da54d381d2c79d8544c2737f8478bc7139 && git checkout fe7200da54d381d2c79d8544c2737f8478bc7139
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87ad30c103bb4e8c5d7b8a399634b59716f3c21f 8a10049e48beaa67589d72c742355f2a55bc29ae && git checkout -B drift-repro 87ad30c103bb4e8c5d7b8a399634b59716f3c21f && git merge --no-ff 8a10049e48beaa67589d72c742355f2a55bc29ae
node scripts/docs-audit/affected-docs.mjs --json 87ad30c103bb4e8c5d7b8a399634b59716f3c21f

⚠️ 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

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

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] An INLINE literal ternary at an object-literal code: is reached by no vocabulary shape — the third stamp position, censused at zero

2 participants

@baozhoutao@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(devx): reach the INLINE literal expression at an object-literal code: - #14625

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape
Sep 2, 2026
Merged

feat(devx): reach the INLINE literal expression at an object-literal code:#14625
baozhoutao merged 1 commit into
mainfrom
claude/issue-13790-inline-literal-code-shape

Conversation

@claude

@claudeclaudeBot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes#13790

scripts/check-dispatcher-error-vocabulary.mjs reached no INLINE literal expression at an object-literal code: — a ternary, or a ||/?? chain, written at the stamp itself with every branch already a literal. That is no site AND no unresolved, the one way the gate's own "REPORTED as unresolved, never dropped" bound cannot notice itself failing, in a third stamp position after #9223's code: CONST and #13233's { code } helper.

This adds the fifth object-literal shape, objlitexpr. Per the triage's ⭐ it needs no resolver: literalCodeValues already reduces the expression, so the shape is the reduction of the value text between code: and the property's terminating top-level comma.

The precision measurement, first

The triage refused to authorise the widening until the precision cost was measured (objlithelper reaches 65 type annotations per value stamp). It was measured over the gate's own population — packages/** non-test source, 2186 files — with the gate's own primitives, before the shape was written. The finding: the ALL-OR-NOTHING reduction is the guard. A type annotation reduces to nothing for the same reason a runtime expression does, so it costs a continue and no verdict row.

code: tokens in the population902
reached by the shape's regex (a bare quoted literal is refused — see below)346
① rejected: enclosing bracket is not { (41 parameter lists, 33 inside a string)74
② rejected: already objlit's (4), objlitconst's (40), objlittemplate's (3)47
② rejected: a bare identifier (objlithelper's candidate / #13478's remainder)9
③ rejected: a CONDITIONAL type (code: T extends X ? 'A' : 'B')0
reaching the reduction216
declined by ALL-OR-NOTHING (~150 of them type annotations, ~64 runtime)214
true positions2
type-annotation positions surviving every guard0
distinct values behind the true positions5
verdict rows owed2
unregistered WIRE codes hiding0

⇒ preventive, not a live defect — the same disposition and evidence standard #13478 and #13233 were closed on. Every figure is frozen in INLINE_LITERAL_EXPRESSION_CENSUS, printed on every run in the bounds line, and its arithmetic is pinned by --self-test.

Every position reached, with its classification

  • packages/rest/src/error-response.ts:1250code: isProvisioning ? 'PROJECT_PROVISIONING' : isFailed ? 'PROJECT_PROVISIONING_FAILED' : 'PROJECT_NOT_FOUND'. All three are in ERROR_CODE_LEDGER, so the scan derives no site and owes no row. This is the REST door file, stamped straight into an HTTP error envelope's body.code — registered today, and now no longer invisible to the gate tomorrow.
  • packages/runtime/src/domains/automation.ts:1125code: body.name === undefined ? 'required' : 'invalid_type'. An ADR-0112 D6 field-addressed validation catalog reaching details.fields[].code, never error.code. Two rows, foreign-vocabulary / door: 'none'.
  • The other 214 candidates all decline at the reduction: type annotations (code: string | undefined, code: FieldErrorCode, code?: 'a' | 'b') and runtime expressions (code: typeof issue.code === 'string' ? issue.code : 'unknown').

Where the lowercase catalog is reported, and why — measured, not assumed

The shape carries lowercase: 'here'. Every pattern check:error-code-casing has needs a quoted literal beside the token code; at an inline ternary there is none. Measured: findViolations() returns 0 findings for domains/automation.ts, while the literally-spelled code: 'invalid_type' a few lines up it does see and correctly skips as D6. That gate's own verdict text says the same thing from its side — "a code value with NO literal at the position — a constant, a template, a ternary, a helper parameter — is out of reach for every pattern here by construction; that half belongs to check:dispatcher-error-vocabulary". So a casing-gate delegation here would be the seam the gate's header describes, not a hand-off. --self-test pins this against that gate's real detector rather than against this paragraph. ⛔ check-error-code-casing.mjs is untouched.

Two deliberate boundaries, declared rather than discovered later

  • The anchor is the strict code:, not objlithelper's code\s*:\s*. Measured: the loose spelling matches the colon of a ternary, so typeof issue.code === 'string' ? issue.code : 'unknown' reads as a code : stamp of 'unknown' — a false position with no structural tell. objlithelper can afford the loose anchor because its parameter guard rejects that; this shape's guard is the reduction, which accepts it.
  • The regex refuses a bare quoted literal ((?!\s*'[^']*'\s*[,;}\n])). [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 pins the kebab-diagnostic declaration by counting recognizer matches, not findings; a bare code: anchor matchescode: 'unknown-component' even though every guard then declines it, and that reds the kebab pin. A bare literal is objlit's anyway. The cost is one declared remainder: a chain whose first operand is a bare quoted literal (code: 'A' || 'B') is handed to objlit, which reports 'A' and not 'B' — partial reporting rather than silence, zero live instances, counted as chainWhoseFirstOperandIsABareLiteral and pinned.

Ablation — every guard proved to fail

Run from a committed tree; each leg proved on disk by blob hash before/after, restored to the HEAD blob and verified equal, with a trap on EXIT/INT/TERM.

ablated--self-testwhat it said
the objlitexpr SHAPES entryexit 1SHAPE 'objlitexpr' matched nothing in its own sample + the nested-ternary pin
the sibling OWNERSHIP guardexit 1one stamp reported under two shape names
the CONDITIONAL-TYPE guardexit 1a CONDITIONAL type at a code: derived ["INLINE_A","INLINE_B"]
the enclosing-BRACKET testexit 1a code: in a function PARAMETER LIST derived ["INLINE_PARAM_A","INLINE_PARAM_B"]

⚠️ Two of these are only honest because the first attempt was not. The bracket-guard ablation initially sat green: the pin used (code: number | null, signal), whose value text the reduction declines anyway — a pin measuring nothing. It now uses a parameter default (code: string = down ? 'A' : 'B'), a value expression only the bracket rejects. And the bare-identifier partition is documented as what it is: with no resolver it changes no output today, so it is declared as a reader-facing statement of the partition rather than as a guard an ablation can see.

What is NOT here

Known limitation found on the way (filed, not fixed here)

The gate's shared textual scanners (enclosingOpeners, sliceBalanced, scanTopLevel) skip a string by seeking its closing quote, so a nested template literal `a ${xs.map((k) => `\`${k}\).join(', ')} b`` — closes the outer template at the first inner backtick and desynchronises everycode:position after it in that file.domains/automation.tscarries one at line 1285, and **two further instances of the identical catalog ternary** (the clone door'snameandlabelchecks,:1384and:1399) sit behind it, invisible to guard ①. Same values, same verdict, so the zero for hidden wire codes is unaffected — but the position count is a floor, not a total. Pre-existing and shared with objlithelper, recorded in the census and in the invalid_type` row rather than repaired inside a shape widening.

Verification

git diff --stat origin/main..HEAD — 2 files, exactly the declared surface:

 packages/runtime/src/dispatcher-error-vocabulary.ts | 83 ++-
scripts/check-dispatcher-error-vocabulary.mjs | 675 +++++++++++++++++++-
2 files changed, 753 insertions(+), 5 deletions(-)

Changeset

skip-changeset. The diff is one gate script plus packages/runtime/src/dispatcher-error-vocabulary.ts, which is a declaration table read textually by the gate and by tests: nothing in packages/runtime/src imports it, it is not re-exported from src/index.ts, and the package publishes only . — so no published bytes change. If a reviewer reads that differently, a changeset is cheap to add.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV


Generated by Claude Code

…`code:`
The vocabulary gate reached a `code:` whose value is a quoted literal
(`objlit`), a SCREAMING_SNAKE constant (`objlitconst`), a template
(`objlittemplate`) or a helper parameter (`objlithelper`), but not an INLINE
literal EXPRESSION — a ternary or a `||`/`??` chain written at the stamp with
every branch already a literal. That is no site AND no unresolved: the one way
the gate's "REPORTED as unresolved, never dropped" bound cannot notice itself
failing, in a third stamp position.
Adds the fifth object-literal shape, `objlitexpr`. It needs no resolver —
`literalCodeValues` reduces the value text between `code:` and the property's
terminating top-level comma directly, and `resolveIdent` is left at its default
so an identifier limb keeps the expression unreducible, which is what keeps this
shape out of the lower-case-LOCAL position that stays censused and open.
Precision measured BEFORE implementing, over the gate's own population: of 902
`code:` tokens the shape reaches 346, three guards reject 130, 216 reach the
reduction and 214 decline — including every type annotation — leaving 2 live
positions, 5 values, 2 verdict rows and 0 unregistered wire codes hiding. The
ALL-OR-NOTHING reduction IS the guard against the type-annotation noise the
helper position pays per value stamp. Frozen in
INLINE_LITERAL_EXPRESSION_CENSUS, printed in the bounds line, arithmetic pinned.
The two rows the widening owes land in the same commit, after the widening,
because the reconciliation runs in both directions: the ADR-0112 D6
field-addressed validation catalog in `domains/automation.ts`. They are reported
here rather than delegated to check:error-code-casing because that gate needs a
quoted literal beside the token `code` and an inline ternary has none —
measured, and pinned against its real detector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLJQhde67SeTccsmnBVarV
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 2, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/runtime, touching 5 documentable anchor(s).

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

  • content/docs/api/error-catalog.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/api/error-handling-server.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/deployment/cli.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))
  • content/docs/protocol/objectui/concept.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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

  • content/docs/releases/v17.mdx(via invalid_type (literal, a string literal in UNREGISTERED_CODE_SITES))

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
  • 4 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 24 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21fpackageMentionDocs.

Which tree this was computed on

This run read content/docs from fe7200da54d381d2c79d8544c2737f8478bc7139 — the merge of head 8a10049e48beaa67589d72c742355f2a55bc29ae into base 87ad30c103bb4e8c5d7b8a399634b59716f3c21f, 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 fe7200da54d381d2c79d8544c2737f8478bc7139 && git checkout fe7200da54d381d2c79d8544c2737f8478bc7139
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 87ad30c103bb4e8c5d7b8a399634b59716f3c21f 8a10049e48beaa67589d72c742355f2a55bc29ae && git checkout -B drift-repro 87ad30c103bb4e8c5d7b8a399634b59716f3c21f && git merge --no-ff 8a10049e48beaa67589d72c742355f2a55bc29ae
node scripts/docs-audit/affected-docs.mjs --json 87ad30c103bb4e8c5d7b8a399634b59716f3c21f

⚠️ 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 87ad30c103bb4e8c5d7b8a399634b59716f3c21f → pass the list as
args.docs, on the commit named under Which tree this was computed on.

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

Labels

size/lskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] An INLINE literal ternary at an object-literal code: is reached by no vocabulary shape — the third stamp position, censused at zero

2 participants

@baozhoutao@claude