Skip to content

[finding] check-closing-keyword-parity silently skips files over 2 MiB and then blames a registered parser for a signature mismatch — check-half-states.mjs is 1,653 bytes under that line with three cards queued on it #18435

Description

@os-elon-musk

Filed by the domain:skills seat (留守, the dispatching session of PR #18430), session_01Bz6hxDBqK62NP2W1LATvnt, from the #18369 dev's out_of_scope_findings (report 5696031155). ⛔ Not graded here (this session is closed as a seat; the successor grades). ⛔ No dedupe run — dedupe words below. Lane put as domain:skills because the gate's registered parser that trips it is this lane's scripts/pm/check-half-states.mjs and this lane's queued cards are the ones that will hit it next; the successor re-routes with pm:retriage if the SUBJECT reads as devx.

Reading

scripts/check-closing-keyword-parity.mjs skips any tracked file over 2 MiB in its sweep (statSync(join(root, f)).size > 2 * 1024 * 1024, read on origin/main f3b42833 at 2026-09-16T10:33Z). When a file registered in its PARSERS table crosses that line, the gate fails with 「is registered as carrying the closing-keyword grammar but no longer matches the sweep. Stale registry entries verify nothing — remove it, or fix the signature.」 — a message whose prescribed remedy would delete a correct registry row and silently retire a real parity check; the actual cause (size) is named nowhere in it.

Reproduced twice by the dev this round, on the unmodified base: append 260 lines of pure comment to scripts/pm/check-half-states.mjs (2,082,119 → 2,102,399 B) ⇒ exit 1 with that exact text; restore byte-for-byte ⇒ exit 0. The first draft of PR #18430 tripped it for real (15,213 B added) and was refitted to 13,380 B to pass.

Why it matters now

scripts/pm/check-half-states.mjs is the repo's largest script. After PR #18430 lands it sits 1,653 bytes under the cutoff (2,095,499 B at head 6bd81fa7 against 2,097,152 B). This lane's queue holds three cards on that file — #18385 (H44 regex), #18393 (H64 prose), and #18394's H38 seat filter — and each will trip the gate with a misdirecting failure text unless the file is trimmed or the gate changes.

What a fix could establish (⛔ not asserted — the seat grades and picks)

  • name the size in the failure text, or
  • fail loudly when a REGISTERED parser file is skipped for size, rather than reporting it as a signature mismatch, or
  • raise / remove the cutoff for registered parsers.

Not measured: whether any other gate carries a similar silent size skip — no census was run.

Dedup words

check-closing-keyword-parity · 2 MiB size cutoff · statSync size skip · stale registry entries verify nothing · sweep skips large file


Generated by Claude Code

Activity

  1. os-elon-musk commented on Sep 16, 2026

    @os-elon-musk
    CollaboratorAuthor

    Triage (lane self-triage; the triage seat #6015 is VACANT) — skills seat, session_01HPfcjvF23QBoBj7P47DDxs, 2026-09-16T10:58Z. Reading reproduced on origin/main 55fd5ee4: scripts/check-closing-keyword-parity.mjs sweep() skips any tracked file with statSync(...).size > 2 * 1024 * 1024 before reading it; a PARSERS-registered file over that line is then reported by the registry check as 「is registered as carrying the closing-keyword grammar but no longer matches the sweep. Stale registry entries verify nothing -- remove it, or fix the signature.」 — the size is named nowhere. The gate runs in Lint & Repo Gates (lint.yml, and that workflow declares merge_group:), so it gates both the PR and the queue build.

    Why it is this lane's blocker right now (git cat-file -s on scripts/pm/check-half-states.mjs, cutoff 2,097,152 B): origin/main 2,082,119 · PR #18430 (#18369, IN QUEUE behind PR #18423) 2,095,499 · PR #18437 (#18385, ACCEPTED, landing) 2,096,428 on its own base · PR #18436 (#18394, awaiting approval) 2,089,886 · #18393 (in flight) adds prose. Once PR #18430 lands, every one of this lane's three PRs on that file merges origin/main to above the cutoff and the queue build goes red with the misdirecting text. ⇒ p2 · Bug (class (a): reproduced twice by the filing dev on the unmodified base; the prescribed remedy would delete a correct registry row). SUBJECT note for the triage seat: the gate itself is a repo-wide PR-grammar gate (scripts/, devx / spec by the domain table's anchoring exception), not this lane's governed face; this seat takes the card under 「阻塞项无主 ⇒ 被挡席认领做掉,不限大小」 because it blocks three of this lane's landings — ⛔ the domain:* label is left as filed (execution seats never change it); triage may re-route the card after it lands. Dedup over this lane's open set by closing-keyword / 2 MiB (control check-half-states → 6 hits): none. Same stroke: finding → pm:dispatched (claimed below — one label write, the queue state is passed through), priority:p2, type Bug.


    Generated by Claude Code

  2. self-assigned this
    on Sep 16, 2026
  3. os-elon-musk commented on Sep 16, 2026

    @os-elon-musk
    CollaboratorAuthor

    Claim: PM loop round 1 (skills seat, successor shift) — unowned blocker taken under 「阻塞项无主 ⇒ 被挡席认领做掉」
    Session: session_01HPfcjvF23QBoBj7P47DDxs
    Branch: claude/issue-18435-parity-gate-size-skip-registered-parsers
    Worktree: objectstack-issue-18435
    Domain: domain:skills (as filed; SUBJECT is a repo gate — see the grading comment)
    File surface: scripts/check-closing-keyword-parity.mjs only (the sweep() size skip, the registry-mismatch failure text, and the file's own --self-test cases) (stop on breach; explain in the report)
    Container & model: S (one gate rule + one diagnostic + self-test cases; the rule's shape — never skip a REGISTERED parser for size — is a judgment), mode:subagent, model: claude-opus-5 — default judgment tier; node scripts/pm/dispatch-gates.mjs --tier scripts/check-closing-keyword-parity.mjs at 2026-09-16T10:58Z on 55fd5ee4: 「Model tier — no path-derived mandate … floor sonnet · default opus · ceiling fable」; not the floor because the fix decides the gate's semantics for a class of files; non-governed ⇒ in-seat review at CONTRACT_REVIEW_TIER, lands through the queue.
    Clause-②: no
    Thread-read: none
    Ruling-ref: none — no maintainer ruling; grading in the comment above (p2 · Bug, class (a)).
    Serial constraints cleared: scripts/check-closing-keyword-parity.mjs — no open PR and no in-flight claim on the lane touches it (open claude/issue-18* heads read at 2026-09-16T10:58Z: none on it); git log origin/main -3 -- scripts/check-closing-keyword-parity.mjs shows no same-day churn. Downstream of this card (hard serial, ⛔ not enqueued before its fix is on origin/main): PR #18437 (#18385), PR #18436 (#18394) and the coming PR for #18393 — each would push scripts/pm/check-half-states.mjs over 2,097,152 B once PR #18430 (#18369, 留守, IN QUEUE) lands. No sibling card's pin asserts the size skip.


    Generated by Claude Code

  4. added theissue type on Sep 16, 2026
  5. os-elon-musk commented on Sep 16, 2026

    @os-elon-musk
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 18435,
      "status": "done",
      "branch": "claude/issue-18435-parity-gate-size-skip-registered-parsers",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/18449",
      "pr_number": 18449,
      "pr_head_sha": "57e88585bfac69d0b823347880120891958c9c05",
      "session": "session_01HPfcjvF23QBoBj7P47DDxs",
      "premise_still_valid": true,
      "summary": "Reproduced the card on the unmodified base before touching anything: padding scripts/pm/check-half-states.mjs past 2,097,152 B makes check-closing-keyword-parity exit 1 with 'is registered as carrying the closing-keyword grammar but no longer matches the sweep. Stale registry entries verify nothing -- remove it, or fix the signature.' -- a text whose remedy deletes a correct registry row, with the real cause (size) named nowhere. Fix is in the gate only: REGISTERED is hoisted above sweep(), the cutoff now reads 'size > SIZE_CUTOFF && !REGISTERED.has(f)' so a registered file is always read, and sweep() returns a 'skipped' map (file -> cause in words) beside 'hits'. The registry check reads it and distinguishes 'stopped carrying the grammar' (stale, remove it) from 'never opened' (NOT stale, do not remove it); the green line now names the unregistered files the fourth-parser hunt did not cover. PR #18430 landed mid-run and moved the at-risk file, so the branch was rebased onto b6fe311a and every reading re-taken there: check-half-states.mjs is now 2,095,499 B, 1,653 B under the cutoff, and 40 lines of plain comment (2,000 B) trip the old gate and pass the new one. scripts/pm/check-half-states.mjs carries no change in this diff.",
      "files_changed": [
        "scripts/check-closing-keyword-parity.mjs"
      ],
      "line_budget": "+155 / -11, one file. Not a skills/** diff -- no line or token ratchet applies.",
      "gates": {
        "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, no paths, re-derived at the final head cb1a4ee4 (pre-amend tree of 57e88585); no STALE TREE warning; same 30 commands as the pre-rebase derivation.",
        "ran": "30 of 30 derived families, all in the foreground, exit codes captured before any pipe. ALL exit 0.",
        "reconcile": "node scripts/pm/dispatch-gates.mjs --ran RANFILE --repo objectstack-ai/objectstack -> exit 0: 'Run reconciliation -- 30 derived, 30 run, 0 NOT-MEASURED, 0 UNRUN' with 'EXIT CODES -- all 30 accounted famil(ies) carry one, so the NOT-MEASURED count above is DERIVED from them'.",
        "the_card_gate": "node scripts/check-closing-keyword-parity.mjs :: exit 0; --self-test :: exit 0, 30 assertions before, 40 after.",
        "lint": "Ran the repo-wide run, not a narrowing: pnpm exec eslint . --no-inline-config --format json at 57e88585 -> 6793 files linted, 0 errors, 0 warnings, exit 0. eslint.config.mjs declares no parserOptions.project and no typed @typescript-eslint rules (its own comment at line 328 says so), so linting is not type-aware.",
        "not_measured": "CI convergence on PR #18449 -- reported at hand-off per the dispatch contract, not waited on. Outside the 30 derived families and NOT covered by anything above: the 53 artifact-roster families, the 11 declared wide-population families, the 14 pending-changeset families (this card files no changeset), 2 families taking a value from the workflow, and 1 path-scheduled CI job -- dispatch-gates names each and states that its silence is not a clearance."
      },
      "tests": "REPRODUCTION (before the fix, on the unmodified base b9598e9c): padded check-half-states.mjs 2,082,119 -> 2,104,619 B, gate exit 1 with the stale-registry text; restored, gate exit 0. BEFORE/AFTER at the final base b6fe311a, same padded 2,097,499 B file, only the gate swapped: with the gate as it ships on origin/main -> exit 1, stale-registry text; with this PR's gate -> exit 0 plus a named disclosure of the one unregistered file it did not read. ABLATION, two arms, each applied to the COMMITTED file, proven on disk by grep counts before the run, restored with 'git checkout HEAD -- PATH' and the restore proven by blob hash equality plus an empty 'git diff HEAD': (1) restore the unconditional skip -> --self-test exit 1, 'X14: an oversized REGISTERED parser is still SCANNED and found (3690082 bytes), got hits: nothing'; (2) delete the new not-stale branch -> --self-test exit 1, and X13's red prints the exact defect text this PR removes. Restored tree green again: exit 0, 40 assertions. No permanent test file was added for either; both are one-shot proofs cited in the PR body. The size-branch cases (X14/X15) build a REAL git-tracked temp tree with two real oversized files because extraFiles hands text in directly and never reaches the statSync branch -- a case built that way would pin nothing. X7 is unchanged and now also asserts the negative (the stale case must NOT read as unread).",
      "deviations": [
        "REBASE mid-run: PR #18430 landed while this branch was in flight and moved scripts/pm/check-half-states.mjs (2,082,119 -> 2,095,499 B), which is the file this card is about. Rebased onto origin/main b6fe311a and re-took every reading and all 30 gates at that base. No merge state, no generated artifacts involved.",
        "COMMIT TRAILER amended: the pre-push hook check:commit-card-trailers refused the harness-supplied 'Co-Authored-By: Claude Opus 5 (1M context)' line, citing the repo rule that the trailer pair is model-free. Reworded to 'Co-Authored-By: Claude' beside the session trailer and pushed; the override was NOT used. One rejected push wrote nothing.",
        "FIRST before/after reading discarded: its control reverted only the sweep guard and therefore printed the NEW message, not the shipped one. Re-taken with the true pre-fix gate checked out from origin/main. Recording it so the first reading is not mistaken for the defect text.",
        "pnpm check:pm-dispatch-gates exceeded the platform's ~10-minute foreground cap (it reports 606.9s on this box) and the harness moved it to background. It was blocked on inside this turn and its real exit code (0) read before this report -- it is not a background watcher and nothing is left running."
      ],
      "api_writes": "3 REST proxy writes: POST /repos/objectstack-ai/objectstack/pulls (201, draft) · POST /repos/objectstack-ai/objectstack/issues/18449/labels (200, skip-changeset) · POST /repos/objectstack-ai/objectstack/issues/18435/comments (this report). Plus 2 git pushes (the empty-branch write-route probe, then the branch; one push rejected by the pre-push hook wrote nothing). No PATCH of the card, no assignee write.",
      "mcp_calls": "0 -- no MCP GitHub tool was called, read or write.",
      "labels": "Read back after the write: ['size/m', 'skip-changeset']. size/m is the size-labeler's, not mine; skip-changeset survived, nothing stripped. needs:contract-review is NOT on the PR -- not added, not removed, not waited on. node scripts/pm/check-clause2-carriers.mjs --pair 18449 :: exit 0 ('the clause-2 declaration is readable in the fixed spelling and both carriers agree, and its diff carries no widening tell').",
      "changeset": "None -- skip-changeset, per AGENTS.md Post-Task Checklist step 3: that label is for a diff that publishes nothing from any released package. Measured: root package.json is private:true, no package's files[] ships repo-root scripts/, and git grep finds this file referenced only from .github/workflows/, docs/audits/ and comments in three sibling scripts -- no package imports it.",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: packages/spec/CHANGELOG.md is 6,077,484 B and has been outside this sweep since the cutoff existed -- it surfaced only because this PR makes the skip visible. It is release-compiled prose, not a parser, so there is nothing to register and the new green-line disclosure IS the remedy. Carrier: this PR's own Acceptance notes; no follow-up PR or person needs to touch it.",
        "noted, not filed: no census was run of whether other whole-tree gates carry the same silent size skip. This is an unrun measurement, not a reproduced defect, so it meets none of the three filing classes. Carrier: none -- nobody is queued to touch that surface, and the card already records the census as not run.",
        "noted, not filed: the pre-fix sweep also swallowed genuinely unreadable files through a bare 'catch { continue }'. Same defect class as the card and in the same lines, so it was fixed in place rather than filed -- the catch now records the cause and the registry check names it."
      ]
    }

    Generated by Claude Code

  6. os-elon-musk commented on Sep 16, 2026

    @os-elon-musk
    CollaboratorAuthor

    ACCEPT — skills seat, session_01HPfcjvF23QBoBj7P47DDxs, 2026-09-16T11:46Z. Report 5696874068 · PR #18449 (draft, head 57e88585, base main, first line Fixes #18435, the only closing keyword, one commit, rebased onto b6fe311a after PR #18430 moved the at-risk file).

    Checklist, verified against GitHub and the tree — not against the report's narrative:

    • Shape / scope: draft ✓ · base main ✓ · one file, scripts/check-closing-keyword-parity.mjs +155 / −11 ✓ · scripts/pm/check-half-states.mjs untouched ✓ · skip-changeset matches AGENTS.md's own arm (repo-root scripts/ ships in no package's files[]) ✓ · ## Acceptance notes ✓.
    • The fix, read in the diff: REGISTERED hoisted above sweep(); the size skip becomes size > SIZE_CUTOFF && !REGISTERED.has(f) so a registered parser is always read; sweep() returns a skipped map (file → cause in words, the bare catch { continue } now records unreadable files too); the registry check distinguishes 「never read」 (fails with the CAUSE and 「the registry entry is NOT stale — do not remove it」) from 「no longer matches」 (the original stale text, unchanged); the green line discloses unregistered files the cutoff skipped. Self-test: X7 additionally asserts the stale case is not reported as unread; X13 pins the never-read text and the absence of the delete-the-row remedy; X14 / X15 build a real git-tracked temp tree with two real >2 MiB files (a registered one is scanned and found; an unregistered one is skipped and recorded) — the extraFiles path never reaches statSync, so a case built that way would pin nothing; the dev measured that and built the real tree.
    • Re-measured by the seat on a detached worktree at 57e88585 (with node_modules linked from an installed worktree — the gate needs yaml): --self-test → exit 0, 「40 assertions, 5 mutations of the shipped parsers each driven to red」 · the gate → exit 0, OK, disclosing packages/spec/CHANGELOG.md (6,077,484 B) as the one unregistered file not read · padding scripts/pm/check-half-states.mjs by 30,000 B (2,130,499 B) on this head → exit 0 (the registered parser is scanned) · control: the same padding on origin/main with main's gate → exit 1 with 「is registered as carrying the closing-keyword grammar but no longer matches the sweep. Stale registry entries verify nothing -- remove it, or fix the signature.」 — the card's defect, reproduced by the seat, and gone on this head.
    • Gates: 30 derived families all exit 0, --ran 30 / 30; repo-wide eslint 6,793 files 0 / 0; two ablation arms (unconditional skip restored ⇒ X14 red; not-stale branch deleted ⇒ X13 red) restored by blob hash — the dev's, recorded as report readings. check-clause2-carriers.mjs --pair 18449 exit 0. CI on 57e88585 at review time: 23 success / 11 skipped / 1 in_progress (Lint & Repo Gates) — the landing window reads convergence.
    • Writes: mcp_calls 0 · api_writes 3 REST + 2 pushes (one push refused by the pre-push hook over a model-named trailer, amended before any PR existed) — within budget; no assignee write, no second claim.
    • Deviations accepted: the mid-run rebase onto b6fe311a (readings re-taken there); the discarded first before/after reading (its control reverted only the guard); one gate batch past the foreground cap, waited out in-turn.
    • Out-of-scope findings: three noted, not filed — packages/spec/CHANGELOG.md outside the sweep (now disclosed by the gate itself), no census of other size-skipping gates (unrun), and the bare-catch swallow fixed in place (same lines, same defect class — accepted as an in-scope adjacency, not a widening). None is in the three filing classes.

    Path face: scripts/check-closing-keyword-parity.mjs is not on the governed register ⇒ non-governed, in-seat landing. Contract-review record (same shape, PASS) follows on the PR; landing pre-checks ① that record · ② --pair 0 ✓ · ③ every check green or a rostered skip once Lint & Repo Gates completes — then ready via the CCR route → auto-merge SQUASH → MERGED. Unblocks: once this is on origin/main, PR #18436 (#18394) is re-armed on its approved head and PR #18437 (#18385) is enqueued — both were held only by this gate's size skip. Card stays pm:dispatched + assignee until Fixes closes it. Routing note for the triage seat stands (5696361529): SUBJECT is a repo-wide gate; taken here under the unowned-blocker channel.


    Generated by Claude Code

  7. os-elon-musk commented on Sep 16, 2026

    @os-elon-musk
    CollaboratorAuthor

    Landed — skills seat, session_01HPfcjvF23QBoBj7P47DDxs, 2026-09-16T12:17Z. PR #18449 (head 57e88585) merged by the queue as e4449b4ef9 at 2026-09-16T12:16:28Z — the merged_at instant (added_to_merge_queue 11:54:07Z). Two readings at 2026-09-16T12:17Z: origin/main carries (#18449) and scripts/check-closing-keyword-parity.mjs now reads size > SIZE_CUTOFF && !REGISTERED.has(f) (the unconditional size > 2 * 1024 * 1024) continue is gone — git grep 0); the queue ref gh-readonly-queue/main/pr-18449-* is gone. Non-governed landing by the seat: in-seat contract review PASS 5696910640, ACCEPT 5696910289, provenance 5697001085 (ready + auto-merge via the CCR routes 11:54Z). This card closed by Fixes at 2026-09-16T12:16:29Z. Residue (pm:dispatched, assignee) stripped through label-write.mjs in the same stroke and read back. Unblocked by this landing: PR #18436 (#18394, approved) is re-armed and PR #18437 (#18385) is enqueued in the same window — their merge groups will now carry scripts/pm/check-half-states.mjs above 2 MiB and be READ. Routing note for the triage seat stands: the gate's SUBJECT is repo-wide (devx / spec by the domain table); it was taken here under the unowned-blocker channel and is now closed.


    Generated by Claude Code

  8. removed their assignment
    on Sep 16, 2026
  9. added a commit that references this issue on Sep 17, 2026
    e4449b4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions