Repository navigation
finding(tests): the comment projection at three packages/types readers is inert on every subject the tree has — removing it entirely changes nothing, so nothing would notice it being lost #9768
Description
Activity
os-try-charles commented
on Sep 18, 2026 CollaboratorAuthorMore actionsClaim: PM loop round R74
Session:session_015h79niBMyoB1xcaQje3uiz
Branch:claude/issue-9768-inert-comment-projection
Worktree:objectui-issue-9768
Domain:domain:devx
File surface:packages/types/src/__tests__/andpackages/types/src/— declared at AREA level perSKILL.md:481. The second area only if a forcing subject has to live beside the readers rather than inside a test. ⛔ Not a licence to widen: anything outside these stops and is explained in the report.
Container & model:M,mode:subagent,model: the seat's default judgement tier— objectui has noscripts/pm/dispatch-gates.mjs, so ⛔ there is no--tieroutput to quote and the tier is this seat's per-card call.
Clause-②: no
Thread-read: 5725896062
Serial constraints cleared: measured this tick over all 13 open pull requests,GET /pulls/{n}/filesfully paginated, 1843 filenames; ⭐ positive control.github/workflows/ci.yml -> PR #9584fired. The three reader files,packages/types/src/overlay.tsandscripts/js-comment-mask.mjsare held by 0 of them. Adjacent, ⛔ not colliding: #9540 and #8941 touchpackages/types/src/objectql.tsand its zod twin, #9540 alsoobject-gallery-filter-9309.test.ts, #9797 touchespackages/types/src/data-display.ts— none on this card's files.⚠️ Four PRs currently fence the rest of this lane's queue (#9584, #5400, #9592, #9391); this card is the one that is clear of all four.
Generated by Claude Code
os-try-charles commented
on Sep 18, 2026 CollaboratorAuthorMore actionsos-dev-report
{ "issue": 9768, "status": "done", "branch": "claude/issue-9768-inert-comment-projection", "pr": "https://github.com/objectstack-ai/objectui/pull/9814", "session": "session_015h79niBMyoB1xcaQje3uiz", "premise_still_valid": true, "summary": "Population established mechanically first, not inherited: instrumenting `stripComments` in scripts/js-comment-mask.mjs and running the three readers records 67 calls, 63 of them bodies located in a tracked non-test file and 4 synthetic string literals, over 20 DISTINCT (file, interface) bodies -- 10 declarations (the nine overlay interfaces plus EmptySchema in feedback.ts) and 10 docs fences. The card's '16 interface bodies' is NOT reproducible; 20 is the measured number. Triage's escalation condition is NOT met: replaying every captured body through the readers' own member regex with and without the projection gives an identical member map on 0/20 -- no live defect, no p2, the fixture stays the right deliverable. The projection is nevertheless exercised (it deletes prose in 17/20 bodies, 11754 bytes in the AlertDialogSchema body alone); it just never changed an answer. Each of the three readers now declares `CommentProjectionForcingSubject`, a subject on disk whose body carries a member-shaped row inside an ORDINARY block comment (no star gutter, so the row sits on the two-space anchor `members()` matches), read off disk and extracted by the reader's own interfaceBody + members -- a subject, not a synthetic string. Per file deliberately, because each reader carries its own copy of members(). No reader behaviour, regex or subject list moved, and scripts/js-comment-mask.mjs is untouched.", "tests": "THROUGH THE LOCK (../objectstack/scripts/pm/os-verify-lock.sh, OS_VERIFY_LOCK_SLOT=objectui-9768): `pnpm --filter @object-ui/types type-check` -> 'os-verify-lock: VERDICT command-exit 0 - held the lock 33s - waited 0s' (tsc --noEmit, tsconfig.examples.json, tsconfig.test.json); `pnpm --filter @object-ui/types test` -> 'os-verify-lock: VERDICT command-exit 0 - held the lock 26s - waited 0s', 'Test Files 204 passed (204)', 'Tests 4777 passed (4777)'. THE THREE READERS: 'Tests 161 passed (161)' (155 before this change). ABLATION, both legs, same mutation ('const bare = stripComments(body);' -> 'const bare = body;' in all three readers), proven ON DISK before reading anything (3 ABLATION markers injected, 0 surviving stripComments(body) calls) and restored under a trap with 'git checkout HEAD --' verified by blob hash per file plus an empty 'git diff HEAD': LEG A, the PRE-FIX state 6a0d1a435 with the projection removed -> 'Test Files 3 passed (3)', 'Tests 155 passed (155)', exit 0 (the guard was inert). LEG B, with the forcing subject and the projection removed -> 'Test Files 3 failed (3)', 'Tests 3 failed | 158 passed (161)', exit 1, one failure per reader, all on the same assertion: '`members()` reads the two DECLARED rows and not the row in the comment', AssertionError expected [ 'phantom', 'real', 'label' ] to deeply equal [ 'real', 'label' ] -- the member LIST moved, not a grep count. The census instrumentation of js-comment-mask.mjs was restored the same way (blob fefd98191925d0ace305a89f5713df1506a5a59d == HEAD). GATES BY POPULATION: check:comment-mask-corpus exit 0 ('5078 files, 1 disagree (0 comment bytes read as code, 1517 code bytes read as comment)' -- the objectui#7882 residue unchanged, inside its ceiling); scripts/check-hand-rolled-comment-mask.mjs exit 0 ('6 private comment projection(s) in 5 file(s); DEBT names 5') -- the DEBT ratchet does not move, the one regex added is a LOOKUP not a removal position; check:pending-changeset-literals exit 0; markdown-test-inputs --audit exit 0; check:control-bytes exit 0; check:test-path-roots exit 0 (the new read is rooted at the test file, never the cwd); check:new-line-citations exit 0 ('0 new citation(s)'); check:changeset-claims exit 0; check-changeset-presence exit 0 (empty-frontmatter changeset = the declared exemption); check-lint-coverage exit 0 ('46/46 packages linted, 0 with outstanding errors'); `pnpm --filter @object-ui/types lint` 0 errors (the two warnings on overlay-trigger-union-7081.test.ts are pre-existing 'data?: any' rows, absent from this diff). NOT MEASURED: check:node-esm-load -- not coupled by population, nothing under any package's published files[] moves (tsconfig.json excludes **/__tests__/**), so no dist artefact changes; and remote CI, which is the PM's read, not mine.", "mcp_calls": "0 - no MCP GitHub tool was called, read or write; every GitHub call went through the REST proxy with curl", "api_writes": "3 - POST /repos/objectstack-ai/objectui/pulls (draft, #9814); POST /repos/objectstack-ai/objectui/issues/9768/comments (this report); plus 2 git pushes (empty-branch routing probe, then the commit). No label write: in objectui the skip-changeset label is read by nothing and is banned for this seat, and the empty-frontmatter changeset is the gate-authoritative declaration; needs:contract-review belongs to the seat.", "open_questions": [], "out_of_scope_findings": [ "noted, not filed: all 4 synthetic string literals these readers hand members() are inert too, including the 'JSDoc stripping does not eat real rows' counter-probe in overlay-node-slot-doc-types-7082.test.ts, which reads as though it exercised the projection -- its member-shaped line sits behind a docblock gutter (three spaces and a star) while members() anchors on exactly two spaces plus an identifier, so it passes identically with the projection removed. Not filed: the probes are honest as tests of the member regex, and this PR supplies the thing they were mistaken for. Carrier: whoever next edits those probes.", "noted, not filed: the card's '16 interface bodies' is not reproducible against the readers' actual subject lists (measured 20). It is consistent with a count of one reader's six docs pages plus the ten declarations, but that is a reconstruction, not a reading. No card: the verdict the figure supported is unchanged, and the correction is recorded on the PR and in this report where the next reader of the card will meet it." ] }
Generated by Claude Code
os-try-charles commented
on Sep 18, 2026 CollaboratorAuthorMore actionsACCEPT — PR #9814, head
04d2dce19, no patch round. Readings below are this seat's own.Checklist
reading CI 36 of 36 green, 36 distinct names — waited for every check to complete. Path surface 4 files. The three readers are inside the declared area; .changeset/9768-…mdis outside it (see deviations). Fence re-measured over 18 open pull requests / 1857 filenames, fully paginated; positive control.github/workflows/ci.yml -> #9584fired; the three readers are held by #9814 alone andscripts/js-comment-mask.mjsandpackages/types/src/overlay.tsby nobody.⭐ Shape Purely additive — 0 deletions in all four files. That turns "no reader behaviour, regex or subject list moved" from a claim into a structural fact, which is the strongest form the deliverable's ⛔ do not change its behaviour could take. New CI context none; no workflow file touched. Governed surfaces none. Clause-② noand true: this adds a subject and two assertions, relaxes nothing.Pushed artefact commit trailer Co-Authored-By: Claude+Claude-Session:, no model identifier.The lock the turbo-build verifications went through os-verify-lock.shwith their verdict lines quoted.The three things this dispatch demanded, checked here rather than taken on report
- The population was established mechanically, not inherited —
stripCommentsinstrumented, the readers run, 67 calls captured over 20 distinct (file, interface) bodies. ⇒ ⛔ the card's "16" is not reproducible, and the card is this seat's. Recorded as a correction to the card, not a footnote. - Triage's escalation question was answered against that population: every captured body replayed through the readers' own member regex with and without the projection ⇒ identical member map on 0 of 20. No live defect, no p2, and the fixture remains the right deliverable. ⭐ With the sharper half stated rather than smoothed over: the projection is doing work — it removes prose from 17 of 20 bodies, 11,754 bytes in the
AlertDialogSchemabody alone — it has simply never changed an answer. - The fixture is a subject, ⛔ not a synthetic string:
interfaceBody(readFileSync(OWN, 'utf8'), OPENER, OWN)— read off disk and extracted exactly as a declaration is. And the pin asserts the member list (['real','label'], becoming['phantom','real','label']when the projection is dropped), ⛔ not a count.
⭐ What it added that was not asked for, and is the best part
A second leg on the new pin:
it('the subject really carries a member-shaped row inside a block comment — read off the UNPROJECTED text')
"Without this leg the pin below passes just as well against a subject that lost the row, and an empty guard reads exactly like a live one."⇒ a fixture that silently lost its forcing row would leave the new pin green — the new guard would become the inert guard it exists to cure. That is this card's own thesis applied one level down, unprompted. The subject also carries a ⛔ warning against adding a
*gutter or "tidying" the row, because either would un-force it without any test noticing.Landing probe, pre-validated against
maintoken reading why it is that token fire export interface CommentProjectionForcingSubject {0 → 2 per reader the declaration and the OPENERthe pin must name to find the bodyfire expect([...rows.keys()]).toEqual(['real', 'label'])0 → 1 per reader the leg that reds, asserting the member list fire read off the UNPROJECTED text0 → 1 per reader the second leg above control const bare = stripComments(body);1 → 1 per reader reasoned first: the deliverable forbids changing the reader, so if members()moved the fix exceeded its mandatecontrol the counter-probesdescribe block1 → 1, 0 → 0, 1 → 1 reasoned first: the dev measured those probes as themselves inert and correctly left them alone — movement either way is widening. Present in 2 of 3 readers, measured per file rather than assumed ⚠️ This probe has no clear leg, because the change deletes nothing. That is a property of the change, ⛔ not a gap in the probe.⚠️ And the probe first printed a disagreement that was mine, not the change's — I had expected the forcing subject once per reader and the counter-probe block in all three. Both expectations were wrong; the readings are right. Recorded because it is the third time this shift that the faulty instrument was this seat's own.Deviations
.changeset/9768-comment-projection-forcing-subject.mdsits outside the declared areas — a required artefact of the changeset gate, ⛔ not a widening.- Reported and correctly not filed: the pre-existing "JSDoc stripping does not eat real rows" counter-probe reads as though it exercised the projection but does not — its member-shaped line sits behind a docblock gutter while
members()anchors on exactly two spaces, so it passes identically with the projection removed. ⭐ A probe mistaken for a guard, in the same file, of the same class as this card — and this pull request supplies the thing it was mistaken for.
Releasing to the merge queue.
Generated by Claude Code
- The population was established mechanically, not inherited —
os-try-charles commented
on Sep 18, 2026 CollaboratorAuthorMore actionsLanded. PR #9814 merged at
2026-09-18T07:25:06Z, squash30a170e51, through the merge queue (enqueued07:04:45Z, receiptadded_to_merge_queue, ⛔ not the enable call's 200). No patch round.Landing probe, pre-validated against
mainbefore release and re-read onmainafter — per reader, all three:token reading why it is that token fire export interface CommentProjectionForcingSubject {0 → 2 the declaration and the OPENERthe pin must name to find the bodyfire expect([...rows.keys()]).toEqual(['real', 'label'])0 → 1 the leg that reds, asserting the member list fire read off the UNPROJECTED text0 → 1 the second leg — the fixture cannot silently lose its forcing row control const bare = stripComments(body);1 → 1 reasoned first: the deliverable forbids changing the reader, so movement here means the fix exceeded its mandate control the counter-probesdescribe block[1, 0, 1] unchanged reasoned first: those probes were measured inert and correctly left alone. Present in 2 of 3 readers — measured per file, ⛔ not assumed ⚠️ No clear leg: the change deletes nothing (0 deletions in all four files). A property of the change, ⛔ not a gap in the probe.Errata 62b: FIRED. By ancestry:
M^is2daa6c001, and2daa6c001...04d2dce19comparesdiverged(ahead 1, behind 5).⛔ A correction this seat owes, and it is about its own instrument
This landing sat 20m21s in the merge queue — past the 20.2-minute figure this seat has been reporting as an ejection margin — and it merged normally.
⇒ the two numbers were never comparable.
timeout-minutes: 20bounds a job's own run; queue dwell is queueing plus the build. objectui#9635's ejection was a job hitting its ceiling (20.2 min of run against 13.1 min on the PR head); the 20 / 19m26s / 18m46s / 20m21s figures are dwell. Two different clocks, and this seat has been reporting them as one — including to the maintainer, as a standing open item about a "pattern in the margin".⭐ That is the same error class this lane keeps cataloguing — measuring a different quantity than the claim names — committed by the seat, three times this shift now, and this is the one that reached a maintainer-facing item. The dwell figures stand as dwell; ⛔ they say nothing about the job ceiling, and the "three landings in a row inside the ejection margin" framing is withdrawn.
What the card produced. The population the card asserted (16 interface bodies) is not reproducible — 20 is the measured number, established by instrumenting
stripCommentsrather than inherited. Triage's escalation condition was answered against that population: identical member maps on 0 of 20 ⇒ no live defect, p3 stands. ⭐ And the sharper half: the projection is doing work — it removes prose from 17 of 20 bodies, 11,754 bytes in theAlertDialogSchemabody alone — it had simply never changed an answer. It now has a subject that makes it change one.
Generated by Claude Code
- added a commit that references this issue
on Sep 28, 2026
The comment projection at three
packages/typesreaders is inert on every subject the tree has today. Measured during objectui#9751: over 16 interface bodies, the member map produced with the projection and with no projection at all are identical, and the test file still passes with the projection removed.⇒ these readers carry a guard that nothing exercises, so nothing would notice if it were deleted, weakened, or quietly reverted to a hand-rolled regex. ⛔ That is not a claim the guard is wrong — it is correct, and objectui#9761 just moved it onto
scripts/js-comment-mask.mjswith zero behavioural risk precisely because it is inert. The finding is that its correctness currently rests on a classification argument and not on anything that reddens.The carriers
packages/types/src/__tests__/overlay-node-slot-doc-types-7082.test.tspackages/types/src/__tests__/alert-dialog-read-dialect-7104.test.tspackages/types/src/__tests__/overlay-trigger-union-7081.test.tsEach strips comments out of a
.tssource before counting interface members. The hazard the original docblock named is real — prose inside a block comment that looks like a member row would be counted as one — but no subject in the tree spells it.Why this is its own card and was not folded into objectui#9761
⛔ Adding a forcing fixture inside that pull request would have mixed a behaviour-preserving conversion with a new assertion, and afterwards a reviewer could not tell which of the two any test result was about. The seat ruled option A (land the conversion as is, state the inertness as measured) with this as the follow-up. Record: objectui#9751's ACCEPT and landing comments.
Sketched direction (⛔ not chosen — a triage call)
Give the projection something to defend: a fixture interface body carrying a member-shaped line inside a block comment, pinned so the member count is wrong when the projection is removed.⚠️ The fixture has to be a subject, not a synthetic string handed to the reader — the distinction objectui#9748 drew between "the file's measured behaviour" and "the shape the file does not have today" applies here too, and a pin that blurs it teaches the wrong thing.
⛔ Not a request to convert anything: objectui#9761 already did the conversion. ⛔ Not objectui#9751 (that was residue plus the recurrence channel, and it is closed).
Provenance
Surfaced by objectui#9751's dev as an open question after its reverse ablation came back green, ruled by the
domain:devx@ objectui execution seat,session_015h79niBMyoB1xcaQje3uiz, R73, 2026-09-18. The measurement is the dev's; the ruling to card it rather than fold it in is the seat's. ⛔ This seat does not grade, route or prioritise.Dedup words:
inert guard·comment projection·overlay-node-slot-doc-types-7082·member count fixture·9761 follow-upGenerated by Claude Code