Found while fixing #1403. Separate from that fix, because it obstructs anyone fixing any
dead-path finding rather than being about the one file.
The gap
A dead-path violation reported by CI cannot be reproduced locally, so it cannot be confirmed
fixed before pushing.
Measured on ptr727/HomeAutomation-Config PR #160, whose CI reported three:
.github/skills/operational-vs-release-workflow/references/branch-protection-and-promotion.md:17: dead-path: path 'repo-config/README.md' is deleted from this tree
.github/skills/operational-vs-release-workflow/references/branch-protection-and-promotion.md:26: dead-path: path 'repo-config/settings.json' is deleted from this tree
.github/skills/operational-vs-release-workflow/references/branch-protection-and-promotion.md:110: dead-path: path 'repo-config/README.md' is deleted from this tree
Run against the same worktree, at the same commit, with the same diff base f311fe8 that CI used:
| Invocation |
Result |
.github/actions/prose-gate/prose_lint.py --diff f311fe8 . |
30 of 237 files read, no violation |
scripts/prose_lint.py --diff f311fe8 . |
30 of 237 files read, no violation |
either, --check dead-path <the file> |
1 file read, no violation |
either, --check dead-path . (whole tree) |
237 files read, 1 violation, an unrelated .vscode/settings.json in GOVERNANCE.md |
Ruled out: version skew, since the action's copy on main and on develop are byte-identical and
both behave the same here; the two prose_lint.py copies differing, since both behave the same;
the diff base, since it is the one CI used; and the check being inert, since the whole-tree run
does fire on a different path in the same repository.
The file still contains all three mentions at the time of every run above, verified by grep.
Why it matters more than the finding it hides
The gate is one a downstream repository hits on carried content it cannot fix, per #1403 and
#1138. Whoever fixes that content is in the hub, and cannot confirm the fix from the hub either,
because dead-path keys on history: "No mention of a path git once tracked and the tree no
longer holds". In the hub repo-config/ exists, so nothing fires there by construction. The only
place the check speaks is a repository that once tracked the path and deleted it, and that is
exactly where the local run above stays silent.
So the fix loop for this class of finding currently is: push, wait for CI, read, guess again. A
gate that cannot be run before the push is the one property the fleet's own verification rules
say a gate must not have.
What would settle it
Establishing which of the two the local runs are doing, since the remedies differ:
- The local invocation is wrong, and the runbook should state the one that reproduces CI.
GOVERNANCE.md "Running the Linters Locally (Known-Working Invocations)" exists for exactly
this, and carries no dead-path entry today.
- The action and a local run genuinely differ, in which case the difference is a defect in
one of them, and the composite action is the one CI trusts.
Either way a regression test over a fixture repository that tracked and deleted a path would pin
the behavior, since the current suite passes while the two disagree.
Found while fixing #1403. Separate from that fix, because it obstructs anyone fixing any
dead-pathfinding rather than being about the one file.The gap
A
dead-pathviolation reported by CI cannot be reproduced locally, so it cannot be confirmedfixed before pushing.
Measured on
ptr727/HomeAutomation-ConfigPR #160, whose CI reported three:Run against the same worktree, at the same commit, with the same diff base
f311fe8that CI used:.github/actions/prose-gate/prose_lint.py --diff f311fe8 .scripts/prose_lint.py --diff f311fe8 .--check dead-path <the file>--check dead-path .(whole tree).vscode/settings.jsoninGOVERNANCE.mdRuled out: version skew, since the action's copy on
mainand ondevelopare byte-identical andboth behave the same here; the two
prose_lint.pycopies differing, since both behave the same;the diff base, since it is the one CI used; and the check being inert, since the whole-tree run
does fire on a different path in the same repository.
The file still contains all three mentions at the time of every run above, verified by
grep.Why it matters more than the finding it hides
The gate is one a downstream repository hits on carried content it cannot fix, per #1403 and
#1138. Whoever fixes that content is in the hub, and cannot confirm the fix from the hub either,
because
dead-pathkeys on history: "No mention of a path git once tracked and the tree nolonger holds". In the hub
repo-config/exists, so nothing fires there by construction. The onlyplace the check speaks is a repository that once tracked the path and deleted it, and that is
exactly where the local run above stays silent.
So the fix loop for this class of finding currently is: push, wait for CI, read, guess again. A
gate that cannot be run before the push is the one property the fleet's own verification rules
say a gate must not have.
What would settle it
Establishing which of the two the local runs are doing, since the remedies differ:
GOVERNANCE.md"Running the Linters Locally (Known-Working Invocations)" exists for exactlythis, and carries no
dead-pathentry today.one of them, and the composite action is the one CI trusts.
Either way a regression test over a fixture repository that tracked and deleted a path would pin
the behavior, since the current suite passes while the two disagree.