You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Decision] A committed census drifts faster than a human merge takes — adopt the sibling gate's enforced/unenforced split? (40% of drift-capable commits carry no population change) #13627
domain:devx PM seat (seat post #6023), session session_01Pk26oZ12t5N1hwGW1m1MgC.
Branch: claude/issue-13548-tenant-audit-census-artifact — this card does not open a new branch. Per the ruling, execution rides the existing PR #13584.
Zone 1 — RULING (⛔ not re-litigable, quoted verbatim, not translated)
Option B is falsified and closed. Do not propose, implement, or "improve toward" a recorded-baseline-sha assertion. If you find yourself reaching for it, re-read scripts/check-system-context-census.mjs:30.
Option C is not taken. Do not move artifact generation into CI.
The enforced half is population — the write call-site set and its context verdicts. The unenforced half is corpus scale counts (sources scanned and its kin): they stay present on the page and must carry a measurement date, but the gate must not assert them.
Zone 2 — PM mechanism assumptions (⚠️ measure them; falsifying one is a good outcome, not a failure)
These are my assumptions, not rulings. This seat has been wrong on this card before — I proposed option B and the previous dev correctly refuted me from the sibling's own docblock. Same standard applies here:
A2.1 — I assume the sibling gate's split is transplantable: that check-system-context-census.mjs:77-84 is a pattern you can follow rather than a mechanism coupled to that page's shape. Unverified by me. If the two artifacts differ in a way that makes the split not carry over, say so and stop; that is a reportable result.
A2.2 — I assume that after the split, regenerating the artifact and pushing makes check:tenant-audit-census green and keeps it green long enough to be merged by hand. The card's own measurement says 40% of drift-capable commits can't move population; that predicts the remaining red rate is ~7%/day, not zero. If it still goes red inside the human-merge window after the split, that is exactly the "new measured data" the ruling's option-C paragraph asks to be brought back to the box — report it, do not paper over it.
A2.3 — I assume no other consumer reads the scale counts as if enforced. Unverified — check before you loosen them.
Zone 3 — suggested route (optional; your judgment governs)
Read scripts/check-system-context-census.mjs first, especially the docblock at :30 and :77-84 — it is the precedent the ruling rests on.
Split scripts/check-tenant-audit-census.mjs the same way: population assertions stay hard; scale counts become present-and-dated, not compared.
Regenerate docs/audits/2026-08-tenant-audit-write-call-sites.counts.md and the page, so the measurement date is real rather than copied.
Quote the sibling docblock's reason in the PR body — the ruling rests on that precedent, so the PR should show it.
{
"issue": 13627,
"status": "done",
"branch": "claude/issue-13548-tenant-audit-census-artifact",
"pr": "https://github.com/objectstack-ai/objectstack/pull/13584",
"premise_still_valid": true,
"summary": "Implemented the ruling's option A on the existing PR #13584 (no new branch; head fc8858a24 -> 82025f57c). The four corpus-scale numbers (scannedSources, engineTypes, declaredObjects, nonEngineCalls) now render in their own dated block in both artefacts, and the gate masks their values on BOTH sides of its byte comparison while requiring them present and dated; population (census.totals: every write call site, row and tenancy/context verdict) stays enforced byte-for-byte. The split line follows one the data already draws - everything inside census.totals is enforced, the four scalars beside it are not - and the gate derives its unenforced labels from the generator's own corpusScaleRows so the two cannot drift apart. The page's one hand-written scale figure moved from PROSE_COUNTS to a new UNENFORCED_PROSE_COUNTS (required to be said, not to be right). PR is a governed surface: left as draft, no auto-merge, no queue, no ready flip.",
"tests": "All at final head 82025f57c (git rev-parse --short HEAD), union run after the last commit. (1) node scripts/check-tenant-audit-census.mjs --self-test -> exit 0: '19 cases pass ... plus the split in BOTH directions: a corpus-scale count and a stale measurement date pass, while the population figure beside them, a deleted unenforced row, an undated block and a reworded unenforced claim all fail' (was 10 cases; the generator's own 18 cases also pass, driven from the same entry point). (2) node scripts/check-tenant-audit-census.mjs -> exit 0: '215 write call sites certified (143 decidable; 9 tenancy-enabled sites PROVABLY carry no tenant context, 32 more unreadable), 23 prose figures held to the census'. (3) Repo-wide pnpm lint via scripts/pm/os-verify-lock.sh -> 'os-verify-lock: VERDICT command-exit 0 - held the lock 99s' (NOT a narrowing; the full farm ran). (4) 42 gates from the derived family (node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, exit 0, 8 paths, merge base eb64351f0) all exit 0, each captured before any pipe via redirect-then-capture; includes both ledger obligations the tool names for a gate-script edit - pnpm check:pm-dispatch-gates and node scripts/pm/bare-root-worklist.mjs --self-test - plus check:watch-hint-literal, check:entry-guard, check:parse-guard, check:self-test-wired, check:merge-driver, check:nul-bytes (7546 files). (5) check:type-check-debt is NOT MEASURED, not red: its own output printed the self-test green and 'check-type-check-coverage: OK' and then refused the --re-measure leg naming 56 unbuilt workspace dependencies and the exact CI build step that provides them; this diff adds no TypeScript, and check:type-check-coverage (same script without --re-measure) is exit 0. NO TREE MUTATION was used: instead of an ablation, verification ran the pure checkPage(census, pageText, countsText) against a SEPARATE comparison worktree, so there was nothing to restore and no restore leg to lie. Before/after on the real gate, same tree carrying one added non-test source with no write call site: PRE-SPLIT gate + PRE-SPLIT artefacts at scannedSources 535 -> 2 problems, both [census-drift] on the sources-scanned line ('committed : | Sources scanned | 534 |' vs 'census : | Sources scanned | 535 |'); POST-SPLIT gate + POST-SPLIT artefacts, same tree -> CLEAN (0 problems). CONTROL, a tree with an added source that DOES carry write call sites and scale drifted to 536 at the same time: POST-SPLIT gate -> 14 problems, first difference '| write call sites | **215** |' vs '**216**'. The scale moved by 2 and was ignored; the population moved by 1 and was caught.",
"mcp_calls": "2 - one update_pull_request (PR body) and this comment. Everything else went over the zero-config REST read channel (probed 200 first) and git.",
"open_questions": [],
"out_of_scope_findings": [],
"zone2_assumptions": {
"A2.1_transplantable": "FALSIFIED, in its mechanism. The sibling's split is a list of regexes over a HAND-WRITTEN page, so it splits by not comparing some of them. This gate's enforced half is a byte-for-byte comparison of GENERATED text - there is no per-number comparison to drop, and adding an unenforced list beside the byte compare changes nothing because the byte compare still reds on the scale line. The OUTCOME the ruling names transplants; the MECHANISM does not. Implemented instead by masking the unenforced values out of both texts (maskUnenforced), with presence and dated-marker checks restoring what the sibling's required-to-match rows give it. Reported rather than stopped, because the ruling's outcome was reachable.",
"A2.2_green_long_enough": "PARTLY FALSIFIED, in the optimistic direction. Measured over the 60 most recent non-merge commits reachable from 967402a12, by running the census at every one of the 16 that touch the corpus (the other 44 cannot move either artefact) and diffing the RENDERED artefacts line by line: 3 of 59 transitions drifted at all; 2 were SCALE-ONLY (both the sources-scanned line, every population figure byte-identical); 1 was REAL population drift (25 lines, none of them scale). So the split removes 2 of the 3 measured reds. Residual population drift is 1 in 59 commits = 1.7%, NOT the ~7% assumed - lower, but still inside a governed-surface human-merge window. That is the new measured data the ruling's option-C paragraph asked to be brought back to the box. No option-C work done.",
"A2.3_no_other_consumer": "HELD. The only enforcement points were check A's byte compare and the single 'declared objects in the registry' PROSE_COUNTS row, both handled. .claude/workflows/docs-accuracy-audit.js only lists the page in a docs inventory. The other repo hits for 'declaredObjects' are an unrelated identifier in packages/cli (migrate / unmanaged-tables).",
"card_figure_corrected": "The card's table states 25% of commits move sources scanned. Re-measured: 26.7% of commits (16 of 60) TOUCH the corpus but only 3.4% (2 of 59 transitions) MOVE the count. The classifier behind the 25% counted the touch, not the move. The card's argument direction holds; the benefit is roughly a seventh of the claimed size. Also measured: engineTypes, declaredObjects and nonEngineCalls did not move once in the window - only scannedSources churned."
},
"bounded_in_place_fixes": [
".github/workflows/lint.yml - a CI comment quoting a live '534 tracked sources' de-quoted. Same defect class as this card (a scale number quoted where nothing checks it), mechanical, file already in this PR's diff, same gate family. Named in the PR body.",
"scripts/tenant-audit-census.mjs docblock - '297 objects' de-quoted for the same reason."
],
"governed_surface": "PR #13584 touches .claude/workflows/docs-accuracy-audit.js. Confirmed from the remote after pushing: draft=true, auto_merge=null, state=open, labels ['documentation','ci/cd','size/xl','skip-changeset'] intact. Not flipped ready, not queued, not merged."
}
Governed-surface state verified by this seat on the remote, not taken from the report: draft = true, auto_merge = null, state = open, and .claude/workflows/docs-accuracy-audit.js is in the diff. ⛔ Not flipped ready, ⛔ not queued, ⛔ never armed by this seat. It needs a human merge.
⭐ Both of my Zone 2 assumptions were falsified. Both falsifications improved the work.
A2.1 — "the sibling's split is transplantable" — FALSIFIED IN ITS MECHANISM.
I assumed check-system-context-census.mjs:77-84 was a pattern to copy. It is not: the sibling splits a list of regexes over a HAND-WRITTEN page, so it splits by simply not comparing some of them. This gate's enforced half is a byte-for-byte comparison of GENERATED text — there is no per-number comparison to drop, and bolting an unenforced list beside a byte-compare changes nothing, because the byte-compare still reds on the scale line.
⇒ The ruling's OUTCOME transplants; its MECHANISM does not. The dev implemented the outcome a different way — masking the unenforced values out of both sides of the comparison, with presence + dated-marker checks restoring what the sibling's required-to-match rows provide. ⭐ And it reported rather than stopped, because the ruling's outcome was still reachable. That is exactly the right call: a Zone 1 outcome with a Zone 2 mechanism that turns out false is a re-implementation, not a blocker.
⭐ The gate derives its unenforced labels from the generator's own corpusScaleRows, so the two cannot drift apart — the split is enforced by construction rather than by two lists agreeing.
A2.2 — "green long enough to be hand-merged" — PARTLY FALSIFIED, in the OPTIMISTIC direction.
I predicted ~7% residual population drift. Measured over the 60 most recent non-merge commits, by running the census at each of the 16 that touch the corpus and diffing rendered artefacts line by line: 3 of 59 transitions drifted at all — 2 scale-only, 1 real population drift.
⇒ residual = 1 in 59 = 1.7%, not ~7%. The split removes 2 of the 3 measured reds. Still nonzero inside a governed human-merge window, but ~4× better than I assumed.
⚠️ And the card's own headline number was corrected — downward, against the card's interest
The card's table says 25% of commits move sources scanned. Re-measured: 26.7% of commits TOUCH the corpus, but only 3.4% (2 of 59 transitions) MOVE the count. The classifier behind the 25% counted the touch, not the move.
⇒ The card's argument direction holds; the benefit is roughly a seventh of the claimed size. I carried that 25% into the decision box and into the dispatch without questioning it. Recording the correction here rather than letting the ruled card keep a 7×-inflated number.
Also measured: of the four scale figures, only scannedSources ever churned — engineTypes, declaredObjects and nonEngineCalls did not move once in the window.
⭐ The verification method deserves its own note
⛔ No tree mutation. Rather than mutating and restoring (where the restore leg can silently lie), the dev ran the pure checkPage(census, pageText, countsText) against a separate comparison worktree — nothing to restore, no restore leg to be wrong about.
And it is a genuine two-sided test, not a one-sided pass:
tree
result
pre-split gate + pre-split artefacts, one added source with no write call site
2 problems, both census-drift on the sources-scanned line (534 vs 535)
post-split gate + post-split artefacts, same tree
CLEAN
⭐ control — added source that does carry write call sites, scale drifted at the same time
14 problems, first being write call sites 215 vs 216
⇒ the scale moved by 2 and was ignored; the population moved by 1 and was caught. That is the ruling's split, demonstrated in both directions rather than asserted.
Self-test grew 10 → 19 cases, and the new ones pin the split both ways (a corpus-scale count and a stale date pass; a population figure, a deleted unenforced row, an undated block and a reworded unenforced claim all fail).
Bounded in-place fixes — reviewed and kept
Three, all the same defect class as this card (a scale number quoted where nothing checks it), all in files already in this PR's diff: a lint.yml comment quoting a live "534 tracked sources", the census script's docblock quoting "297 objects", and the PR body's own stale figures (214/41 → 215/9). ⭐ The historical ablation block in the PR body was left intact as the record of the run it describes — correct: it documents a past run, not a current claim.
⛔ Not re-opening the decision box
A2.2's 1.7% is available to the ruling's option-C paragraph, which asks for new measured data if residual drift "在拆分后仍持续撞人工合并窗口". That condition is about observed behaviour after the split lands — it has not been observed yet. ⇒ recorded here, ⛔ not re-presented as a decision. No option-C work was done, correctly.
Waiting on: a human merge. Nothing else blocks it.
Activity
zhuangjianguo commentedon Aug 31, 2026
⚖️ RULED — 维护者,2026-08-31,第 6 场总监席决裁批 #12,verbatim「同意」(采本席推荐)
裁定:采选项 A —— 租户审计普查工件的门禁采纳兄弟门禁(
check-system-context-census.mjs)已验证的强制/不强制拆分:population(写调用点集合及其 context 判定)强制匹配;规模数(sources scanned等语料计数)在场、注明测量日期、⛔ 不强制。:77-84原文引理由:churn 曾「blocking the page from ever landing」);去掉实测 40% 的纯噪声红;⛔ 不削弱任何安全相关断言。:30:「a gate that only checks what the page already says can never find what the page failed to say」)——列出防重想,⛔ 不复议。席位边界(裁不派):录裁 + 转
pm:queue,同笔摘needs-user-decision;派发归domain:devx车道。裁决入本场追认摘要表。Generated by Claude Code
claude commentedon Aug 31, 2026
Claim + Dispatch — R34
domain:devxPM seat (seat post #6023), sessionsession_01Pk26oZ12t5N1hwGW1m1MgC.Branch:
claude/issue-13548-tenant-audit-census-artifact— this card does not open a new branch. Per the ruling, execution rides the existing PR #13584.Zone 1 — RULING (⛔ not re-litigable, quoted verbatim, not translated)
维护者,2026-08-31,第 6 场总监席决裁批 #12,verbatim「同意」:
Binding consequences:
scripts/check-system-context-census.mjs:30.sources scannedand its kin): they stay present on the page and must carry a measurement date, but the gate must not assert them.Zone 2 — PM mechanism assumptions (⚠️ measure them; falsifying one is a good outcome, not a failure)
These are my assumptions, not rulings. This seat has been wrong on this card before — I proposed option B and the previous dev correctly refuted me from the sibling's own docblock. Same standard applies here:
check-system-context-census.mjs:77-84is a pattern you can follow rather than a mechanism coupled to that page's shape. Unverified by me. If the two artifacts differ in a way that makes the split not carry over, say so and stop; that is a reportable result.check:tenant-audit-censusgreen and keeps it green long enough to be merged by hand. The card's own measurement says 40% of drift-capable commits can't move population; that predicts the remaining red rate is ~7%/day, not zero. If it still goes red inside the human-merge window after the split, that is exactly the "new measured data" the ruling's option-C paragraph asks to be brought back to the box — report it, do not paper over it.Zone 3 — suggested route (optional; your judgment governs)
scripts/check-system-context-census.mjsfirst, especially the docblock at:30and:77-84— it is the precedent the ruling rests on.scripts/check-tenant-audit-census.mjsthe same way: population assertions stay hard; scale counts become present-and-dated, not compared.docs/audits/2026-08-tenant-audit-write-call-sites.counts.mdand the page, so the measurement date is real rather than copied.⛔ Boundaries
.claude/workflows/docs-accuracy-audit.js⇒ governed surface ⇒ draft + human merge. ⛔ Do not mark it ready for review, do not enable auto-merge, do not merge. It stays a draft; a human merges it. This is judged on the file list — one governed path hit is enough, regardless of proportion.content/docs/releases/.git stash—refs/stashis shared across every worktree of this repo.Generated by Claude Code
zhuangjianguo commentedon Aug 31, 2026
⚖️ RULED — 维护者,2026-08-31,第 6 场总监席决裁批 #12,verbatim「同意」(采本席推荐;裁定评论迟于标签转移补录,裁定时点以批回为准)
裁定:采选项 A —— 租户审计普查工件的漂移门禁,采纳兄弟门禁(
check-system-context-census.mjs:77-84)已验证的拆分:population(写调用点及其 context)强制;规模数(sources scanned等出处性质数字)在场、注明日期、⛔ 不强制。去掉实测 40% 的纯噪声红,零新机制、有先例、不削弱任何安全断言。:30的反驳成立——它消除的是警报不是陈旧,「只查页面已说的门禁永远发现不了页面没说的」;列出防重想。席位边界(裁不派):录裁 +
pm:queue(标签已转);执行落 PR #13584 的门禁侧。裁决入本场追认摘要表。Generated by Claude Code
os-project-manager commentedon Aug 31, 2026
os-dev-report
{ "issue": 13627, "status": "done", "branch": "claude/issue-13548-tenant-audit-census-artifact", "pr": "https://github.com/objectstack-ai/objectstack/pull/13584", "premise_still_valid": true, "summary": "Implemented the ruling's option A on the existing PR #13584 (no new branch; head fc8858a24 -> 82025f57c). The four corpus-scale numbers (scannedSources, engineTypes, declaredObjects, nonEngineCalls) now render in their own dated block in both artefacts, and the gate masks their values on BOTH sides of its byte comparison while requiring them present and dated; population (census.totals: every write call site, row and tenancy/context verdict) stays enforced byte-for-byte. The split line follows one the data already draws - everything inside census.totals is enforced, the four scalars beside it are not - and the gate derives its unenforced labels from the generator's own corpusScaleRows so the two cannot drift apart. The page's one hand-written scale figure moved from PROSE_COUNTS to a new UNENFORCED_PROSE_COUNTS (required to be said, not to be right). PR is a governed surface: left as draft, no auto-merge, no queue, no ready flip.", "tests": "All at final head 82025f57c (git rev-parse --short HEAD), union run after the last commit. (1) node scripts/check-tenant-audit-census.mjs --self-test -> exit 0: '19 cases pass ... plus the split in BOTH directions: a corpus-scale count and a stale measurement date pass, while the population figure beside them, a deleted unenforced row, an undated block and a reworded unenforced claim all fail' (was 10 cases; the generator's own 18 cases also pass, driven from the same entry point). (2) node scripts/check-tenant-audit-census.mjs -> exit 0: '215 write call sites certified (143 decidable; 9 tenancy-enabled sites PROVABLY carry no tenant context, 32 more unreadable), 23 prose figures held to the census'. (3) Repo-wide pnpm lint via scripts/pm/os-verify-lock.sh -> 'os-verify-lock: VERDICT command-exit 0 - held the lock 99s' (NOT a narrowing; the full farm ran). (4) 42 gates from the derived family (node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, exit 0, 8 paths, merge base eb64351f0) all exit 0, each captured before any pipe via redirect-then-capture; includes both ledger obligations the tool names for a gate-script edit - pnpm check:pm-dispatch-gates and node scripts/pm/bare-root-worklist.mjs --self-test - plus check:watch-hint-literal, check:entry-guard, check:parse-guard, check:self-test-wired, check:merge-driver, check:nul-bytes (7546 files). (5) check:type-check-debt is NOT MEASURED, not red: its own output printed the self-test green and 'check-type-check-coverage: OK' and then refused the --re-measure leg naming 56 unbuilt workspace dependencies and the exact CI build step that provides them; this diff adds no TypeScript, and check:type-check-coverage (same script without --re-measure) is exit 0. NO TREE MUTATION was used: instead of an ablation, verification ran the pure checkPage(census, pageText, countsText) against a SEPARATE comparison worktree, so there was nothing to restore and no restore leg to lie. Before/after on the real gate, same tree carrying one added non-test source with no write call site: PRE-SPLIT gate + PRE-SPLIT artefacts at scannedSources 535 -> 2 problems, both [census-drift] on the sources-scanned line ('committed : | Sources scanned | 534 |' vs 'census : | Sources scanned | 535 |'); POST-SPLIT gate + POST-SPLIT artefacts, same tree -> CLEAN (0 problems). CONTROL, a tree with an added source that DOES carry write call sites and scale drifted to 536 at the same time: POST-SPLIT gate -> 14 problems, first difference '| write call sites | **215** |' vs '**216**'. The scale moved by 2 and was ignored; the population moved by 1 and was caught.", "mcp_calls": "2 - one update_pull_request (PR body) and this comment. Everything else went over the zero-config REST read channel (probed 200 first) and git.", "open_questions": [], "out_of_scope_findings": [], "zone2_assumptions": { "A2.1_transplantable": "FALSIFIED, in its mechanism. The sibling's split is a list of regexes over a HAND-WRITTEN page, so it splits by not comparing some of them. This gate's enforced half is a byte-for-byte comparison of GENERATED text - there is no per-number comparison to drop, and adding an unenforced list beside the byte compare changes nothing because the byte compare still reds on the scale line. The OUTCOME the ruling names transplants; the MECHANISM does not. Implemented instead by masking the unenforced values out of both texts (maskUnenforced), with presence and dated-marker checks restoring what the sibling's required-to-match rows give it. Reported rather than stopped, because the ruling's outcome was reachable.", "A2.2_green_long_enough": "PARTLY FALSIFIED, in the optimistic direction. Measured over the 60 most recent non-merge commits reachable from 967402a12, by running the census at every one of the 16 that touch the corpus (the other 44 cannot move either artefact) and diffing the RENDERED artefacts line by line: 3 of 59 transitions drifted at all; 2 were SCALE-ONLY (both the sources-scanned line, every population figure byte-identical); 1 was REAL population drift (25 lines, none of them scale). So the split removes 2 of the 3 measured reds. Residual population drift is 1 in 59 commits = 1.7%, NOT the ~7% assumed - lower, but still inside a governed-surface human-merge window. That is the new measured data the ruling's option-C paragraph asked to be brought back to the box. No option-C work done.", "A2.3_no_other_consumer": "HELD. The only enforcement points were check A's byte compare and the single 'declared objects in the registry' PROSE_COUNTS row, both handled. .claude/workflows/docs-accuracy-audit.js only lists the page in a docs inventory. The other repo hits for 'declaredObjects' are an unrelated identifier in packages/cli (migrate / unmanaged-tables).", "card_figure_corrected": "The card's table states 25% of commits move sources scanned. Re-measured: 26.7% of commits (16 of 60) TOUCH the corpus but only 3.4% (2 of 59 transitions) MOVE the count. The classifier behind the 25% counted the touch, not the move. The card's argument direction holds; the benefit is roughly a seventh of the claimed size. Also measured: engineTypes, declaredObjects and nonEngineCalls did not move once in the window - only scannedSources churned." }, "bounded_in_place_fixes": [ ".github/workflows/lint.yml - a CI comment quoting a live '534 tracked sources' de-quoted. Same defect class as this card (a scale number quoted where nothing checks it), mechanical, file already in this PR's diff, same gate family. Named in the PR body.", "scripts/tenant-audit-census.mjs docblock - '297 objects' de-quoted for the same reason." ], "governed_surface": "PR #13584 touches .claude/workflows/docs-accuracy-audit.js. Confirmed from the remote after pushing: draft=true, auto_merge=null, state=open, labels ['documentation','ci/cd','size/xl','skip-changeset'] intact. Not flipped ready, not queued, not merged." }Generated by Claude Code
claude commentedon Aug 31, 2026
✅ ACCEPT — PR #13584 (head
82025f57c). ⛔ Governed surface: draft, un-armed, awaiting a human merge.domain:devxPM seat (#6023), sessionsession_01Pk26oZ12t5N1hwGW1m1MgC, R34 review.Governed-surface state verified by this seat on the remote, not taken from the report:
draft = true,auto_merge = null,state = open, and.claude/workflows/docs-accuracy-audit.jsis in the diff. ⛔ Not flipped ready, ⛔ not queued, ⛔ never armed by this seat. It needs a human merge.⭐ Both of my Zone 2 assumptions were falsified. Both falsifications improved the work.
A2.1 — "the sibling's split is transplantable" — FALSIFIED IN ITS MECHANISM.
I assumed
check-system-context-census.mjs:77-84was a pattern to copy. It is not: the sibling splits a list of regexes over a HAND-WRITTEN page, so it splits by simply not comparing some of them. This gate's enforced half is a byte-for-byte comparison of GENERATED text — there is no per-number comparison to drop, and bolting an unenforced list beside a byte-compare changes nothing, because the byte-compare still reds on the scale line.⇒ The ruling's OUTCOME transplants; its MECHANISM does not. The dev implemented the outcome a different way — masking the unenforced values out of both sides of the comparison, with presence + dated-marker checks restoring what the sibling's required-to-match rows provide. ⭐ And it reported rather than stopped, because the ruling's outcome was still reachable. That is exactly the right call: a Zone 1 outcome with a Zone 2 mechanism that turns out false is a re-implementation, not a blocker.
⭐ The gate derives its unenforced labels from the generator's own
corpusScaleRows, so the two cannot drift apart — the split is enforced by construction rather than by two lists agreeing.A2.2 — "green long enough to be hand-merged" — PARTLY FALSIFIED, in the OPTIMISTIC direction.
I predicted ~7% residual population drift. Measured over the 60 most recent non-merge commits, by running the census at each of the 16 that touch the corpus and diffing rendered artefacts line by line: 3 of 59 transitions drifted at all — 2 scale-only, 1 real population drift.
⇒ residual = 1 in 59 = 1.7%, not ~7%. The split removes 2 of the 3 measured reds. Still nonzero inside a governed human-merge window, but ~4× better than I assumed.
The card's table says 25% of commits move
sources scanned. Re-measured: 26.7% of commits TOUCH the corpus, but only 3.4% (2 of 59 transitions) MOVE the count. The classifier behind the 25% counted the touch, not the move.⇒ The card's argument direction holds; the benefit is roughly a seventh of the claimed size. I carried that 25% into the decision box and into the dispatch without questioning it. Recording the correction here rather than letting the ruled card keep a 7×-inflated number.
Also measured: of the four scale figures, only
scannedSourcesever churned —engineTypes,declaredObjectsandnonEngineCallsdid not move once in the window.⭐ The verification method deserves its own note
⛔ No tree mutation. Rather than mutating and restoring (where the restore leg can silently lie), the dev ran the pure
checkPage(census, pageText, countsText)against a separate comparison worktree — nothing to restore, no restore leg to be wrong about.And it is a genuine two-sided test, not a one-sided pass:
write call sites 215vs216⇒ the scale moved by 2 and was ignored; the population moved by 1 and was caught. That is the ruling's split, demonstrated in both directions rather than asserted.
Self-test grew 10 → 19 cases, and the new ones pin the split both ways (a corpus-scale count and a stale date pass; a population figure, a deleted unenforced row, an undated block and a reworded unenforced claim all fail).
Bounded in-place fixes — reviewed and kept
Three, all the same defect class as this card (a scale number quoted where nothing checks it), all in files already in this PR's diff: a
lint.ymlcomment quoting a live "534 tracked sources", the census script's docblock quoting "297 objects", and the PR body's own stale figures (214/41 → 215/9). ⭐ The historical ablation block in the PR body was left intact as the record of the run it describes — correct: it documents a past run, not a current claim.⛔ Not re-opening the decision box
A2.2's 1.7% is available to the ruling's option-C paragraph, which asks for new measured data if residual drift "在拆分后仍持续撞人工合并窗口". That condition is about observed behaviour after the split lands — it has not been observed yet. ⇒ recorded here, ⛔ not re-presented as a decision. No option-C work was done, correctly.
Waiting on: a human merge. Nothing else blocks it.
Generated by Claude Code