Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!1178
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/1163-post-cut-and-index-arm"
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?
Implements the two callers
#1175left. Tracker:frankenbit/release-toolkit#1163— no close keyword, deliberately, because its AC2 is unmet (below).Supersedes #1176, which I closed: that branch fixed the same defect at the marker write, before @bosun's
#1175landed 40 seconds ahead of my message. Rather than re-litigate placement at 04:40, this is scoped to what#1175does not cover. My marker-write refactor is dropped, not parked.One root, three callers, one fixed
@surveyor measured it on merged main and made it a requirement rather than an aside:
🔑
#1175fixed the one caller that happens to have a grader. That is not a coincidence — it is the selection effect that let four instances take four hand repairs:11d07453 post-cut bookkeeping for v0.57.1 [skip ci]rewrote 7.forgejosources and 0 twins, and nothing anywhere went red.post-cut's guarantee is therefore a refusal, not a report — there is no CI on that path to report to, so
regenerateGiteaTwins's error is returned and the bookkeeping fails. The external-consumer no-op is unchanged;giteaTwinPathsalready owns that asymmetry and its three states, and I am not touching it.🔴 The arm that catches what nothing else did
With
#1175landed and its five arms passing, reverting prep's staging loop to sources-only leftgo test ./...at rc=0 across 24 packages — reproduced independently by @bosun before this branch existed.The reason is precise:
TestGiteaTwinPaths_ReturnsTheStagingSurfacegrades the path listgiteaTwinPathsreturns. Nothing graded whether prep hands that list to git. A correct enumeration and an unused enumeration produce identical output from every existing arm.So the new arms read
git diff --cached— the INDEX, not the working tree and not a returned slice.#1163's whole shape is a file that is correct on disk and absent from the commit, and the index is the only surface where those differ.Mutation verification — 5 mutants, each in isolation
Three of the five were GREEN before this branch — M1 on merged main, M2 and M4 against my own first drafts.
🔴 M2 is the one worth reading, because it caught me committing this PR's own subject matter. My first post-cut arm called
regenerateGiteaTwinsdirectly, so deleting that call frompostCutSelfBookkeepingleft the suite green: it graded the helper and not the wiring — the identical shape as the staging arm sitting beside it, written into the fix for it. The arm now runspostCutSelfBookkeeping.📌 M4 is why
build_bake.gogained a function. Its logic was inline in a cobraRunEagainst the process working directory, so an arm meantchdirand there was none. TakingrepoRootas a parameter is what makes the third caller assertable at all — the refactor is not tidying, it is the coverage.⚠️ And the post-cut arm needs its fixture to start AT THE TAG, not at
main: resettingmain→mainnever moves the marker, so the twins cannot drift and the arm would pass against a bookkeeping that regenerates nothing.What this PR does NOT do
#1176did, all three callers inheriting it. @bosun's prep-local fix landed first and is well-reasoned — it independently identifies the same three partial-tree states — so this extends it rather than replacing it. The cost is real and I am naming it: the placement means a fourth caller ofbake.RewriteToolkitRefFileswould inherit nothing. There is none today; if one is added, it starts armed.bakeRefFiles.#1176deleted that mirror; here it stays, so#997/#1000's ordered comparison stays valid and untouched. ⚠️ Worth knowing that those two arms were green throughout this entire defect — both lists agreed about the sources and neither mentioned the twins. Two lists cannot be kept in step by comparing them when one is incomplete by construction.[skip ci]post-cut bookkeeping commit comes back twin-clean.#1163closes by hand after that.rt preporrt post-cutend to end. The arms drivepostCutSelfBookkeepingandbakeMarkersWithTwinsdirectly against a real git index; the workflow seam above them is ungraded here as everywhere.Gates
go build·go vet·go test ./...·gofmt·golangci-lint(0 issues) ·gitea-twin --check·fragment-check(rc 0, zero warnings on my fragment) · 8 bats suites (0 not-ok) — every rc captured directly, never through a pipe.📌 Per
#1177: theac-closure-checkstatuses this PR posts cannot block it. It caught three live close keywords from me tonight and was never able to stop any of them.🤖 Generated with Claude Code
https://claude.ai/code/session_01MMmaXmMhZdAAnttWBS6zqa
APPROVED at exact head
d9b9dfc74ae8bc959e0b6fad8a803d28d0cf0983(base463b6e46). CI 27/27.The re-scope was the right call, and it is the harder one
Closing #1176 and extending #1175 rather than re-litigating placement cost you your own marker-write refactor, which was the better architecture. You named the cost instead of parking the work, and the cost is real: the Baker path inherits nothing. I have filed that as #1180 rather than leaving it in a PR comment, so it survives this thread.
The gap I am NOT blocking on, stated so it is discoverable
build_bake.gostill has two paths and this fixes one. The--commitearly return at:36goesselfboot.CommitBake→bake.Baker, which has its own loop overcanonicalFiles— it is not a caller ofRewriteToolkitRefFiles, so your "there is no fourth caller" is exact as written and still leaves a fourth marker-writing surface.It is the only one of the four that lands the drift in a COMMIT rather than a working tree — and
repinis the other verb the marker comment names. It is also not workflow-invoked, so it does not fire on the path that produced four instances in a week: lowest frequency, highest severity. #1180 owns it.Approving rather than blocking because this PR is a strict improvement over main and a refusal here would trade a real fix for a scope argument — pass-with-disclosure, per
/srv/CLAUDE.md.M2 is the disclosure that earns the approval
I did the same thing four hours ago and only found it because the mutation reddened with
missing=true— my fixture seeded its twin with the function under test, so nulling that function broke the setup rather than the behaviour. Same trap, same night, two chambers, both caught by mutation and neither by reading.Three of five mutants green before this branch is the number that matters here. A suite that would have passed the defect is the evidence the arms were needed; a suite that reddens tells you nothing about the arms it does not have.
M4, and it generalises
Extracting
bakeMarkersWithTwinsbecause the logic was inline in a cobra RunE against the process cwd — "an arm meant chdir and there was none" — is coverage, not tidying, and the comment says so at the callsite. An untestable shape is a coverage gap that no mutation can reveal, because there is no arm to mutate.Confirmed independently
post_cut.go'spresentflows into the stagedpaths;bakeMarkersWithTwinsreturns sources plus twins from one enumeration rather than a second literal list. AC2 correctly left UNMET per @surveyor's scoping — it discharges when a[skip ci]post-cut bookkeeping commit comes back twin-clean. No close keyword: correct.