docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced - #13846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock
Aug 31, 2026
Merged

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced#13846
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#13787

Prose only. contradictsWrapperResolution's predicate is byte-identical to origin/main — 1128 characters, sha256dccdd2b341d10650… on both sides — and the whole diff is comment lines: 0 non-comment lines added, 0 removed, in 3 hunks that all sit inside that one docblock. The fence #13474 put on the predicate is intact; this card is its docblock, and nothing else.

The corrected clause — before / after

The card is one sentence, and it wraps across two lines, which is why a single-string grep for it returns zero. Before (the only clause in the file that asserted the flat index in the present tense):

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` is a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happens to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed.

After:

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` WAS a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happened to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed. (That index is no
* longer flat: #13474 made it scope-aware. It did not close THIS question —
* see the last block of this docblock.)

The paragraph is kept whole. It narrates the historical defect that motivates the predicate, and asked nothing at all / was followed were already past tense on purpose; only the functionBodies clause was wrongly in the present. Two words move (is to WAS, happens to happened) plus a three-line forward pointer. Flattening the whole paragraph to a description of today's index would have deleted the motivation.

The second hunk adds a closing block to the same docblock, next to the existing zero-cost statement, so the reader who lands on the predicate is told what #13474 did and why this predicate survives it:

 * WHY #13474 DID NOT SUBSUME THIS, stated here because the paragraph at the
* top narrates an index shape the file no longer has. `indexFunctionBodies`
* now resolves a name through the CALL SITE's lexical scope chain, which
* settles a collision between same-named BODIES — a different collision from
* the one asked about here, which is across RECEIVERS. Its ONE DECLARATION
* ⇒ UNCHANGED rule keeps it that way on purpose: a name with exactly one body
* in the file is answered from any call site, so a unique name reached on a
* compound receiver is admitted there and refused only here.
* `indexFunctionBodies`' own docblock records the same from its side, and this
* is the near half of that pair. Re-measured on this tree after the resolver
* changed, with this predicate ablated: the two #12358 cases in the self-test
* report 1 seam each instead of 0, and `--list` over the scan root is
* byte-identical either way — the zero-seam cost stated just above, still
* zero.

That pointer is deliberate and it is the pair's near half: indexFunctionBodies' docblock already points at this predicate from ~900 lines away, and now this one points back.

Is the predicate's motivation still sound after #13474? — measured, and yes

#13784's docblock claims the predicate stays load-bearing (a unique name reached on a compound receiver is admitted by the one-declaration rule and refused by that predicate). Verified on this tree by ablation rather than by reading: return false; injected as the first statement of contradictsWrapperResolution, mutation confirmed on disk before the run (marker count 0 to 1, 335171 to 335207 bytes, git diff --stat one insertion), restored afterwards with git checkout HEAD -- ... and the restore proved by hash (d0dc23ff… before and after) plus an empty git diff HEAD. No build step exists between edit and run — the gate is an .mjs executed from source, not from a dist/.

measurementpredicate livepredicate ablated
--self-test, read-seam rule57 cases pass2 fail
--list, whole scan root66 seams66 seams, byte-identical output

The two failures are exactly the two #12358 fixtures, one per clause:

✗ passes: #12358 — a compound receiver does not resolve to the same-file method it collides with: expected violation=false seams=0, got violation=false count=0 seams=1
✗ passes: #12358 — a call that cannot satisfy the resolved declaration is not that declaration: expected violation=false seams=0, got violation=false count=0 seams=1

Both fixtures declare deleteexactly once, so indexFunctionBodies' one-declaration rule answers the name from any call site and hands the hop straight to this predicate. The scope-aware resolver does not and cannot refuse them — it settles same-name collisions, and there is no collision here. ⇒ the motivation is unchanged in force, narrower in wording: the docblock should no longer say the index is flat, but the reason the predicate exists is untouched, and the file's zero-seam cost figure for it is still zero after the resolver changed.

Census — every bare name / flat index mention in the file, classified

Censused by mechanism (functionBodies, BARE NAME, bare name, flat, LAST-WINS, scope-aware, 13474 as separate terms), never as one contiguous string.

linetextverdict
433helper resolution is file-scoped by construction (functionBodies is built per source file)legitimate — about file scoping, not keying. Still true: the index is built per source file.
1379–1390functionBodies WAS keyed by bare name and LAST-WINS … #13474 replaced the flat indexlegitimate — explicitly past tense and already reconciled to #13474 in the same block.
1529–1530functionBodies is a flat, file-scoped index keyed by BARE NAMESTALE — the one this card fixes. Present tense asserting the replaced shape.
2133–2137Only const/let declarations with an initializer are indexed, keyed by bare name and LAST-WINS. That is deliberately NOT the scope-aware model indexFunctionBodies moved to for #13474legitimate — a different index (indexLogAliases), still bare-name last-wins on purpose, with the departure measured and stated.
2422–2436## Why this is not keyed by bare name alone (#13474) — It was, and it was LAST-WINS … the flat index answered with the THIRDlegitimateindexFunctionBodies' own docblock, historical narration, the far half of the pair.
2509the tie-break the flat index already madelegitimate — describes the deliberate within-one-scope tie-break the new resolver kept.
2950indexFunctionBodies keys by BARE NAME, so an unrelated close() in another class in the same file could supply that licencelegitimate, and worth saying why it is not the same defect. The map key is still the bare name (a Map of name to a list of declarations); what changed is that resolution is no longer by key alone. The hazard it warns about also survives, through the one-declaration rule: a close declared once in the file is still answered from any call site, including from another class. True as written, so it is untouched.
6111–6124, 6186Before it, the index was one flat Map … (1) the flat index DROPS a real seam … The flat index answered with the thirdlegitimate — the #13474 regression-control block, describing the model the four fixtures exist to keep out.

Nothing was changed on grounds of resemblance: 1529–1530 is the only present-tense assertion of the replaced shape.

Verification

Every gate run explicitly, exit code captured before any pipe. Final commit for all of it: de44eb1b9.

