Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/sync-upstream/references/translation.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ A sync must keep these even when upstream's line differs.
- orchestrate and swarm isolation: remote by default for orchestrate workers, and a worktree for any swarm worker that checks out, builds, or runs.
- `.claude-plugin/plugin.json` carries no `version`, where upstream's `.cursor-plugin/plugin.json` does. Claude Code then versions a GitHub-hosted install by commit SHA, so every merge to `main` reaches `claude plugin update`. A version string that does not change blocks updates. The `plugin-version` rule in `scripts/check-port.ts` keeps it out. `claude plugin validate` warns about the missing version. That warning is expected.
- interrogate adds the blind-spot lenses (`references/blind-spots.md`, Step 3 item 5), a PR number or URL as scope, the lead checking each Act on and Consider finding against source, and the someone-else's-PR flow (`references/review-comments.md`), all folded in from Lucas's retired pr-review-swarm skill. When a playbook runs it as the pre-PR gate, it hands the verdict back instead of ending the turn. The gate's rules live in Opening a PR step 2. It runs no tool-based analyzers: a CodeScene change-set step was tried and removed after an eval showed the reviewers already covered everything it found (PR #2).
- `skills/poteto-mode/scripts/merge-gate/` is port-only. It reuses watch-pr's readiness verdict without editing watch-pr, and adds the policy: allowed repos, human-only paths needing a human approval on the head, and head pinning with `--match-head-commit`. A PR in a GitHub native stack refuses `gh pr merge`, so the gate falls back to the merge-async REST endpoint with the same head SHA. Every playbook merges only through it, and a refusal is final: human-only changes are the user's to merge. The policy lives outside git, and editing it is on poteto-mode's always-pause list.
- `skills/poteto-mode/scripts/merge-gate/` is port-only. It reuses watch-pr's readiness verdict without editing watch-pr, and adds the policy: allowed repos, human-only paths needing a human approval on the head, and head pinning with `--match-head-commit`. A PR in a GitHub native stack refuses `gh pr merge`, so the gate falls back to the merge-async REST endpoint with the same head SHA. `--stack` gates native stack positions 1 to the target as one unit: each open PR runs the same per-PR decision, with its expected base being the head of the open PR below it instead of trunk, and one merge-async call on the target, pinned to its head, lands the range atomically. merge-async pins only that head, so the gate re-reads every head and the stack just before the call and refuses a merged head it did not gate (`merged-ungated-head`). Upstream has no native stacks. Every playbook merges only through it, and a refusal is final: human-only changes are the user's to merge. The policy lives outside git, and editing it is on poteto-mode's always-pause list.
- `principle-never-block-on-the-human` narrows its force-push example to "force-push to a shared branch", matching poteto-mode's Autonomy. Autopilot owners force-push their own branches with a lease on every rebase.
- models.md uses only `opus` and `sonnet`. `fable` is dropped for cost: every role that upstream maps to it, and every panel slot, goes to `opus` or `sonnet`. interrogate runs two reviewers (`opus`, `sonnet`), accepting that both share one family and give less independent review than a cross-family pair.
- `orch frontier set` walks the PR base chain with `gh` only. Upstream's `--forge` option and its Origin branch are removed, so the command takes no forge.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ mkdir -p ~/.claude/pstack && [ -e ~/.claude/pstack/merge-policy.json ] || curl -

Edit it for your repos. Both `defaults.humanOnly` and `repos` are required, and a repo with no entry is refused. `humanOnly` globs mark paths that need a human's approval on the exact head commit before the agent merges. The approver must be a collaborator other than the PR author, so on a solo repo those paths mean you merge them yourself. `requireHumanApprovalOnHead` asks for that approval on every PR in the repo. `mergeCommitBranches` lists branch globs that merge with a merge commit instead of a squash.

`merge-gate` also refuses unless `gh` is signed in as the PR author, the PR targets the default branch (so upper PRs in a stack wait for their turn), and the head has passing checks. A repo with no CI is refused with `checks-missing`.
`merge-gate` also refuses unless `gh` is signed in as the PR author, the PR targets the default branch (so upper PRs in a stack wait for their turn), and the head has passing checks. A repo with no CI is refused with `checks-missing`. For a GitHub native stack, `merge-gate <pr> --stack --merge` gates every open PR from the bottom up to `<pr>`, each based on the one below it, and merges them together.

