From 6fa1710b4ff3417e8c2be94a43cfa1a5c8c00d4b Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Thu, 3 Sep 2026 15:19:40 +0700 Subject: [PATCH] docs(skill): re-measuring a number is not testing the claim, and the tree I measured had lost 296 files Refs #2983 Three lessons, all from a delayed adversarial phase and the state it found the worktree in. RE-MEASURING IS NOT TESTING THE CLAIM. I hand-verified three STALE verdicts because a fan-out's skeptic phase had not run, and one of the three was wrong. The skeptic, arriving days later, refuted it on four grounds -- and I had written all four into that skeptic's own prompt and then not applied them. The issue claimed 125 damaged lines in 65 files; I measured 0, proved the pattern could match by planting a file, and confirmed 63 files once carried it. Every step sound, verdict still wrong: - the number is dated BY CONSTRUCTION -- the title's subject is `freeze`, the body pins a snapshot hash, and the companion script prints "REFUSING: the corpus moved since the snapshot was frozen"; - the owner had ALREADY commented the new figures a week after filing; - the load-bearing sentence describes a substitution RULE's reach, not the tree, and the 18 lines it does not reach were settled by the owner language decision the issue predicted -- so reporting 0 presented a CONFIRMED FORECAST as a wrong number; - their own control reproduces 125/65/15 over the pre-repair corpus. Only a claim about the tree AS IT IS can be stale. A verification you write for yourself tests the half you already believe. A REPLACEMENT NUMBER CAN BE A MOVING TARGET. Two readers measured one branch divergence twenty minutes apart: behind_by 1833 and 1841, whole-tree difference 5309 and 5315. Both right when taken; either one published undated is the next stale number. Sort replacements into structural facts (1 commit ahead, 10 files in the three-dot compare, the head's parent IS the merge-base) and readings, and date the second group in the same sentence. THE MEASUREMENT TREE HAD LOST 296 FILES. `git status` reported 296 tracked files deleted and 293 of them exist on origin/master -- the worktree was truncated, not the repository. 19 of 49 files were gone from `.github/workflows/`, which two commands shipped this week read off disk. Found only because git itself stopped working: all three worktrees under /private/tmp had lost their `.git` pointer while the checkout outside it had not. `git worktree repair` and `git checkout -f origin/master` restored both. The cause is NOT established; a tmp reaper fits and was not tested. What saved the published numbers was luck: `tri issues stale` had printed `workflow files 49`, matching origin/master, which is what proves that reading was taken on an intact tree. Print the size of what you walked, every time. And the skeptic that found no `.git` measured against the GitHub API instead, making its answer stronger than the scout's. Corrected sample, now complete at 24 of 24: STALE 8 claimed, 6 judged, 5 confirmed, 1 refuted; HOLDS 3, UNMEASURABLE 13. The 21/7/3/11 I published was a partial reading of 7 of 8 agents. Skill 431-433. Co-Authored-By: Claude Opus 5 --- .claude/skills/ci-gates/SKILL.md | 89 +++++++++++++++++++ ...lost-296-files-and-the-adversary-that-r.md | 9 ++ 2 files changed, 98 insertions(+) create mode 100644 docs/now/2026-09-03-the-measurement-tree-lost-296-files-and-the-adversary-that-r.md diff --git a/.claude/skills/ci-gates/SKILL.md b/.claude/skills/ci-gates/SKILL.md index a60e894d43..61174e74d5 100644 --- a/.claude/skills/ci-gates/SKILL.md +++ b/.claude/skills/ci-gates/SKILL.md @@ -10885,3 +10885,92 @@ The rule has two halves and the second is the useful one: Same shape as §421 one layer over: there a loose matcher inflated a count, here a sound matcher measured a moving one. Both times the repair was to stop quoting the number and start naming the members. + +## 431. Re-measuring the number is not testing the claim + +I hand-verified three STALE verdicts because the adversarial phase of a fan-out had +not run, and one of the three was wrong. `tri`'s own skeptic, arriving hours later, +refuted it on four independent grounds — and I had written all four into that +skeptic's prompt myself and then not applied them. + +The issue claimed **125 damaged lines in 65 files**. I measured the shape and got +**0**, confirmed the pattern could match by feeding it a planted file, and confirmed +from history that 63 files once carried it. Every step was sound and the verdict was +still wrong: + +- **The number is dated by construction.** The title's own subject is *freeze*; the + body pins a snapshot hash; and the companion script prints *"REFUSING: the corpus + moved since the snapshot was frozen"*. A number whose own tooling declares itself + invalid the moment the tree moves is a historical reading, not a claim about today. +- **A later comment already recorded the movement** — the owner posted the new figures + a week after filing. An issue that announces its own supersession misleads nobody. +- **The load-bearing sentence was about a RULE, not a tree.** "The rule does not reach + 18 lines" describes the substitution rule's reach; those 18 were then settled by an + owner language decision, which is exactly what the issue predicted. Reporting `0` + presented a **confirmed forecast as a wrong number**. +- **Their own control reproduces the headline**: run the script over the pre-repair + corpus and it prints 125 / 65 / 15 exactly. + +The rule that survives: before calling a number stale, ask what KIND of claim carries +it. A dated snapshot, a statement about an instrument's reach, and a prediction that +came true all produce "the number is different today" while the issue is entirely +sound. **Only a claim about the tree AS IT IS can be stale**, and the cheapest test is +one `gh issue view` for a comment that already says so. + +And the meta-lesson, which is the expensive half: I substituted my own check for the +adversary's because the adversary was late. My check was weaker in exactly the way an +adversary is built to be strong — it asked *is the number different* where the skeptic +asked *is the claim wrong*. **A verification you write for yourself tends to test the +half you already believe.** + +## 432. A replacement number can be a moving target too + +Correcting a stale figure with an undated one repeats the failure being audited. + +Two readers measured the same branch divergence twenty minutes apart and got +`behind_by` **1833** and **1841**, whole-tree difference **5309** and **5315** — master +advanced eight commits between them. Both were right when taken. Published without a +timestamp, either is the next stale number on the page. + +The skeptic separated the two kinds in its own correction, which is the practice worth +copying: **1 commit ahead**, **10 files in the three-dot compare**, and *the branch +head's parent IS the merge-base* are structural facts that will not drift. `behind_by` +and the two-dot tree difference move with every push to master and must carry the date +they were read. + +When you withdraw a number, sort its replacements into the ones that are stable and +the ones that are readings, and date the second group in the same sentence. + + +## 433. The measurement tree lost 296 files, and nothing said so + +`git status` in the loop's worktree reported **296 tracked files deleted**. They were +not deleted from the repository: **293 of the 296 exist on `origin/master`**. The +worktree had been silently truncated. Worst of it: **19 of 49 files were gone from +`.github/workflows/`**, and two commands shipped this week read that directory off +disk to build their population. + +It was found by accident. `git` itself stopped working — all three worktrees under +`/private/tmp` had lost their `.git` pointer file, while the checkout outside +`/private/tmp` still had one. `git -C
worktree repair ` restored all +three in one call, and `git checkout -f origin/master` restored the files. + +**The cause is not established.** A `/private/tmp` reaper is the obvious hypothesis +and fits both symptoms, and I did not test it; writing "tmp cleanup did it" would be +a cause invented to fit a symptom. What IS established is the shape: a tool that reads +a directory off disk reports the truncation as a measurement. + +Two things saved the published numbers, and both were luck rather than design: + +- **A printed population is a timestamp.** `tri issues stale` had printed + `workflow files 49` at the time it ran, which matches `origin/master` — so that + reading was taken on an intact tree. Had the command printed only its verdict, the + reading would be unrecoverable now. **Print the size of what you walked, every time.** +- **The adversary routed around the damage.** The skeptic verifying a branch-divergence + claim found no `.git` at all and measured against the GitHub API instead. Its answer + is therefore stronger than the scout's, which read local refs. + +What to add before any measurement over a checkout that is not the main one: +`git status --porcelain | grep -c '^ D'` must be zero, and a count of the population +directory must match `git ls-tree`. A worktree is an instrument, and this one had been +quietly losing parts. diff --git a/docs/now/2026-09-03-the-measurement-tree-lost-296-files-and-the-adversary-that-r.md b/docs/now/2026-09-03-the-measurement-tree-lost-296-files-and-the-adversary-that-r.md new file mode 100644 index 0000000000..5204de5cea --- /dev/null +++ b/docs/now/2026-09-03-the-measurement-tree-lost-296-files-and-the-adversary-that-r.md @@ -0,0 +1,9 @@ +# NOW -- The measurement tree lost 296 files, and the adversary that routed around it was right (2026-09-03) + +## The measurement tree lost 296 files, and the adversary that routed around it was right (Refs #2983) + +- git status in the loop worktree reported 296 tracked files deleted; 293 of them exist on origin/master, so the worktree was silently truncated rather than the repository. 19 of 49 files were missing from .github/workflows, which two commands shipped this week read off disk to build their population. +- Found by accident: git stopped working because all three worktrees under /private/tmp had lost their .git pointer file, while the checkout outside /private/tmp still had one. git worktree repair restored all three; git checkout -f origin/master restored the files. The cause is NOT established -- a tmp reaper fits both symptoms and was not tested. +- What saved the published numbers was luck, not design. tri issues stale had printed workflow files 49, matching origin/master, which is what proves that reading was taken on an intact tree. Print the size of what you walked, every time. +- And the delayed adversarial phase corrected me: I hand-verified three STALE verdicts because the skeptic had not run, and one was wrong. The issue's number is an explicitly frozen hash-pinned reading whose own tool refuses to run when the corpus moves, the owner had already commented the new figures, and the load-bearing sentence was about a substitution RULE's reach rather than the tree -- so its prediction was vindicated and I reported a confirmed forecast as a wrong number. +- Final sample: 24 of 24, STALE 8 claimed, 6 judged, 5 confirmed, 1 refuted; HOLDS 3, UNMEASURABLE 13. My published 21/7/3/11 was a partial reading and is corrected here.