diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index bffe736..23d2abc 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "pstack", - "version": "0.15.25-shared.6", + "version": "0.15.25-shared.7", "description": "Shared pstack engineering workflows for Claude Code and Codex, with one configuration and host-specific runtime adapters.", "author": { "name": "Local adaptation; upstream Lauren Tan" diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 990901f..ad41835 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "pstack-codex", - "version": "0.15.25-shared.6", + "version": "0.15.25-shared.7", "description": "Shared pstack engineering workflows for Codex and Claude Code, with one configuration and native host adapters.", "author": { "name": "Lauren Tan; local Codex adaptation" diff --git a/ADAPTATION.md b/ADAPTATION.md index cad9a0c..fdcc04b 100644 --- a/ADAPTATION.md +++ b/ADAPTATION.md @@ -39,7 +39,11 @@ The 0.15.21 sync (upstream 0.15.16–0.15.21, #484, #486, #536, #538, #539, #570 The 0.15.25 sync (upstream 0.15.22–0.15.25, #633 and #634: #595, #597, #602, #604, #606, #609, #613, #615, #616, #628, #633) takes the `in-your-own-words` and `sharpen` skills with the local frontmatter and runtime-contract line, the shorter visual `ketchup` reply (host-rendered charts instead of `/visualize`), ketchup catch-ups at the end of autopilot ticks and replies, the restated attack-the-premise, fix-root-causes, make-operations-idempotent, and test-behavior principles, the cut marginal sections in interrogate's lead-judgment reference, swarm, and the migrate-callers and type-system-discipline principles, the always-on signal after a deep dig, the full-swarm-once review cadence in autopilot-full and multi-phase-plan, the principle-first rewrites of autopilot-full, autopilot-stack, and shipping, and Graphite's removal from `orch frontier set`. The per-job effort rule ("match the model to the job") becomes "match effort to the job" in poteto-mode's Subagents section: workers start from the resolved role and `reasoning_effort`, rise one step for the hardest work and drop one step for judgment or two or more for routine work, and pass the value only through each host's separate effort control (Codex `reasoning_effort`, the Claude Agent `effort` field, T3 `target.options`). It never changes a role's model, T3 target, or `xagent:` entry, so panels stay diverse. xagent workers originally kept their CLI's own setting; they now get the adjusted value through `bin/xagent --effort`. Upstream's urgency-based fast mode is skipped: fast mode and priority tiers cost more and stay off unless the user asks, which also matches the T3 overlay. The autopilot and shipping rewrites keep this fork's isolated host workers instead of Cursor cloud agents, the project harness instead of `control-ui`/`control-cli`, the selected state directory instead of the root agent's system-prompt store, an authorized host scheduler instead of `/loop 1h`, the installed playbook instead of `origin/main`, merges only under explicit merge authorization, `--auto` only on request, and replacement of a stuck agent only after its ownership is resolved. `orch frontier set` takes upstream's base-chain discovery through `gh` or `--forge origin` in place of the optional Graphite path, but keeps this fork's authoritative `--prs` list, which reads each PR's state and head SHA with `gh pr view` and so works from a detached worker worktree; `--prs` with `--forge origin` fails because Origin's list output carries no head SHA. The discovery path also carries local fixes for defects in upstream's version, found in independent review: `gh` queries pin `--repo` to the GitHub origin and drop PRs whose head repository is another fork, so a same-named fork branch never gets the local SHA; every list passes `--limit 1000` and fails when the result may be truncated, since `gh pr list` returns 30 rows by default; trunk comes from `origin/HEAD`, else from whichever of `main` and `master` exists, remote refs first, and fails when both or neither exist instead of assuming `main`; and `ssh://git@github.com/` origins are accepted alongside HTTPS and scp-style ones, here and in `worktree-audit.sh`. Recovery hints offer `--prs` only where it works, on GitHub. Origin's list output has no head repository, so `--forge origin` cannot drop same-named fork PRs; prefer `gh` or `--prs` where forks exist. Shipping reads and fixes the bottom PR's base before every merge, the first after a restart included, because a PR still targeting its merged parent merges into that branch. The T3 overlay treats a queued `WAITING`/`merge-queue` as a wait in Shipping, which stops only at `COMPLETE` or a blocker. The multi-phase-plan skeleton makes its rebase items depend on the execution playbook, because Autopilot-stack owners never rebase. `worktree-audit.sh` keeps its GitHub-only PR query, because Origin's list output has no head repository and the audit must not match a same-named fork branch. `poteto-agent.md` resolves poteto-mode from the Claude install record or the Codex plugin cache instead of `~/.cursor/plugins/`. The T3 overlay's no-polling watch-pr rule now covers Shipping as well as Babysit. The Cursor `/` menu note in the README is skipped. -Model tiering by role follows upstream again. Poteto-mode's Subagents section restores upstream's "Code delegates tier by difficulty" routing that earlier adaptations dropped: each code playbook's delegate reads its role, the hardest changes read `hardest tasks`, prose and judgment read `judgment and prose`, and verification workers read `swarm workers`. The models come from `config.json`, where every role still inherits the parent by default, instead of upstream's Cursor slug defaults, and effort still moves per job within the role's model. `how`, `why` and `reflect` name their role keys, such as `how explorer` and `reflect judgment`, so a configured role is the one they read. +Model tiering by role follows upstream again. Poteto-mode's Subagents section restores upstream's "Code delegates tier by difficulty" routing that earlier adaptations dropped: each code playbook's delegate reads its role, the hardest changes read `hardest tasks`, prose and judgment read `judgment and prose`, and verification workers read `verification workers`. The models come from `config.json`, where every role still inherits the parent by default, instead of upstream's Cursor slug defaults, and effort still moves per job within the role's model. `how`, `why` and `reflect` name their role keys, such as `how explorer` and `reflect judgment`, so a configured role is the one they read. + +`verification workers` is a local role with no upstream line. Upstream runs orchestrate's verifier and show-me-your-work's handback review on a different model family than the work. On Codex or Claude Code another family needs an `xagent:` entry, so verification takes its own role instead of sharing `swarm workers` with fan-out workers, and each host can point it at the other vendor while swarms keep their own worker. A swarm's verify lanes, as in autopilot's swarm-verify, and the handback review read it too. On T3 a candidate role picks the candidate whose resolved model family differs from the checked work's, because a provider name alone does not identify the family. + +Two local rules keep cross-vendor panels usable. Shared `auxiliary_panel_members` names external members whose unresolved outcome is a reported gap rather than a blocker, so a supporting vendor's outage does not stop a review its primary members finished; upstream reaches the same availability by falling back within a family, which xagent entries never do. Native agent definitions own their effort: on Codex and Claude Code a worker's effort goes to a native agent type only when its definition sets none, so `reasoning_effort` mainly reaches `xagent:` workers, whose CLIs otherwise run at the user's interactive default. setup-pstack proposes a cross-vendor layout for multi-party steps when another vendor's CLI is signed in, because this fork's `inherit-parent` defaults stay one family where upstream's defaults pair two. The orch store lock carries a local fix for three races that upstream still has at `e5136d82`: a writer killed between the exclusive open and its pid write left an empty lock that only `--force` could pass, two writers that saw the same dead holder could both take the lock, and a release could unlink the lock a `--force` writer had just put in its place. `acquireLock` now writes the pid to a private file and hard-links it into place, falling back to the exclusive open where hard links are unsupported. Every read-then-unlink of the lock, in a takeover or a release, runs behind a `.orch.lock.takeover` claim, and a takeover re-reads the holder before it unlinks. A writer that meets a live claim is refused with `is being released or replaced; retry`; a release that meets one retries every 10 ms, so `close` waits while a live claimant, even a stopped one, holds it. The fix and its multi-process race tests are adapted from michael-denyer/pstack-claude #219 (`eef8f7c6`) and #238 (`de804764`), MIT, Copyright (c) 2026 Michael Denyer, whose notice is added to `LICENSE`. That fork's TLA+ model and its retry when a lock vanishes before its holder is read are not taken. The lock lives in `skills/poteto-mode/scripts/orch/lock.ts`, with `UserError` and `errorCode` in `orch/errors.ts`, because this fork replaced upstream's lock wholesale and `store.ts` was already past 1,000 lines; its race tests live in `orch/lock.test.ts`, sharing `orch/store.test-helper.ts` with `orch.test.ts`. Each acquire also removes the private pid files and staged claims that a writer killed mid-claim leaves behind, judged by the pid in their names, which the kill-at-every-step test now checks. The frontier code stays in `store.ts` even though it is large, so upstream's edits there still merge file by file. Its GitHub remote parsing is `skills/poteto-mode/scripts/github-remote.ts`, moved out of upstream's `watch-pr/github.ts` so `orch` and `watch-pr` share one parser. diff --git a/README.md b/README.md index 457d799..a33be8d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Marketplace registration is needed only once per host. Host caches are generated - Claude Code entry: `/pstack:poteto-mode`. - Optional setup: `$pstack-codex:setup-pstack` or `/pstack:setup-pstack`. -Preferences are shared in `~/.config/pstack/config.json`. Roles inherit the main conversation unless configured; workers receive the resolved policy and do not need setup. Concrete model choices are host-scoped so one vendor's model ID never leaks into another host. The exception is an external agent's own model, such as `xagent:claude/claude-opus-5-5`: xagent hands it to that agent's CLI from either host, so it can be shared. Shared reasoning and panel-size preferences apply to both when the actual runtime supports them. Shared `required_panel_members` adds external agents such as `xagent:grok` to every panel on both hosts, and those entries are never silently skipped. See [the runtime contract](./references/runtime.md). +Preferences are shared in `~/.config/pstack/config.json`. Roles inherit the main conversation unless configured; workers receive the resolved policy and do not need setup. Concrete model choices are host-scoped so one vendor's model ID never leaks into another host. The exception is an external agent's own model, such as `xagent:claude/claude-opus-5-5`: xagent hands it to that agent's CLI from either host, so it can be shared. Shared reasoning and panel-size preferences apply to both when the actual runtime supports them. Shared `required_panel_members` adds external agents such as `xagent:grok` to every panel on both hosts, and those entries are never silently skipped. Shared `auxiliary_panel_members` marks external members, such as `xagent:gemini`, whose failure after a retry is reported as a gap instead of blocking a panel the other members finished. On Codex and Claude Code, an agent type whose definition sets its own effort keeps it; shared reasoning reaches the rest, including external agents. See [the runtime contract](./references/runtime.md). Examples below use `$skill` as a short reference to the bundled skill; in Claude Code invoke `/pstack:skill` or read its file through the host's skill interface. diff --git a/README.zh-CN.md b/README.zh-CN.md index f1e8510..6102218 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -192,6 +192,8 @@ pstack 本身不安装定时器;长任务流程也不保证会话退出或主 共享配置中的 `required_panel_members`(例如 `["xagent:grok", "xagent:gemini"]`)会把这些外部 Agent 追加到两个主控的每个评审组和默认评审组,单个评审组或主控覆盖都无法遗漏它们。评审组里的 `xagent:` 不会被替换成继承模型,也不会以 N-1 静默跳过;重试和失败报告规则见[运行时契约](./references/runtime.md)。 +共享配置中的 `auxiliary_panel_members`(例如 `["xagent:gemini"]`)把这些外部 Agent 标为辅助成员:重试一次后仍失败,只记为覆盖缺口,不阻塞其余成员已完成的评审组;它们仍不会被替换成别的模型。在 Codex 和 Claude Code 上,agent 定义里自己设了推理强度的子 Agent 保持定义里的值,共享的 `reasoning_effort` 作用于其余 worker,包括外部 Agent。 + | 配置值 | 本机执行入口 | |---|---| | `xagent:claude` | `claude` | diff --git a/bin/config.mjs b/bin/config.mjs index 789ec58..2f99053 100755 --- a/bin/config.mjs +++ b/bin/config.mjs @@ -22,6 +22,9 @@ const REASONING_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]); const DEFAULT_PANEL = ["inherit-parent", "inherit-parent"]; // External agents that must join every panel, so a per-panel or per-host list cannot leave them out. const REQUIRED_MEMBERS = "required_panel_members"; +// External agents whose unresolved outcome is reported as a gap instead of blocking their panel. +const AUXILIARY_MEMBERS = "auxiliary_panel_members"; +const MEMBER_LISTS = [REQUIRED_MEMBERS, AUXILIARY_MEMBERS]; export function getDefaultConfigPath(homeDir = homedir()) { return path.join(homeDir, ".config", "pstack", "config.json"); @@ -121,17 +124,19 @@ function validateEffort(policy, label) { } // null means unset, in a stored config as in a patch. -function validateRequiredMembers(policy, scope, label) { - if (!Object.hasOwn(policy, REQUIRED_MEMBERS)) return; - const field = `${label}.${REQUIRED_MEMBERS}`; - if (scope !== "common") throw new Error(`${field} is shared policy and cannot be set per host`); - const members = policy[REQUIRED_MEMBERS]; - if (members === null) return; - if (!Array.isArray(members) || members.length === 0) throw new Error(`${field} must be a nonempty array or null`); - for (const member of members) { - if (typeof member !== "string" || !XAGENT_VALUE.test(member)) throw new Error(`${field} entries must be xagent:[/]`); +function validateMemberLists(policy, scope, label) { + for (const key of MEMBER_LISTS) { + if (!Object.hasOwn(policy, key)) continue; + const field = `${label}.${key}`; + if (scope !== "common") throw new Error(`${field} is shared policy and cannot be set per host`); + const members = policy[key]; + if (members === null) continue; + if (!Array.isArray(members) || members.length === 0) throw new Error(`${field} must be a nonempty array or null`); + for (const member of members) { + if (typeof member !== "string" || !XAGENT_VALUE.test(member)) throw new Error(`${field} entries must be xagent:[/]`); + } + if (new Set(members).size !== members.length) throw new Error(`${field} entries must be unique`); } - if (new Set(members).size !== members.length) throw new Error(`${field} entries must be unique`); } function validatePolicy(policy, scope, label) { @@ -142,7 +147,7 @@ function validatePolicy(policy, scope, label) { validateRoles(policy.roles, scope, label); validatePanels(policy.panels, scope, label); validateEffort(policy, label); - validateRequiredMembers(policy, scope, label); + validateMemberLists(policy, scope, label); } function validateConfig(config) { @@ -157,7 +162,7 @@ function validateConfig(config) { function validatePatch(patch, scope, label) { requireObject(patch, label); - const allowed = new Set(["roles", "panels", "reasoning_effort", REQUIRED_MEMBERS]); + const allowed = new Set(["roles", "panels", "reasoning_effort", ...MEMBER_LISTS]); for (const key of Object.keys(patch)) { if (!allowed.has(key)) throw new Error(`${label}.${key} is not a supported update field`); } @@ -181,7 +186,7 @@ function validatePatch(patch, scope, label) { } } } - validateRequiredMembers(patch, scope, label); + validateMemberLists(patch, scope, label); if (Object.hasOwn(patch, "reasoning_effort") && patch.reasoning_effort !== null && !REASONING_EFFORTS.has(patch.reasoning_effort)) { throw new Error(`${label}.reasoning_effort must be one of ${[...REASONING_EFFORTS].join(", ")} or null`); } @@ -288,7 +293,7 @@ function applyPatch(policy, patch) { }); } } - for (const key of ["reasoning_effort", REQUIRED_MEMBERS]) { + for (const key of ["reasoning_effort", ...MEMBER_LISTS]) { if (!Object.hasOwn(patch, key)) continue; if (patch[key] === null) delete policy[key]; else policy[key] = cloneJson(patch[key]); @@ -328,6 +333,7 @@ export function showConfig({ configPath = getDefaultConfigPath(), host } = {}) { roles: { ...config.roles, ...hostPolicy.roles }, panels: Object.fromEntries(Object.entries(panels).map(([name, panel]) => [name, withRequired(panel)])), [REQUIRED_MEMBERS]: [...required], + [AUXILIARY_MEMBERS]: [...(config[AUXILIARY_MEMBERS] ?? [])], reasoning_effort: hostPolicy.reasoning_effort ?? config.reasoning_effort ?? null, defaultModel: "inherit-parent", defaultPanel: withRequired(DEFAULT_PANEL), diff --git a/references/claude-runtime.md b/references/claude-runtime.md index e474121..b32db44 100644 --- a/references/claude-runtime.md +++ b/references/claude-runtime.md @@ -3,7 +3,7 @@ Read [the shared runtime](./runtime.md) first. This file defines only Claude Code behavior. Use the current tool schemas even when an installed CLI version differs from the version used to validate this package. - Entry points are `/pstack:poteto-mode`, `/pstack:setup-pstack`, and other `/pstack:` names. The same `skills/` files are used by Codex. Do not call `$pstack-codex:*` as Claude commands. -- Resolve preferences with `node /bin/config.mjs show --host claude`. Default to the main conversation's model. For shared agents, frontmatter `model: inherit` preserves inheritance. Use a concrete per-call model only when the actual Agent schema and account support it. Claude aliases/model IDs are not Cursor slugs or Codex IDs; GPT/Grok models require a separately configured, authorized provider/bridge and must not be assumed available; `xagent:` policy entries are that bridge for local agent CLIs (see the shared runtime). Pass a worker's effort, including poteto-mode's per-job adjustment, through the Agent tool's separate `effort` field when its schema exposes one; otherwise inherit session effort. +- Resolve preferences with `node /bin/config.mjs show --host claude`. Default to the main conversation's model unless the selected agent type's definition sets one. For shared agents, frontmatter `model: inherit` preserves inheritance. Use a concrete per-call model only when the actual Agent schema and account support it. Claude aliases/model IDs are not Cursor slugs or Codex IDs; GPT/Grok models require a separately configured, authorized provider/bridge and must not be assumed available; `xagent:` policy entries are that bridge for local agent CLIs (see the shared runtime). Pass a worker's effort, including poteto-mode's per-job adjustment, through the Agent tool's separate `effort` field when its schema exposes one, except to an agent type whose definition sets its own `effort`: that definition owns the worker's effort, as it owns the model when the role is `inherit-parent`. Without the field, the worker inherits session effort. - Use Claude's actual `Agent` tool with its supported `subagent_type`; available types can include `general-purpose`, `Explore`, `pstack:poteto-agent`, and `pstack:comment-sicko`. The two plugin agent files are native Claude definitions. The comment reviewer has only Read/Grep/Glob and returns proposals, not edits. The general workflow agent reads the same poteto-mode and shared configuration as the parent. - Respect the current nesting and concurrency limits. Select background execution only when the tool supports it. Track returned IDs and actual completion notifications/output, and inspect artifacts before accepting results. Do not call Codex `collaboration.*`, assume an empty output means success, or interrupt merely to tidy the agent list. If a role cannot delegate, it performs feasible scoped work and returns evidence. - In a one-shot/headless parent (`claude -p`), join external workers before the final reply. Run parallel xagent commands with `&` inside one foreground Bash call and `wait` for every returned PID; give that call a timeout longer than the worker deadlines and termination grace. Use a native blocking wait only when its current schema actually provides one. Ending with a promise to receive background notifications can exit the parent and cancel those workers; a Monitor or shell sentinel is not a substitute for collecting their terminal results. diff --git a/references/codex-runtime.md b/references/codex-runtime.md index 4d40d51..631774b 100644 --- a/references/codex-runtime.md +++ b/references/codex-runtime.md @@ -3,7 +3,7 @@ Read [the shared runtime](./runtime.md) first. This file defines only Codex-specific behavior. - Entry points keep the existing namespace, such as `$pstack-codex:poteto-mode` and `$pstack-codex:setup-pstack`. -- Resolve preferences with `node /bin/config.mjs show --host codex`. Validate concrete IDs and effort against the current collaboration schema. Fixed-model roles cannot be overridden. `inherit-parent`/`auto` omit the model field. Pass `reasoning_effort`, including poteto-mode's per-job adjustment, only if the selected role and actual schema accept it. +- Resolve preferences with `node /bin/config.mjs show --host codex`. Validate concrete IDs and effort against the current collaboration schema. Fixed-model roles cannot be overridden. `inherit-parent`/`auto` omit the model field. Pass `reasoning_effort`, including poteto-mode's per-job adjustment, only if the selected role and actual schema accept it and the role's definition sets no `model_reasoning_effort`; a definition that sets one owns the worker's effort. - Use exposed collaboration tools, which may include `spawn_agent`, `send_message`, `followup_task`, `list_agents`, `wait_agent`, and `interrupt_agent`. Use the real `agent_type` and available role names. Do not send Claude/Cursor-only fields such as `subagent_type`, `run_in_background`, `readonly`, `environment`, or `cloud_base_branch`. - `agents/poteto-agent.md` and `agents/comment-sicko.md` are prompt templates here, not registered Codex roles. Pass the file pointer to an appropriate supported role. Claude frontmatter in those shared files does not register a Codex role or enforce its tools; enforce scope through the selected host role and brief. - Close children only after a final answer, explicit completion event, or confirmed completed/failed/canceled status. Preserve host-specific cancellation and progress rules. diff --git a/references/runtime.md b/references/runtime.md index 8de8035..4c0e41f 100644 --- a/references/runtime.md +++ b/references/runtime.md @@ -27,11 +27,11 @@ node /bin/config.mjs show --host codex Resolve `` from this skill's installed path. The canonical configuration is `~/.config/pstack/config.json`, outside host plugin caches. If the file is absent, the helper returns inherited defaults without writing anything. Only setup or an explicit configuration request writes preferences. Do not ask every worker to run setup. -Shared `roles`, `panels`, `reasoning_effort`, and `required_panel_members` define policy. Codex and Claude Code apply their respective host overrides from `hosts.codex` and `hosts.claude`; Antigravity's `show` view ignores both and returns only common policy. A T3 session applies the optional `hosts.t3` section instead, and ignores `hosts.codex` and `hosts.claude` whichever host runs it. Shared model choices are `inherit-parent`, `auto`, or an `xagent:[/]` entry (below); other concrete model IDs belong only in `hosts.codex` or `hosts.claude`, and T3 targets `/` only in `hosts.t3`. Missing roles inherit the main conversation; a missing panel uses the helper's `defaultPanel`, two independent inherited-model attempts plus any required panel members. Model availability is validated against the running host, not against upstream names or this JSON schema. A requested unavailable model is an unresolved choice, not permission to silently substitute. Never splice reasoning effort into a model ID. In Antigravity, `reasoning_effort` is a displayed shared preference only; use it only if the current host exposes compatible support. +Shared `roles`, `panels`, `reasoning_effort`, `required_panel_members`, and `auxiliary_panel_members` define policy. Codex and Claude Code apply their respective host overrides from `hosts.codex` and `hosts.claude`; Antigravity's `show` view ignores both and returns only common policy. A T3 session applies the optional `hosts.t3` section instead, and ignores `hosts.codex` and `hosts.claude` whichever host runs it. Shared model choices are `inherit-parent`, `auto`, or an `xagent:[/]` entry (below); other concrete model IDs belong only in `hosts.codex` or `hosts.claude`, and T3 targets `/` only in `hosts.t3`. Missing roles inherit the main conversation; a missing panel uses the helper's `defaultPanel`, two independent inherited-model attempts plus any required panel members. Model availability is validated against the running host, not against upstream names or this JSON schema. A requested unavailable model is an unresolved choice, not permission to silently substitute. Never splice reasoning effort into a model ID. On Codex and Claude Code, a native agent type's own definition owns its effort when it sets one, and its model when the role is `inherit-parent`; the effective `reasoning_effort` reaches every other worker, including `xagent:` workers through `--effort`. The host adapter names the definition fields. In Antigravity, `reasoning_effort` is a displayed shared preference only; use it only if the current host exposes compatible support. A value `xagent:` (for example `xagent:grok`) names an external agent CLI, not a host model, so it is valid in shared policy. `xagent:/` (for example `xagent:claude/claude-opus-5-5`) also pins that CLI's own model; the model belongs to the agent, not the host, so it is shared policy too. Never pass either as a subagent `model`. Run that worker with `/bin/xagent [/] [--effort ]`, passing everything after `xagent:` as the first argument and the worker's effort as `--effort` (omitted when there is no effective value), only when the selected host exposes the required process execution capability and the task authorizes delegation, as specified in the bundled [xagent skill](../skills/xagent/SKILL.md): `ro` for reviewers, judges, and explorers; `rw` for writers. The parent gives every external worker, including readers, an exclusively owned worktree at the intended revision and every attempt a new output directory. Give it the same standalone brief a native worker would get. Its evidence is process completion, `meta.json` completed/status, its recorded `model`, `effort` and `resolved_models`, and `result.md`, held to the same standard as a native worker's result; a `PASS` still needs the parent's own check. Reject read-only violations and unavailable snapshots without resetting a shared checkout. -Shared `required_panel_members` lists `xagent:` entries that Codex and Claude Code `show` append to every effective panel and to `defaultPanel`, so no per-panel or host override can leave them out. Antigravity's read-only view also displays these common entries, but does not start them; apply the delegation rules above only when the host's actual tools and the task authorization support it. On hosts that execute a panel, run every entry of the effective panel; a pool such as `arena cross-judge pool` still selects one. An `xagent:` entry is never replaced by an inherited model or another agent and never dropped to finish with N-1. Unless the user set a time limit, give an external worker at least xagent's 900-second default. A pinned model that the CLI reports it did not run is `DROPOUT` with reason `model_mismatch`, never a quiet substitute. On `DROPOUT`, inspect partial changes and rerun once into a new output directory; without a user-set limit, double the timeout when the first attempt timed out. A second `DROPOUT`, `BLOCKED`, a missing CLI, or an agent xagent rejects is an unresolved required outcome: report it by agent name, keep it out of coverage and consensus claims, and do not call the panel or task complete unless the user waives it. +Shared `required_panel_members` lists `xagent:` entries that Codex and Claude Code `show` append to every effective panel and to `defaultPanel`, so no per-panel or host override can leave them out. Antigravity's read-only view also displays these common entries, but does not start them; apply the delegation rules above only when the host's actual tools and the task authorization support it. On hosts that execute a panel, run every entry of the effective panel; a pool such as `arena cross-judge pool` still selects one. An `xagent:` entry is never replaced by an inherited model or another agent and never dropped to finish with N-1. Unless the user set a time limit, give an external worker at least xagent's 900-second default. A pinned model that the CLI reports it did not run is `DROPOUT` with reason `model_mismatch`, never a quiet substitute. On `DROPOUT`, inspect partial changes and rerun once into a new output directory; without a user-set limit, double the timeout when the first attempt timed out. A second `DROPOUT`, `BLOCKED`, a missing CLI, or an agent xagent rejects is an unresolved required outcome: report it by agent name, keep it out of coverage and consensus claims, and do not call the panel or task complete unless the user waives it. The one exception is a panel entry also listed in shared `auxiliary_panel_members`: it gets the same retry, but its unresolved outcome is a reported gap that does not block a panel whose other members completed. Name it as a gap, keep it out of coverage and consensus claims, and never replace it with another model or agent. The listing never makes a role or any other panel member optional. Each worker brief carries the selected host, plugin root, configuration path, resolved role/panel policy, scope, and verification predicate. A read-only child without command execution uses this supplied snapshot. If none was supplied, it may read the single shared JSON file and apply the host-over-common precedence; an absent file means inherited defaults. It must not invent a Bash tool or run setup. Use the same policy snapshot throughout one task unless the user changes it. A worker inherits this policy; it does not edit shared preferences. Same-family reviewers are independent attempts, not cross-family evidence. diff --git a/scripts/check-fork.mjs b/scripts/check-fork.mjs index 21e1073..aa8c67d 100644 --- a/scripts/check-fork.mjs +++ b/scripts/check-fork.mjs @@ -167,6 +167,27 @@ export const REQUIRED = [ hint: "fast mode stays off unless the user asks; urgency does not turn it on", section: "upstream-behavior-retained", }, + { + id: "verification-workers-role", + file: "skills/poteto-mode/SKILL.md", + pattern: /Verification workers, including a swarm's verify lanes and the \*\*show-me-your-work\*\* handback review, read `verification workers`\./, + hint: "verifiers read their own role so each host can point it at another vendor", + section: "upstream-behavior-retained", + }, + { + id: "swarm-verify-role", + file: "skills/swarm/SKILL.md", + pattern: /Workers that verify another agent's work, as in a swarm-verify, read `verification workers` instead\./, + hint: "a swarm's verify lanes read verification workers, not swarm workers", + section: "upstream-behavior-retained", + }, + { + id: "handback-review-role", + file: "skills/show-me-your-work/SKILL.md", + pattern: /spawn a subagent on the `verification workers` role from the effective policy/, + hint: "the handback review runs on the verification workers role", + section: "upstream-behavior-retained", + }, { id: "t3-no-service-tier", file: "references/t3-runtime.md", diff --git a/scripts/check-fork.test.mjs b/scripts/check-fork.test.mjs index 61835e6..a6d6011 100644 --- a/scripts/check-fork.test.mjs +++ b/scripts/check-fork.test.mjs @@ -166,6 +166,9 @@ const DROPPED = [ ["autopilot-push-authorization", "skills/poteto-mode/playbooks/autopilot-full.md", "Within the program's push authorization, force-push", "Force-push"], ["autopilot-merge-authorization", "skills/poteto-mode/playbooks/autopilot-full.md", "Only the operator's explicit authorization to merge this queue, together with your clean verdict, permits the merge.", "Green CI alone never authorizes a merge."], ["fast-mode-on-request", "skills/poteto-mode/SKILL.md", "Fast mode and priority service tiers cost more, so use them only when the user asked.", "Use fast mode only when the job is urgent, meaning CI or trunk is red or a person is blocked on the result right now."], + ["verification-workers-role", "skills/poteto-mode/SKILL.md", "Verification workers, including a swarm's verify lanes and the **show-me-your-work** handback review, read `verification workers`.", ""], + ["swarm-verify-role", "skills/swarm/SKILL.md", "Workers that verify another agent's work, as in a swarm-verify, read `verification workers` instead.", ""], + ["handback-review-role", "skills/show-me-your-work/SKILL.md", "on the `verification workers` role from the effective policy, on a different available model family", "on a different model family"], ["t3-no-service-tier", "references/t3-runtime.md", "The preview adds no speed or service-tier option; do not add one unless the user asked.", ""], ["t3-catalog-preview", "references/t3-runtime.md", "config.mjs resolve --host t3", "removed-by-sync"], ["t3-worktree-isolation", "references/t3-runtime.md", 'isolation: "worktree"', "removed-by-sync"], diff --git a/scripts/config.test.mjs b/scripts/config.test.mjs index 20ad158..9796a8e 100644 --- a/scripts/config.test.mjs +++ b/scripts/config.test.mjs @@ -428,6 +428,64 @@ test("Given malformed or host-scoped required panel members, When update or show assert.match(shown.stderr, /required_panel_members/); }); +test("Given auxiliary panel members, When every host view runs show, Then each lists them and panels keep their configured entries", (t) => { + const dir = tempDir(); + t.after(() => rmSync(dir, { recursive: true, force: true })); + const configPath = path.join(dir, "config.json"); + const inputPath = path.join(dir, "patch.json"); + const config = validConfig(); + config.hosts.codex.panels["interrogate reviewers"] = ["inherit-parent", "xagent:claude", "xagent:gemini"]; + config.hosts.codex.panels["arena cross-judge pool"] = ["xagent:claude"]; + writeJson(configPath, config); + writeJson(inputPath, { auxiliary_panel_members: ["xagent:gemini"] }); + + const update = runCli(["update", "--input", inputPath, "--config", configPath]); + assert.equal(update.status, 0, update.stderr); + for (const host of ["codex", "claude", "t3", "antigravity"]) { + const effective = JSON.parse(runCli(["show", "--host", host, "--config", configPath]).stdout).effective; + assert.deepEqual(effective.auxiliary_panel_members, ["xagent:gemini"], host); + assert.deepEqual(effective.required_panel_members, [], host); + assert.deepEqual(effective.defaultPanel, ["inherit-parent", "inherit-parent"], host); + } + const codex = JSON.parse(runCli(["show", "--host", "codex", "--config", configPath]).stdout).effective; + assert.deepEqual(codex.panels["interrogate reviewers"], ["inherit-parent", "xagent:claude", "xagent:gemini"]); + assert.deepEqual(codex.panels["arena cross-judge pool"], ["xagent:claude"]); + + writeJson(inputPath, { auxiliary_panel_members: null }); + assert.equal(runCli(["update", "--input", inputPath, "--config", configPath]).status, 0); + assert.deepEqual(JSON.parse(runCli(["show", "--host", "codex", "--config", configPath]).stdout).effective.auxiliary_panel_members, []); + assert.equal(Object.hasOwn(JSON.parse(readFileSync(configPath, "utf8")), "auxiliary_panel_members"), false); +}); + +test("Given malformed or host-scoped auxiliary panel members, When update or show runs, Then they are rejected without writing", (t) => { + const dir = tempDir(); + t.after(() => rmSync(dir, { recursive: true, force: true })); + const configPath = path.join(dir, "config.json"); + const inputPath = path.join(dir, "patch.json"); + writeJson(configPath, validConfig()); + const original = readFileSync(configPath, "utf8"); + + for (const value of [[], "xagent:gemini", ["inherit-parent"], ["xagent:gemini", "xagent:gemini"], ["xagent:Gemini Pro"]]) { + writeJson(inputPath, { auxiliary_panel_members: value }); + const result = runCli(["update", "--input", inputPath, "--config", configPath]); + assert.notEqual(result.status, 0, JSON.stringify(value)); + assert.equal(readFileSync(configPath, "utf8"), original); + } + writeJson(inputPath, { auxiliary_panel_members: ["xagent:gemini"] }); + for (const host of ["codex", "claude", "t3"]) { + const hostUpdate = runCli(["update", "--host", host, "--input", inputPath, "--config", configPath]); + assert.notEqual(hostUpdate.status, 0, host); + assert.equal(readFileSync(configPath, "utf8"), original); + } + + const handWritten = validConfig(); + handWritten.hosts.codex.auxiliary_panel_members = ["xagent:gemini"]; + writeJson(configPath, handWritten); + const shown = runCli(["show", "--host", "codex", "--config", configPath]); + assert.notEqual(shown.status, 0); + assert.match(shown.stderr, /auxiliary_panel_members/); +}); + test("Given a malformed xagent entry in common policy, When update runs, Then it is rejected without writing", (t) => { const dir = tempDir(); t.after(() => rmSync(dir, { recursive: true, force: true })); diff --git a/scripts/pstack-host-e2e-native.test.py b/scripts/pstack-host-e2e-native.test.py index bfdc1c6..3fad5d1 100644 --- a/scripts/pstack-host-e2e-native.test.py +++ b/scripts/pstack-host-e2e-native.test.py @@ -621,7 +621,8 @@ def test_given_stub_hosts_when_exercised_then_launch_settings_prompt_rules_and_n self.assertIn(f"exclusive worktree at fixture base {report['base']} and have it leave its change uncommitted", prompt) self.assertIn(f"a native reviewer changes no files and runs python3 -B {ROOT / 'scripts/e2e-snapshot.py'} " "as its first and as its last shell command", prompt) - self.assertIn("pass an effort to every worker, native or xagent", prompt) + self.assertIn("pass an effort to every worker, native or xagent; dispatch each native worker as an agent type " + "whose definition sets no effort of its own", prompt) if host == "claude": self.assertIn("-p", launch["argv"]) self.assertIn("--no-session-persistence", launch["argv"]) diff --git a/scripts/pstack-host-e2e.py b/scripts/pstack-host-e2e.py index ef179fd..0d48f18 100644 --- a/scripts/pstack-host-e2e.py +++ b/scripts/pstack-host-e2e.py @@ -614,7 +614,8 @@ def exercise(host, run, host_timeout, check_timeout=30): host's file-edit tool (Write or Edit in Claude Code, apply_patch in Codex); a native reviewer changes no files and runs python3 -B {SNAPSHOT_TOOL} as its first and as its last shell command in that worktree, each as a command of its own. -When the effective policy sets reasoning_effort, pass an effort to every worker, native or xagent. +When the effective policy sets reasoning_effort, pass an effort to every worker, native or xagent; dispatch each native +worker as an agent type whose definition sets no effort of its own, so that effort applies. Report the resolved routes, actual worker receipt paths, findings, your own test output, and any gaps. End with PSTACK_E2E: PASS only if the repair, all configured reviews and your independent tests are complete, with no unresolved reproduced violation of the stated contract; otherwise PSTACK_E2E: FAIL. diff --git a/skills/poteto-mode/SKILL.md b/skills/poteto-mode/SKILL.md index 3c63e09..645e85a 100644 --- a/skills/poteto-mode/SKILL.md +++ b/skills/poteto-mode/SKILL.md @@ -91,11 +91,11 @@ The chat that receives `$poteto-mode` runs the playbook. Never spawn a `poteto-a For a worker using the full pstack workflow, include a pointer to this plugin's `agents/poteto-agent.md` prompt template. Review workflows use their own narrower templates. Read the effective policy from `node /bin/config.mjs show --host `; absent values inherit the parent, and model/effort overrides must be supported by the current role. -**Match the model to the role.** Code delegates tier by difficulty. Each code playbook's delegate, trivial mechanical edits included, reads its role (`feature`, `refactoring`, `bug-fix`, `perf-issue`, or `hillclimb`). The hardest changes (cross-cutting design, gnarly concurrency, subtle algorithms) read `hardest tasks`, whether the task needs judgment on vague intent or is a precisely specified sequence of steps to execute to the letter. Prose and judgment read `judgment and prose`. Verification workers read `swarm workers`. The routed skills (`how`, `why`, `reflect`, `swarm`, `arena`, `architect`, `interrogate`) read the roles and panels they name. A role absent from the effective policy inherits the parent. +**Match the model to the role.** Code delegates tier by difficulty. Each code playbook's delegate, trivial mechanical edits included, reads its role (`feature`, `refactoring`, `bug-fix`, `perf-issue`, or `hillclimb`). The hardest changes (cross-cutting design, gnarly concurrency, subtle algorithms) read `hardest tasks`, whether the task needs judgment on vague intent or is a precisely specified sequence of steps to execute to the letter. Prose and judgment read `judgment and prose`. Verification workers, including a swarm's verify lanes and the **show-me-your-work** handback review, read `verification workers`. The routed skills (`how`, `why`, `reflect`, `swarm`, `arena`, `architect`, `interrogate`) read the roles and panels they name. A role absent from the effective policy inherits the parent. Classify the current delegate's work, not the whole project's difficulty. After a hard design is settled, routine implementation returns to its ordinary code-playbook role. Keep `hardest tasks` only for implementation that still requires difficult reasoning. Complex architecture exploration uses `hardest architect runners` when that panel is configured, otherwise the existing `architect runners` panel. An already running worker keeps its model; start a fresh worker for a new phase under the fresh-worker rule below. In each brief record the phase, difficulty and one-sentence reason for the selected role or panel. -On T3, a role may declare `candidates`. Resolve exactly one through the T3 helper: prefer the parent provider when listed, otherwise the first configured candidate. To request another configured provider for a different model perspective, pass `--provider` and record the reason. Do not spawn every candidate or retry a failed selection on another candidate. Explicit `@latest` family selectors use the task's live catalog and resolve to exact model IDs before dispatch; reuse those resolved IDs throughout this task. Native host policy and exact pinned targets keep their existing meaning. +On T3, a role may declare `candidates`. Resolve exactly one through the T3 helper: prefer the parent provider when listed, otherwise the first configured candidate. To request another configured provider for a different model perspective, pass `--provider` and record the reason. A `verification workers` candidate role selects, with `--provider`, a candidate whose resolved model is a different family from the checked work's. A provider name alone does not identify the family; when every candidate resolves to that family, label the review same-family. Do not spawn every candidate or retry a failed selection on another candidate. Explicit `@latest` family selectors use the task's live catalog and resolve to exact model IDs before dispatch; reuse those resolved IDs throughout this task. Native host policy and exact pinned targets keep their existing meaning. **Match effort to the job.** Before each spawn, start from the role's resolved policy and the effective `reasoning_effort`, then pick the effort the job needs. The policy order is `low`, `medium`, `high`, `xhigh`, `max`; one step above `high` is `xhigh`. Raise it one step, up to `max`, for the hardest or subtlest work. Lower it one step for judgment and two or more steps, down to `low`, for routine work. Verification workers keep the resolved effort. Change only the effort, never the role's model, T3 target, or `xagent:` entry, so a diverse panel stays diverse. Pass it only through the separate effort control the host adapter names, never inside a model ID. With no effective value or no such control, the worker inherits and the reply says so. An `xagent:` worker gets the adjusted value through `bin/xagent --effort`, and with no effective value runs at its CLI's own setting. If the host rejects the adjusted value, do not try another one. Use the resolved value and say so. Fast mode and priority service tiers cost more, so use them only when the user asked. diff --git a/skills/poteto-mode/playbooks/orchestrate.md b/skills/poteto-mode/playbooks/orchestrate.md index 0c2e88f..21f4995 100644 --- a/skills/poteto-mode/playbooks/orchestrate.md +++ b/skills/poteto-mode/playbooks/orchestrate.md @@ -86,7 +86,7 @@ A dependency is a context relay, not just ordering. Undeclared upstream context #### Verification -Scale verification to the unit. When VERIFY is a single cheap command, the worker runs it and reports the output, and the coordinator spot-checks receipts. A dedicated verifier agent (on a different available model family (or explicitly labeled same-family independent review) than the worker) is for units whose verification is expensive, judgment-laden, or high-blast-radius. A verifier agent whose entire product would be rerunning one command is ceremony, not verification. +Scale verification to the unit. When VERIFY is a single cheap command, the worker runs it and reports the output, and the coordinator spot-checks receipts. A dedicated verifier agent (on the `verification workers` role, a different available model family (or explicitly labeled same-family independent review) than the worker) is for units whose verification is expensive, judgment-laden, or high-blast-radius. A verifier agent whose entire product would be rerunning one command is ceremony, not verification. Write ledger rows with `orch ledger record`. Check the current PR and head SHA with `orch ledger check`. `ledger.tsv`, one row per verdict, keyed by PR number plus head SHA: `live-ui-verified | unit-test-verified | type-check-only | verifier-blocked | verifier-failed`. CI green is an input to a verdict, not a verdict. Behavioral work needs better than `type-check-only`. `verifier-blocked` is not a pass. Respawn when the environment heals. `verifier-failed` gets a fix unit, not a re-verify. A worker may self-report. A verifier overrides it on the same key. A new head SHA voids the row, so re-verify after restack. The ledger answers "was this verified", not memory and not the transcript. diff --git a/skills/setup-pstack/SKILL.md b/skills/setup-pstack/SKILL.md index 6a1754e..3137b6d 100644 --- a/skills/setup-pstack/SKILL.md +++ b/skills/setup-pstack/SKILL.md @@ -20,7 +20,7 @@ In Antigravity, run `node /bin/config.mjs show --host antigravity` 1. Identify the current host from its actual tools and read the effective configuration with `node /bin/config.mjs show --host `. Missing configuration means all roles inherit and panels use two independent attempts; setup is optional. 2. For a setup request, run `node /bin/config.mjs init`. It creates `~/.config/pstack/config.json` only when absent and imports any legacy `~/.codex/pstack/models.json` or `~/.claude/pstack/models.json` into that host's overrides. Existing shared configuration is authoritative. Legacy files remain untouched and are no longer runtime sources. 3. Honor preferences already given. Shared roles and panel entries can use only `inherit-parent`, `auto`, or `xagent:` (an external agent CLI dispatched through xagent, for example `xagent:grok`), optionally with that CLI's own model as `xagent:/`, for example `xagent:claude/claude-opus-5-5`; check the model with that CLI, such as `grok models` or `pi --list-models`, before saving it. Any other concrete model goes into the current host's override after checking actual availability and role constraints. Keep reasoning separate. Do not infer IDs from upstream brand names or silently substitute for an unavailable explicit choice. Preserve the other host's choices. -4. Write a small JSON patch containing only the requested `roles`, `panels`, `reasoning_effort`, and/or `required_panel_members`. Apply shared preferences with `node /bin/config.mjs update --input `; add `--host codex`, `--host claude`, or `--host t3` for host-specific overrides. The helper merges per-role changes atomically. A null role/panel or null effort removes that override and restores inheritance from the next layer. Delete the scratch patch after readback, not the evidence. Concurrent edits fail visibly rather than overwriting each other. +4. Write a small JSON patch containing only the requested `roles`, `panels`, `reasoning_effort`, `required_panel_members`, and/or `auxiliary_panel_members`. Apply shared preferences with `node /bin/config.mjs update --input `; add `--host codex`, `--host claude`, or `--host t3` for host-specific overrides. The helper merges per-role changes atomically. A null role/panel or null effort removes that override and restores inheritance from the next layer. Delete the scratch patch after readback, not the evidence. Concurrent edits fail visibly rather than overwriting each other. 5. Read back both hosts with `show --host codex` and `show --host claude`, plus `show --host t3` when a T3 section exists. Report the shared path and effective choices. Validation of JSON/model names is not proof of model execution. Workers inherit the resolved policy from the parent; do not configure each worker separately. 6. Inspect the current project's existing verify skill or harness. If neither exists, mention `create-verification-skill` once; generate and exercise one only when requested. @@ -34,6 +34,12 @@ Example shared patch, usable on both hosts: } ``` -Role names follow the bundled workflow: the code playbook roles `feature`, `refactoring`, `bug-fix`, `perf-issue`, and `hillclimb`; `hardest tasks` for the hardest changes; `judgment and prose`; `how explorer`, `how explainer`, `why investigators`, `why synthesizer`, `reflect judgment`, and `reflect tooling`; and `swarm workers`, which verification workers also read. Panels include `arena runners`, `arena cross-judge pool`, `architect runners`, optional `hardest architect runners`, and `interrogate reviewers`. Use the role a workflow actually requests; do not populate unused choices. +Role names follow the bundled workflow: the code playbook roles `feature`, `refactoring`, `bug-fix`, `perf-issue`, and `hillclimb`; `hardest tasks` for the hardest changes; `judgment and prose`; `how explorer`, `how explainer`, `why investigators`, `why synthesizer`, `reflect judgment`, and `reflect tooling`; `swarm workers` for swarm fan-out; and `verification workers` for verifier agents, a swarm's verify lanes, and the show-me-your-work handback review. Set `verification workers` per host to a model family other than that host's writers, for example `xagent:claude` under `hosts.codex`; on T3, list candidates from different model families. Panels include `arena runners`, `arena cross-judge pool`, `architect runners`, optional `hardest architect runners`, and `interrogate reviewers`. Use the role a workflow actually requests; do not populate unused choices. Shared `required_panel_members`, for example `["xagent:grok", "xagent:gemini"]`, adds those external agents to every panel and the default panel on both hosts. It is rejected in a host override; `null` removes it. + +Shared `auxiliary_panel_members`, for example `["xagent:gemini"]`, marks external panel members whose failure after the retry is a reported gap instead of a blocker. It adds no member to any panel, so list the agent in the panels it should join. It is rejected in a host override; `null` removes it. + +Multi-party steps are the panels above, `reflect judgment` with `reflect tooling`, and `verification workers`. Upstream gives each of them two model families by default; this fork's `inherit-parent` defaults stay one family until configured. When another vendor's CLI is installed and signed in, propose a cross-vendor layout for them: the host's own model plus the other vendor through `xagent:` in each panel, and only the other vendor in `arena cross-judge pool`, since arena picks a single judge from it. Mark a supporting vendor auxiliary rather than required when it should not hold up a review. Confirm the proposal with the user before writing it. + +On Codex and Claude Code, `reasoning_effort` reaches `xagent:` workers and native agent types whose definition sets no effort; a definition that sets its own effort keeps it. Without a value, an external CLI runs at its own default, which may be the user's interactive setting. diff --git a/skills/show-me-your-work/SKILL.md b/skills/show-me-your-work/SKILL.md index 51ef9cc..4201128 100644 --- a/skills/show-me-your-work/SKILL.md +++ b/skills/show-me-your-work/SKILL.md @@ -65,7 +65,7 @@ Correct the log, not the story. The audit never edits or removes a row, even an ## Cross-model review of the trail -Before handing back, spawn a subagent on a different available model family (or explicitly labeled same-family independent review) from the one that did the work. Self-review is not a substitute. The subagent reads the audit trail and the run's transcript, then flags what the user should pay attention to. Not a redo of the work, a scan for what's suboptimal or risky. Set each worker's reasoning effort for the job, per the Subagents section of the **poteto-mode** skill. +Before handing back, spawn a subagent on the `verification workers` role from the effective policy, on a different available model family (or explicitly labeled same-family independent review) from the one that did the work. Self-review is not a substitute. The subagent reads the audit trail and the run's transcript, then flags what the user should pay attention to. Not a redo of the work, a scan for what's suboptimal or risky. Set each worker's reasoning effort for the job, per the Subagents section of the **poteto-mode** skill. - Decisions logged with weak or absent evidence. - Verification steps skipped or claimed without proof in the transcript. diff --git a/skills/swarm/SKILL.md b/skills/swarm/SKILL.md index 2e458af..5f20c8d 100644 --- a/skills/swarm/SKILL.md +++ b/skills/swarm/SKILL.md @@ -20,7 +20,7 @@ Open a todolist with one entry per phase before launching anything. 1. State the done predicate and the artifact or report the swarm must return. 2. Choose the shape. Partition into slices, race N workers on identical briefs, or mix both. For a race or mixed shape, declare `first pass`, `rank all`, or `best-of` before spawning. -3. Pick the worker model from `swarm workers` in the effective policy from `node /bin/config.mjs show --host ` when present. Otherwise use `inherit-parent`. For a model race, name each arm's model up front. Set each worker's reasoning effort for the job, per the Subagents section of the **poteto-mode** skill. +3. Pick the worker model from `swarm workers` in the effective policy from `node /bin/config.mjs show --host ` when present. Otherwise use `inherit-parent`. Workers that verify another agent's work, as in a swarm-verify, read `verification workers` instead. For a model race, name each arm's model up front. Set each worker's reasoning effort for the job, per the Subagents section of the **poteto-mode** skill. 4. Give each worker its own writable output when it writes. When workers verify or measure commits, name the exact SHAs in each brief. Measurement briefs also name the sample count, what constitutes a sample, and execution order. Require the worker to record those SHAs and the method in its result. ## Phase B: Fan out