guard: refuse every commit on the default branch after the first push, with no override #665

Closed
opened 2026-09-29 18:36:59 +00:00 by hexajon · 2 comments
Owner

ADR 0006 and ADR 0046 say that the only write to the default branch is the first push into an empty repo. madt_commit and madtea commit break that rule in two ways today:

  • A per-call override lets a commit land on the default branch: allow_default_branch on MCP (internal/mcp/tools_localgit.go) and --allow-default-branch on the CLI (internal/cmd/git/commit.go). ADR 0006 says that no guard in this tier has an override.
  • A commit that finishes a merge, revert, or cherry-pick on the default branch is exempt (internal/service/git/commit.go). ADR 0006 refuses it.

Scope:

  • Remove the override from both surfaces, with no alias and no replacement flag.
  • Remove the in-progress exemption. The empty-repo exemption stays.
  • The refusal text follows ADR 0026.

Acceptance:

  • Against the live forge and a test repo: a commit on the default branch is refused, both with and without a merge in progress. A commit in an empty repo succeeds.
  • Neither surface accepts an override parameter or flag.

Depends on #659 (the git write functions call the guard). Decision records: ADR 0006, ADR 0046.

ADR 0006 and ADR 0046 say that the only write to the default branch is the first push into an empty repo. `madt_commit` and `madtea commit` break that rule in two ways today: - A per-call override lets a commit land on the default branch: `allow_default_branch` on MCP (`internal/mcp/tools_localgit.go`) and `--allow-default-branch` on the CLI (`internal/cmd/git/commit.go`). ADR 0006 says that no guard in this tier has an override. - A commit that finishes a merge, revert, or cherry-pick on the default branch is exempt (`internal/service/git/commit.go`). ADR 0006 refuses it. Scope: - Remove the override from both surfaces, with no alias and no replacement flag. - Remove the in-progress exemption. The empty-repo exemption stays. - The refusal text follows ADR 0026. Acceptance: - Against the live forge and a test repo: a commit on the default branch is refused, both with and without a merge in progress. A commit in an empty repo succeeds. - Neither surface accepts an override parameter or flag. Depends on #659 (the git write functions call the guard). Decision records: ADR 0006, ADR 0046.
Author
Owner

The code for this landed on main, and the host tests pass: a commit on the default branch is refused on both surfaces, with and without a merge in progress, the empty-repo first commit still works, and the override is gone from both surfaces with no alias. There is no forge-tagged test for this one; the proof is the real-git tests on the host. Keeping this open until the forge-test gate for the breaking set is green.

The code for this landed on main, and the host tests pass: a commit on the default branch is refused on both surfaces, with and without a merge in progress, the empty-repo first commit still works, and the override is gone from both surfaces with no alias. There is no forge-tagged test for this one; the proof is the real-git tests on the host. Keeping this open until the forge-test gate for the breaking set is green.
Author
Owner

The v0.20.0 breaking set is complete and green on main. The code landed across the v0.20.0 branches, the full local gate passes, and the forge suite is green on both forges at both pinned versions on current main (31693766). Closing as done.

The v0.20.0 breaking set is complete and green on main. The code landed across the v0.20.0 branches, the full local gate passes, and the forge suite is green on both forges at both pinned versions on current main (31693766). Closing as done.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
sixfold-space/madtea#665
No description provided.