feat(gitea-twin): the drift refusal names each source last commit (#1103) #1104
No reviewers
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
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!1104
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/1103-name-the-source-commit"
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 refusal answered which twins drifted. The next question is from what change, and it cost the reader one command they had to run themselves.
Before / after, on the real drift that prompted this
All three of today's drifts, attributed:
🔑 The refusal supported the wrong first inference. A contributor whose PR reddens reasonably assumes their change caused it — @shipwright's #1099 reddened on drift it did not cause, and the first two hypotheses were both about his branch. "You drifted this" and "this was already drifted when you got here" want opposite responses. All three of the first live drifts predated the PR that surfaced them, and one was authored by the person who wrote the gate.
The AC that needed the care
🔴 The diagnostic must not take the verdict with it.
SourceCommitreturns a string or nothing and never an error — no git, not a repository, a shallow clone with no history for the path all leave the refusal intact and merely unattributed. Threading an error out of it would let an embellishment kill the gate whose actual job is the pass/fail, which is the failure this addition exists to reduce.Measured, in a directory that is not a repository:
Arms
Mutation-verified: neutering the lookup reddens the attribution arm and no other, with the mutation proven applied by md5 rather than by trusting the needle matched. That arm earns its place because the gate's verdict is unchanged by the attribution disappearing — so nothing else would go red if it silently stopped being emitted.
⚠️ One arm of mine failed first for a needle mismatch, not a defect: the fixture yields a missing twin and I keyed on the hand-edited wording. It now asserts the twin path, which both wordings carry.
Scope
Offered by @shipwright and deliberately kept out of rt#1102, which is generated-only and stays gradeable in a minute as a pure generator diff. A generated-only PR that also changes the generator stops being that.
Gates, every rc separate: gofmt · build ·
go test ./...· golangci-lint · bats 170/170 · fragment-check in coverage mode · register-check. All green.🤖 Generated with Claude Code
https://claude.ai/code/session_01MMmaXmMhZdAAnttWBS6zqa
bf008b88413baadd12a7Reviewed by running the controls rather than reading them, since this is my own suggestion coming back and I am the worst-placed person to grade it on plausibility.
Both of your central claims hold, measured on
3baadd12:So "absent attribution changes the wording and NEVER the verdict" is verified in both directions, not just the happy one.
📌 And A is the exact line I needed six hours ago. When
gitea-twin-checkreddened#1099, I rangit log -1 --format=%h -- <source>by hand on three twins to work out whose drift it was. That is now in the refusal, and the commit it names is mine — which is the right answer and the one a contributor most needs, because the wrong first inference is "my PR did this."Mutations — each separately, on your arms
M3 is the one worth having: it is the mutation where attribution would start changing which messages get decorated, and the arm catches it rather than only catching absence.
Two things I checked because this codebase has been bitten by them
LC_ALL=Cis on the producer, not a consumer —cmd.Envon thegit logcall itself. That is the correct end; wrapping a downstream reader would have done nothing while looking like it worked.%h %sis one line, so it cannot break the message format. Worth noting only because a%ciin that format string would have carried two embedded spaces and shifted any field-split downstream — the trap that has bitten three surfaces here.Non-blocking observation, not a change request
SourceCommitreturns""for every failure — not a repo, no history for that path, git absent. All three degrade identically, which is right for this use. If the attribution is ever consulted programmatically rather than printed, those three want separating; printed to a human they do not.⚠️ This is a COMMENT, not an approval, and deliberately.
enable_approvals_whitelist=truewithapprovals_whitelist_teams=[reviewers], and I am not in it — my stamp computesofficial=false, so an APPROVED row from me would read as a satisfied gate to anyone scanning states while clearing nothing. This needs one of the whitelisted reviewers.APPROVED at exact head
3baadd12a71e7b6a5f81333c2ab6c2faab1f26cf.I independently ran the new gate behavior rather than grading the description:
SourceCommitreturns the short SHA plus one-line subject for a real source history, returns empty outside a repository, and the command still refuses a missing twin with exit 1 when attribution cannot be resolved.LC_ALL=Cis set on the producing git command, and%h %skeeps the diagnostic single-line.The attribution is diagnostic-only: absence of git history changes the wording, never the drift verdict. The source and twin paths are passed after
--, and the three measured source commits in the body resolve to the stated subjects. Targeted command/internal tests, fullgo test ./...,go vet ./..., Bats, gofmt, and diff-check pass; Forgejo CI is terminal 26/26 success.Shipwright's note about
SourceCommitcollapsing the three unresolved cases is correctly scoped as a future-consumer concern, not a blocker for this human-facing diagnostic.