## Differences from upstream

Expand Down
2 changes: 1 addition & 1 deletion skills/poteto-mode/playbooks/opening-a-pr.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ After the sections, attach videos or screenshots when they prove a claim. Full S
2. Gate. Run the **interrogate** skill against trunk. Apply each Act on finding that fits the PR's intent without changing a public API or deleting data. An Act on finding you won't fix here is a blocker, unless the lead re-buckets it to Consider or Dismissed with a reason. Commit the fixes after `/simplify` over them, rerun the checks they affect, and push. When a fix changed behavior beyond the lines its finding cited, run the gate once more on the new head and apply its findings the same way. Never run a third round.
3. No blockers: `gh pr create` without `--draft`, or `gh pr ready <number>` for your own draft that you have not readied before. A PR that went back to draft after you readied it is a hold: report it and stop. In a stack, ready only your own PR. `gh stack submit --auto --open` is for one agent that gated every PR in the stack, followed by `gh pr edit` for each title and body. With blockers: the PR stays or opens as a draft.
4. Merge, when this PR is the whole task rather than a layer mid-stack or mid-phase, and never for a revert PR. Run the **Babysit** playbook in `drive` mode until the watcher reports `READY`, then `scripts/merge-gate/merge-gate <number> --merge`. Never run `gh pr merge` yourself. A final refusal is never overridden that way: the user merges it.
- Final (report the reason and any listed files, and stop): `needs-human-approval`, `repo-not-allowed`, `not-author`, `changes-requested`, `base-not-trunk`, `policy-invalid`, `threads-unverified`, `reviews-unverified`, `files-incomplete`, `draft` (someone drafted it after you readied it, which means hold). A verdict with any final reason is final.
- Final (report the reason and any listed files, and stop): `needs-human-approval`, `repo-not-allowed`, `not-author`, `changes-requested`, `base-not-trunk`, `policy-invalid`, `threads-unverified`, `reviews-unverified`, `files-incomplete`, `method-mismatch`, `draft` (someone drafted it after you readied it, which means hold), and `merged-ungated-head`. A verdict with any final reason is final. `merged-ungated-head` means the merge landed a head the gate never gated: tell the user at once with each PR's gated and merged SHA from the detail, and merge nothing else until they have reviewed what landed. A `base-not-trunk` refusal on a PR in a GitHub native stack means it lands with its stack, through Shipping's `--stack`, and only on an explicit request to land.
- Back to Babysit, then re-gate: `checks-failed`, `threads-unresolved`, and `not-mergeable` when the detail says `DIRTY` or `BEHIND` (rebase first).
- Transient (wait for the watcher, rerun once, then report): `checks-pending`, `head-moved`, `github-error`, and any other `not-mergeable`.
- `merge-unverified`: run `gh pr view <number> --json state,mergeCommit`. If it merged, continue with the post-merge watch on that commit. If not, a stacked PR's async merge may still be queued, so poll `gh pr view` for a few minutes before you rerun with `--merge`. If it is still open after that, treat it as transient.
Expand Down
2 changes: 1 addition & 1 deletion skills/poteto-mode/playbooks/shipping.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This is the half after `playbooks/babysit.md`. Run it only on an explicit reques
1. **Verify each PR independently before it lands.** Every PR operation goes through `gh`. Never require Graphite (`gt`). One verifier per PR, each a background subagent with `isolation: "worktree"`, runs the change the way a user would with the matching control skill (such as the `claude-in-chrome` browser tools or the built-in `run` skill), parent against head, and posts `PASS`, `PASS+NOTES`, or `FAIL` on that PR. Only a verdict from an agent that did not write the code counts, because an author checks what it meant to build. Green CI and an approving bot review are not verdicts, because neither runs the change as a user would.
2. **Land only the contiguous verified run rooted at the bottom.** Walk up from the lowest unmerged PR and stop at the first one without `PASS` or `PASS+NOTES`. The PRs below it are the run, and the top one is the ceiling. A verified PR above an unverified one waits, because it cannot land without the code below it. Moving one out of a `gh stack` takes the interactive `gh stack modify`, so leave that to the user. Once its branch neither holds nor needs that code and it targets trunk, it can land on its own after a fresh verdict, because its old one ran with that code beneath it and trunk does not have it.
3. **Re-check that the verdicts still describe the code.** A verdict covers a patch, and a chain rebase moves every PR above it to a new SHA without failing any check. Compare `git patch-id` at the verdict SHA with the current head before trusting an older verdict. When the patches differ only in tests, docs, or lint config, a lane's result stands if what it ran builds the same at both SHAs apart from noise. Noise is a difference that also shows up between two builds of the verdict SHA, or an embedded commit SHA. Report each kind of noise with its files, so a reader can check the call. The change itself still gets fresh checks and a review, because the old verdict never saw it. A lane with no build output, such as a dev server, cannot show this, so rerun it, and re-verify anything else that drifted.
4. **Land bottom-up, one PR at a time.** Always merge the run's lowest unmerged PR. Bring its branch onto the exact trunk tip when needed, with `gh stack rebase --downstack` and `gh stack push` from the bottom branch, and re-run step 3 after the push. Merge with `scripts/merge-gate/merge-gate <pr> --merge`, which refuses a PR whose base is not trunk, because one whose base is still its parent's branch would merge into that branch. A refusal stops the landing. For `needs-human-approval`, report the PR and the human-only files the gate listed, and leave the merge to the user. Read the PR back (`gh pr view <pr> --json state,mergedAt,baseRefName`), because a merge can report success when a merge queue only queued the PR. A landed PR reads merged with trunk as its base. Never arm `--auto`, because without required checks GitHub merges it at once. After a merge lands, GitHub restacks the rest of a `gh stack` server-side. Run `gh stack sync`, confirm the next PR now targets trunk, and let step 3's patch-id rule decide whether its verdict survives. Merge it once its checks pass and its verdict survives.
4. **Land bottom-up, one PR at a time.** Always merge the run's lowest unmerged PR. Bring its branch onto the exact trunk tip when needed, with `gh stack rebase --downstack` and `gh stack push` from the bottom branch, and re-run step 3 after the push. Merge with `scripts/merge-gate/merge-gate <pr> --merge`, which refuses a PR whose base is not trunk, because one whose base is still its parent's branch would merge into that branch. In a GitHub native stack, land the whole run at once with `scripts/merge-gate/merge-gate <ceiling> --stack --merge` instead. It gates every open PR from position 1 to the ceiling, each against the head of the PR below it, and lands them in one atomic merge-async call. GitHub pins only the ceiling's head, so the gate re-reads every head and the stack just before that call and checks each merged head after it. A push to a lower PR between that re-read and the merge still lands. The gate then reports `merged-ungated-head`, which is final, so step 5 keeps everyone off the stack while it lands. `stack-changed` means a PR was added, merged, closed, or retargeted after gating: find out why, re-verify any PR it touched, and rerun. `method-mismatch` means the run's PRs call for different merge methods, which one call cannot honor: report it and leave the landing to the user. A refusal stops the landing. For `needs-human-approval`, report the PR and the human-only files the gate listed, and leave the merge to the user. Read the PR back (`gh pr view <pr> --json state,mergedAt,baseRefName`), because a merge can report success when a merge queue only queued the PR. A landed PR reads merged with trunk as its base. Never arm `--auto`, because without required checks GitHub merges it at once. After a merge lands, GitHub restacks the rest of a `gh stack` server-side. Run `gh stack sync`, confirm the next PR now targets trunk, and let step 3's patch-id rule decide whether its verdict survives. Merge it once its checks pass and its verdict survives.
5. **Leave the stack alone while it lands.** Step 4's rebase, push, and sync are the only changes to a branch or base, because a merge lands whatever its branch and base hold at that moment, verdict or not. Use `scripts/watch-pr/watch-pr --queued-stack --stack-prs <bottom>` only as an event wake under `/loop` in dynamic mode, and after each wake read `gh pr view <pr> --json state,mergedAt,mergeStateStatus,statusCheckRollup` for the current PR until `mergedAt` is set. A base that moves to trunk when its parent merges is expected, not damage to repair. If a merge stalls, find out why before you change anything.
6. **Stop at the ceiling.** Extending the run takes new verdicts, so it is a new pass through step 1.

Expand Down
Loading
Loading