fix: route five git pushes through the guarded writer #858
No reviewers
Labels
No labels
breaking
bug
documentation
enhancement
epic
good first issue
help wanted
refactoring
resolution/duplicate
resolution/invalid
resolution/wontfix
security
severity/critical
severity/high
severity/low
severity/medium
status/abandoned
status/blocked
status/needs-decision
status/needs-info
status/needs-verification
testing
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sixfold-space/madtea!858
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-833-pushes-through-writer"
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?
Summary
Refs #833
What was wrong
The write guard of ADR 0046 runs inside the Writer in
internal/git. Five push calls skipped the Writer and used a raw git runner. They were the two initial-finish pushes ininternal/service/workflow/finish_initial.go, the branch push inDevelopininternal/service/issue/develop.go, the--pushpath ofrunTagCreateininternal/cmd/git/tag.go, and the push inInitininternal/service/workflow/init.go. The guard and the refspec checks did not run on them.Two more problems showed up while I moved them.
git push -uwrites "branch 'x' set up to track ..." there. That text landed on the MCP protocol channel, and before the JSON of a CLI--jsonrun. The standard finish push andmadt_pushon main had the same fault.origin/<default>ref was absent. A stale tracking ref (the forge repo was deleted and created again empty) refused a real first push. A missing ref (never fetched) allowed a push onto a forge default that already exists.What changed
internal/git/writer.go: newWriter.PushHead(push -u origin HEAD:<branch>) andWriter.PushHeadWithCredentials(the same push with explicit credentials, forInit, whose repo holds no credentials yet). Both run the refspec check and the guard before any backend.runInitialFinish,runInitialFinishFromFeatureBranch,Develop,runTagCreate(through a newtagPushTagseam) andInit.internal/git/auth.goandinternal/git/ssh_transport.go: both push runners (HTTPS and SSH) now usecaptureStdoutTeeStderr. It discards stdout. It tees stderr to the process stderr on the CLI only. Under the MCP server nothing streams. The comments onRunGitAuthDirWithStderrand the SSH runner now state this.internal/service/git/writer.go: the guard reads the forge default branch and the empty flag in one call (forgeRepoStateForDir).writerDefaultStatedecides the rule. When the forge answers, its empty flag decides. The local tracking ref is the fallback only when the forge cannot be read, so offline behaviour stays.internal/parity/writeguard_git_drift.go: the five entries leavewriteGuardGitAllowlist, so a push around the Writer at these sites fails the drift test again. The Writer-method check now also counts the credentials backend.What the tests cover
internal/git/writer_head_test.go:PushHeadandPushHeadWithCredentialsrun the refspec check and the guard before a backend.internal/service/git/writer_hermetic_test.goandwriter_test.go: a decision table pinswriterDefaultStatewith stated forge answers, including the stale ref, the missing ref and the offline fallback.internal/service/workflow/finish_initial_writer_test.go: the initial finish pushes through the Writer.internal/cmd/git/tag_push_writer_test.goandtag_test.go: tag--pushgoes through the Writer.internal/parity/writeguard_git_drift_test.go: the drift test with the smaller allowlist.internal/testforge/first_push_forge_test.go: forge-tagged tests cover the initial finish into a recreated empty forge repo with a stale tracking ref, and the first push of init../scripts/gate.shpasses on this commit.Closes #833