Skip to content
Open
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
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ O `pi-pstack` preserva o método verification-first do projeto original: context
- `/poteto-mode` persistente durante a sessão ativa.
- Feature maps, artifacts de navegador e receipts vinculados ao `HEAD` exato.
- Evals cegos entre modelos, com hard assertions que o judge não pode ignorar.
- Stacked PRs com `gh stack` por padrão e Graphite como backend opcional.
- Stacked PRs com `gh stack`.
- Benny em modo draft-only: ele pode preparar uma draft PR, mas nunca faz merge ou deploy.

## Requisitos
Expand All @@ -26,8 +26,7 @@ O `pi-pstack` preserva o método verification-first do projeto original: context
- Bun para as ferramentas locais que o utilizam.
- `portless` para fluxos locais que expõem serviços.
- Playwright Chromium para verificação de navegador.
- `github/gh-stack` como backend padrão de stacked PRs.
- Graphite `gt` somente quando o backend opcional for selecionado.
- `github/gh-stack` como backend de stacked PRs.
- Um provider externo de Slack e tracker para executar Benny contra serviços reais.

## Instalação
Expand Down Expand Up @@ -84,7 +83,7 @@ O modo sticky vale somente para a sessão ativa. O Pi restaura o estado pelo his

## Stacked PRs

`gh stack` é o backend padrão. O adapter Graphite só aparece quando `gt` está instalado. O pacote traduz operações para os CLIs oficiais e não mantém um segundo grafo de branches.
`gh stack` é o backend de delivery. O pacote traduz operações para o CLI oficial e não mantém um segundo grafo de branches.

O merge atômico exige um receipt por PR até o alvo. Gere cada receipt no checkout limpo do respectivo `HEAD` e mantenha os artifacts em caminhos imutáveis disponíveis durante a validação final. Se um digest de uma camada anterior não estiver disponível no checkout atual, o merge falha fechado.

Expand Down
34 changes: 9 additions & 25 deletions extensions/poteto-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export default function potetoModeExtension(pi: ExtensionAPI): void {
}

function restore(ctx: ExtensionContext): void {
// This closure is intentionally reset from the active branch on every
// session lifecycle event. It prevents state leaking across sessions.
active = branchState(ctx);
}