commandresult
pnpm check:durability-log-levelexit=0✓ self-test (log-level rule): 63 case(s) passed · ✓ self-test (read-seam invention rule): 57 case(s) passed · ✓ read-seam invention …: 66 read seam(s), none invents an unreported answer
pnpm check:ratchet-remedy-authorityexit=0OK check-ratchet-remedy-authority: 176 scripts swept (scripts/*.{mjs,mts}); 11 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 160 hand out no ratchet-expanding remedy.
node scripts/check-ratchet-remedy-authority.mjs --self-testexit=0OK self-test: the lexer holds, messages are bounded, …
pnpm check:nul-bytesexit=0
pnpm lint (repo-wide eslint . --no-inline-config, not narrowed)exit=0, no findings
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literalall exit=0
node scripts/check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs, check-shard-attestation.mjsall exit=0
node scripts/check-test-completeness.mjsexit=3NOT MEASURED, not a red: the gate grades a saved turbo run test log and none was named. Its own text says to record it as NOT MEASURED when run from the derived family.
node scripts/pm/bare-root-worklist.mjs --self-testexit=0 — convention-triggered (this edits a gate script)
pnpm check:pm-dispatch-gatesexit=0 — same convention trigger
pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts src/protocol.metadata-store-outage.test.tsexit=0Test Files 2 passed (2), Tests 44 passed (44). These are the pin tests that read this script by path, so they are owed on top of the path-derived family.

The family was re-derived from the real diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed), which also surfaced the two convention-triggered obligations above.

Why there is no changeset

The dispatch order asked for one. This diff publishes nothing: it is comment lines in scripts/check-durability-degradation-log-level.mjs, a repo-root gate script that belongs to no published package, so a changeset would have to name a package and fabricate a CHANGELOG entry for a comment. An empty-frontmatter changeset is not the alternative — scripts/check-empty-changeset.mjs rejects newly added ones outright, and its header records why. Precedent on this exact file is uniform: of the last 12 commits touching it, the 10 that were script-only carried zero changeset files, #13474's own PR (6207c9ecc) among them. skip-changeset is applied to this PR instead, and read back after applying.


Generated by Claude Code

…he flat bare-name index
#13474 replaced indexFunctionBodies' flat last-wins map with call-site
lexical resolution, which made one clause of this predicate's docblock
false: the paragraph narrates the historical defect in the past tense but
asserted the flat index in the PRESENT. The paragraph is kept — it is why
the predicate exists — and only that clause moves to the past tense.
A closing block states what #13474 did and why this predicate survives it:
the resolver settles collisions between same-named BODIES, this one asks
about a collision across RECEIVERS, and the ONE DECLARATION => UNCHANGED
rule routes a unique name reached on a compound receiver straight here.
Re-measured on this tree, ablating the predicate: the two #12358 self-test
cases report 1 seam each instead of 0, and --list over the scan root is
byte-identical (66 seams either way).
Prose only. The predicate's body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 31, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 31, 2026 15:43
@os-project-manager
os-project-manager added this pull request to the merge queueAug 31, 2026
Merged via the queue into main with commit 36cf8d8Aug 31, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13787-wrapper-resolution-docblock branch August 31, 2026 16:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contradictsWrapperResolution's docblock still calls functionBodies a flat bare-name index — #13474 made it scope-aware

2 participants

@os-project-manager@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

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced - #13846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock
Aug 31, 2026
Merged

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced#13846
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#13787

Prose only. contradictsWrapperResolution's predicate is byte-identical to origin/main — 1128 characters, sha256dccdd2b341d10650… on both sides — and the whole diff is comment lines: 0 non-comment lines added, 0 removed, in 3 hunks that all sit inside that one docblock. The fence #13474 put on the predicate is intact; this card is its docblock, and nothing else.

The corrected clause — before / after

The card is one sentence, and it wraps across two lines, which is why a single-string grep for it returns zero. Before (the only clause in the file that asserted the flat index in the present tense):

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` is a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happens to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed.

After:

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` WAS a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happened to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed. (That index is no
* longer flat: #13474 made it scope-aware. It did not close THIS question —
* see the last block of this docblock.)

The paragraph is kept whole. It narrates the historical defect that motivates the predicate, and asked nothing at all / was followed were already past tense on purpose; only the functionBodies clause was wrongly in the present. Two words move (is to WAS, happens to happened) plus a three-line forward pointer. Flattening the whole paragraph to a description of today's index would have deleted the motivation.

The second hunk adds a closing block to the same docblock, next to the existing zero-cost statement, so the reader who lands on the predicate is told what #13474 did and why this predicate survives it:

 * WHY #13474 DID NOT SUBSUME THIS, stated here because the paragraph at the
* top narrates an index shape the file no longer has. `indexFunctionBodies`
* now resolves a name through the CALL SITE's lexical scope chain, which
* settles a collision between same-named BODIES — a different collision from
* the one asked about here, which is across RECEIVERS. Its ONE DECLARATION
* ⇒ UNCHANGED rule keeps it that way on purpose: a name with exactly one body
* in the file is answered from any call site, so a unique name reached on a
* compound receiver is admitted there and refused only here.
* `indexFunctionBodies`' own docblock records the same from its side, and this
* is the near half of that pair. Re-measured on this tree after the resolver
* changed, with this predicate ablated: the two #12358 cases in the self-test
* report 1 seam each instead of 0, and `--list` over the scan root is
* byte-identical either way — the zero-seam cost stated just above, still
* zero.

That pointer is deliberate and it is the pair's near half: indexFunctionBodies' docblock already points at this predicate from ~900 lines away, and now this one points back.

Is the predicate's motivation still sound after #13474? — measured, and yes

#13784's docblock claims the predicate stays load-bearing (a unique name reached on a compound receiver is admitted by the one-declaration rule and refused by that predicate). Verified on this tree by ablation rather than by reading: return false; injected as the first statement of contradictsWrapperResolution, mutation confirmed on disk before the run (marker count 0 to 1, 335171 to 335207 bytes, git diff --stat one insertion), restored afterwards with git checkout HEAD -- ... and the restore proved by hash (d0dc23ff… before and after) plus an empty git diff HEAD. No build step exists between edit and run — the gate is an .mjs executed from source, not from a dist/.

measurementpredicate livepredicate ablated
--self-test, read-seam rule57 cases pass2 fail
--list, whole scan root66 seams66 seams, byte-identical output

The two failures are exactly the two #12358 fixtures, one per clause:

✗ passes: #12358 — a compound receiver does not resolve to the same-file method it collides with: expected violation=false seams=0, got violation=false count=0 seams=1
✗ passes: #12358 — a call that cannot satisfy the resolved declaration is not that declaration: expected violation=false seams=0, got violation=false count=0 seams=1

Both fixtures declare deleteexactly once, so indexFunctionBodies' one-declaration rule answers the name from any call site and hands the hop straight to this predicate. The scope-aware resolver does not and cannot refuse them — it settles same-name collisions, and there is no collision here. ⇒ the motivation is unchanged in force, narrower in wording: the docblock should no longer say the index is flat, but the reason the predicate exists is untouched, and the file's zero-seam cost figure for it is still zero after the resolver changed.

Census — every bare name / flat index mention in the file, classified

Censused by mechanism (functionBodies, BARE NAME, bare name, flat, LAST-WINS, scope-aware, 13474 as separate terms), never as one contiguous string.

linetextverdict
433helper resolution is file-scoped by construction (functionBodies is built per source file)legitimate — about file scoping, not keying. Still true: the index is built per source file.
1379–1390functionBodies WAS keyed by bare name and LAST-WINS … #13474 replaced the flat indexlegitimate — explicitly past tense and already reconciled to #13474 in the same block.
1529–1530functionBodies is a flat, file-scoped index keyed by BARE NAMESTALE — the one this card fixes. Present tense asserting the replaced shape.
2133–2137Only const/let declarations with an initializer are indexed, keyed by bare name and LAST-WINS. That is deliberately NOT the scope-aware model indexFunctionBodies moved to for #13474legitimate — a different index (indexLogAliases), still bare-name last-wins on purpose, with the departure measured and stated.
2422–2436## Why this is not keyed by bare name alone (#13474) — It was, and it was LAST-WINS … the flat index answered with the THIRDlegitimateindexFunctionBodies' own docblock, historical narration, the far half of the pair.
2509the tie-break the flat index already madelegitimate — describes the deliberate within-one-scope tie-break the new resolver kept.
2950indexFunctionBodies keys by BARE NAME, so an unrelated close() in another class in the same file could supply that licencelegitimate, and worth saying why it is not the same defect. The map key is still the bare name (a Map of name to a list of declarations); what changed is that resolution is no longer by key alone. The hazard it warns about also survives, through the one-declaration rule: a close declared once in the file is still answered from any call site, including from another class. True as written, so it is untouched.
6111–6124, 6186Before it, the index was one flat Map … (1) the flat index DROPS a real seam … The flat index answered with the thirdlegitimate — the #13474 regression-control block, describing the model the four fixtures exist to keep out.

Nothing was changed on grounds of resemblance: 1529–1530 is the only present-tense assertion of the replaced shape.

Verification

Every gate run explicitly, exit code captured before any pipe. Final commit for all of it: de44eb1b9.

commandresult
pnpm check:durability-log-levelexit=0✓ self-test (log-level rule): 63 case(s) passed · ✓ self-test (read-seam invention rule): 57 case(s) passed · ✓ read-seam invention …: 66 read seam(s), none invents an unreported answer
pnpm check:ratchet-remedy-authorityexit=0OK check-ratchet-remedy-authority: 176 scripts swept (scripts/*.{mjs,mts}); 11 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 160 hand out no ratchet-expanding remedy.
node scripts/check-ratchet-remedy-authority.mjs --self-testexit=0OK self-test: the lexer holds, messages are bounded, …
pnpm check:nul-bytesexit=0
pnpm lint (repo-wide eslint . --no-inline-config, not narrowed)exit=0, no findings
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literalall exit=0
node scripts/check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs, check-shard-attestation.mjsall exit=0
node scripts/check-test-completeness.mjsexit=3NOT MEASURED, not a red: the gate grades a saved turbo run test log and none was named. Its own text says to record it as NOT MEASURED when run from the derived family.
node scripts/pm/bare-root-worklist.mjs --self-testexit=0 — convention-triggered (this edits a gate script)
pnpm check:pm-dispatch-gatesexit=0 — same convention trigger
pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts src/protocol.metadata-store-outage.test.tsexit=0Test Files 2 passed (2), Tests 44 passed (44). These are the pin tests that read this script by path, so they are owed on top of the path-derived family.

The family was re-derived from the real diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed), which also surfaced the two convention-triggered obligations above.

Why there is no changeset

The dispatch order asked for one. This diff publishes nothing: it is comment lines in scripts/check-durability-degradation-log-level.mjs, a repo-root gate script that belongs to no published package, so a changeset would have to name a package and fabricate a CHANGELOG entry for a comment. An empty-frontmatter changeset is not the alternative — scripts/check-empty-changeset.mjs rejects newly added ones outright, and its header records why. Precedent on this exact file is uniform: of the last 12 commits touching it, the 10 that were script-only carried zero changeset files, #13474's own PR (6207c9ecc) among them. skip-changeset is applied to this PR instead, and read back after applying.


Generated by Claude Code

…he flat bare-name index
#13474 replaced indexFunctionBodies' flat last-wins map with call-site
lexical resolution, which made one clause of this predicate's docblock
false: the paragraph narrates the historical defect in the past tense but
asserted the flat index in the PRESENT. The paragraph is kept — it is why
the predicate exists — and only that clause moves to the past tense.
A closing block states what #13474 did and why this predicate survives it:
the resolver settles collisions between same-named BODIES, this one asks
about a collision across RECEIVERS, and the ONE DECLARATION => UNCHANGED
rule routes a unique name reached on a compound receiver straight here.
Re-measured on this tree, ablating the predicate: the two #12358 self-test
cases report 1 seam each instead of 0, and --list over the scan root is
byte-identical (66 seams either way).
Prose only. The predicate's body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 31, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 31, 2026 15:43
@os-project-manager
os-project-manager added this pull request to the merge queueAug 31, 2026
Merged via the queue into main with commit 36cf8d8Aug 31, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13787-wrapper-resolution-docblock branch August 31, 2026 16:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contradictsWrapperResolution's docblock still calls functionBodies a flat bare-name index — #13474 made it scope-aware

2 participants

@os-project-manager@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

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced - #13846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock
Aug 31, 2026
Merged

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced#13846
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#13787

Prose only. contradictsWrapperResolution's predicate is byte-identical to origin/main — 1128 characters, sha256dccdd2b341d10650… on both sides — and the whole diff is comment lines: 0 non-comment lines added, 0 removed, in 3 hunks that all sit inside that one docblock. The fence #13474 put on the predicate is intact; this card is its docblock, and nothing else.

The corrected clause — before / after

The card is one sentence, and it wraps across two lines, which is why a single-string grep for it returns zero. Before (the only clause in the file that asserted the flat index in the present tense):

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` is a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happens to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed.

After:

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` WAS a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happened to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed. (That index is no
* longer flat: #13474 made it scope-aware. It did not close THIS question —
* see the last block of this docblock.)

The paragraph is kept whole. It narrates the historical defect that motivates the predicate, and asked nothing at all / was followed were already past tense on purpose; only the functionBodies clause was wrongly in the present. Two words move (is to WAS, happens to happened) plus a three-line forward pointer. Flattening the whole paragraph to a description of today's index would have deleted the motivation.

The second hunk adds a closing block to the same docblock, next to the existing zero-cost statement, so the reader who lands on the predicate is told what #13474 did and why this predicate survives it:

 * WHY #13474 DID NOT SUBSUME THIS, stated here because the paragraph at the
* top narrates an index shape the file no longer has. `indexFunctionBodies`
* now resolves a name through the CALL SITE's lexical scope chain, which
* settles a collision between same-named BODIES — a different collision from
* the one asked about here, which is across RECEIVERS. Its ONE DECLARATION
* ⇒ UNCHANGED rule keeps it that way on purpose: a name with exactly one body
* in the file is answered from any call site, so a unique name reached on a
* compound receiver is admitted there and refused only here.
* `indexFunctionBodies`' own docblock records the same from its side, and this
* is the near half of that pair. Re-measured on this tree after the resolver
* changed, with this predicate ablated: the two #12358 cases in the self-test
* report 1 seam each instead of 0, and `--list` over the scan root is
* byte-identical either way — the zero-seam cost stated just above, still
* zero.

That pointer is deliberate and it is the pair's near half: indexFunctionBodies' docblock already points at this predicate from ~900 lines away, and now this one points back.

Is the predicate's motivation still sound after #13474? — measured, and yes

#13784's docblock claims the predicate stays load-bearing (a unique name reached on a compound receiver is admitted by the one-declaration rule and refused by that predicate). Verified on this tree by ablation rather than by reading: return false; injected as the first statement of contradictsWrapperResolution, mutation confirmed on disk before the run (marker count 0 to 1, 335171 to 335207 bytes, git diff --stat one insertion), restored afterwards with git checkout HEAD -- ... and the restore proved by hash (d0dc23ff… before and after) plus an empty git diff HEAD. No build step exists between edit and run — the gate is an .mjs executed from source, not from a dist/.

measurementpredicate livepredicate ablated
--self-test, read-seam rule57 cases pass2 fail
--list, whole scan root66 seams66 seams, byte-identical output

The two failures are exactly the two #12358 fixtures, one per clause:

✗ passes: #12358 — a compound receiver does not resolve to the same-file method it collides with: expected violation=false seams=0, got violation=false count=0 seams=1
✗ passes: #12358 — a call that cannot satisfy the resolved declaration is not that declaration: expected violation=false seams=0, got violation=false count=0 seams=1

Both fixtures declare deleteexactly once, so indexFunctionBodies' one-declaration rule answers the name from any call site and hands the hop straight to this predicate. The scope-aware resolver does not and cannot refuse them — it settles same-name collisions, and there is no collision here. ⇒ the motivation is unchanged in force, narrower in wording: the docblock should no longer say the index is flat, but the reason the predicate exists is untouched, and the file's zero-seam cost figure for it is still zero after the resolver changed.

Census — every bare name / flat index mention in the file, classified

Censused by mechanism (functionBodies, BARE NAME, bare name, flat, LAST-WINS, scope-aware, 13474 as separate terms), never as one contiguous string.

linetextverdict
433helper resolution is file-scoped by construction (functionBodies is built per source file)legitimate — about file scoping, not keying. Still true: the index is built per source file.
1379–1390functionBodies WAS keyed by bare name and LAST-WINS … #13474 replaced the flat indexlegitimate — explicitly past tense and already reconciled to #13474 in the same block.
1529–1530functionBodies is a flat, file-scoped index keyed by BARE NAMESTALE — the one this card fixes. Present tense asserting the replaced shape.
2133–2137Only const/let declarations with an initializer are indexed, keyed by bare name and LAST-WINS. That is deliberately NOT the scope-aware model indexFunctionBodies moved to for #13474legitimate — a different index (indexLogAliases), still bare-name last-wins on purpose, with the departure measured and stated.
2422–2436## Why this is not keyed by bare name alone (#13474) — It was, and it was LAST-WINS … the flat index answered with the THIRDlegitimateindexFunctionBodies' own docblock, historical narration, the far half of the pair.
2509the tie-break the flat index already madelegitimate — describes the deliberate within-one-scope tie-break the new resolver kept.
2950indexFunctionBodies keys by BARE NAME, so an unrelated close() in another class in the same file could supply that licencelegitimate, and worth saying why it is not the same defect. The map key is still the bare name (a Map of name to a list of declarations); what changed is that resolution is no longer by key alone. The hazard it warns about also survives, through the one-declaration rule: a close declared once in the file is still answered from any call site, including from another class. True as written, so it is untouched.
6111–6124, 6186Before it, the index was one flat Map … (1) the flat index DROPS a real seam … The flat index answered with the thirdlegitimate — the #13474 regression-control block, describing the model the four fixtures exist to keep out.

Nothing was changed on grounds of resemblance: 1529–1530 is the only present-tense assertion of the replaced shape.

Verification

Every gate run explicitly, exit code captured before any pipe. Final commit for all of it: de44eb1b9.

commandresult
pnpm check:durability-log-levelexit=0✓ self-test (log-level rule): 63 case(s) passed · ✓ self-test (read-seam invention rule): 57 case(s) passed · ✓ read-seam invention …: 66 read seam(s), none invents an unreported answer
pnpm check:ratchet-remedy-authorityexit=0OK check-ratchet-remedy-authority: 176 scripts swept (scripts/*.{mjs,mts}); 11 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 160 hand out no ratchet-expanding remedy.
node scripts/check-ratchet-remedy-authority.mjs --self-testexit=0OK self-test: the lexer holds, messages are bounded, …
pnpm check:nul-bytesexit=0
pnpm lint (repo-wide eslint . --no-inline-config, not narrowed)exit=0, no findings
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literalall exit=0
node scripts/check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs, check-shard-attestation.mjsall exit=0
node scripts/check-test-completeness.mjsexit=3NOT MEASURED, not a red: the gate grades a saved turbo run test log and none was named. Its own text says to record it as NOT MEASURED when run from the derived family.
node scripts/pm/bare-root-worklist.mjs --self-testexit=0 — convention-triggered (this edits a gate script)
pnpm check:pm-dispatch-gatesexit=0 — same convention trigger
pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts src/protocol.metadata-store-outage.test.tsexit=0Test Files 2 passed (2), Tests 44 passed (44). These are the pin tests that read this script by path, so they are owed on top of the path-derived family.

The family was re-derived from the real diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed), which also surfaced the two convention-triggered obligations above.

Why there is no changeset

The dispatch order asked for one. This diff publishes nothing: it is comment lines in scripts/check-durability-degradation-log-level.mjs, a repo-root gate script that belongs to no published package, so a changeset would have to name a package and fabricate a CHANGELOG entry for a comment. An empty-frontmatter changeset is not the alternative — scripts/check-empty-changeset.mjs rejects newly added ones outright, and its header records why. Precedent on this exact file is uniform: of the last 12 commits touching it, the 10 that were script-only carried zero changeset files, #13474's own PR (6207c9ecc) among them. skip-changeset is applied to this PR instead, and read back after applying.


Generated by Claude Code

…he flat bare-name index
#13474 replaced indexFunctionBodies' flat last-wins map with call-site
lexical resolution, which made one clause of this predicate's docblock
false: the paragraph narrates the historical defect in the past tense but
asserted the flat index in the PRESENT. The paragraph is kept — it is why
the predicate exists — and only that clause moves to the past tense.
A closing block states what #13474 did and why this predicate survives it:
the resolver settles collisions between same-named BODIES, this one asks
about a collision across RECEIVERS, and the ONE DECLARATION => UNCHANGED
rule routes a unique name reached on a compound receiver straight here.
Re-measured on this tree, ablating the predicate: the two #12358 self-test
cases report 1 seam each instead of 0, and --list over the scan root is
byte-identical (66 seams either way).
Prose only. The predicate's body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 31, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 31, 2026 15:43
@os-project-manager
os-project-manager added this pull request to the merge queueAug 31, 2026
Merged via the queue into main with commit 36cf8d8Aug 31, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13787-wrapper-resolution-docblock branch August 31, 2026 16:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contradictsWrapperResolution's docblock still calls functionBodies a flat bare-name index — #13474 made it scope-aware

2 participants

@os-project-manager@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

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced - #13846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock
Aug 31, 2026
Merged

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced#13846
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#13787

Prose only. contradictsWrapperResolution's predicate is byte-identical to origin/main — 1128 characters, sha256dccdd2b341d10650… on both sides — and the whole diff is comment lines: 0 non-comment lines added, 0 removed, in 3 hunks that all sit inside that one docblock. The fence #13474 put on the predicate is intact; this card is its docblock, and nothing else.

The corrected clause — before / after

The card is one sentence, and it wraps across two lines, which is why a single-string grep for it returns zero. Before (the only clause in the file that asserted the flat index in the present tense):

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` is a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happens to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed.

After:

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` WAS a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happened to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed. (That index is no
* longer flat: #13474 made it scope-aware. It did not close THIS question —
* see the last block of this docblock.)

The paragraph is kept whole. It narrates the historical defect that motivates the predicate, and asked nothing at all / was followed were already past tense on purpose; only the functionBodies clause was wrongly in the present. Two words move (is to WAS, happens to happened) plus a three-line forward pointer. Flattening the whole paragraph to a description of today's index would have deleted the motivation.

The second hunk adds a closing block to the same docblock, next to the existing zero-cost statement, so the reader who lands on the predicate is told what #13474 did and why this predicate survives it:

 * WHY #13474 DID NOT SUBSUME THIS, stated here because the paragraph at the
* top narrates an index shape the file no longer has. `indexFunctionBodies`
* now resolves a name through the CALL SITE's lexical scope chain, which
* settles a collision between same-named BODIES — a different collision from
* the one asked about here, which is across RECEIVERS. Its ONE DECLARATION
* ⇒ UNCHANGED rule keeps it that way on purpose: a name with exactly one body
* in the file is answered from any call site, so a unique name reached on a
* compound receiver is admitted there and refused only here.
* `indexFunctionBodies`' own docblock records the same from its side, and this
* is the near half of that pair. Re-measured on this tree after the resolver
* changed, with this predicate ablated: the two #12358 cases in the self-test
* report 1 seam each instead of 0, and `--list` over the scan root is
* byte-identical either way — the zero-seam cost stated just above, still
* zero.

That pointer is deliberate and it is the pair's near half: indexFunctionBodies' docblock already points at this predicate from ~900 lines away, and now this one points back.

Is the predicate's motivation still sound after #13474? — measured, and yes

#13784's docblock claims the predicate stays load-bearing (a unique name reached on a compound receiver is admitted by the one-declaration rule and refused by that predicate). Verified on this tree by ablation rather than by reading: return false; injected as the first statement of contradictsWrapperResolution, mutation confirmed on disk before the run (marker count 0 to 1, 335171 to 335207 bytes, git diff --stat one insertion), restored afterwards with git checkout HEAD -- ... and the restore proved by hash (d0dc23ff… before and after) plus an empty git diff HEAD. No build step exists between edit and run — the gate is an .mjs executed from source, not from a dist/.

measurementpredicate livepredicate ablated
--self-test, read-seam rule57 cases pass2 fail
--list, whole scan root66 seams66 seams, byte-identical output

The two failures are exactly the two #12358 fixtures, one per clause:

✗ passes: #12358 — a compound receiver does not resolve to the same-file method it collides with: expected violation=false seams=0, got violation=false count=0 seams=1
✗ passes: #12358 — a call that cannot satisfy the resolved declaration is not that declaration: expected violation=false seams=0, got violation=false count=0 seams=1

Both fixtures declare deleteexactly once, so indexFunctionBodies' one-declaration rule answers the name from any call site and hands the hop straight to this predicate. The scope-aware resolver does not and cannot refuse them — it settles same-name collisions, and there is no collision here. ⇒ the motivation is unchanged in force, narrower in wording: the docblock should no longer say the index is flat, but the reason the predicate exists is untouched, and the file's zero-seam cost figure for it is still zero after the resolver changed.

Census — every bare name / flat index mention in the file, classified

Censused by mechanism (functionBodies, BARE NAME, bare name, flat, LAST-WINS, scope-aware, 13474 as separate terms), never as one contiguous string.

linetextverdict
433helper resolution is file-scoped by construction (functionBodies is built per source file)legitimate — about file scoping, not keying. Still true: the index is built per source file.
1379–1390functionBodies WAS keyed by bare name and LAST-WINS … #13474 replaced the flat indexlegitimate — explicitly past tense and already reconciled to #13474 in the same block.
1529–1530functionBodies is a flat, file-scoped index keyed by BARE NAMESTALE — the one this card fixes. Present tense asserting the replaced shape.
2133–2137Only const/let declarations with an initializer are indexed, keyed by bare name and LAST-WINS. That is deliberately NOT the scope-aware model indexFunctionBodies moved to for #13474legitimate — a different index (indexLogAliases), still bare-name last-wins on purpose, with the departure measured and stated.
2422–2436## Why this is not keyed by bare name alone (#13474) — It was, and it was LAST-WINS … the flat index answered with the THIRDlegitimateindexFunctionBodies' own docblock, historical narration, the far half of the pair.
2509the tie-break the flat index already madelegitimate — describes the deliberate within-one-scope tie-break the new resolver kept.
2950indexFunctionBodies keys by BARE NAME, so an unrelated close() in another class in the same file could supply that licencelegitimate, and worth saying why it is not the same defect. The map key is still the bare name (a Map of name to a list of declarations); what changed is that resolution is no longer by key alone. The hazard it warns about also survives, through the one-declaration rule: a close declared once in the file is still answered from any call site, including from another class. True as written, so it is untouched.
6111–6124, 6186Before it, the index was one flat Map … (1) the flat index DROPS a real seam … The flat index answered with the thirdlegitimate — the #13474 regression-control block, describing the model the four fixtures exist to keep out.

Nothing was changed on grounds of resemblance: 1529–1530 is the only present-tense assertion of the replaced shape.

Verification

Every gate run explicitly, exit code captured before any pipe. Final commit for all of it: de44eb1b9.

commandresult
pnpm check:durability-log-levelexit=0✓ self-test (log-level rule): 63 case(s) passed · ✓ self-test (read-seam invention rule): 57 case(s) passed · ✓ read-seam invention …: 66 read seam(s), none invents an unreported answer
pnpm check:ratchet-remedy-authorityexit=0OK check-ratchet-remedy-authority: 176 scripts swept (scripts/*.{mjs,mts}); 11 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 160 hand out no ratchet-expanding remedy.
node scripts/check-ratchet-remedy-authority.mjs --self-testexit=0OK self-test: the lexer holds, messages are bounded, …
pnpm check:nul-bytesexit=0
pnpm lint (repo-wide eslint . --no-inline-config, not narrowed)exit=0, no findings
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literalall exit=0
node scripts/check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs, check-shard-attestation.mjsall exit=0
node scripts/check-test-completeness.mjsexit=3NOT MEASURED, not a red: the gate grades a saved turbo run test log and none was named. Its own text says to record it as NOT MEASURED when run from the derived family.
node scripts/pm/bare-root-worklist.mjs --self-testexit=0 — convention-triggered (this edits a gate script)
pnpm check:pm-dispatch-gatesexit=0 — same convention trigger
pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts src/protocol.metadata-store-outage.test.tsexit=0Test Files 2 passed (2), Tests 44 passed (44). These are the pin tests that read this script by path, so they are owed on top of the path-derived family.

The family was re-derived from the real diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed), which also surfaced the two convention-triggered obligations above.

Why there is no changeset

The dispatch order asked for one. This diff publishes nothing: it is comment lines in scripts/check-durability-degradation-log-level.mjs, a repo-root gate script that belongs to no published package, so a changeset would have to name a package and fabricate a CHANGELOG entry for a comment. An empty-frontmatter changeset is not the alternative — scripts/check-empty-changeset.mjs rejects newly added ones outright, and its header records why. Precedent on this exact file is uniform: of the last 12 commits touching it, the 10 that were script-only carried zero changeset files, #13474's own PR (6207c9ecc) among them. skip-changeset is applied to this PR instead, and read back after applying.


Generated by Claude Code

…he flat bare-name index
#13474 replaced indexFunctionBodies' flat last-wins map with call-site
lexical resolution, which made one clause of this predicate's docblock
false: the paragraph narrates the historical defect in the past tense but
asserted the flat index in the PRESENT. The paragraph is kept — it is why
the predicate exists — and only that clause moves to the past tense.
A closing block states what #13474 did and why this predicate survives it:
the resolver settles collisions between same-named BODIES, this one asks
about a collision across RECEIVERS, and the ONE DECLARATION => UNCHANGED
rule routes a unique name reached on a compound receiver straight here.
Re-measured on this tree, ablating the predicate: the two #12358 self-test
cases report 1 seam each instead of 0, and --list over the scan root is
byte-identical (66 seams either way).
Prose only. The predicate's body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 31, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 31, 2026 15:43
@os-project-manager
os-project-manager added this pull request to the merge queueAug 31, 2026
Merged via the queue into main with commit 36cf8d8Aug 31, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13787-wrapper-resolution-docblock branch August 31, 2026 16:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contradictsWrapperResolution's docblock still calls functionBodies a flat bare-name index — #13474 made it scope-aware

2 participants

@os-project-manager@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

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced - #13846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock
Aug 31, 2026
Merged

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced#13846
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#13787

Prose only. contradictsWrapperResolution's predicate is byte-identical to origin/main — 1128 characters, sha256dccdd2b341d10650… on both sides — and the whole diff is comment lines: 0 non-comment lines added, 0 removed, in 3 hunks that all sit inside that one docblock. The fence #13474 put on the predicate is intact; this card is its docblock, and nothing else.

The corrected clause — before / after

The card is one sentence, and it wraps across two lines, which is why a single-string grep for it returns zero. Before (the only clause in the file that asserted the flat index in the present tense):

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` is a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happens to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed.

After:

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` WAS a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happened to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed. (That index is no
* longer flat: #13474 made it scope-aware. It did not close THIS question —
* see the last block of this docblock.)

The paragraph is kept whole. It narrates the historical defect that motivates the predicate, and asked nothing at all / was followed were already past tense on purpose; only the functionBodies clause was wrongly in the present. Two words move (is to WAS, happens to happened) plus a three-line forward pointer. Flattening the whole paragraph to a description of today's index would have deleted the motivation.

The second hunk adds a closing block to the same docblock, next to the existing zero-cost statement, so the reader who lands on the predicate is told what #13474 did and why this predicate survives it:

 * WHY #13474 DID NOT SUBSUME THIS, stated here because the paragraph at the
* top narrates an index shape the file no longer has. `indexFunctionBodies`
* now resolves a name through the CALL SITE's lexical scope chain, which
* settles a collision between same-named BODIES — a different collision from
* the one asked about here, which is across RECEIVERS. Its ONE DECLARATION
* ⇒ UNCHANGED rule keeps it that way on purpose: a name with exactly one body
* in the file is answered from any call site, so a unique name reached on a
* compound receiver is admitted there and refused only here.
* `indexFunctionBodies`' own docblock records the same from its side, and this
* is the near half of that pair. Re-measured on this tree after the resolver
* changed, with this predicate ablated: the two #12358 cases in the self-test
* report 1 seam each instead of 0, and `--list` over the scan root is
* byte-identical either way — the zero-seam cost stated just above, still
* zero.

That pointer is deliberate and it is the pair's near half: indexFunctionBodies' docblock already points at this predicate from ~900 lines away, and now this one points back.

Is the predicate's motivation still sound after #13474? — measured, and yes

#13784's docblock claims the predicate stays load-bearing (a unique name reached on a compound receiver is admitted by the one-declaration rule and refused by that predicate). Verified on this tree by ablation rather than by reading: return false; injected as the first statement of contradictsWrapperResolution, mutation confirmed on disk before the run (marker count 0 to 1, 335171 to 335207 bytes, git diff --stat one insertion), restored afterwards with git checkout HEAD -- ... and the restore proved by hash (d0dc23ff… before and after) plus an empty git diff HEAD. No build step exists between edit and run — the gate is an .mjs executed from source, not from a dist/.

measurementpredicate livepredicate ablated
--self-test, read-seam rule57 cases pass2 fail
--list, whole scan root66 seams66 seams, byte-identical output

The two failures are exactly the two #12358 fixtures, one per clause:

✗ passes: #12358 — a compound receiver does not resolve to the same-file method it collides with: expected violation=false seams=0, got violation=false count=0 seams=1
✗ passes: #12358 — a call that cannot satisfy the resolved declaration is not that declaration: expected violation=false seams=0, got violation=false count=0 seams=1

Both fixtures declare deleteexactly once, so indexFunctionBodies' one-declaration rule answers the name from any call site and hands the hop straight to this predicate. The scope-aware resolver does not and cannot refuse them — it settles same-name collisions, and there is no collision here. ⇒ the motivation is unchanged in force, narrower in wording: the docblock should no longer say the index is flat, but the reason the predicate exists is untouched, and the file's zero-seam cost figure for it is still zero after the resolver changed.

Census — every bare name / flat index mention in the file, classified

Censused by mechanism (functionBodies, BARE NAME, bare name, flat, LAST-WINS, scope-aware, 13474 as separate terms), never as one contiguous string.

linetextverdict
433helper resolution is file-scoped by construction (functionBodies is built per source file)legitimate — about file scoping, not keying. Still true: the index is built per source file.
1379–1390functionBodies WAS keyed by bare name and LAST-WINS … #13474 replaced the flat indexlegitimate — explicitly past tense and already reconciled to #13474 in the same block.
1529–1530functionBodies is a flat, file-scoped index keyed by BARE NAMESTALE — the one this card fixes. Present tense asserting the replaced shape.
2133–2137Only const/let declarations with an initializer are indexed, keyed by bare name and LAST-WINS. That is deliberately NOT the scope-aware model indexFunctionBodies moved to for #13474legitimate — a different index (indexLogAliases), still bare-name last-wins on purpose, with the departure measured and stated.
2422–2436## Why this is not keyed by bare name alone (#13474) — It was, and it was LAST-WINS … the flat index answered with the THIRDlegitimateindexFunctionBodies' own docblock, historical narration, the far half of the pair.
2509the tie-break the flat index already madelegitimate — describes the deliberate within-one-scope tie-break the new resolver kept.
2950indexFunctionBodies keys by BARE NAME, so an unrelated close() in another class in the same file could supply that licencelegitimate, and worth saying why it is not the same defect. The map key is still the bare name (a Map of name to a list of declarations); what changed is that resolution is no longer by key alone. The hazard it warns about also survives, through the one-declaration rule: a close declared once in the file is still answered from any call site, including from another class. True as written, so it is untouched.
6111–6124, 6186Before it, the index was one flat Map … (1) the flat index DROPS a real seam … The flat index answered with the thirdlegitimate — the #13474 regression-control block, describing the model the four fixtures exist to keep out.

Nothing was changed on grounds of resemblance: 1529–1530 is the only present-tense assertion of the replaced shape.

Verification

Every gate run explicitly, exit code captured before any pipe. Final commit for all of it: de44eb1b9.

commandresult
pnpm check:durability-log-levelexit=0✓ self-test (log-level rule): 63 case(s) passed · ✓ self-test (read-seam invention rule): 57 case(s) passed · ✓ read-seam invention …: 66 read seam(s), none invents an unreported answer
pnpm check:ratchet-remedy-authorityexit=0OK check-ratchet-remedy-authority: 176 scripts swept (scripts/*.{mjs,mts}); 11 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 160 hand out no ratchet-expanding remedy.
node scripts/check-ratchet-remedy-authority.mjs --self-testexit=0OK self-test: the lexer holds, messages are bounded, …
pnpm check:nul-bytesexit=0
pnpm lint (repo-wide eslint . --no-inline-config, not narrowed)exit=0, no findings
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literalall exit=0
node scripts/check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs, check-shard-attestation.mjsall exit=0
node scripts/check-test-completeness.mjsexit=3NOT MEASURED, not a red: the gate grades a saved turbo run test log and none was named. Its own text says to record it as NOT MEASURED when run from the derived family.
node scripts/pm/bare-root-worklist.mjs --self-testexit=0 — convention-triggered (this edits a gate script)
pnpm check:pm-dispatch-gatesexit=0 — same convention trigger
pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts src/protocol.metadata-store-outage.test.tsexit=0Test Files 2 passed (2), Tests 44 passed (44). These are the pin tests that read this script by path, so they are owed on top of the path-derived family.

The family was re-derived from the real diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed), which also surfaced the two convention-triggered obligations above.

Why there is no changeset

The dispatch order asked for one. This diff publishes nothing: it is comment lines in scripts/check-durability-degradation-log-level.mjs, a repo-root gate script that belongs to no published package, so a changeset would have to name a package and fabricate a CHANGELOG entry for a comment. An empty-frontmatter changeset is not the alternative — scripts/check-empty-changeset.mjs rejects newly added ones outright, and its header records why. Precedent on this exact file is uniform: of the last 12 commits touching it, the 10 that were script-only carried zero changeset files, #13474's own PR (6207c9ecc) among them. skip-changeset is applied to this PR instead, and read back after applying.


Generated by Claude Code

…he flat bare-name index
#13474 replaced indexFunctionBodies' flat last-wins map with call-site
lexical resolution, which made one clause of this predicate's docblock
false: the paragraph narrates the historical defect in the past tense but
asserted the flat index in the PRESENT. The paragraph is kept — it is why
the predicate exists — and only that clause moves to the past tense.
A closing block states what #13474 did and why this predicate survives it:
the resolver settles collisions between same-named BODIES, this one asks
about a collision across RECEIVERS, and the ONE DECLARATION => UNCHANGED
rule routes a unique name reached on a compound receiver straight here.
Re-measured on this tree, ablating the predicate: the two #12358 self-test
cases report 1 seam each instead of 0, and --list over the scan root is
byte-identical (66 seams either way).
Prose only. The predicate's body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 31, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 31, 2026 15:43
@os-project-manager
os-project-manager added this pull request to the merge queueAug 31, 2026
Merged via the queue into main with commit 36cf8d8Aug 31, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13787-wrapper-resolution-docblock branch August 31, 2026 16:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contradictsWrapperResolution's docblock still calls functionBodies a flat bare-name index — #13474 made it scope-aware

2 participants

@os-project-manager@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

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced - #13846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock
Aug 31, 2026
Merged

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced#13846
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#13787

Prose only. contradictsWrapperResolution's predicate is byte-identical to origin/main — 1128 characters, sha256dccdd2b341d10650… on both sides — and the whole diff is comment lines: 0 non-comment lines added, 0 removed, in 3 hunks that all sit inside that one docblock. The fence #13474 put on the predicate is intact; this card is its docblock, and nothing else.

The corrected clause — before / after

The card is one sentence, and it wraps across two lines, which is why a single-string grep for it returns zero. Before (the only clause in the file that asserted the flat index in the present tense):

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` is a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happens to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed.

After:

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` WAS a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happened to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed. (That index is no
* longer flat: #13474 made it scope-aware. It did not close THIS question —
* see the last block of this docblock.)

The paragraph is kept whole. It narrates the historical defect that motivates the predicate, and asked nothing at all / was followed were already past tense on purpose; only the functionBodies clause was wrongly in the present. Two words move (is to WAS, happens to happened) plus a three-line forward pointer. Flattening the whole paragraph to a description of today's index would have deleted the motivation.

The second hunk adds a closing block to the same docblock, next to the existing zero-cost statement, so the reader who lands on the predicate is told what #13474 did and why this predicate survives it:

 * WHY #13474 DID NOT SUBSUME THIS, stated here because the paragraph at the
* top narrates an index shape the file no longer has. `indexFunctionBodies`
* now resolves a name through the CALL SITE's lexical scope chain, which
* settles a collision between same-named BODIES — a different collision from
* the one asked about here, which is across RECEIVERS. Its ONE DECLARATION
* ⇒ UNCHANGED rule keeps it that way on purpose: a name with exactly one body
* in the file is answered from any call site, so a unique name reached on a
* compound receiver is admitted there and refused only here.
* `indexFunctionBodies`' own docblock records the same from its side, and this
* is the near half of that pair. Re-measured on this tree after the resolver
* changed, with this predicate ablated: the two #12358 cases in the self-test
* report 1 seam each instead of 0, and `--list` over the scan root is
* byte-identical either way — the zero-seam cost stated just above, still
* zero.

That pointer is deliberate and it is the pair's near half: indexFunctionBodies' docblock already points at this predicate from ~900 lines away, and now this one points back.

Is the predicate's motivation still sound after #13474? — measured, and yes

#13784's docblock claims the predicate stays load-bearing (a unique name reached on a compound receiver is admitted by the one-declaration rule and refused by that predicate). Verified on this tree by ablation rather than by reading: return false; injected as the first statement of contradictsWrapperResolution, mutation confirmed on disk before the run (marker count 0 to 1, 335171 to 335207 bytes, git diff --stat one insertion), restored afterwards with git checkout HEAD -- ... and the restore proved by hash (d0dc23ff… before and after) plus an empty git diff HEAD. No build step exists between edit and run — the gate is an .mjs executed from source, not from a dist/.

measurementpredicate livepredicate ablated
--self-test, read-seam rule57 cases pass2 fail
--list, whole scan root66 seams66 seams, byte-identical output

The two failures are exactly the two #12358 fixtures, one per clause:

✗ passes: #12358 — a compound receiver does not resolve to the same-file method it collides with: expected violation=false seams=0, got violation=false count=0 seams=1
✗ passes: #12358 — a call that cannot satisfy the resolved declaration is not that declaration: expected violation=false seams=0, got violation=false count=0 seams=1

Both fixtures declare deleteexactly once, so indexFunctionBodies' one-declaration rule answers the name from any call site and hands the hop straight to this predicate. The scope-aware resolver does not and cannot refuse them — it settles same-name collisions, and there is no collision here. ⇒ the motivation is unchanged in force, narrower in wording: the docblock should no longer say the index is flat, but the reason the predicate exists is untouched, and the file's zero-seam cost figure for it is still zero after the resolver changed.

Census — every bare name / flat index mention in the file, classified

Censused by mechanism (functionBodies, BARE NAME, bare name, flat, LAST-WINS, scope-aware, 13474 as separate terms), never as one contiguous string.

linetextverdict
433helper resolution is file-scoped by construction (functionBodies is built per source file)legitimate — about file scoping, not keying. Still true: the index is built per source file.
1379–1390functionBodies WAS keyed by bare name and LAST-WINS … #13474 replaced the flat indexlegitimate — explicitly past tense and already reconciled to #13474 in the same block.
1529–1530functionBodies is a flat, file-scoped index keyed by BARE NAMESTALE — the one this card fixes. Present tense asserting the replaced shape.
2133–2137Only const/let declarations with an initializer are indexed, keyed by bare name and LAST-WINS. That is deliberately NOT the scope-aware model indexFunctionBodies moved to for #13474legitimate — a different index (indexLogAliases), still bare-name last-wins on purpose, with the departure measured and stated.
2422–2436## Why this is not keyed by bare name alone (#13474) — It was, and it was LAST-WINS … the flat index answered with the THIRDlegitimateindexFunctionBodies' own docblock, historical narration, the far half of the pair.
2509the tie-break the flat index already madelegitimate — describes the deliberate within-one-scope tie-break the new resolver kept.
2950indexFunctionBodies keys by BARE NAME, so an unrelated close() in another class in the same file could supply that licencelegitimate, and worth saying why it is not the same defect. The map key is still the bare name (a Map of name to a list of declarations); what changed is that resolution is no longer by key alone. The hazard it warns about also survives, through the one-declaration rule: a close declared once in the file is still answered from any call site, including from another class. True as written, so it is untouched.
6111–6124, 6186Before it, the index was one flat Map … (1) the flat index DROPS a real seam … The flat index answered with the thirdlegitimate — the #13474 regression-control block, describing the model the four fixtures exist to keep out.

Nothing was changed on grounds of resemblance: 1529–1530 is the only present-tense assertion of the replaced shape.

Verification

Every gate run explicitly, exit code captured before any pipe. Final commit for all of it: de44eb1b9.

commandresult
pnpm check:durability-log-levelexit=0✓ self-test (log-level rule): 63 case(s) passed · ✓ self-test (read-seam invention rule): 57 case(s) passed · ✓ read-seam invention …: 66 read seam(s), none invents an unreported answer
pnpm check:ratchet-remedy-authorityexit=0OK check-ratchet-remedy-authority: 176 scripts swept (scripts/*.{mjs,mts}); 11 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 160 hand out no ratchet-expanding remedy.
node scripts/check-ratchet-remedy-authority.mjs --self-testexit=0OK self-test: the lexer holds, messages are bounded, …
pnpm check:nul-bytesexit=0
pnpm lint (repo-wide eslint . --no-inline-config, not narrowed)exit=0, no findings
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literalall exit=0
node scripts/check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs, check-shard-attestation.mjsall exit=0
node scripts/check-test-completeness.mjsexit=3NOT MEASURED, not a red: the gate grades a saved turbo run test log and none was named. Its own text says to record it as NOT MEASURED when run from the derived family.
node scripts/pm/bare-root-worklist.mjs --self-testexit=0 — convention-triggered (this edits a gate script)
pnpm check:pm-dispatch-gatesexit=0 — same convention trigger
pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts src/protocol.metadata-store-outage.test.tsexit=0Test Files 2 passed (2), Tests 44 passed (44). These are the pin tests that read this script by path, so they are owed on top of the path-derived family.

The family was re-derived from the real diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed), which also surfaced the two convention-triggered obligations above.

Why there is no changeset

The dispatch order asked for one. This diff publishes nothing: it is comment lines in scripts/check-durability-degradation-log-level.mjs, a repo-root gate script that belongs to no published package, so a changeset would have to name a package and fabricate a CHANGELOG entry for a comment. An empty-frontmatter changeset is not the alternative — scripts/check-empty-changeset.mjs rejects newly added ones outright, and its header records why. Precedent on this exact file is uniform: of the last 12 commits touching it, the 10 that were script-only carried zero changeset files, #13474's own PR (6207c9ecc) among them. skip-changeset is applied to this PR instead, and read back after applying.


Generated by Claude Code

…he flat bare-name index
#13474 replaced indexFunctionBodies' flat last-wins map with call-site
lexical resolution, which made one clause of this predicate's docblock
false: the paragraph narrates the historical defect in the past tense but
asserted the flat index in the PRESENT. The paragraph is kept — it is why
the predicate exists — and only that clause moves to the past tense.
A closing block states what #13474 did and why this predicate survives it:
the resolver settles collisions between same-named BODIES, this one asks
about a collision across RECEIVERS, and the ONE DECLARATION => UNCHANGED
rule routes a unique name reached on a compound receiver straight here.
Re-measured on this tree, ablating the predicate: the two #12358 self-test
cases report 1 seam each instead of 0, and --list over the scan root is
byte-identical (66 seams either way).
Prose only. The predicate's body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 31, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 31, 2026 15:43
@os-project-manager
os-project-manager added this pull request to the merge queueAug 31, 2026
Merged via the queue into main with commit 36cf8d8Aug 31, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13787-wrapper-resolution-docblock branch August 31, 2026 16:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contradictsWrapperResolution's docblock still calls functionBodies a flat bare-name index — #13474 made it scope-aware

2 participants

@os-project-manager@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

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced - #13846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock
Aug 31, 2026
Merged

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced#13846
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#13787

Prose only. contradictsWrapperResolution's predicate is byte-identical to origin/main — 1128 characters, sha256dccdd2b341d10650… on both sides — and the whole diff is comment lines: 0 non-comment lines added, 0 removed, in 3 hunks that all sit inside that one docblock. The fence #13474 put on the predicate is intact; this card is its docblock, and nothing else.

The corrected clause — before / after

The card is one sentence, and it wraps across two lines, which is why a single-string grep for it returns zero. Before (the only clause in the file that asserted the flat index in the present tense):

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` is a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happens to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed.

After:

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` WAS a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happened to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed. (That index is no
* longer flat: #13474 made it scope-aware. It did not close THIS question —
* see the last block of this docblock.)

The paragraph is kept whole. It narrates the historical defect that motivates the predicate, and asked nothing at all / was followed were already past tense on purpose; only the functionBodies clause was wrongly in the present. Two words move (is to WAS, happens to happened) plus a three-line forward pointer. Flattening the whole paragraph to a description of today's index would have deleted the motivation.

The second hunk adds a closing block to the same docblock, next to the existing zero-cost statement, so the reader who lands on the predicate is told what #13474 did and why this predicate survives it:

 * WHY #13474 DID NOT SUBSUME THIS, stated here because the paragraph at the
* top narrates an index shape the file no longer has. `indexFunctionBodies`
* now resolves a name through the CALL SITE's lexical scope chain, which
* settles a collision between same-named BODIES — a different collision from
* the one asked about here, which is across RECEIVERS. Its ONE DECLARATION
* ⇒ UNCHANGED rule keeps it that way on purpose: a name with exactly one body
* in the file is answered from any call site, so a unique name reached on a
* compound receiver is admitted there and refused only here.
* `indexFunctionBodies`' own docblock records the same from its side, and this
* is the near half of that pair. Re-measured on this tree after the resolver
* changed, with this predicate ablated: the two #12358 cases in the self-test
* report 1 seam each instead of 0, and `--list` over the scan root is
* byte-identical either way — the zero-seam cost stated just above, still
* zero.

That pointer is deliberate and it is the pair's near half: indexFunctionBodies' docblock already points at this predicate from ~900 lines away, and now this one points back.

Is the predicate's motivation still sound after #13474? — measured, and yes

#13784's docblock claims the predicate stays load-bearing (a unique name reached on a compound receiver is admitted by the one-declaration rule and refused by that predicate). Verified on this tree by ablation rather than by reading: return false; injected as the first statement of contradictsWrapperResolution, mutation confirmed on disk before the run (marker count 0 to 1, 335171 to 335207 bytes, git diff --stat one insertion), restored afterwards with git checkout HEAD -- ... and the restore proved by hash (d0dc23ff… before and after) plus an empty git diff HEAD. No build step exists between edit and run — the gate is an .mjs executed from source, not from a dist/.

measurementpredicate livepredicate ablated
--self-test, read-seam rule57 cases pass2 fail
--list, whole scan root66 seams66 seams, byte-identical output

The two failures are exactly the two #12358 fixtures, one per clause:

✗ passes: #12358 — a compound receiver does not resolve to the same-file method it collides with: expected violation=false seams=0, got violation=false count=0 seams=1
✗ passes: #12358 — a call that cannot satisfy the resolved declaration is not that declaration: expected violation=false seams=0, got violation=false count=0 seams=1

Both fixtures declare deleteexactly once, so indexFunctionBodies' one-declaration rule answers the name from any call site and hands the hop straight to this predicate. The scope-aware resolver does not and cannot refuse them — it settles same-name collisions, and there is no collision here. ⇒ the motivation is unchanged in force, narrower in wording: the docblock should no longer say the index is flat, but the reason the predicate exists is untouched, and the file's zero-seam cost figure for it is still zero after the resolver changed.

Census — every bare name / flat index mention in the file, classified

Censused by mechanism (functionBodies, BARE NAME, bare name, flat, LAST-WINS, scope-aware, 13474 as separate terms), never as one contiguous string.

linetextverdict
433helper resolution is file-scoped by construction (functionBodies is built per source file)legitimate — about file scoping, not keying. Still true: the index is built per source file.
1379–1390functionBodies WAS keyed by bare name and LAST-WINS … #13474 replaced the flat indexlegitimate — explicitly past tense and already reconciled to #13474 in the same block.
1529–1530functionBodies is a flat, file-scoped index keyed by BARE NAMESTALE — the one this card fixes. Present tense asserting the replaced shape.
2133–2137Only const/let declarations with an initializer are indexed, keyed by bare name and LAST-WINS. That is deliberately NOT the scope-aware model indexFunctionBodies moved to for #13474legitimate — a different index (indexLogAliases), still bare-name last-wins on purpose, with the departure measured and stated.
2422–2436## Why this is not keyed by bare name alone (#13474) — It was, and it was LAST-WINS … the flat index answered with the THIRDlegitimateindexFunctionBodies' own docblock, historical narration, the far half of the pair.
2509the tie-break the flat index already madelegitimate — describes the deliberate within-one-scope tie-break the new resolver kept.
2950indexFunctionBodies keys by BARE NAME, so an unrelated close() in another class in the same file could supply that licencelegitimate, and worth saying why it is not the same defect. The map key is still the bare name (a Map of name to a list of declarations); what changed is that resolution is no longer by key alone. The hazard it warns about also survives, through the one-declaration rule: a close declared once in the file is still answered from any call site, including from another class. True as written, so it is untouched.
6111–6124, 6186Before it, the index was one flat Map … (1) the flat index DROPS a real seam … The flat index answered with the thirdlegitimate — the #13474 regression-control block, describing the model the four fixtures exist to keep out.

Nothing was changed on grounds of resemblance: 1529–1530 is the only present-tense assertion of the replaced shape.

Verification

Every gate run explicitly, exit code captured before any pipe. Final commit for all of it: de44eb1b9.

commandresult
pnpm check:durability-log-levelexit=0✓ self-test (log-level rule): 63 case(s) passed · ✓ self-test (read-seam invention rule): 57 case(s) passed · ✓ read-seam invention …: 66 read seam(s), none invents an unreported answer
pnpm check:ratchet-remedy-authorityexit=0OK check-ratchet-remedy-authority: 176 scripts swept (scripts/*.{mjs,mts}); 11 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 160 hand out no ratchet-expanding remedy.
node scripts/check-ratchet-remedy-authority.mjs --self-testexit=0OK self-test: the lexer holds, messages are bounded, …
pnpm check:nul-bytesexit=0
pnpm lint (repo-wide eslint . --no-inline-config, not narrowed)exit=0, no findings
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literalall exit=0
node scripts/check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs, check-shard-attestation.mjsall exit=0
node scripts/check-test-completeness.mjsexit=3NOT MEASURED, not a red: the gate grades a saved turbo run test log and none was named. Its own text says to record it as NOT MEASURED when run from the derived family.
node scripts/pm/bare-root-worklist.mjs --self-testexit=0 — convention-triggered (this edits a gate script)
pnpm check:pm-dispatch-gatesexit=0 — same convention trigger
pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts src/protocol.metadata-store-outage.test.tsexit=0Test Files 2 passed (2), Tests 44 passed (44). These are the pin tests that read this script by path, so they are owed on top of the path-derived family.

The family was re-derived from the real diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed), which also surfaced the two convention-triggered obligations above.

Why there is no changeset

The dispatch order asked for one. This diff publishes nothing: it is comment lines in scripts/check-durability-degradation-log-level.mjs, a repo-root gate script that belongs to no published package, so a changeset would have to name a package and fabricate a CHANGELOG entry for a comment. An empty-frontmatter changeset is not the alternative — scripts/check-empty-changeset.mjs rejects newly added ones outright, and its header records why. Precedent on this exact file is uniform: of the last 12 commits touching it, the 10 that were script-only carried zero changeset files, #13474's own PR (6207c9ecc) among them. skip-changeset is applied to this PR instead, and read back after applying.


Generated by Claude Code

…he flat bare-name index
#13474 replaced indexFunctionBodies' flat last-wins map with call-site
lexical resolution, which made one clause of this predicate's docblock
false: the paragraph narrates the historical defect in the past tense but
asserted the flat index in the PRESENT. The paragraph is kept — it is why
the predicate exists — and only that clause moves to the past tense.
A closing block states what #13474 did and why this predicate survives it:
the resolver settles collisions between same-named BODIES, this one asks
about a collision across RECEIVERS, and the ONE DECLARATION => UNCHANGED
rule routes a unique name reached on a compound receiver straight here.
Re-measured on this tree, ablating the predicate: the two #12358 self-test
cases report 1 seam each instead of 0, and --list over the scan root is
byte-identical (66 seams either way).
Prose only. The predicate's body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 31, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 31, 2026 15:43
@os-project-manager
os-project-manager added this pull request to the merge queueAug 31, 2026
Merged via the queue into main with commit 36cf8d8Aug 31, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13787-wrapper-resolution-docblock branch August 31, 2026 16:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contradictsWrapperResolution's docblock still calls functionBodies a flat bare-name index — #13474 made it scope-aware

2 participants

@os-project-manager@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

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced - #13846

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock
Aug 31, 2026
Merged

docs(gate): contradictsWrapperResolution's docblock still described the flat bare-name index #13474 replaced#13846
os-project-manager merged 1 commit into
mainfrom
claude/issue-13787-wrapper-resolution-docblock

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#13787

Prose only. contradictsWrapperResolution's predicate is byte-identical to origin/main — 1128 characters, sha256dccdd2b341d10650… on both sides — and the whole diff is comment lines: 0 non-comment lines added, 0 removed, in 3 hunks that all sit inside that one docblock. The fence #13474 put on the predicate is intact; this card is its docblock, and nothing else.

The corrected clause — before / after

The card is one sentence, and it wraps across two lines, which is why a single-string grep for it returns zero. Before (the only clause in the file that asserted the flat index in the present tense):

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` is a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happens to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed.

After:

 * `contradictsDriverReadShape` asks it of `IDataDriver`. The wrapper hop in
* `isReadCall` asked nothing at all. `functionBodies` WAS a flat, file-scoped
* index keyed by BARE NAME, so any call whose `calleeName` happened to equal a
* function declared in the same file was followed into that function's body —
* whatever it was called ON, and whatever it was passed. (That index is no
* longer flat: #13474 made it scope-aware. It did not close THIS question —
* see the last block of this docblock.)

The paragraph is kept whole. It narrates the historical defect that motivates the predicate, and asked nothing at all / was followed were already past tense on purpose; only the functionBodies clause was wrongly in the present. Two words move (is to WAS, happens to happened) plus a three-line forward pointer. Flattening the whole paragraph to a description of today's index would have deleted the motivation.

The second hunk adds a closing block to the same docblock, next to the existing zero-cost statement, so the reader who lands on the predicate is told what #13474 did and why this predicate survives it:

 * WHY #13474 DID NOT SUBSUME THIS, stated here because the paragraph at the
* top narrates an index shape the file no longer has. `indexFunctionBodies`
* now resolves a name through the CALL SITE's lexical scope chain, which
* settles a collision between same-named BODIES — a different collision from
* the one asked about here, which is across RECEIVERS. Its ONE DECLARATION
* ⇒ UNCHANGED rule keeps it that way on purpose: a name with exactly one body
* in the file is answered from any call site, so a unique name reached on a
* compound receiver is admitted there and refused only here.
* `indexFunctionBodies`' own docblock records the same from its side, and this
* is the near half of that pair. Re-measured on this tree after the resolver
* changed, with this predicate ablated: the two #12358 cases in the self-test
* report 1 seam each instead of 0, and `--list` over the scan root is
* byte-identical either way — the zero-seam cost stated just above, still
* zero.

That pointer is deliberate and it is the pair's near half: indexFunctionBodies' docblock already points at this predicate from ~900 lines away, and now this one points back.

Is the predicate's motivation still sound after #13474? — measured, and yes

#13784's docblock claims the predicate stays load-bearing (a unique name reached on a compound receiver is admitted by the one-declaration rule and refused by that predicate). Verified on this tree by ablation rather than by reading: return false; injected as the first statement of contradictsWrapperResolution, mutation confirmed on disk before the run (marker count 0 to 1, 335171 to 335207 bytes, git diff --stat one insertion), restored afterwards with git checkout HEAD -- ... and the restore proved by hash (d0dc23ff… before and after) plus an empty git diff HEAD. No build step exists between edit and run — the gate is an .mjs executed from source, not from a dist/.

measurementpredicate livepredicate ablated
--self-test, read-seam rule57 cases pass2 fail
--list, whole scan root66 seams66 seams, byte-identical output

The two failures are exactly the two #12358 fixtures, one per clause:

✗ passes: #12358 — a compound receiver does not resolve to the same-file method it collides with: expected violation=false seams=0, got violation=false count=0 seams=1
✗ passes: #12358 — a call that cannot satisfy the resolved declaration is not that declaration: expected violation=false seams=0, got violation=false count=0 seams=1

Both fixtures declare deleteexactly once, so indexFunctionBodies' one-declaration rule answers the name from any call site and hands the hop straight to this predicate. The scope-aware resolver does not and cannot refuse them — it settles same-name collisions, and there is no collision here. ⇒ the motivation is unchanged in force, narrower in wording: the docblock should no longer say the index is flat, but the reason the predicate exists is untouched, and the file's zero-seam cost figure for it is still zero after the resolver changed.

Census — every bare name / flat index mention in the file, classified

Censused by mechanism (functionBodies, BARE NAME, bare name, flat, LAST-WINS, scope-aware, 13474 as separate terms), never as one contiguous string.

linetextverdict
433helper resolution is file-scoped by construction (functionBodies is built per source file)legitimate — about file scoping, not keying. Still true: the index is built per source file.
1379–1390functionBodies WAS keyed by bare name and LAST-WINS … #13474 replaced the flat indexlegitimate — explicitly past tense and already reconciled to #13474 in the same block.
1529–1530functionBodies is a flat, file-scoped index keyed by BARE NAMESTALE — the one this card fixes. Present tense asserting the replaced shape.
2133–2137Only const/let declarations with an initializer are indexed, keyed by bare name and LAST-WINS. That is deliberately NOT the scope-aware model indexFunctionBodies moved to for #13474legitimate — a different index (indexLogAliases), still bare-name last-wins on purpose, with the departure measured and stated.
2422–2436## Why this is not keyed by bare name alone (#13474) — It was, and it was LAST-WINS … the flat index answered with the THIRDlegitimateindexFunctionBodies' own docblock, historical narration, the far half of the pair.
2509the tie-break the flat index already madelegitimate — describes the deliberate within-one-scope tie-break the new resolver kept.
2950indexFunctionBodies keys by BARE NAME, so an unrelated close() in another class in the same file could supply that licencelegitimate, and worth saying why it is not the same defect. The map key is still the bare name (a Map of name to a list of declarations); what changed is that resolution is no longer by key alone. The hazard it warns about also survives, through the one-declaration rule: a close declared once in the file is still answered from any call site, including from another class. True as written, so it is untouched.
6111–6124, 6186Before it, the index was one flat Map … (1) the flat index DROPS a real seam … The flat index answered with the thirdlegitimate — the #13474 regression-control block, describing the model the four fixtures exist to keep out.

Nothing was changed on grounds of resemblance: 1529–1530 is the only present-tense assertion of the replaced shape.

Verification

Every gate run explicitly, exit code captured before any pipe. Final commit for all of it: de44eb1b9.

commandresult
pnpm check:durability-log-levelexit=0✓ self-test (log-level rule): 63 case(s) passed · ✓ self-test (read-seam invention rule): 57 case(s) passed · ✓ read-seam invention …: 66 read seam(s), none invents an unreported answer
pnpm check:ratchet-remedy-authorityexit=0OK check-ratchet-remedy-authority: 176 scripts swept (scripts/*.{mjs,mts}); 11 mark the expanding remedy ⛔ MAINTAINER-ONLY, 5 turn it down outright, 160 hand out no ratchet-expanding remedy.
node scripts/check-ratchet-remedy-authority.mjs --self-testexit=0OK self-test: the lexer holds, messages are bounded, …
pnpm check:nul-bytesexit=0
pnpm lint (repo-wide eslint . --no-inline-config, not narrowed)exit=0, no findings
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs, check:entry-guard, check:parse-guard, check:pnpm-filter-targets, check:watch-hint-literalall exit=0
node scripts/check-ci-filter-parity.mjs, check-cross-package-test-inputs.mjs, check-shard-attestation.mjsall exit=0
node scripts/check-test-completeness.mjsexit=3NOT MEASURED, not a red: the gate grades a saved turbo run test log and none was named. Its own text says to record it as NOT MEASURED when run from the derived family.
node scripts/pm/bare-root-worklist.mjs --self-testexit=0 — convention-triggered (this edits a gate script)
pnpm check:pm-dispatch-gatesexit=0 — same convention trigger
pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts src/protocol.metadata-store-outage.test.tsexit=0Test Files 2 passed (2), Tests 44 passed (44). These are the pin tests that read this script by path, so they are owed on top of the path-derived family.

The family was re-derived from the real diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (no paths passed), which also surfaced the two convention-triggered obligations above.

Why there is no changeset

The dispatch order asked for one. This diff publishes nothing: it is comment lines in scripts/check-durability-degradation-log-level.mjs, a repo-root gate script that belongs to no published package, so a changeset would have to name a package and fabricate a CHANGELOG entry for a comment. An empty-frontmatter changeset is not the alternative — scripts/check-empty-changeset.mjs rejects newly added ones outright, and its header records why. Precedent on this exact file is uniform: of the last 12 commits touching it, the 10 that were script-only carried zero changeset files, #13474's own PR (6207c9ecc) among them. skip-changeset is applied to this PR instead, and read back after applying.


Generated by Claude Code

…he flat bare-name index
#13474 replaced indexFunctionBodies' flat last-wins map with call-site
lexical resolution, which made one clause of this predicate's docblock
false: the paragraph narrates the historical defect in the past tense but
asserted the flat index in the PRESENT. The paragraph is kept — it is why
the predicate exists — and only that clause moves to the past tense.
A closing block states what #13474 did and why this predicate survives it:
the resolver settles collisions between same-named BODIES, this one asks
about a collision across RECEIVERS, and the ONE DECLARATION => UNCHANGED
rule routes a unique name reached on a compound receiver straight here.
Re-measured on this tree, ablating the predicate: the two #12358 self-test
cases report 1 seam each instead of 0, and --list over the scan root is
byte-identical (66 seams either way).
Prose only. The predicate's body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 31, 2026
@os-project-manager
os-project-manager marked this pull request as ready for review August 31, 2026 15:43
@os-project-manager
os-project-manager added this pull request to the merge queueAug 31, 2026
Merged via the queue into main with commit 36cf8d8Aug 31, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-13787-wrapper-resolution-docblock branch August 31, 2026 16:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contradictsWrapperResolution's docblock still calls functionBodies a flat bare-name index — #13474 made it scope-aware

2 participants

@os-project-manager@claude