diff --git a/AGENTS.md b/AGENTS.md index 0d9b1cf..3d06456 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -77,7 +77,11 @@ The branch rule requires the **`merge-gate`** check, which is path-scoped: - **Docs/org-only PRs** (no `.rs`/`Cargo`/`idl`/`rust-toolchain`) — the heavy `foundry` job is **skipped**; the PR merges on `org-governance` + `merge-gate` in seconds. - **OS-code PRs** — `foundry` **runs** and `merge-gate` refuses to pass unless it succeeds. OS-code changes are forced through the full Foundry suite. -All PRs are opened by the `ramen-implementer` bot (A2) and approved + merged by a human (A3); see `docs/org/RAMEN_IMPLEMENTER_BOT.md`. +### PR flow: open as the bot, approve as a different identity +Every PR is opened by the `ramen-implementer` bot (A2) and approved + merged by a **different** identity (A3) — GitHub blocks self-approval, which enforces the separation of duties. +- **Open (as the bot):** `export GH_TOKEN=$(python3 tools/org/mint_app_token.py --app-id 4129163 --key ~/.config/ramenos/ramen-implementer.private-key.pem)` → `git push -u origin ` → `gh pr create …`. The PR author is `ramen-implementer[bot]`. +- **Approve + merge (as a different identity):** **`unset GH_TOKEN` first** — otherwise the approve runs as the bot and GitHub rejects the self-approval — then `gh pr review --approve` + `gh pr merge --squash --delete-branch` as the human (A3). (Stage 2: a second bot, `ramen-reviewer`, approves as A3.) +- Full details — identity, key, token mint, bot verification, separation of duties: see `docs/org/RAMEN_IMPLEMENTER_BOT.md`. ## IDL workflow 1. Define the interface in `idl/harness/*.toml` (harness) or `idl/portals/*.toml` (portal). diff --git a/docs/org/RAMEN_IMPLEMENTER_BOT.md b/docs/org/RAMEN_IMPLEMENTER_BOT.md index 486fcdd..a3d3062 100644 --- a/docs/org/RAMEN_IMPLEMENTER_BOT.md +++ b/docs/org/RAMEN_IMPLEMENTER_BOT.md @@ -90,14 +90,22 @@ The PR is authored by `ramen-implementer[bot]`. Confirm: gh pr view --json author --jq .author.login # → app/ramen-implementer ``` -## Approving + merging (the human, A3) +## Approving + merging (a different identity, A3) -GitHub forbids a PR author from approving their own PR, so the bot-opened PR -**requires** a different identity to approve — i.e. the human: +GitHub forbids a PR author from approving their own PR, so a bot-opened PR +**requires a different identity** to approve — today the human, later a second +bot (see Stage 2). + +> **Critical gotcha — drop the bot token before approving.** `gh pr create` runs +> as the bot because `GH_TOKEN` holds the bot token. The next `gh pr review +> --approve` will *also* run as the bot unless you clear the token first, and +> GitHub rejects it: *"Review cannot approve your own pull request."* **Always +> `unset GH_TOKEN` (or switch to a different credential) between opening and +> approving.** ```sh -unset GH_TOKEN # back to maxwellsantoro (reviewer/A3) -gh pr review --approve --body "..." +unset GH_TOKEN # REQUIRED: drop the bot token first +gh pr review --approve --body "..." # now runs as the human (A3) gh pr merge --squash --delete-branch ```