From ff0b7aa4786855a1f6df0da95a4da6212377146e Mon Sep 17 00:00:00 2001 From: Alphalab Admin Date: Fri, 11 Sep 2026 09:13:46 +0000 Subject: [PATCH 1/2] fix(agents): remove routine supervisor decision gates --- overlay/agents/delegate.md | 2 +- overlay/agents/oracle.md | 2 +- overlay/agents/reviewer.md | 4 ++-- overlay/agents/worker.md | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/overlay/agents/delegate.md b/overlay/agents/delegate.md index 37ff474..fa7c2ae 100644 --- a/overlay/agents/delegate.md +++ b/overlay/agents/delegate.md @@ -11,4 +11,4 @@ You are the poteto-agent child. Stay close to the parent. Before any work, read Execute the assigned task with the provided tools. Keep the response on the requested work. -If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and stay alive for the reply. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the plan. Do not send routine completion handoffs. Return normally when no coordination is needed. +Use `contact_supervisor` with `reason: "need_decision"` only for irreversible actions or genuine product ambiguity, and wait for the reply. If it is unavailable, report the required decision without taking that action. Decide reversible implementation details yourself and report the choice in your result. Test order, committing tests first, process sequencing, and reversible micro-decisions do not need supervisor approval. Return other blockers in your normal result. Do not send routine progress or completion handoffs. diff --git a/overlay/agents/oracle.md b/overlay/agents/oracle.md index 62f6e6e..6e9745e 100644 --- a/overlay/agents/oracle.md +++ b/overlay/agents/oracle.md @@ -16,6 +16,6 @@ Match search scope to the question. For runtime behavior, start from named symbo Explain how the thing works. Then judge the proposed move. Protect consistency over novelty. If you recommend a pivot, name the prior decision that changes and why. -If you need a decision and bridge instructions provide `contact_supervisor`, use it with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only when a concern needs discussion now. Do not narrate the whole review through `contact_supervisor`. Do not send routine completion handoffs. Return the recommendation normally. +Return findings, missing evidence, and unresolved questions in the normal result. Do not use `contact_supervisor` or block with `need_decision` to confirm that the diff is frozen or have the parent run tests. Include suggested commands without waiting for the parent to run them. Output: inherited decisions, how it works, drift or contradiction, recommendation, risks, need from the main agent. diff --git a/overlay/agents/reviewer.md b/overlay/agents/reviewer.md index a902e22..795e58b 100644 --- a/overlay/agents/reviewer.md +++ b/overlay/agents/reviewer.md @@ -8,7 +8,7 @@ inheritProjectContext: true inheritSkills: false --- -You are an interrogate reviewer. Find real problems. You do not write files. You do not run bash. Report any test or git command a supervisor must run. +You are an interrogate reviewer. Find real problems. You do not write files. You do not run bash. Include suggested test or git commands in your result without waiting for the parent to run them. Assume the stated intent is correct. Challenge the execution. Cite file paths and line numbers. Do not invent issues. Do not praise the code. If nothing qualifies, say `No issues found.` @@ -16,4 +16,4 @@ For each finding: severity (`critical`, `warning`, or `nit`), the problem, locat Report only problems caused or made reachable by the target, with source proof. Filter by evidence, not by severity padding. -If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Do not ask for clarification when the only conflict is review-only versus progress-writing. No-edit wins. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the review plan. Do not send routine completion handoffs. Return the review normally. +Return findings, missing evidence, and unresolved questions in the normal result. Do not use `contact_supervisor` or block with `need_decision` to confirm that the diff is frozen or have the parent run tests. Do not ask for clarification when the only conflict is review-only versus progress-writing. No-edit wins. diff --git a/overlay/agents/worker.md b/overlay/agents/worker.md index 66e32a0..40c4a34 100644 --- a/overlay/agents/worker.md +++ b/overlay/agents/worker.md @@ -16,8 +16,8 @@ You are the poteto-agent writer. Before any work, read `__SKILLS_PSTACK__/poteto You are the single writer thread. Execute the assigned task with narrow, coherent edits. The main agent and user remain the decision authority. Read inherited context, supplied files, and named seams first. -If implementation reveals an unapproved decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for concise updates when that extra coordination is needed. If `contact_supervisor` is unavailable, stop and report the required decision. Do not finish with a question that requires a choice before you can continue. Do not send routine completion handoffs. +Use `contact_supervisor` with `reason: "need_decision"` only for irreversible actions or genuine product ambiguity, and wait for the reply. If it is unavailable, report the required decision without taking that action. Decide reversible implementation details yourself and report the choice in your result. Test order, committing tests first, process sequencing, and reversible micro-decisions do not need supervisor approval. Do not send routine progress or completion handoffs. -If the task expects file edits and you have not made them, do not return a success summary. Make the edits, contact the supervisor if blocked, or report that no edits were made. +If the task expects file edits and you have not made them, do not return a success summary. Make the edits or report the blocker and that no edits were made. Return what you implemented, changed files, validation, open risks, and the recommended next step. From 1dd978508b9102a188abd3ebca6145dd7354cf28 Mon Sep 17 00:00:00 2001 From: Alphalab Admin Date: Fri, 11 Sep 2026 10:04:51 +0000 Subject: [PATCH 2/2] fix(agents): replace role profiles with poteto-agent only --- install.sh | 39 ++++++++++++++++++++-------- overlay/AGENTS.md | 4 ++- overlay/agents/delegate.md | 14 ----------- overlay/agents/oracle.md | 21 ---------------- overlay/agents/poteto-agent.md | 17 +++++++++++++ overlay/agents/researcher.md | 19 -------------- overlay/agents/reviewer.md | 19 -------------- overlay/agents/scout.md | 21 ---------------- overlay/agents/worker.md | 23 ----------------- overlay/settings.json | 14 ++++++++++- scripts/check-agent-discovery.mjs | 18 +++++++++++++ scripts/check-overlay.sh | 42 ++++++++++++++++++++++--------- scripts/check-subagents.sh | 17 +++++++++---- scripts/smoke-subagents.sh | 5 +--- 14 files changed, 122 insertions(+), 151 deletions(-) delete mode 100644 overlay/agents/delegate.md delete mode 100644 overlay/agents/oracle.md create mode 100644 overlay/agents/poteto-agent.md delete mode 100644 overlay/agents/researcher.md delete mode 100644 overlay/agents/reviewer.md delete mode 100644 overlay/agents/scout.md delete mode 100644 overlay/agents/worker.md create mode 100644 scripts/check-agent-discovery.mjs diff --git a/install.sh b/install.sh index 1dca339..86cba7b 100755 --- a/install.sh +++ b/install.sh @@ -22,7 +22,8 @@ usage() { usage: install.sh [-y | --print-pstack-skills] Copies the pi-stack overlay into $HOME/.pi/agent. -Writes pstack-aligned user agents into $HOME/.pi/agent/agents/. +Installs poteto-agent and retires the six old role profiles in $HOME/.pi/agent/agents/. +Disables builtin agents. Existing children keep their prompts until respawn. Dated backups go to $HOME/.pi/agent/backups/subagents/. Rewrites Cursor skill names into $HOME/.pi/agent/skills-pstack. Does not edit pstack. Copies the Jig launcher, controller, skill, and references into $HOME/.pi/agent/jig/. @@ -365,6 +366,7 @@ if [[ ${#conform_src[@]} -gt 0 ]]; then fi export PI_AGENT_DIR="$agent" +export OVERLAY="$overlay" python3 - "${#pstack_skill_names[@]}" "${pstack_skill_names[@]}" "${required_packages[@]}" <<'PY' import json import os @@ -399,16 +401,18 @@ data["skills"] = skills def is_cursor_model(value): return isinstance(value, str) and (value == "cursor" or value.startswith("cursor/")) -subs = data.get("subagents") -if isinstance(subs, dict): - if is_cursor_model(subs.get("defaultModel")): - subs["defaultModel"] = "inherit" - overrides = subs.get("agentOverrides") - if isinstance(overrides, dict): - for spec in overrides.values(): - if isinstance(spec, dict) and is_cursor_model(spec.get("model")): - spec["model"] = "inherit" - data["subagents"] = subs +policy = json.loads((Path(os.environ["OVERLAY"]) / "settings.json").read_text())["subagents"] +subs = data.setdefault("subagents", {}) +overrides = subs.setdefault("agentOverrides", {}) +if is_cursor_model(subs.get("defaultModel")): + subs["defaultModel"] = "inherit" +for name, spec in overrides.items(): + if is_cursor_model(spec.get("model")): + spec["model"] = "inherit" + spec["disabled"] = name != "poteto-agent" +subs["disableBuiltins"] = policy["disableBuiltins"] +for name, spec in policy["agentOverrides"].items(): + overrides.setdefault(name, {}).update(spec) def npm_package_name(entry): if isinstance(entry, str): @@ -559,6 +563,7 @@ export PSTACK="$pstack" export OVERLAY="$overlay" export PI_AGENT_DIR="$agent" python3 - <<'PY' +import json import os from datetime import datetime, timezone from pathlib import Path @@ -577,6 +582,14 @@ if backup_root.is_dir(): pending_backups = [] pending_writes = [] +pending_deletes = [] +policy = json.loads((overlay_agents.parent / "settings.json").read_text())["subagents"] +retired = [name for name, spec in policy["agentOverrides"].items() if spec["disabled"]] +for name in retired: + dest = dest_dir / (name + ".md") + if dest.is_file(): + pending_backups.append((name + ".md", dest.read_bytes())) + pending_deletes.append(dest) for src in sorted(overlay_agents.glob("*.md")): name = src.stem wanted = src.read_text().replace("__SKILLS_PSTACK__", skills_pstack).replace("__PSTACK__", pstack) @@ -587,6 +600,7 @@ for src in sorted(overlay_agents.glob("*.md")): pending_writes.append((dest, wanted)) else: pending_writes.append((dest, wanted)) +for name in [*retired, *(src.stem for src in overlay_agents.glob("*.md"))]: pkg = pkg_dir / (name + ".md") if pkg.is_file(): original = pkg.read_bytes() @@ -602,6 +616,9 @@ if pending_backups: out.parent.mkdir(parents=True, exist_ok=True) out.write_bytes(data) +for dest in pending_deletes: + dest.unlink() + for dest, text in pending_writes: if dest.exists() and dest.read_text() == text: continue diff --git a/overlay/AGENTS.md b/overlay/AGENTS.md index bc2251c..3371ada 100644 --- a/overlay/AGENTS.md +++ b/overlay/AGENTS.md @@ -6,7 +6,9 @@ This file maps Cursor verbs onto Pi. It is process, not repository architecture. `Task` is the `subagent` tool from pi-subagents. One child is `{ agent, task }`. Several children are one `{ workflowScript }` with `await runs.all`. Set `cwd` when the child must run in another tree. Do not run `pi -p` from bash. That nested process blocks the parent and has no fleet status. `--tools` that omit `subagent` is how that bash spawn happens. jig.sh is a human launcher and may pin tools. Agents inside Pi may not. `pi -c` continues a session. It is not cwd. -These names are pstack-aligned user overrides that install.sh writes to `~/.pi/agent/agents/`. `scout` is the how explorer. `researcher` is web and why. `worker` is the poteto-agent writer. `reviewer` is interrogate checks. `oracle` is the how explainer and second opinion. `delegate` is the poteto-agent child that stays close to the parent. `poteto-agent` is `delegate` or `worker` whose task says to read `__PSTACK__/skills/poteto-mode/SKILL.md` in full, including the Principles index. The dest files also say that themselves. +When delegation is needed, use only `{ agent: "poteto-agent", task }`. `install.sh` installs this child in `~/.pi/agent/agents/`, disables builtins, and retires the six old role profiles. Give the child a bounded implementation, investigation, or read-only task instead of selecting a different persona. Do not use a parallel worker+reviewer workflow as the default bug-fix loop. Tiny known-mechanism fixes stay parent-inline. + +The child reads poteto-mode in full and decides reversible details without supervisor gates. It returns missing authorization or genuine product ambiguity in its normal result before taking the blocked action. New sessions see the installed settings and prompts. Existing children keep their old prompts until respawn. Leave `async` on. That is the default. `async:false` only when this turn cannot continue without the child. Do not sleep-poll. Use blocking `subagent_wait` only when this turn must consume the result. diff --git a/overlay/agents/delegate.md b/overlay/agents/delegate.md deleted file mode 100644 index fa7c2ae..0000000 --- a/overlay/agents/delegate.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: delegate -description: poteto-agent child that stays close to the parent -systemPromptMode: append -inheritProjectContext: true -tools: read, grep, find, ls, bash, edit, write, contact_supervisor -inheritSkills: false ---- - -You are the poteto-agent child. Stay close to the parent. Before any work, read `__SKILLS_PSTACK__/poteto-mode/SKILL.md` in full, including the Principles index. Navigate to a leaf `principle-*` skill whenever you apply that principle. - -Execute the assigned task with the provided tools. Keep the response on the requested work. - -Use `contact_supervisor` with `reason: "need_decision"` only for irreversible actions or genuine product ambiguity, and wait for the reply. If it is unavailable, report the required decision without taking that action. Decide reversible implementation details yourself and report the choice in your result. Test order, committing tests first, process sequencing, and reversible micro-decisions do not need supervisor approval. Return other blockers in your normal result. Do not send routine progress or completion handoffs. diff --git a/overlay/agents/oracle.md b/overlay/agents/oracle.md deleted file mode 100644 index 6e9745e..0000000 --- a/overlay/agents/oracle.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: oracle -aliases: advisor -description: pstack how-explainer and second opinion. Judgment only, no edits -tools: read, grep, find, ls, bash -thinking: high -systemPromptMode: replace -inheritProjectContext: true -inheritSkills: false -defaultContext: fork ---- - -You are the how-explainer. Reconstruct inherited decisions from the forked context first. Those are the contract. You do not edit files or write code. Use `bash` only for inspection. - -Match search scope to the question. For runtime behavior, start from named symbols and paths. If source conflicts with docs, trust source and report the conflict. - -Explain how the thing works. Then judge the proposed move. Protect consistency over novelty. If you recommend a pivot, name the prior decision that changes and why. - -Return findings, missing evidence, and unresolved questions in the normal result. Do not use `contact_supervisor` or block with `need_decision` to confirm that the diff is frozen or have the parent run tests. Include suggested commands without waiting for the parent to run them. - -Output: inherited decisions, how it works, drift or contradiction, recommendation, risks, need from the main agent. diff --git a/overlay/agents/poteto-agent.md b/overlay/agents/poteto-agent.md new file mode 100644 index 0000000..5d04ef6 --- /dev/null +++ b/overlay/agents/poteto-agent.md @@ -0,0 +1,17 @@ +--- +name: poteto-agent +description: Poteto child for a bounded implementation, investigation, or review task +systemPromptMode: append +inheritProjectContext: true +inheritSkills: false +defaultContext: fork +tools: read, grep, find, ls, bash, edit, write +--- + +Read `__SKILLS_PSTACK__/poteto-mode/SKILL.md` in full, including the Principles index. Read each leaf principle you apply. + +Execute the assigned task inline. Do not spawn children or use supervisor coordination. Follow an explicit read-only task without edits. For implementation, make the smallest coherent change and run the relevant checks yourself. + +Decide reversible details and report the choice. Test order, commit order, and confirmation that a diff is frozen do not require approval. If an irreversible action lacks authorization or genuine product ambiguity blocks the task, stop before that action and return the required decision in your normal result. Never treat silence as approval. + +Return the result, changed files, verification evidence, and unresolved risks. Report blockers honestly. Do not claim implementation success without the requested edits and verification. diff --git a/overlay/agents/researcher.md b/overlay/agents/researcher.md deleted file mode 100644 index ed4f71f..0000000 --- a/overlay/agents/researcher.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: researcher -description: pstack web and why investigator. Searches the web and synthesizes a cited research brief -tools: read, write, web_search, fetch_content, get_search_content -thinking: medium -systemPromptMode: replace -inheritProjectContext: true -inheritSkills: false -output: research.md -defaultProgress: true ---- - -You are the why-investigator for the public web. Evidence before narrative. Cite every claim. Name the gaps. - -Break the question into distinct angles. Use `web_search` with `queries` so one call covers them. Read search results first. Fetch full content only for the strongest sources. Prefer primary docs, specs, and direct evidence. Drop SEO filler. - -If asked to write output, write `research.md` at the provided path. Give a short direct answer, numbered findings with URLs, kept and dropped sources, and what you could not answer. - -If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the plan. Do not send routine completion handoffs. Return the research brief normally. diff --git a/overlay/agents/reviewer.md b/overlay/agents/reviewer.md deleted file mode 100644 index 795e58b..0000000 --- a/overlay/agents/reviewer.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: reviewer -description: pstack interrogate reviewer. Adversarial checks, no edits -tools: read, grep, find, ls -thinking: high -systemPromptMode: replace -inheritProjectContext: true -inheritSkills: false ---- - -You are an interrogate reviewer. Find real problems. You do not write files. You do not run bash. Include suggested test or git commands in your result without waiting for the parent to run them. - -Assume the stated intent is correct. Challenge the execution. Cite file paths and line numbers. Do not invent issues. Do not praise the code. If nothing qualifies, say `No issues found.` - -For each finding: severity (`critical`, `warning`, or `nit`), the problem, location, and evidence. Do not apply fixes. - -Report only problems caused or made reachable by the target, with source proof. Filter by evidence, not by severity padding. - -Return findings, missing evidence, and unresolved questions in the normal result. Do not use `contact_supervisor` or block with `need_decision` to confirm that the diff is frozen or have the parent run tests. Do not ask for clarification when the only conflict is review-only versus progress-writing. No-edit wins. diff --git a/overlay/agents/scout.md b/overlay/agents/scout.md deleted file mode 100644 index 47b5a5a..0000000 --- a/overlay/agents/scout.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: scout -description: pstack how-explorer. Fast codebase recon that writes context.md for handoff -tools: read, grep, find, ls, bash, write -thinking: low -systemPromptMode: replace -inheritProjectContext: true -inheritSkills: false -output: context.md -defaultProgress: true ---- - -You are the how-explorer. Gather facts another agent can act on. Trace code. Do not guess from names. - -Start from task-provided paths and symbols. Use `find` for path discovery. Prefer targeted search and selective `read`. Use `bash` only for non-interactive inspection. - -When asked to write output, write `context.md` at the provided path and keep the final response short. Cite exact file paths and line ranges. - -Return components found, flow, files read, boundaries, non-obvious things, and open questions. - -If runtime bridge instructions identify a safe supervisor target and you are blocked or need a decision, use `contact_supervisor` with `reason: "need_decision"` and wait for the reply. Use `reason: "progress_update"` only for meaningful progress or unexpected discoveries that change the plan. Do not send routine completion handoffs. Return the scout findings normally. diff --git a/overlay/agents/worker.md b/overlay/agents/worker.md deleted file mode 100644 index 40c4a34..0000000 --- a/overlay/agents/worker.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: worker -description: poteto-agent writer. Implements the assigned task with edits -aliases: developer, coder, implementer, develop -thinking: high -systemPromptMode: replace -inheritProjectContext: true -inheritSkills: false -tools: read, grep, find, ls, bash, edit, write, contact_supervisor -defaultContext: fork -defaultReads: context.md, plan.md -defaultProgress: true ---- - -You are the poteto-agent writer. Before any work, read `__SKILLS_PSTACK__/poteto-mode/SKILL.md` in full, including the Principles index. Navigate to a leaf `principle-*` skill whenever you apply that principle. - -You are the single writer thread. Execute the assigned task with narrow, coherent edits. The main agent and user remain the decision authority. Read inherited context, supplied files, and named seams first. - -Use `contact_supervisor` with `reason: "need_decision"` only for irreversible actions or genuine product ambiguity, and wait for the reply. If it is unavailable, report the required decision without taking that action. Decide reversible implementation details yourself and report the choice in your result. Test order, committing tests first, process sequencing, and reversible micro-decisions do not need supervisor approval. Do not send routine progress or completion handoffs. - -If the task expects file edits and you have not made them, do not return a success summary. Make the edits or report the blocker and that no edits were made. - -Return what you implemented, changed files, validation, open risks, and the recommended next step. diff --git a/overlay/settings.json b/overlay/settings.json index 87867c0..4911f69 100644 --- a/overlay/settings.json +++ b/overlay/settings.json @@ -1,4 +1,16 @@ { "defaultTools": ["read", "write", "edit", "bash", "grep", "find", "ls"], - "skills": [] + "skills": [], + "subagents": { + "disableBuiltins": true, + "agentOverrides": { + "scout": {"disabled": true}, + "researcher": {"disabled": true}, + "reviewer": {"disabled": true}, + "oracle": {"disabled": true}, + "worker": {"disabled": true}, + "delegate": {"disabled": true}, + "poteto-agent": {"disabled": false} + } + } } diff --git a/scripts/check-agent-discovery.mjs b/scripts/check-agent-discovery.mjs new file mode 100644 index 0000000..7fdfef6 --- /dev/null +++ b/scripts/check-agent-discovery.mjs @@ -0,0 +1,18 @@ +import assert from 'node:assert/strict'; +import { createRequire } from 'node:module'; +import { resolve } from 'node:path'; + +const packageDir = resolve(process.argv[2]); +const require = createRequire(resolve(packageDir, 'package.json')); +const { createJiti } = require('jiti'); +const jiti = createJiti(import.meta.url); +const { discoverAgents } = await jiti.import(resolve(packageDir, 'src/agents/agents.ts')); +const { agents } = discoverAgents(process.cwd(), 'both'); +assert.deepEqual(agents.map(agent => agent.name).sort(), ['poteto-agent']); +const [agent] = agents; +assert.equal(agent.source, 'user'); +assert.equal(agent.disabled, false); +assert.deepEqual(agent.tools, ['read', 'grep', 'find', 'ls', 'bash', 'edit', 'write']); +assert.match(agent.systemPrompt, /poteto-mode\/SKILL\.md/); +assert.match(agent.systemPrompt, /Do not spawn children or use supervisor coordination/); +console.log('check-agent-discovery ok: only poteto-agent; no children launched'); diff --git a/scripts/check-overlay.sh b/scripts/check-overlay.sh index d0781d0..91d8050 100755 --- a/scripts/check-overlay.sh +++ b/scripts/check-overlay.sh @@ -29,9 +29,9 @@ grep -q 'npm:@narumitw/pi-goal' install.sh || fail "install.sh must install npm: grep -q 'PI_STACK_SKIP_PACKAGES' install.sh || fail "install.sh must honor PI_STACK_SKIP_PACKAGES" grep -q 'backups/subagents' install.sh || fail "install.sh must name backups/subagents" grep -q 'agents/' install.sh || fail "install.sh must name agents/" +test -f overlay/agents/poteto-agent.md || fail "missing poteto-agent profile" for name in scout researcher oracle reviewer worker delegate; do - test -f "overlay/agents/${name}.md" || fail "missing overlay/agents/${name}.md" - grep -q "name: ${name}" "overlay/agents/${name}.md" || fail "overlay/agents/${name}.md must contain name: ${name}" + test ! -e "overlay/agents/${name}.md" || fail "retired overlay agent ${name} remains" done grep -q 'conform-skills.py' install.sh || fail "install.sh must run conform-skills.py" grep -q 'skills-pstack' install.sh || fail "install.sh must write skills-pstack" @@ -149,8 +149,10 @@ cat >"$home/.pi/agent/settings.json" <<'EOF' "subagents": { "defaultModel": "cursor/auto", "agentOverrides": { - "scout": {"model": "cursor/auto"}, - "oracle": {"model": "openai-codex/gpt-5.4"} + "scout": {"model": "cursor/auto", "disabled": false}, + "oracle": {"model": "openai-codex/gpt-5.4"}, + "planner": {"disabled": false}, + "poteto-agent": {"disabled": true} } } } @@ -229,6 +231,11 @@ if (overrides.get("scout") or {}).get("model") != "inherit": raise SystemExit("scout model was not inherit") if (overrides.get("oracle") or {}).get("model") != "openai-codex/gpt-5.4": raise SystemExit("oracle model pin was rewritten") +assert subs["disableBuiltins"] is True +for name in ("scout", "researcher", "oracle", "reviewer", "worker", "delegate"): + assert overrides[name]["disabled"] is True, name +assert overrides["poteto-agent"]["disabled"] is False +assert all(spec["disabled"] is True for name, spec in overrides.items() if name != "poteto-agent") PY grep -q '^name: poteto-mode$' "$home/.pi/agent/skills-pstack/poteto-mode/SKILL.md" || fail "install did not slug Poteto Mode" grep -q 'name: Poteto Mode' "$stub/skills/poteto-mode/SKILL.md" || fail "install edited upstream pstack" @@ -253,12 +260,16 @@ grep -F -q "$root" "$home/.pi/agent/bin/update-pstack" || fail "installed update if grep -F -q "$root" "$home/.pi/agent/bin/jig" "$home/.pi/agent/skills-pstack/jig/SKILL.md"; then fail "installed Jig entry points depend on the source checkout" fi -test -f "$home/.pi/agent/agents/oracle.md" || fail "piped install did not write agents/oracle.md" -grep -q poteto-mode "$home/.pi/agent/agents/worker.md" || fail "worker.md must mention poteto-mode" +test -f "$home/.pi/agent/agents/poteto-agent.md" || fail "piped install did not write poteto-agent" +grep -q poteto-mode "$home/.pi/agent/agents/poteto-agent.md" || fail "poteto-agent must read poteto-mode" mkdir -p "$home/.pi/agent/npm/node_modules/pi-subagents/agents" printf '%s\n' 'UPSTREAM-ORACLE' >"$home/.pi/agent/npm/node_modules/pi-subagents/agents/oracle.md" printf '%s\n' 'USER-ORACLE' >"$home/.pi/agent/agents/oracle.md" +for name in scout researcher reviewer worker delegate; do + printf 'USER-%s\n' "$name" >"$home/.pi/agent/agents/$name.md" +done +printf 'USER-POTETO\n' >"$home/.pi/agent/agents/poteto-agent.md" stamp_n() { local d="$home/.pi/agent/backups/subagents" if [[ ! -d "$d" ]]; then @@ -280,21 +291,28 @@ fi grep -q '^custom goal prompt$' "$home/.pi/agent/prompts/goal.md" || fail "install removed a custom goal prompt" printf '%s\n' "$second_out" | grep -q 'keeping it' || fail "install did not warn about the custom goal prompt" cmp -s "$home/.pi/agent/pi-goal.json" "$tmp/pi-goal.after-custom" || fail "install overwrote existing pi-goal settings" -if grep -q USER-ORACLE "$home/.pi/agent/agents/oracle.md"; then - fail "dest oracle.md still USER-ORACLE" -fi -grep -q 'name: oracle' "$home/.pi/agent/agents/oracle.md" || fail "dest oracle.md is not the overlay" +for name in scout researcher reviewer worker delegate oracle; do + test ! -e "$home/.pi/agent/agents/$name.md" || fail "retired installed agent $name remains" +done +for name in scout researcher reviewer worker delegate; do + grep -R -q "USER-$name" "$home/.pi/agent/backups/subagents" || fail "missing backup for $name" +done +grep -R -q USER-POTETO "$home/.pi/agent/backups/subagents" || fail "missing poteto backup" +grep -q 'name: poteto-agent' "$home/.pi/agent/agents/poteto-agent.md" || fail "poteto-agent is not the overlay" grep -R -q USER-ORACLE "$home/.pi/agent/backups/subagents" || fail "backups missing USER-ORACLE" grep -R -q UPSTREAM-ORACLE "$home/.pi/agent/backups/subagents" || fail "backups missing UPSTREAM-ORACLE" stamps_after_replace="$(stamp_n)" [[ "$stamps_after_replace" -ge 1 ]] || fail "replace install created no stamp dir" -cp "$home/.pi/agent/agents/oracle.md" "$tmp/oracle.after-replace" +cp "$home/.pi/agent/agents/poteto-agent.md" "$tmp/poteto.after-replace" cp "$home/.pi/agent/settings.json" "$tmp/settings.after-replace" ( cd "$tmp" HOME="$home" PI_STACK="$root" PSTACK="$stub" PI_STACK_SKIP_PACKAGES=1 bash <"$root/install.sh" ) || fail "third piped install failed" -cmp -s "$home/.pi/agent/agents/oracle.md" "$tmp/oracle.after-replace" || fail "third install rewrote dest oracle.md" +cmp -s "$home/.pi/agent/agents/poteto-agent.md" "$tmp/poteto.after-replace" || fail "third install rewrote poteto-agent" +for name in scout researcher reviewer worker delegate oracle; do + test ! -e "$home/.pi/agent/agents/$name.md" || fail "third install restored $name" +done cmp -s "$home/.pi/agent/settings.json" "$tmp/settings.after-replace" || fail "third install changed converged settings.json" [[ "$(stamp_n)" == "$stamps_after_replace" ]] || fail "third install created a new stamp dir" diff --git a/scripts/check-subagents.sh b/scripts/check-subagents.sh index a0a016c..7a31bf6 100755 --- a/scripts/check-subagents.sh +++ b/scripts/check-subagents.sh @@ -15,18 +15,25 @@ if grep -q '`Task` is `pi -p`' overlay/AGENTS.md; then fail "AGENTS.md still maps Task to bash pi -p" fi +test -f overlay/agents/poteto-agent.md || fail "missing poteto-agent" for agent in scout worker reviewer oracle delegate researcher; do - test -f "overlay/agents/${agent}.md" || fail "missing overlay/agents/${agent}.md" + test ! -e "overlay/agents/${agent}.md" || fail "retired overlay agent ${agent} remains" done +python3 - <<'PY' +import json +from pathlib import Path +policy = json.loads(Path("overlay/settings.json").read_text())["subagents"] +assert policy["disableBuiltins"] is True +assert {p.stem for p in Path("overlay/agents").glob("*.md")} == {"poteto-agent"} +assert {name for name, spec in policy["agentOverrides"].items() if not spec["disabled"]} == {"poteto-agent"} +PY pkg="${HOME}/.pi/agent/npm/node_modules/pi-subagents" if command -v pi >/dev/null 2>&1 && [[ -d "$pkg" ]]; then pi list | grep -q 'npm:pi-subagents' || fail "pi list missing npm:pi-subagents" grep -q 'name: "subagent"' "$pkg/src/extension/index.ts" || fail "pi-subagents does not register subagent" grep -q 'name: "subagent_wait"' "$pkg/src/runs/background/wait-tool.ts" || fail "pi-subagents does not register subagent_wait" - for agent in scout worker reviewer oracle delegate researcher; do - test -f "$pkg/agents/${agent}.md" || fail "missing builtin agent ${agent}.md" - done + node scripts/check-agent-discovery.mjs "$pkg" || fail "live discovery is not poteto-only" grep -q 'Do not run `pi -p`' "${HOME}/.pi/agent/AGENTS.md" || fail "live AGENTS.md missing bash pi -p ban" grep -q 'subagent' "${HOME}/.pi/agent/APPEND_SYSTEM.md" || fail "live APPEND_SYSTEM.md missing subagent" fi @@ -34,7 +41,7 @@ fi test -f scripts/smoke-subagents.sh || fail "missing scripts/smoke-subagents.sh" grep -q -- '--tools subagent' scripts/smoke-subagents.sh || fail "smoke must pin parent tools to subagent" grep -q 'action doctor' scripts/smoke-subagents.sh || fail "smoke must call subagent doctor" -grep -q 'agent delegate' scripts/smoke-subagents.sh || fail "smoke must spawn a delegate child" +grep -q 'agent poteto-agent' scripts/smoke-subagents.sh || fail "smoke must select poteto-agent" if [[ "${PI_STACK_SMOKE:-}" == 1 ]]; then bash "$root/scripts/smoke-subagents.sh" || fail "live subagent smoke failed" diff --git a/scripts/smoke-subagents.sh b/scripts/smoke-subagents.sh index f637431..d7c5a3c 100755 --- a/scripts/smoke-subagents.sh +++ b/scripts/smoke-subagents.sh @@ -1,7 +1,4 @@ #!/usr/bin/env bash -# Live smoke: a parent pi -p must call the subagent tool from this overlay. -# 1) action doctor (no child LLM) -# 2) delegate child, async false, unique token set -euo pipefail root="$(cd "$(dirname "$0")/.." && pwd)" @@ -162,7 +159,7 @@ printf '%s\n' "$doctor_report" | grep -q 'builtin' || fail "doctor result missin echo "smoke spawn" spawn_json="$work/spawn.jsonl" spawn_err="$work/spawn.err" -spawn_prompt="Call the subagent tool exactly once with these fields: agent delegate, async false, context fresh, task: Reply with exactly ${token} and no other text. Do not call tools. After the child returns, print ${token} if it appears in the child output. If it failed, print the error." +spawn_prompt="Call the subagent tool exactly once with these fields: agent poteto-agent, async false, context fresh, task: Reply with exactly ${token} and no other text. Do not call tools. After the child returns, print ${token} if it appears in the child output. If it failed, print the error." run_parent "$spawn_prompt" "$spawn_json" "$spawn_err" 300 \ || fail "spawn pi -p failed\n$(cat "$spawn_err")\n$(tail -c 8000 "$spawn_json")" spawn_report="$(parse "$spawn_json" "$spawn_err")"