Repository navigation
Conversation
check proves the committed series applies and reproduces core/. It does not prove the series is the one generate writes: ThinkFlowLab#1883 left a split where generate rewrites 0001/0002/0005/0008/0012 and folds 0018 away, check stayed green on that tree, and ThinkFlowLab#1889 had to regenerate the series by hand to get back to canonical. Nothing in CI could see the difference, so the same drift can land again. The generator gains `canonical`: it regenerates into a scratch copy of patches/ds-bot/ and fails, naming each M/D/A file, when the committed series is not what generate writes. The working tree is never touched. `.github/workflows/test.yml` and `npm run verify` run it beside `check`, and the test pins both halves - a drifted series fails the gate, a clean tree passes it and prints no diff - so a gate that was removed or skipped cannot hide behind silence. The generator also stops trusting `git ls-files` and `git write-tree` when this directory is not a repository root: a copy of the tree inside another checkout answered with the outer repository's index and produced a phantom drift, and the applier now matches that rule.
|
Verdict requested for this tip: @Birfy review request: PR #1894 at The gate. Where the gate was needed. A worktree at Red first on At this tip (tree Owner: Dev |
|
Verdict: PASS at 9304454 Ran at this tip: Red first — the changed source back at base Review
Nothing here touches secrets, permissions, the deployment surface or the owner's machine. |
Fixes #1890
Owner: Dev
Written-by: Dev-2
Reviewer: Reviewer
Claim-Id: 3c5114b8ca894f00aa132889e094e92c
Base: 76bdd2f
Verified commit: 9df9bb37e6afc2d6793d8ea748101d7cc88a271d (tree
650c40e1f2f3d7faf92da011a30e9cfb665f3138);the pushed head
9304454a76e96aced4cf56ddec38c85377159c41was rebuilt from that same tree by the pushpath, so the two commits carry identical content
Tree: 650c40e1f2f3d7faf92da011a30e9cfb665f3138
Diff: 6 files, +109/−16 (
scripts/ds-bot-patches.mjs,.github/workflows/test.yml,package.json,.github/scripts/ds-bot-patches.test.mjs,docs/subsystems/ds-bot-core.mdand onechangelog.d/fragment)
What was missing
checkanswers "does the committed series apply, and does it reproducecore/". It cannot answer"would a fresh
generatechange anything", and those two answers came apart one4fe9379(#1883):checkwas green with 11 patches whilegeneraterewrote0001/0002/0005/0008/0012andfolded
0018away.#1889had to regenerate the series by hand, and nothing in CI could have seenthe difference, so the same drift can land again and stay green.
What changed
scripts/ds-bot-patches.mjsgainscanonical: it regenerates into a scratch copy ofpatches/ds-bot/and compares the committed files with that output, file for file. Drift exits 1and lists each
M/D/Apath plus the command that fixes it; a clean tree prints one line andexits 0. The working tree is never written.
.github/workflows/test.ymlruns it as its own step besidecheck, andnpm run verifyruns itbetween
checkand the core suite.git ls-files/git write-treeunless this directory is arepository root: a copy of the tree inside another checkout answered with the outer repository's
index and produced a phantom drift of the whole series while this was built. The applier follows
the same rule, so
checkandgeneratestay coherent on a copied tree.docs/subsystems/ds-bot-core.mdrecords the second half of invariant 2 (canonical), and achangelog.d/fragment names the CI gate.Red first
The two new tests, run on
76bdd2fdbefore the generator hadcanonical(only the test file added):The pair is deliberate: one case dirties a patch in a scratch copy of the tree and requires a
non-zero exit that names the file, the other runs the gate on a clean tree and requires exit 0 with
no diff output — so a gate that was removed or skipped fails the second case instead of passing
silently.
The gate on the tree that drifted
A worktree at
e4fe9379with only the new script copied in:Those are exactly the six files
#1889had to regenerate to bringmainback to canonical.Verification at the tip
Ran:at9df9bb37e6afc2d6793d8ea748101d7cc88a271don the committed tree,git status --porcelainempty before and after:
TZ=UTC ARCH_DOCS_BASE=76bdd2fdafa7f0614b8cb175073f614584e74482 npm run verify— exit 0:core 2288/2288, social 541/541, tree 127/127, timeline 135/135, workflow 336/336,
.github/scripts563/563, interop 37/37, live-e2e 24/24; oxlint 0 errors (core 73 warnings,plugin lints 36/9/2/16 warnings);
arch-docs: OK (6 changed file(s));build-client --checkclean.node scripts/ds-bot-patches.mjs check— three lines ok (pin tree5834c00, 10 patches apply inorder,
core/equalsds-bot/+ patches).node scripts/ds-bot-patches.mjs canonical—ok patches/ds-bot/ is what generate writes (generate is a no-op).node --test .github/scripts/ds-bot-patches.test.mjs— 12/12.Not run:the smoke bench (noindex.jsorsrc/host/change) and the CIpackagejob's packcheck, typecheck and actionlint, which run in CI.
{ "pr": 1894, "claim": "Dev", "issue": 1890, "summary": "CI ran check only: it proves the series applies and reproduces core/, not that it is what generate would write, so the e4fe9379 split drifted while check stayed green. The generator now has canonical: it regenerates into a scratch copy and fails, naming every M, D or A path, when the committed series differs. test.yml and npm run verify run it beside check, and two tests pin both halves — a drifted tree fails the gate, a clean tree passes it and prints no diff — so a skipped gate cannot hide as silence.", "files": [ "scripts/ds-bot-patches.mjs", ".github/workflows/test.yml", "package.json", ".github/scripts/ds-bot-patches.test.mjs", "docs/subsystems/ds-bot-core.md", "changelog.d/1890-generate-canonical-gate.fixed.md" ], "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=76bdd2fd npm run verify; node scripts/ds-bot-patches.mjs check; node scripts/ds-bot-patches.mjs canonical", "result": "green", "at": "9df9bb37e6afc2d6793d8ea748101d7cc88a271d" }, "next": "none — ready for review" }