Skip to content

A dead-path Violation CI Reports Cannot Be Reproduced Locally, So the Fix Loop Is Push and Guess #1412

Description

@ptr727

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:

  1. 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.
  2. 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.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions