feat!: build the remaining first-push and revert rulings of ADR 0061 #892

Merged
hexajon merged 9 commits from issue-890-first-push-revert-rulings into main 2026-10-23 23:47:42 +00:00
Owner

Summary

This builds the ADR 0061 rulings that the last change left open.

  • finish refuses an origin on a different forge host than the one where it creates the repo, and names both hosts.
  • A repo create that seeds content (auto-init, a template generate that copies git content, a migration, or a fork) asks a person whether this is a new repo, and refuses when no person can be asked. A create body that madtea cannot parse counts as seeded.
  • With the forge unreadable, a push refuses unless a local remote-tracking ref shows that the forge repo already has a branch, and refuses when no local default branch can be found.
  • finish on an outside (dir=) target whose forge repo is empty refuses before the pre-checks and names madtea init.
  • A revert retry reuses only an issue that the login user opened, reuses a clean leftover revert branch and its open PR, and stops on a parked conflict worktree, naming it and its conflicted files.
  • An MCP init suggestion appears only in the question text, never as a default answer.
  • A client on MCP protocol 2026-07-28 or later gets the question as a SEP-2322 input request, as the protocol standard requires.
  • The forge tests poll the forge after a push, because Forgejo and Gitea apply a push's empty flag and default branch through a background queue.

The ADR 0061 forge tests run green on Forgejo and Gitea, baseline and latest.

Closes #890

## Summary This builds the ADR 0061 rulings that the last change left open. - `finish` refuses an origin on a different forge host than the one where it creates the repo, and names both hosts. - A repo create that seeds content (auto-init, a template generate that copies git content, a migration, or a fork) asks a person whether this is a new repo, and refuses when no person can be asked. A create body that madtea cannot parse counts as seeded. - With the forge unreadable, a push refuses unless a local remote-tracking ref shows that the forge repo already has a branch, and refuses when no local default branch can be found. - `finish` on an outside (`dir=`) target whose forge repo is empty refuses before the pre-checks and names `madtea init`. - A revert retry reuses only an issue that the login user opened, reuses a clean leftover revert branch and its open PR, and stops on a parked conflict worktree, naming it and its conflicted files. - An MCP `init` suggestion appears only in the question text, never as a default answer. - A client on MCP protocol 2026-07-28 or later gets the question as a SEP-2322 input request, as the protocol standard requires. - The forge tests poll the forge after a push, because Forgejo and Gitea apply a push's empty flag and default branch through a background queue. The ADR 0061 forge tests run green on Forgejo and Gitea, baseline and latest. Closes #890
Red tests for issue #890 (ADR 0061, ADR 0046): a seeded repo create asks
the new-repo question, an origin on another forge host refuses and names
both hosts, the from-feature refusal does not say the local repo has no
commits, a dir= finish into an empty forge repo refuses and names madtea
init, an unreadable forge needs a tracking ref before a push, a revert
retry reuses only the login user's issue and a clean leftover branch and
stops on a parked conflict, and an init suggestion never fills the answer
field. The code that makes them pass is not in this commit.
A create with auto-init, a template generate that copies git content, a
migration, or a fork is a first push (ADR 0061, ADR 0046). The forge write
guard asks the person through the first-push asker, and refuses with madtea
init when no person can be asked. A create with no content does not ask.
The MCP tools and the CLI commands carry the asker. A 2026-07-28 client gets
an input request and never a direct elicitation; a test pins this.
A finish that creates the missing forge repo refuses when the origin names
another forge host, before any question and before the create, and names
both hosts. A finish on a dir= target whose forge repo is empty refuses
before the pre-checks and names madtea init. The from-feature refusal no
longer says that the local repo has no commits (ADR 0061).
With the forge unreadable, a branch push refuses unless a local
origin/<branch> ref shows that the forge repo already has a branch; a tag
push stays outside the rule. A revert retry reuses only an open revert
issue that the login user opened, reuses a clean leftover
issue-M-revert-pr-N branch and its open PR, and stops on a leftover
worktree with a parked conflict, naming the worktree and the files. This
holds for orchestrate, madt_prs revert, and madtea pr revert (ADR 0061).
The forge tests check that finish refuses an origin on another forge host,
that a seeded repo create asks and a create with no content does not, that
a push with the forge unreadable and no tracking ref refuses, that a dir=
finish into an empty forge repo refuses, and that a revert retry reuses
only the login user's issue and finds the leftover PR (ADR 0061). go fix
also moves the forge removal test to slices.Contains.
Each revert caller (orchestrate, madt_prs revert, madtea pr revert) now has a
temp-repo test that reuses the open PR of a clean leftover revert branch, and
one that stops on a leftover worktree with a parked conflict and names the
worktree and the conflicted file (ADR 0061). madt_api_call runs in a real
serve process with the production write guard, so a seeded create must ask
the person, and refuses with no person. A probe command run through RootCmd
proves that PersistentPreRunE gives commands the terminal asker.
With the forge unreadable and a tracking ref present, a push now refuses
when no local default branch can be found, because madtea cannot tell
whether it writes the default branch. A repo create whose body does not
parse counts as seeded for every create kind, so it asks the person and
refuses with no person. The forge-unreadable branch of writerDefaultState
and the writerRemoteDefaultExists seam had no production caller, so they
are gone with the test rows that only drove them.
test: poll the forge API after a first push, because the forge applies a push through its async push queue
Some checks failed
ci / gate (pull_request) Has been cancelled
drift / govulncheck (pull_request) Has been cancelled
drift / surface-diff (pull_request) Has been cancelled
drift / forgejo-smoke (pull_request) Has been cancelled
ci / gate (push) Has been cancelled
drift / govulncheck (push) Has been cancelled
drift / surface-diff (push) Has been cancelled
drift / forgejo-smoke (push) Has been cancelled
9da9c520e5
Sign in to join this conversation.
No reviewers
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.

Dependencies

No dependencies set.

Reference
sixfold-space/madtea!892
No description provided.