chore(recovery): guard the recover workflow's git add --all -- changelog.d (AGENTS.md section 5a) instead of relying on the verb to create the directory #1537
Labels
No labels
bump
major
bump
minor
bump
patch
kind
bug
kind
chore
kind
docs
kind
epic
kind
feature
loop/paused
mirror-drift
priority
critical
priority
high
priority
low
priority
medium
size
L
size
M
size
S
size
XL
status
blocked
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
frankenbit/release-toolkit#1537
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The recovery workflow stages
changelog.dby name underset -euo pipefail, without the existence-or-tracked guard of AGENTS.md section 5a. Today it cannot fail, but only because the Go verb creates the directory as a side effect, and nothing in the workflow says it depends on that. This is defence in depth, not a live failure.Measured
At origin/main
8086700:The line came in with
dfe9a85(2026-09-05, PR #1182 for #1166).What git does with that pathspec (git 2.55.0.windows.3, scratch repo):
changelog.dgit add --all -- changelog.dfatal: pathspec 'changelog.d' did not match any files, rc=128.keep.keepWhy it is green today. The guarantee comes from the verb, not the workflow:
rt recover-pending-cutrefuses a prepare that deleted no fragment (cmd/rt/recover_pending_cut.go:399-400). A successful run then writes at least one file intochangelog.d, afteros.MkdirAllinapplyRecovery(:474 onward). So the directory always exists when :379 runs.6979efc) adds a successful path that restores zero fragments (release_notes.source: commits). ItsapplyRecoverykeeps theMkdirAlland adds a comment saying the directory is created "even when nothing is restored", because the workflow's pathspec "is fatal when the directory does not exist". Its testrecoverCommitOnlyPreparereplays the twogit addlines from a copy in Go.So the workflow's staging line depends on a side effect of another layer. That dependency is stated in a Go comment and pinned by a Go test that copies the YAML line. If the side effect ever goes, :379 kills the step after the fold has been written in the runner's checkout and before the commit and push. The run goes red, nothing is pushed, and the error names a pathspec rather than the recovery.
A trap for the fix. AGENTS.md section 5a spells its guard
git add -A -- "$FILE". The bats armworkflows: recovery never commits the toolkit checkout (#1135)(tests/workflows.bats, around :4953) refuses any code line matching^\s*git add -A\b. Copying section 5a verbatim would redden that arm. The long form--allat :379 passes it.Not covered by #1530. That consolidation lists
recover-pending-cutamong the workflows that stay unchanged.Why it matters
Recovery (B) is the documented remedy for a stranded cut (#1135, #1166). When it fails, it should fail about the recovery, not about a pathspec. Section 5a exists because this exact
git addshape has bitten before (#77). A guard in the workflow removes the cross-layer coupling instead of documenting it.Acceptance criteria
[[ -d changelog.d ]]orgit ls-files --error-unmatch -- changelog.dsucceeds. The long form--allis kept, or the #1135 arm's regex is narrowed in the same PR._recover_runand #1160's arm do, underset -euo pipefailin a repo with nochangelog.d. It asserts rc 0 and the trackedCHANGELOG.mdchange staged. Mutation check: removing the guard reddens it (AGENTS.md section 8, Axis B).applyRecoverycomment stops calling the workflow's pathspec fatal, or points at the guard..giteatwin is regenerated, andrt gitea-twin --checkpasses.Out of scope
MkdirAll. It is harmless and keeps the manual recipe working.docs/integration.md:985(git add -u && git add -A -- changelog.d). An operator runs it by hand and sees the error.changelog.dconfigurable. Both the verb and the workflow hard-code it.Anchor
Found 2026-10-03 while reviewing PR #1531 / issue #1529. It was listed in the PR's "Not in this PR" follow-ups as the optional section 5a guard. The git behaviour above was probed the same day.