Expand All @@ -68,8 +66,6 @@ export default function potetoModeExtension(pi: ExtensionAPI): void {

pi.on("session_start", async (_event, ctx) => {
restore(ctx);
// Probe all host capability surfaces during startup without changing
// settings or failing print/JSON sessions. A task invocation fails closed.
preflight(ctx);
});

Expand Down Expand Up @@ -245,7 +241,7 @@ export default function potetoModeExtension(pi: ExtensionAPI): void {
description:
"Hash local verification, review, and eval artifacts into a receipt for the current repository HEAD.",
parameters: Type.Object({
backend: Type.Union([Type.Literal("gh-stack"), Type.Literal("graphite")]),
backend: Type.Literal("gh-stack"),
featureMapPath: Type.String({ minLength: 1 }),
skillPath: Type.String({ minLength: 1 }),
reviewPath: Type.String({ minLength: 1 }),
Expand Down Expand Up @@ -303,9 +299,9 @@ export default function potetoModeExtension(pi: ExtensionAPI): void {
name: "pstack_delivery",
label: "Run gated pstack delivery",
description:
"Inspect a stack or run a receipt-gated gh-stack or Graphite mutation. Auto-merge also verifies the live PR head and checks.",
"Inspect a stack or run a receipt-gated gh-stack mutation. Auto-merge also verifies the live PR head and checks.",
parameters: Type.Object({
backend: Type.Union([Type.Literal("gh-stack"), Type.Literal("graphite")]),
backend: Type.Literal("gh-stack"),
operation: Type.Union([
Type.Literal("inspect"),
Type.Literal("prepare"),
Expand Down Expand Up @@ -344,8 +340,6 @@ export default function potetoModeExtension(pi: ExtensionAPI): void {
paths.map((path) => loadEvidenceReceipt(path, ctx.cwd)),
);
if (params.operation === "auto-merge") {
if (params.backend !== "gh-stack")
return deliveryRejected("Graphite auto-merge lacks stack-wide receipt verification");
if (!params.pullRequest)
return deliveryRejected("auto-merge requires a pull request number");
const stackResult = await pi.exec("gh", ["stack", "view", "--json"], {
Expand All @@ -368,7 +362,7 @@ export default function potetoModeExtension(pi: ExtensionAPI): void {
root: ctx.cwd,
repoIdentity: repository.stdout.trim(),
headSha: entry.headSha,
backend: params.backend as StackBackendName,
backend: params.backend,
level,
});
if (rejection) return deliveryRejected(rejection);
Expand All @@ -391,15 +385,15 @@ export default function potetoModeExtension(pi: ExtensionAPI): void {
root: ctx.cwd,
repoIdentity: repository.stdout.trim(),
headSha: currentHead.stdout.trim(),
backend: params.backend as StackBackendName,
backend: params.backend,
level,
});
if (rejection) return deliveryRejected(rejection);
const authorization = authorizeDelivery({
receipt,
repoIdentity: repository.stdout.trim(),
currentHeadSha: currentHead.stdout.trim(),
backend: params.backend as StackBackendName,
backend: params.backend,
level,
});
if (authorization.draftOnly && params.operation === "submit" && params.draft === false)
Expand All @@ -414,18 +408,8 @@ export default function potetoModeExtension(pi: ExtensionAPI): void {
return { exitCode: result.code, stdout: result.stdout, stderr: result.stderr };
},
};
const availableCommands = ["gh"];
if (params.backend === "graphite") {
const gt = await pi.exec("gt", ["--version"], { cwd: ctx.cwd, signal });
if (gt.code === 0) availableCommands.push("gt");
}
const backends = createDeliveryBackends({
runner,
availableCommands,
});
const backend = params.backend === "graphite" ? backends.graphite : backends.ghStack;
if (!backend)
return deliveryRejected("Graphite is unavailable; install and authenticate gt first");
const backends = createDeliveryBackends({ runner });
const backend = backends.ghStack;
const operation = deliveryOperation(params);
const result = await backend.execute(operation);
return {
Expand Down Expand Up @@ -581,7 +565,6 @@ async function verifyPullRequestState(
return undefined;
}

/** Flatten shell-like and structured tool payloads before applying merge gates. */
function normalizeToolCallInput(input: unknown): string {
const values: string[] = [];
const seen = new WeakSet<object>();
Expand Down Expand Up @@ -692,6 +675,7 @@ function deliveryOperation(params: {
case "rebase":
return { kind: "rebase" };
case "auto-merge":
if (!params.pullRequest) throw new Error("auto-merge requires pull request");
return { kind: "auto-merge", pullRequest: params.pullRequest };
default:
throw new Error(`unsupported delivery operation: ${params.operation}`);
Expand Down
7 changes: 3 additions & 4 deletions skills/poteto-mode/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ managed worktrees isolate their edits. Resolve models through Pi profiles and
agent roles, never through provider-specific slugs embedded in a skill.

Delivery resources prepare evidence and receipts only. The default named
backend is `gh stack`; Graphite is an optional named backend. Executable
delivery behavior belongs to the later `src/delivery` adapters, not these
skills.
backend is `gh stack`. Executable delivery behavior belongs to the later
`src/delivery` adapters, not these skills.

## Non-negotiables

Expand Down Expand Up @@ -139,7 +138,7 @@ A large or cross-cutting effort (a migration across many call sites, an ambitiou
- **Authoring or modifying a skill.** Writing or editing a SKILL.md. `playbooks/authoring-a-skill.md`.
- **Eval.** Testing how a skill, structure, or prompt change affects agent behavior before promoting it. `playbooks/eval.md`.
- **Babysit.** Driving a PR or a stack to merge-ready: conflicts, review threads, CI. `playbooks/babysit.md`.
- **Shipping.** The half after Babysit. Independently verifying a green stack, then handing the contiguous verified run to the default `gh stack` adapter (Graphite is optional). `playbooks/shipping.md`.
- **Shipping.** The half after Babysit. Independently verifying a green stack, then handing the contiguous verified run to the `gh stack` adapter. `playbooks/shipping.md`.
- **Autonomous run.** A long task to drive to completion without stopping ("run until done", "wait until X"). `playbooks/autonomous-run.md`.
- **Orchestrate.** A standing project handed to one coordinator chat: multi-day, many stacked PRs, dozens to hundreds of subagents, minimal human turns ("run this whole project", "own this migration until it lands"). Distinct from Autonomous run, which drives one task to a predicate; work one agent could finish inside the session's budget routes there, not here, however program-shaped the phrasing sounds. `playbooks/orchestrate.md`.
- **Autopilot-full.** A queue of independent PRs run to merged with full autonomy: one owner per PR carries build through merge, and the root swarm-verifies each merge-ready head before its owner merges ("autopilot this queue", "full autopilot", one-owner-per-PR programs). `playbooks/autopilot-full.md`.
Expand Down
2 changes: 1 addition & 1 deletion skills/poteto-mode/playbooks/autopilot-stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**You own the stack, never the landing. Build and verify the queue with full
autonomy, then hand the operator one linear reviewed stack.** `gh stack` is
the default named backend; Graphite is optional. For "autopilot-stack", "stack
the delivery backend. For "autopilot-stack", "stack
them, don't ship", "build the stack, I'll land it". The sibling of
**Autopilot-full**. The owner loop and verification gate are the same; only
the terminal differs. Nothing auto-ships from this skill.
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 @@ -20,7 +20,7 @@ Invoked at the end of every other playbook.

After these sections, attach videos or screenshots when they prove a claim. Do not use `## Summary` or `## Test plan` boilerplate. A commit body does not restate its subject.

**Size and stacks.** Prefer narrow PRs to one large PR. Use the configured delivery adapter, with `gh stack` as the default and Graphite as an explicit option. Keep the ordered stack visible to reviewers. Branch from main only for independent work. Rebase on `main` before substantial stack work.
**Size and stacks.** Prefer narrow PRs to one large PR. Use the `gh stack` delivery adapter. Keep the ordered stack visible to reviewers. Branch from main only for independent work. Rebase on `main` before substantial stack work.

**Readiness.** Open every PR ready, never as a draft. Set `draft: false` on every PR creation call. If a PR still opens as a draft, run the host's ready command, such as `gh pr ready <number>`. Run `gh pr view <number>` before you refer to PR status.

Expand Down
8 changes: 3 additions & 5 deletions skills/poteto-mode/playbooks/shipping.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@

This is the half after `playbooks/babysit.md`. Babysit makes a stack mergeable.
Shipping decides what is actually safe to merge and hands a verified receipt to
the selected delivery adapter. `gh stack` is the default backend; Graphite is
an optional named backend. These resources do not implement backend state.
the selected delivery adapter. `gh stack` is the delivery backend. These resources do not implement backend state.
Green is not safe, and the gap between those two words is where this playbook
lives.

1. **Verify every PR independently before arming anything.** One subagent per PR, not batched, each a managed-worktree subagent, each exercising the real surface through the available browser, CLI, desktop, or mobile verification skill against parent versus head. Each returns `PASS`, `PASS+NOTES` or `FAIL` and posts that verdict on its own PR so the record outlives the chat. Safe means a verdict from an agent that did not write the code. CI green is not a verdict, and an approving bot review is not a verdict.
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 a passing verdict, where both `PASS` and `PASS+NOTES` pass. A verified PR sitting above an unverified one is not landable, because merging it would pull the gap in underneath it. Report the ceiling as a PR number and say what breaks the chain.
3. **Re-check that the verdicts still describe the code.** A restack rewrites every SHA above it and silently invalidates every verdict without touching a single check. Compare `git patch-id` at the verdict SHA against the current head before trusting an older verdict, and re-verify anything that actually drifted. Twenty-one verdicts went stale this way in one run with no signal at all.
4. **Hand the receipt to the delivery adapter.** Use the default `gh stack`
adapter unless the operator explicitly selected the named Graphite adapter.
Do not invent or mutate stack state in a skill; the later
4. **Hand the receipt to the delivery adapter.** Use the `gh stack`
adapter. Do not invent or mutate stack state in a skill; the later
`src/delivery` adapter owns submission, merge-when-ready, and exact-head
checks.
5. **Never enable GitHub auto-merge on a stack directly.** Only the selected
Expand Down
Loading