@fro.bot/systematic 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/HARNESSES.md ADDED
@@ -0,0 +1,97 @@
1
+ # Harnesses
2
+
3
+ This is the evidence registry for Systematic's harness-portability work. **Every tool or mechanism named here is backed by an in-repo path with line numbers, installed or cloned source, or an authoritative URL.** If the supplied research did not verify a capability, it is explicitly marked **UNVERIFIED**; absence of evidence is not evidence of absence.
4
+
5
+ **Tiers.** Tier 1 means Systematic ships a controlled adapter: OpenCode and Pi. Tier 2 means the harness is documented for portability but has no Systematic adapter: Claude Code, Codex CLI, Gemini CLI, and GitHub Copilot.
6
+
7
+ ## Capability matrix
8
+
9
+ The four capability rows use the vocabulary in the [OpenCode profile](skills/using-systematic/references/opencode-profile.md#L3-L8) and [Pi profile](skills/using-systematic/references/pi-profile.md#L3-L8).
10
+
11
+ | Capability | OpenCode (Tier 1) | Pi (Tier 1) | Claude Code (Tier 2) | Codex CLI (Tier 2) | Gemini CLI (Tier 2) | GitHub Copilot (Tier 2) |
12
+ |---|---|---|---|---|---|---|
13
+ | Subagent delegation | `task`, including `subagent_type`, resume, and background execution [OC-1] | `systematic_delegate({agent, task})`; sequential, capped at 20 turns [PI-1] | `context: fork` for skills; `subagent_type` is **UNVERIFIED** [CC-1] | **UNVERIFIED** [U] | **UNVERIFIED** [U] | Built-in/custom agents [GH-1][GH-2] |
14
+ | Blocking user interaction | `question` [OC-2] | No native blocking tool; numbered-chat fallback [PI-2] | `AskUserQuestion` [CC-2] | `request_user_input`; blocking and root-thread-only [CX-1][CX-2] | `ask_user`; pauses until answers [GE-1][GE-2] | No dedicated tool name verified; plan-mode clarification and `--no-ask-user` are documented [GH-3][GH-4] |
15
+ | Task tracking | `todowrite` [OC-3] | No native mechanism; visible list fallback [PI-2] | `TodoWrite` is deprecated/disabled by default; `TaskCreate`/`TaskGet`/`TaskList`/`TaskUpdate` replace it [CC-3][CC-4] | **UNVERIFIED** [U] | **UNVERIFIED** [U] | No `TodoWrite` equivalent verified; cloud-agent tasks/sessions API is documented [GH-5] |
16
+ | Skill loading | Skills become commands and `systematic_skill` is registered [OC-4][OC-5] | `systematic_skill` adapter and Pi-native activation [PI-3][PI-4] | Skill tool, `SKILL.md`, and `.claude/skills/` [CC-5][CC-6] | **UNVERIFIED** [U] | **UNVERIFIED** [U] | `SKILL.md` skills [GH-6] |
17
+ | Skills-file support | `SKILL.md` is loaded by the Systematic skill path [OC-4] | `pi.skills` ships `./skills`, including `SKILL.md` discovery [PI-4][PI-5] | `SKILL.md` and `.claude/skills/` [CC-5][CC-6] | **UNVERIFIED** [U] | **UNVERIFIED** [U] | `SKILL.md` [GH-6] |
18
+
19
+ `[U]` means the capability was not checked in the supplied research pack. It is not a claim that the capability does not exist.
20
+
21
+ ## OpenCode — Tier 1 shipped adapter
22
+
23
+ OpenCode is the primary controlled integration. Its profile defines delegation, blocking interaction, task tracking, and skill loading [OC-P]. The underlying source registers `task` with specialized-agent, resume, and background fields [OC-1], `question` as a user-facing tool [OC-2], and `todowrite` as a built-in tool [OC-3]. Systematic converts bundled skills into commands in `src/lib/config-handler.ts:467-485` and registers the skill tool in `src/lib/skill-tool.ts:41-101` [OC-4][OC-5]. Bundled agent markdown omits a model field by invariant [OC-6]; runtime configuration may still supply source-owned defaults [OC-7].
24
+
25
+ Compatibility is direct: OpenCode consumes the concrete invocation language in the profile. The adapter is not a generic claim about other harnesses.
26
+
27
+ ## Pi — Tier 1 shipped adapter
28
+
29
+ Pi's profile records degraded or unavailable native capabilities and explicit fallbacks [PI-P]. The adapter registers `systematic_skill` in `src/pi.ts:85-103` and `systematic_delegate` in `src/pi.ts:106-113` [PI-3]. Delegation is explicitly sequential (`executionMode: 'sequential'`), capped at `MAX_DELEGATE_TURNS = 20`, and guarded against re-entry in `src/lib/pi-delegate-tool.ts:14-18,245-249` [PI-1].
30
+
31
+ The package manifest exposes the extension and skills at `package.json:17-23`, with tests verifying both manifest entries and their packaged paths `tests/unit/package-exports.test.ts:42-66,241-267` [PI-4]. Pi's RPC/JSONL test fixture isolates its environment (`tests/integration/pi.test.ts:349-388`), and the installed runtime exposes environment-specific agent/session directories `node_modules/@earendil-works/pi-coding-agent/dist/config.js:396-398` [PI-5].
32
+
33
+ Pi does not consume `disabled_skills` or Systematic's OpenCode configuration, and its skill loading has no OpenCode-style permission gate `docs/src/content/docs/guides/pi-harness.mdx:39-47` [PI-6]. Those are deliberate honesty boundaries, not implied parity.
34
+
35
+ ## Claude Code — Tier 2 documented portability target
36
+
37
+ Claude Code documents `AskUserQuestion` [CC-2], current task tracking through `TaskCreate`/`TaskGet`/`TaskList`/`TaskUpdate`, and the deprecated `TodoWrite` [CC-3][CC-4]. Its skill model includes the skill tool, `SKILL.md`, `~/.claude/skills/`, and `.claude/skills/` [CC-5][CC-6]. Skills may run with `context: fork`; a public-docs verification of a `subagent_type` parameter was not found, so that name remains **UNVERIFIED** [CC-1]. Systematic ships no Claude Code adapter or profile.
38
+
39
+ ## Codex CLI — Tier 2 documented portability target
40
+
41
+ The supplied evidence verifies only `request_user_input`: its definition names the tool [CX-1], and its handler blocks while restricting use to the root thread, rejecting subagents [CX-2]. Delegation, task tracking, skill loading, and skills-file support were not checked and remain **UNVERIFIED**. Systematic ships no Codex adapter or profile.
42
+
43
+ ## Gemini CLI — Tier 2 documented portability target
44
+
45
+ The supplied evidence verifies `ask_user`: the official documentation says it pauses execution until answers arrive [GE-1], and the implementation defines `ASK_USER_TOOL_NAME` [GE-2]. Other capabilities, including delegation, task tracking, and skill-file support, were not checked and remain **UNVERIFIED**. Systematic ships no Gemini adapter or profile.
46
+
47
+ ## GitHub Copilot — Tier 2 documented portability target
48
+
49
+ Copilot documents built-in agents and custom-agent invocation [GH-1][GH-2]. Its documented blocking behavior is plan-mode clarification, with `--no-ask-user` disabling asks; no dedicated blocking-tool name was verified [GH-3][GH-4]. The cloud-agent tasks/sessions API is documented, but no `TodoWrite` equivalent was verified [GH-5]. `SKILL.md` skills are documented [GH-6], as are instruction files including `AGENTS.md`, `.github/copilot-instructions.md`, and `.github/instructions/**/*.instructions.md` [GH-7][GH-8]. Systematic ships no Copilot adapter or profile.
50
+
51
+ ## Similarities and differences
52
+
53
+ `SKILL.md` is the clearest cross-harness convergence: it is documented for Claude Code and Copilot, consumed by OpenCode's Systematic skill path, and shipped through Systematic-on-Pi [OC-4][PI-4][CC-5][GH-6]. `AGENTS.md` is also converging as an instruction-file convention: this repository uses it (`AGENTS.md:1-7`), and Copilot documents it [GH-7][GH-8].
54
+
55
+ Delegation semantics diverge materially: OpenCode supports parallel/background dispatch [OC-1], Pi's adapter is sequential-only [PI-1], Claude's `context: fork` is skill-scoped [CC-1], and the remaining Tier 2 delegation claims are **UNVERIFIED**. Blocking input likewise ranges from native tools (`question`, `request_user_input`, `ask_user`, `AskUserQuestion`) to Pi's numbered-chat fallback and Copilot's plan-mode clarification [OC-2][PI-2][CC-2][CX-1][GE-1][GH-3].
56
+
57
+ ## Maintenance
58
+
59
+ Update this file evidence-first: verify the implementation path and line range, installed/cloned source, or authoritative URL before adding a tool name. Re-check URLs when their pinned revision or behavior matters. Preserve **UNVERIFIED** when a capability has not been checked; do not fill gaps from intuition. Tier 1 changes require updating the corresponding profile and this registry together.
60
+
61
+ Migrated-skill discipline is enforced by the [content-integrity gate](scripts/content-integrity.ts); keep exact harness identifiers in the designated profile/evidence surfaces and follow the gate's allowlist policy rather than weakening the gate.
62
+
63
+ ## Evidence registry
64
+
65
+ - **OC-P** — [OpenCode profile](skills/using-systematic/references/opencode-profile.md#L3-L8).
66
+ - **OC-1** — cloned OpenCode source, `.slim/clonedeps/repos/anomalyco__opencode/packages/opencode/src/tool/task.ts:24-62`.
67
+ - **OC-2** — cloned OpenCode source, `.slim/clonedeps/repos/anomalyco__opencode/packages/core/src/tool/question.ts:10-25`.
68
+ - **OC-3** — cloned OpenCode source, `.slim/clonedeps/repos/anomalyco__opencode/packages/core/src/tool/todowrite.ts:1-10`.
69
+ - **OC-4** — `src/lib/config-handler.ts:467-485`.
70
+ - **OC-5** — `src/lib/skill-tool.ts:41-101`.
71
+ - **OC-6** — `ARCHITECTURE.md:75-85` and `agents/`.
72
+ - **OC-7** — `src/lib/config-handler.ts:276-289`.
73
+ - **PI-P** — [Pi profile](skills/using-systematic/references/pi-profile.md#L3-L8).
74
+ - **PI-1** — `src/lib/pi-delegate-tool.ts:14-18,245-249,279-291`.
75
+ - **PI-2** — [Pi profile](skills/using-systematic/references/pi-profile.md#L5-L8).
76
+ - **PI-3** — `src/pi.ts:85-113`.
77
+ - **PI-4** — `package.json:17-23`; `tests/unit/package-exports.test.ts:42-66,241-267`.
78
+ - **PI-5** — `tests/integration/pi.test.ts:349-388`; installed Pi source `node_modules/@earendil-works/pi-coding-agent/dist/config.js:396-398`.
79
+ - **PI-6** — `docs/src/content/docs/guides/pi-harness.mdx:39-47`.
80
+ - **CC-1** — [Claude Code skills](https://code.claude.com/docs/en/skills) (`context: fork`); public-docs `subagent_type` verification is **UNVERIFIED**.
81
+ - **CC-2** — [Claude Code tools reference](https://code.claude.com/docs/en/tools-reference).
82
+ - **CC-3** — [Claude Code tools reference](https://code.claude.com/docs/en/tools-reference).
83
+ - **CC-4** — [Claude Code todo tracking](https://code.claude.com/docs/en/agent-sdk/todo-tracking.md).
84
+ - **CC-5** — [Claude Code skills](https://code.claude.com/docs/en/skills).
85
+ - **CC-6** — [Claude Code Agent SDK skills](https://code.claude.com/docs/en/agent-sdk/skills.md).
86
+ - **CX-1** — [Codex request_user_input definition](https://github.com/openai/codex/blob/35aaa5d9/codex-rs/tools/src/request_user_input_tool.rs).
87
+ - **CX-2** — [Codex request_user_input handler](https://github.com/openai/codex/blob/d47b755a/codex-rs/core/src/tools/handlers/request_user_input.rs).
88
+ - **GE-1** — [Gemini ask-user documentation](https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/ask-user.md).
89
+ - **GE-2** — [Gemini ask-user implementation](https://github.com/google-gemini/gemini-cli/blob/d2cd12a7/packages/core/src/tools/ask-user.ts).
90
+ - **GH-1** — [Copilot CLI built-in agents](https://docs.github.com/en/copilot/concepts/agents/copilot-cli/about-custom-agents).
91
+ - **GH-2** — [Copilot CLI custom agents](https://docs.github.com/en/copilot/how-tos/copilot-cli/use-copilot-cli/invoke-custom-agents).
92
+ - **GH-3** — [Copilot CLI](https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli).
93
+ - **GH-4** — [Copilot CLI automation](https://docs.github.com/en/copilot/how-tos/copilot-cli/automate-copilot-cli/run-cli-programmatically).
94
+ - **GH-5** — [Copilot cloud-agent tasks/sessions API](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/cloud-agent/use-cloud-agent-via-the-api).
95
+ - **GH-6** — [Copilot CLI skills](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills).
96
+ - **GH-7** — [Copilot best-practices instructions](https://docs.github.com/en/copilot/get-started/best-practices).
97
+ - **GH-8** — [Copilot `AGENTS.md` support](https://github.blog/changelog/2025-08-28-copilot-coding-agent-now-supports-agents-md-custom-instructions/).
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  modify,
10
10
  parse,
11
11
  parseTree
12
- } from "./index-yskzf7vh.js";
12
+ } from "./index-6yz7bra8.js";
13
13
 
14
14
  // src/cli.ts
15
15
  import fs2 from "fs";
@@ -16074,6 +16074,9 @@ var REMOVED_BUNDLED_AGENT_NAMES = [
16074
16074
  "security-sentinel",
16075
16075
  "workflow/lint"
16076
16076
  ];
16077
+ var REMOVED_BUNDLED_AGENT_CATEGORIES = [
16078
+ "docs"
16079
+ ];
16077
16080
 
16078
16081
  // src/lib/config-schema.ts
16079
16082
  var permissionSettingSchema = exports_external.enum(["ask", "allow", "deny"]);
@@ -16296,16 +16299,19 @@ var CURRENT_AGENT_NAMES_SET = new Set([
16296
16299
  ...BUNDLED_AGENT_NAMES,
16297
16300
  ...BUNDLED_AGENT_QUALIFIED_IDS
16298
16301
  ]);
16302
+ var REMOVED_AGENT_CATEGORIES_SET = new Set(REMOVED_BUNDLED_AGENT_CATEGORIES);
16299
16303
  function computeDroppedNames(names, allowedSet) {
16300
16304
  return names.filter((n) => !allowedSet.has(n));
16301
16305
  }
16302
16306
  var MIGRATION_DOCS_URL = "https://fro.bot/systematic/guides/v3-migration/";
16303
- function warnDroppedNames(dropped, field, warned) {
16307
+ function warnDroppedNames(dropped, field, warned, removalVersion) {
16304
16308
  for (const name of dropped) {
16305
16309
  if (warned.has(name))
16306
16310
  continue;
16307
16311
  warned.add(name);
16308
- console.warn(`[systematic] "${name}" in \`${field}\` is no longer a bundled name and will be ignored. Remove it from your config to silence this warning. See ${MIGRATION_DOCS_URL} for migration guidance.`);
16312
+ const displayName = field === "categories" ? `${field}.${name}` : name;
16313
+ const removalNote = removalVersion ? ` It was removed in ${removalVersion}.` : "";
16314
+ console.warn(`[systematic] "${displayName}" in \`${field}\` is no longer a bundled name and will be ignored.${removalNote} Remove it from your config to silence this warning. See ${MIGRATION_DOCS_URL} for migration guidance.`);
16309
16315
  }
16310
16316
  }
16311
16317
  function resolveConfigPath(dir, basename) {
@@ -16443,7 +16449,15 @@ function loadConfigWithSources(projectDir) {
16443
16449
  const projectSource = loadConfigSource(paths.projectConfig, "project");
16444
16450
  const customSource = paths.customConfig ? loadConfigSource(paths.customConfig, "custom") : null;
16445
16451
  const sources = [userSource, projectSource, customSource].filter((source) => source !== null);
16446
- const overlays = mergeOverlaySources(sources);
16452
+ const mergedOverlays = mergeOverlaySources(sources);
16453
+ const droppedCategories = Object.keys(mergedOverlays.categories).filter((name) => REMOVED_AGENT_CATEGORIES_SET.has(name));
16454
+ const warned = new Set;
16455
+ warnDroppedNames(droppedCategories, "categories", warned, "v3.0.0");
16456
+ const droppedCategorySet = new Set(droppedCategories);
16457
+ const overlays = droppedCategorySet.size === 0 ? mergedOverlays : {
16458
+ ...mergedOverlays,
16459
+ categories: Object.fromEntries(Object.entries(mergedOverlays.categories).filter(([key]) => !droppedCategorySet.has(key)))
16460
+ };
16447
16461
  const userConfig = userSource?.config;
16448
16462
  const projectConfig = projectSource?.config;
16449
16463
  const customConfig = customSource?.config;
@@ -16461,7 +16475,6 @@ function loadConfigWithSources(projectDir) {
16461
16475
  categories: overlayValues(overlays.categories),
16462
16476
  skills_as_commands: customConfig?.skills_as_commands ?? projectConfig?.skills_as_commands ?? userConfig?.skills_as_commands ?? DEFAULT_CONFIG.skills_as_commands
16463
16477
  };
16464
- const warned = new Set;
16465
16478
  const droppedSkills = computeDroppedNames(result.disabled_skills, CURRENT_SKILL_NAMES_SET);
16466
16479
  warnDroppedNames(droppedSkills, "disabled_skills", warned);
16467
16480
  const droppedAgents = computeDroppedNames(result.disabled_agents, CURRENT_AGENT_NAMES_SET);
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  loadConfigWithSources,
15
15
  parseFrontmatter,
16
16
  walkDir
17
- } from "./index-yskzf7vh.js";
17
+ } from "./index-6yz7bra8.js";
18
18
 
19
19
  // src/index.ts
20
20
  import fs8 from "fs";
@@ -188,6 +188,15 @@ var applyBootstrapContent = (output, content) => {
188
188
 
189
189
  ${content}` : content;
190
190
  };
191
+ function readHarnessProfile(bundledSkillsDir, name) {
192
+ const profilePath = path2.join(bundledSkillsDir, "using-systematic/references", `${name}-profile.md`);
193
+ try {
194
+ return fs2.readFileSync(profilePath, "utf8");
195
+ } catch (error) {
196
+ console.error(`Failed to read harness profile ${profilePath}: ${error instanceof Error ? error.message : String(error)}`);
197
+ return null;
198
+ }
199
+ }
191
200
  function getSkillUsageTemplate() {
192
201
  return `**Skills naming:**
193
202
  - Systematic bundled skills use the \`systematic:\` prefix (e.g., \`systematic:onboarding\`)
@@ -202,7 +211,7 @@ function getSkillUsageTemplate() {
202
211
  Bundled skills ship with the Systematic plugin and are discoverable via \`systematic_skill\`.`;
203
212
  }
204
213
  function getBootstrapContent(config, deps) {
205
- const { bundledSkillsDir, usageTemplate } = deps;
214
+ const { bundledSkillsDir, usageTemplate, profileBlock } = deps;
206
215
  if (!config.bootstrap.enabled)
207
216
  return null;
208
217
  if (config.bootstrap.file) {
@@ -225,6 +234,9 @@ function getBootstrapContent(config, deps) {
225
234
  const catalogSection = catalog.length > 0 ? `
226
235
 
227
236
  ${catalog}` : "";
237
+ const profileSection = profileBlock === undefined ? "" : `
238
+
239
+ ${profileBlock}`;
228
240
  return `<SYSTEMATIC_WORKFLOWS>
229
241
  You have access to structured engineering workflows via the Systematic plugin.
230
242
 
@@ -232,7 +244,7 @@ You have access to structured engineering workflows via the Systematic plugin.
232
244
 
233
245
  ${content}
234
246
 
235
- ${skillUsage}${catalogSection}
247
+ ${skillUsage}${profileSection}${catalogSection}
236
248
  </SYSTEMATIC_WORKFLOWS>`;
237
249
  }
238
250
 
@@ -1439,7 +1451,10 @@ var getPackageVersion = () => {
1439
1451
  var initializePlugin = async ({ client, directory }) => {
1440
1452
  let hasLoggedInit = false;
1441
1453
  const config = loadConfig(directory);
1442
- const bootstrapContent = getBootstrapContent(config, { bundledSkillsDir });
1454
+ const bootstrapContent = getBootstrapContent(config, {
1455
+ bundledSkillsDir,
1456
+ profileBlock: readHarnessProfile(bundledSkillsDir, "opencode") ?? undefined
1457
+ });
1443
1458
  const configHandler = createConfigHandler({
1444
1459
  directory,
1445
1460
  bundledSkillsDir,
@@ -21,7 +21,10 @@ export declare const applyBootstrapContent: (output: {
21
21
  export interface BootstrapDeps {
22
22
  bundledSkillsDir: string;
23
23
  usageTemplate?: string;
24
+ profileBlock?: string;
24
25
  }
26
+ /** Reads a harness capability profile from the packaged using-systematic references. */
27
+ export declare function readHarnessProfile(bundledSkillsDir: string, name: string): string | null;
25
28
  type BootstrapContentConfig = Pick<SystematicConfig, 'bootstrap' | 'disabled_skills'>;
26
29
  /** Safely computes default bootstrap content, returning null instead of throwing. */
27
30
  export declare function computeBootstrapContentSafe(deps: BootstrapDeps, reportError?: (error: unknown) => void): string | null;
@@ -40,7 +40,7 @@ export declare function computeDroppedNames(names: readonly string[], allowedSet
40
40
  * single load call -- callers must NOT share it across independent loads.
41
41
  * Passing a fresh set per load ensures no cross-load suppression.
42
42
  */
43
- export declare function warnDroppedNames(dropped: string[], field: string, warned: Set<string>): void;
43
+ export declare function warnDroppedNames(dropped: string[], field: string, warned: Set<string>, removalVersion?: string): void;
44
44
  export declare function loadConfig(projectDir: string): SystematicConfig;
45
45
  export declare function loadConfigWithSources(projectDir: string): SourceAwareConfigResult;
46
46
  export declare function getConfigPaths(projectDir: string): {
@@ -13,3 +13,4 @@
13
13
  */
14
14
  export declare const REMOVED_BUNDLED_SKILL_NAMES: readonly string[];
15
15
  export declare const REMOVED_BUNDLED_AGENT_NAMES: readonly string[];
16
+ export declare const REMOVED_BUNDLED_AGENT_CATEGORIES: readonly string[];
package/dist/pi.js CHANGED
@@ -3078,6 +3078,15 @@ ${bullets}`;
3078
3078
  }
3079
3079
 
3080
3080
  // src/lib/bootstrap.ts
3081
+ function readHarnessProfile(bundledSkillsDir, name) {
3082
+ const profilePath = path4.join(bundledSkillsDir, "using-systematic/references", `${name}-profile.md`);
3083
+ try {
3084
+ return fs5.readFileSync(profilePath, "utf8");
3085
+ } catch (error) {
3086
+ console.error(`Failed to read harness profile ${profilePath}: ${error instanceof Error ? error.message : String(error)}`);
3087
+ return null;
3088
+ }
3089
+ }
3081
3090
  var DEFAULT_BOOTSTRAP_CONFIG = {
3082
3091
  bootstrap: { enabled: true },
3083
3092
  disabled_skills: []
@@ -3120,7 +3129,7 @@ function getSkillUsageTemplate() {
3120
3129
  Bundled skills ship with the Systematic plugin and are discoverable via \`systematic_skill\`.`;
3121
3130
  }
3122
3131
  function getBootstrapContent(config, deps) {
3123
- const { bundledSkillsDir, usageTemplate } = deps;
3132
+ const { bundledSkillsDir, usageTemplate, profileBlock } = deps;
3124
3133
  if (!config.bootstrap.enabled)
3125
3134
  return null;
3126
3135
  if (config.bootstrap.file) {
@@ -3143,6 +3152,9 @@ function getBootstrapContent(config, deps) {
3143
3152
  const catalogSection = catalog.length > 0 ? `
3144
3153
 
3145
3154
  ${catalog}` : "";
3155
+ const profileSection = profileBlock === undefined ? "" : `
3156
+
3157
+ ${profileBlock}`;
3146
3158
  return `<SYSTEMATIC_WORKFLOWS>
3147
3159
  You have access to structured engineering workflows via the Systematic plugin.
3148
3160
 
@@ -3150,7 +3162,7 @@ You have access to structured engineering workflows via the Systematic plugin.
3150
3162
 
3151
3163
  ${content}
3152
3164
 
3153
- ${skillUsage}${catalogSection}
3165
+ ${skillUsage}${profileSection}${catalogSection}
3154
3166
  </SYSTEMATIC_WORKFLOWS>`;
3155
3167
  }
3156
3168
 
@@ -3599,7 +3611,8 @@ async function systematicPiExtension(pi, deps = defaultPiExtensionDependencies)
3599
3611
  const resolverOptions = { bundledSkillsDir, disabledSkills };
3600
3612
  const bootstrapContent = computeBootstrapContentSafe({
3601
3613
  bundledSkillsDir,
3602
- usageTemplate: PI_BOOTSTRAP_USAGE_TEMPLATE
3614
+ usageTemplate: PI_BOOTSTRAP_USAGE_TEMPLATE,
3615
+ profileBlock: readHarnessProfile(bundledSkillsDir, "pi") ?? undefined
3603
3616
  }, reportPiBootstrapFailure);
3604
3617
  pi.on("before_agent_start", (event) => {
3605
3618
  const systemPrompt = composeSystemPromptWithBootstrap(event.systemPrompt, bootstrapContent);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "Structured engineering workflows for OpenCode",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
@@ -26,7 +26,8 @@
26
26
  "dist",
27
27
  "skills",
28
28
  "agents",
29
- "ATTRIBUTIONS.md"
29
+ "ATTRIBUTIONS.md",
30
+ "HARNESSES.md"
30
31
  ],
31
32
  "workspaces": [
32
33
  "docs"
@@ -88,8 +89,8 @@
88
89
  "devDependencies": {
89
90
  "@biomejs/biome": "2.5.3",
90
91
  "@earendil-works/pi-coding-agent": "0.80.6",
91
- "@opencode-ai/plugin": "1.17.20",
92
- "@opencode-ai/sdk": "1.17.20",
92
+ "@opencode-ai/plugin": "1.18.0",
93
+ "@opencode-ai/sdk": "1.18.0",
93
94
  "@semantic-release/exec": "7.1.0",
94
95
  "@types/bun": "latest",
95
96
  "@types/js-yaml": "4.0.9",
@@ -2,6 +2,8 @@
2
2
  name: ce:brainstorm
3
3
  description: 'Explore requirements and approaches through collaborative dialogue before writing a right-sized requirements document and planning implementation. Use for feature ideas, problem framing, when the user says ''let''s brainstorm'', or when they want to think through options before deciding what to build. Also use when a user describes a vague or ambitious feature request, asks ''what should we build'', ''help me think through X'', presents a problem with multiple valid solutions, or seems unsure about scope or direction — even if they don''t explicitly ask to brainstorm.'
4
4
  argument-hint: "[feature idea or problem to explore]"
5
+ metadata:
6
+ harness-portability: neutral-v1
5
7
  ---
6
8
 
7
9
  # Brainstorm a Feature or Improvement
@@ -30,7 +32,7 @@ This skill does not implement code. It explores, clarifies, and documents decisi
30
32
  1. **Ask one question at a time** - Do not batch several unrelated questions into one message.
31
33
  2. **Prefer single-select multiple choice** - Use single-select when choosing one direction, one priority, or one next step.
32
34
  3. **Use multi-select rarely and intentionally** - Use it only for compatible sets such as goals, constraints, non-goals, or success criteria that can all coexist. If prioritization matters, follow up by asking which selected item is primary.
33
- 4. **Use the platform's question tool when available** - When asking the user a question, prefer the platform's blocking question tool if one exists (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). Otherwise, present numbered options in chat and wait for the user's reply before proceeding.
35
+ 4. **Use the platform's question tool when available** - When asking the user a question, prefer the platform's blocking question tool if one exists (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). Otherwise, present numbered options in chat and wait for the user's reply before proceeding.
34
36
 
35
37
  ## Output Guidance
36
38
 
@@ -32,7 +32,7 @@ When spawning subagents, pass the relevant file contents into the task prompt so
32
32
 
33
33
  ## Execution Strategy
34
34
 
35
- Present the user with two options before proceeding, using the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the options and wait for the user's reply.
35
+ Present the user with two options before proceeding, using the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). If no question tool is available, present the options and wait for the user's reply.
36
36
 
37
37
  ```
38
38
  1. Full (recommended) — the complete compound workflow. Researches,
@@ -263,7 +263,7 @@ After the learning is written and the refresh decision is made, check whether th
263
263
 
264
264
  `docs/solutions/` — documented solutions to past problems (bugs, best practices, workflow patterns), organized by category with YAML frontmatter (`module`, `tags`, `problem_type`). Relevant when implementing or debugging in documented areas.
265
265
  ```
266
- c. In full mode, explain to the user why this matters — agents working in this repo (including fresh sessions, other tools, or collaborators without the plugin) won't know to check `docs/solutions/` unless the instruction file surfaces it. Show the proposed change and where it would go, then use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini) to get consent before making the edit. If no question tool is available, present the proposal and wait for the user's reply. In lightweight mode, output a one-liner note and move on
266
+ c. In full mode, explain to the user why this matters — agents working in this repo (including fresh sessions, other tools, or collaborators without the plugin) won't know to check `docs/solutions/` unless the instruction file surfaces it. Show the proposed change and where it would go, then use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait) to get consent before making the edit. If no question tool is available, present the proposal and wait for the user's reply. In lightweight mode, output a one-liner note and move on
267
267
 
268
268
  ### Phase 3: Optional Enhancement
269
269
 
@@ -413,7 +413,7 @@ What's next?
413
413
  5. Other
414
414
  ```
415
415
 
416
- **After displaying the success output, present the "What's next?" options using the platform's blocking question tool** (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the numbered options and wait for the user's reply before proceeding. Do not continue the workflow or end the turn without the user's selection.
416
+ **After displaying the success output, present the "What's next?" options using the platform's blocking question tool** (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). If no question tool is available, present the numbered options and wait for the user's reply before proceeding. Do not continue the workflow or end the turn without the user's selection.
417
417
 
418
418
  **Alternate output (when updating an existing doc due to high overlap):**
419
419
 
@@ -33,7 +33,7 @@ Check if `$ARGUMENTS` contains `mode:autofix`. If present, strip it from argumen
33
33
 
34
34
  Follow the same interaction style as `ce:brainstorm`:
35
35
 
36
- - Ask questions **one at a time** — use the platform's blocking question tool when available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). Otherwise, present numbered options in plain text and wait for the user's reply before continuing
36
+ - Ask questions **one at a time** — use the platform's blocking question tool when available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). Otherwise, present numbered options in plain text and wait for the user's reply before continuing
37
37
  - Prefer **multiple choice** when natural options exist
38
38
  - Start with **scope and intent**, then narrow only when needed
39
39
  - Do **not** ask the user to make decisions before you have evidence
@@ -395,7 +395,7 @@ Do **not** ask questions about whether code changes were intentional, whether th
395
395
 
396
396
  #### Question Style
397
397
 
398
- Always present choices using the platform's blocking question tool when available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). Otherwise, present numbered options in plain text and wait for the user's reply before proceeding.
398
+ Always present choices using the platform's blocking question tool when available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). Otherwise, present numbered options in plain text and wait for the user's reply before proceeding.
399
399
 
400
400
  Question rules:
401
401
 
@@ -675,6 +675,6 @@ After the refresh report is generated, check whether the project's instruction f
675
675
 
676
676
  `docs/solutions/` — documented solutions to past problems (bugs, best practices, workflow patterns), organized by category with YAML frontmatter (`module`, `tags`, `problem_type`). Relevant when implementing or debugging in documented areas.
677
677
  ```
678
- c. In interactive mode, explain to the user why this matters — agents working in this repo (including fresh sessions, other tools, or collaborators without the plugin) won't know to check `docs/solutions/` unless the instruction file surfaces it. Show the proposed change and where it would go, then use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini) to get consent before making the edit. If no question tool is available, present the proposal and wait for the user's reply. In autofix mode, include it as a "Discoverability recommendation" line in the report — do not attempt to edit instruction files (autofix scope is doc maintenance, not project config).
678
+ c. In interactive mode, explain to the user why this matters — agents working in this repo (including fresh sessions, other tools, or collaborators without the plugin) won't know to check `docs/solutions/` unless the instruction file surfaces it. Show the proposed change and where it would go, then use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait) to get consent before making the edit. If no question tool is available, present the proposal and wait for the user's reply. In autofix mode, include it as a "Discoverability recommendation" line in the report — do not attempt to edit instruction files (autofix scope is doc maintenance, not project config).
679
679
 
680
680
  5. **Amend or create a follow-up commit when the check produces edits.** If step 4 resulted in an edit to an instruction file and Phase 5 already committed the refresh changes, stage the newly edited file and either amend the existing commit (if still on the same branch and no push has occurred) or create a small follow-up commit (e.g., `docs: add docs/solutions/ discoverability to AGENTS.md`). If Phase 5 already pushed the branch to a remote (e.g., the branch+PR path), push the follow-up commit as well so the open PR includes the discoverability change. This keeps the working tree clean and the remote in sync at the end of the run. If the user chose "Don't commit" in Phase 5, leave the instruction-file edit unstaged alongside the other uncommitted refresh changes — no separate commit logic needed.
@@ -2,6 +2,8 @@
2
2
  name: ce:ideate
3
3
  description: "Generate and critically evaluate grounded improvement ideas for the current project. Use when asking what to improve, requesting idea generation, exploring surprising improvements, or wanting the AI to proactively suggest strong project directions before brainstorming one in depth. Triggers on phrases like 'what should I improve', 'give me ideas', 'ideate on this project', 'surprise me with improvements', 'what would you change', or any request for AI-generated project improvement suggestions rather than refining the user's own idea."
4
4
  argument-hint: "[feature, focus area, or constraint]"
5
+ metadata:
6
+ harness-portability: neutral-v1
5
7
  ---
6
8
 
7
9
  # Generate Improvement Ideas
@@ -18,7 +20,7 @@ This workflow produces a ranked ideation artifact in `docs/ideation/`. It does *
18
20
 
19
21
  ## Interaction Method
20
22
 
21
- Use the platform's blocking question tool when available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). Otherwise, present numbered options in chat and wait for the user's reply before proceeding.
23
+ Use the platform's blocking question tool when available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). Otherwise, present numbered options in chat and wait for the user's reply before proceeding.
22
24
 
23
25
  Ask one question at a time. Prefer concise single-select choices when natural options exist.
24
26
 
@@ -2,6 +2,8 @@
2
2
  name: ce:plan
3
3
  description: "Create structured plans for any multi-step task -- software features, research workflows, events, study plans, or any goal that benefits from structured breakdown. Also deepen existing plans with interactive review of sub-agent findings. Use for plan creation when the user says 'plan this', 'create a plan', 'write a tech plan', 'plan the implementation', 'how should we build', 'what's the approach for', 'break this down', 'plan a trip', 'create a study plan', or when a brainstorm/requirements document is ready for planning. Use for plan deepening when the user says 'deepen the plan', 'deepen my plan', 'deepening pass', or uses 'deepen' in reference to a plan."
4
4
  argument-hint: "[optional: feature description, requirements doc path, plan path to deepen, or any task to plan]"
5
+ metadata:
6
+ harness-portability: neutral-v1
5
7
  ---
6
8
 
7
9
  # Create Technical Plan
@@ -16,7 +18,7 @@ This workflow produces a durable implementation plan. It does **not** implement
16
18
 
17
19
  ## Interaction Method
18
20
 
19
- Use the platform's question tool when available. When asking the user a question, prefer the platform's blocking question tool if one exists (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). Otherwise, present numbered options in chat and wait for the user's reply before proceeding.
21
+ Use the platform's question tool when available. When asking the user a question, prefer the platform's blocking question tool if one exists (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). Otherwise, present numbered options in chat and wait for the user's reply before proceeding.
20
22
 
21
23
  Ask one question at a time. Prefer a concise single-select choice when natural options exist.
22
24
 
@@ -2,6 +2,8 @@
2
2
  name: ce:review
3
3
  description: "Structured code review using tiered persona agents, confidence-gated findings, and a merge/dedup pipeline. Use when reviewing code changes before creating a PR."
4
4
  argument-hint: "[blank to review current branch, or provide PR link]"
5
+ metadata:
6
+ harness-portability: neutral-v1
5
7
  ---
6
8
 
7
9
  # Code Review
@@ -59,7 +61,7 @@ All tokens are optional. Each one present means one less thing to infer. When ab
59
61
 
60
62
  ### Headless mode rules
61
63
 
62
- - **Skip all user questions.** Never use the platform question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini) or other interactive prompts. Infer intent conservatively if the diff metadata is thin.
64
+ - **Skip all user questions.** Never use the platform question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait) or other interactive prompts. Infer intent conservatively if the diff metadata is thin.
63
65
  - **Require a determinable diff scope.** If headless mode cannot determine a diff scope (no branch, PR, or `base:` ref determinable without user interaction), emit `Review failed (headless mode). Reason: no diff scope detected. Re-invoke with a branch name, PR number, or base:<ref>.` and stop without dispatching agents.
64
66
  - **Apply only `safe_auto -> review-fixer` findings in a single pass.** No bounded re-review rounds. Leave `gated_auto`, `manual`, `human`, and `release` work unresolved and return them in the structured output.
65
67
  - **Return all non-auto findings as structured text output.** Use the headless output envelope format (see Stage 6 below) preserving severity, autofix_class, owner, requires_verification, confidence, pre_existing, and suggested_fix per finding. Enrich with detail-tier fields (why_it_matters, evidence[]) from the per-agent artifact files on disk (see Detail enrichment in Stage 6).
@@ -311,7 +313,7 @@ Pass this to every reviewer in their spawn prompt. Intent shapes *how hard each
311
313
 
312
314
  **When intent is ambiguous:**
313
315
 
314
- - **Interactive mode:** Ask one question using the platform's interactive question tool (question in OpenCode, request_user_input in Codex): "What is the primary goal of these changes?" Do not spawn reviewers until intent is established.
316
+ - **Interactive mode:** Ask one question using the platform's interactive question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait): "What is the primary goal of these changes?" Do not spawn reviewers until intent is established.
315
317
  - **Autofix/report-only/headless modes:** Infer intent conservatively from the branch name, diff, PR metadata, and caller context. Note the uncertainty in Coverage or Verdict reasoning instead of blocking.
316
318
 
317
319
  ### Stage 2b: Plan discovery (requirements verification)
@@ -634,7 +636,7 @@ After presenting findings and verdict (Stage 6), route the next steps by mode. R
634
636
  **Interactive mode**
635
637
 
636
638
  - Apply `safe_auto -> review-fixer` findings automatically without asking. These are safe by definition.
637
- - Ask a policy question **using the platform's blocking question tool** (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini) only when `gated_auto` or `manual` findings remain after safe fixes. Do not replace with a conversational open-ended question. Adapt the options to match what actually remains:
639
+ - Ask a policy question **using the platform's blocking question tool** (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait) only when `gated_auto` or `manual` findings remain after safe fixes. Do not replace with a conversational open-ended question. Adapt the options to match what actually remains:
638
640
 
639
641
  **When `gated_auto` findings are present** (with or without `manual`):
640
642
  ```
@@ -22,7 +22,7 @@ This skill does **not** turn plans into implementation scripts. It identifies we
22
22
 
23
23
  ## Interaction Method
24
24
 
25
- Use the platform's question tool when available. When asking the user a question, prefer the platform's blocking question tool if one exists (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). Otherwise, present numbered options in chat and wait for the user's reply before proceeding.
25
+ Use the platform's question tool when available. When asking the user a question, prefer the platform's blocking question tool if one exists (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). Otherwise, present numbered options in chat and wait for the user's reply before proceeding.
26
26
 
27
27
  Ask one question at a time. Prefer a concise single-select choice when natural options exist.
28
28
 
@@ -53,7 +53,7 @@ Based on detected signals, choose a mode:
53
53
 
54
54
  ### Asking the User
55
55
 
56
- When context is ambiguous, use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, assume "partial" mode and proceed conservatively.
56
+ When context is ambiguous, use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). If no question tool is available, assume "partial" mode and proceed conservatively.
57
57
 
58
58
  Example question: "I found [detected signals]. Should I follow your existing design patterns or create something distinctive?"
59
59
 
@@ -37,7 +37,7 @@ These local branches have been deleted from the remote:
37
37
  Delete all of them? (y/n)
38
38
  ```
39
39
 
40
- Wait for the user's answer using the platform's question tool (e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the list and wait for the user's reply before proceeding.
40
+ Wait for the user's answer using the platform's question tool (e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). If no question tool is available, present the list and wait for the user's reply before proceeding.
41
41
 
42
42
  This is a yes-or-no decision on the entire list -- do not offer multi-selection or per-branch choices.
43
43
 
@@ -56,7 +56,7 @@ If both fail, fall back to `main`.
56
56
 
57
57
  If the git status from the context above shows a clean working tree (no staged, modified, or untracked files), report that there is nothing to commit and stop.
58
58
 
59
- If the current branch from the context above is empty, the repository is in detached HEAD state. Explain that a branch is required before committing if the user wants this work attached to a branch. Ask whether to create a feature branch now. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the options and wait for the user's reply before proceeding.
59
+ If the current branch from the context above is empty, the repository is in detached HEAD state. Explain that a branch is required before committing if the user wants this work attached to a branch. Ask whether to create a feature branch now. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). If no question tool is available, present the options and wait for the user's reply before proceeding.
60
60
 
61
61
  - If the user chooses to create a branch, derive the name from the change content, create it with `git checkout -b <branch-name>`, then run `git branch --show-current` again and use that result as the current branch name for the rest of the workflow.
62
62
  - If the user declines, continue with the detached HEAD commit.
@@ -80,7 +80,7 @@ Keep this lightweight:
80
80
 
81
81
  ### Step 4: Stage and commit
82
82
 
83
- If the current branch from the context above is `main`, `master`, or the resolved default branch from Step 1, warn the user and ask whether to continue committing here or create a feature branch first. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the options and wait for the user's reply before proceeding. If the user chooses to create a branch, derive the name from the change content, create it with `git checkout -b <branch-name>`, then continue.
83
+ If the current branch from the context above is `main`, `master`, or the resolved default branch from Step 1, warn the user and ask whether to continue committing here or create a feature branch first. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). If no question tool is available, present the options and wait for the user's reply before proceeding. If the user chooses to create a branch, derive the name from the change content, create it with `git checkout -b <branch-name>`, then continue.
84
84
 
85
85
  Write the commit message:
86
86
  - **Subject line**: Concise, imperative mood, focused on *why* not *what*. Follow the convention determined in Step 2.
@@ -7,7 +7,7 @@ description: Commit, push, and open a PR with an adaptive, value-first descripti
7
7
 
8
8
  Go from working changes to an open pull request, or rewrite an existing PR description.
9
9
 
10
- **Asking the user:** When this skill says "ask the user", use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If unavailable, present the question and wait for a reply.
10
+ **Asking the user:** When this skill says "ask the user", use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). If unavailable, present the question and wait for a reply.
11
11
 
12
12
  ## Mode detection
13
13
 
@@ -385,7 +385,7 @@ Write the file to the repo root as `ONBOARDING.md`.
385
385
 
386
386
  ### Phase 5: Present Result
387
387
 
388
- After writing, inform the user that `ONBOARDING.md` has been generated. Offer next steps using the platform's blocking question tool when available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). Otherwise, present numbered options in chat.
388
+ After writing, inform the user that `ONBOARDING.md` has been generated. Offer next steps using the platform's blocking question tool when available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait). Otherwise, present numbered options in chat.
389
389
 
390
390
  Options:
391
391
  1. Open the file for review
@@ -1,125 +1,131 @@
1
1
  ---
2
2
  name: orchestrating-subagents
3
- description: Use when dispatching parallel or serial subagents in OpenCode, coordinating multi-unit plan execution, synthesizing results from independent subagent runs, or handling subagent failure and retry. Triggers on requests to run tasks in parallel, divide work across subagents, orchestrate a pipeline of dependent steps, or coordinate multiple agents without shared-file conflicts.
3
+ description: Use when dispatching parallel or serial subagents, coordinating multi-unit plan execution, synthesizing results from independent subagent runs, or handling subagent failure and retry. Triggers on requests to run tasks in parallel, divide work, orchestrate a pipeline of dependent steps, or coordinate multiple agents without shared-file conflicts.
4
+ metadata:
5
+ harness-portability: neutral-v1
4
6
  ---
5
7
 
6
8
  # Orchestrating Subagents
7
9
 
8
- Dispatch, coordinate, and synthesize results from OpenCode subagents using the `task()` primitive.
10
+ Dispatch, coordinate, and synthesize results from subagents using the harness's delegation mechanism (see the active harness profile).
9
11
 
10
12
  ## The Portable Primitive
11
13
 
12
- Every subagent dispatch goes through `task()`:
14
+ Every subagent dispatch should carry the same bounded brief, expressed through the active harness's delegation mechanism:
13
15
 
14
- ```typescript
15
- task({
16
- subagent_type: "systematic-implementer",
17
- description: "Implement auth module",
18
- prompt: "...",
19
- })
16
+ ```text
17
+ Specialist: systematic-implementer
18
+ Objective: Implement the auth module
19
+ Scope: Make only the changes needed for the auth module.
20
+ Return: List the changed files and summarize the implementation.
20
21
  ```
21
22
 
22
- **Required parameters:**
23
- - `subagent_type` — the registered agent name (e.g., `systematic-implementer`, `best-practices-researcher`)
24
- - `description`3–5 word label shown in the UI
25
- - `prompt` — full instructions for the subagent
23
+ **Required brief elements:**
24
+ - **Specialist** — the registered agent or persona best suited to the work (for example, an implementer or researcher)
25
+ - **Objective**a concise statement of the outcome
26
+ - **Scope** — full instructions, boundaries, dependencies, and files in scope
27
+ - **Return** — the result format expected from the specialist
26
28
 
27
- **Optional:**
28
- - `task_id` — resume a prior subagent session instead of creating a new one
29
- - `command` — the slash command that triggered this task
29
+ **Optional brief elements:**
30
+ - **Session reference** — resume a prior specialist session instead of creating a new one, where the harness supports session reuse
31
+ - **Trigger context** — the command or workflow that initiated the dispatch
30
32
 
31
- Foreground dispatch (no `background` parameter) blocks until the subagent returns its result. **This is the default and works on all OpenCode versions.**
33
+ A foreground dispatch blocks until the specialist returns its result. Use the active harness profile to determine whether foreground, background, or other dispatch modes are available. Run independent dispatches concurrently where the harness supports it; otherwise dispatch sequentially in dependency order.
32
34
 
33
- ## Background Dispatch (Experimental)
35
+ ## Background Dispatch (When Available)
34
36
 
35
- Background dispatch is gated by a runtime flag. It is **not available by default**.
37
+ Background dispatch may be gated by a runtime capability or feature flag. Check the active harness profile and rely on whether the mechanism accepts background work.
36
38
 
37
- ```typescript
38
- // Only use when the runtime exposes background support
39
- task({
40
- subagent_type: "systematic-implementer",
41
- description: "Implement auth module",
42
- prompt: "...",
43
- background: true, // experimental — see below
44
- })
45
- ```
46
-
47
- **When background is available:** `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true` (or the umbrella `OPENCODE_EXPERIMENTAL=true`) must be set. When enabled, `background: true` runs the subagent asynchronously. OpenCode automatically injects the result into the parent session as a synthetic message when the subagent completes. You are notified; you do not poll.
48
-
49
- **When background is unavailable:** Passing `background: true` returns an error. Fall back to foreground dispatch — dispatch subagents serially or in small foreground batches instead.
39
+ When background dispatch is available, it runs asynchronously and the harness reports the result to the parent session when the specialist completes. Do not poll or sleep.
50
40
 
51
- **Check before assuming:** Rely on whether `background: true` is accepted (i.e., the env flag is set). If it returns an error, use foreground dispatch only.
41
+ When background dispatch is unavailable, fall back to foreground dispatch—serially or in small foreground batches.
52
42
 
53
43
  ## Serial vs Parallel Dispatch
54
44
 
55
45
  ### Serial (default, always safe)
56
46
 
57
- Dispatch one subagent, wait for its result, then dispatch the next. Use when:
47
+ Dispatch one specialist, wait for its result, then dispatch the next. Use when:
58
48
  - Units have dependencies (unit B needs unit A's output)
59
49
  - Units touch overlapping files
60
50
  - You need to verify each result before proceeding
61
51
 
62
- ```typescript
63
- const researchResult = task({
64
- subagent_type: "best-practices-researcher",
65
- description: "Research caching patterns",
66
- prompt: "Research Redis caching best practices for Rails APIs...",
67
- })
68
-
69
- // Use research output to guide implementation
70
- task({
71
- subagent_type: "systematic-implementer",
72
- description: "Implement caching",
73
- prompt: `Implement caching based on this research:\n\n${researchResult}`,
74
- })
52
+ ```text
53
+ First dispatch:
54
+ Specialist: best-practices-researcher
55
+ Objective: Research caching patterns
56
+ Scope: Research Redis caching best practices for Rails APIs.
57
+ Return: Summarize recommendations and constraints.
58
+
59
+ After the first result, dispatch:
60
+ Specialist: systematic-implementer
61
+ Objective: Implement caching
62
+ Scope: Implement caching based on the research result below.
63
+ Input: Include the first specialist's returned research.
64
+ Return: List changed files and summarize the implementation.
75
65
  ```
76
66
 
77
- ### Parallel (foreground batches)
67
+ Use the first specialist's returned research to guide the dependent implementation dispatch.
78
68
 
79
- Dispatch multiple foreground subagents in the same turn. OpenCode runs them concurrently when dispatched together. Use when:
69
+ ### Parallel (independent dispatches)
70
+
71
+ Dispatch multiple independent specialists concurrently where the harness supports it. Use when:
80
72
  - Units are fully independent (no shared files, no dependency on each other's output)
81
73
  - You have passed the Parallel Safety Check (see below)
82
74
 
83
- ```typescript
84
- // Dispatch independent review subagents together
85
- task({ subagent_type: "security-reviewer", description: "Security review", prompt: "..." })
86
- task({ subagent_type: "performance-reviewer", description: "Performance review", prompt: "..." })
87
- task({ subagent_type: "correctness-reviewer", description: "Correctness review", prompt: "..." })
88
- // All three run; orchestrator synthesizes results after all complete
75
+ ```text
76
+ Concurrent dispatch 1:
77
+ Specialist: security-reviewer
78
+ Objective: Perform a security review
79
+ Scope: Review the proposed changes for security issues.
80
+ Return: Findings with severity and file references.
81
+
82
+ Concurrent dispatch 2:
83
+ Specialist: performance-reviewer
84
+ Objective: Perform a performance review
85
+ Scope: Review the proposed changes for performance issues.
86
+ Return: Findings with severity and file references.
87
+
88
+ Concurrent dispatch 3:
89
+ Specialist: correctness-reviewer
90
+ Objective: Perform a correctness review
91
+ Scope: Review the proposed changes for functional issues.
92
+ Return: Findings with severity and file references.
89
93
  ```
90
94
 
95
+ All three review dispatches run independently; the orchestrator synthesizes their results after all complete.
96
+
91
97
  ## Parallel Safety Check
92
98
 
93
99
  Before dispatching units in parallel, verify:
94
100
 
95
101
  1. **No file overlap** — build a file-to-unit map from each unit's declared files. Any file appearing in 2+ units means overlap → use serial dispatch instead.
96
- 2. **No git index contention** — parallel subagents must not stage files (`git add`), create commits, or run the full test suite. If the current workflow owns git operations, the orchestrator handles staging and committing after all parallel units complete; otherwise, synthesize results and file lists and leave staging/committing to the caller or user.
97
- 3. **No test interference** — concurrent test runs pick up each other's in-progress changes. Instruct parallel subagents not to run the project test suite.
102
+ 2. **No git index contention** — parallel specialists must not stage files (`git add`), create commits, or run the full test suite. If the current workflow owns git operations, the orchestrator handles staging and committing after all parallel units complete; otherwise, synthesize results and file lists and leave staging/committing to the caller or user.
103
+ 3. **No test interference** — concurrent test runs pick up each other's in-progress changes. Instruct parallel specialists not to run the project test suite.
98
104
 
99
- If any check fails, downgrade to serial dispatch. Log the reason (e.g., "Units 2 and 4 share `config/routes.rb` — using serial dispatch").
105
+ If any check fails, downgrade to serial dispatch. Log the reason (for example, "Units 2 and 4 share `config/routes.rb` — using serial dispatch").
100
106
 
101
107
  ## Subagent Constraints for Parallel Work
102
108
 
103
- When dispatching units in parallel, include these instructions in each subagent's prompt:
109
+ When dispatching units in parallel, include these instructions in each specialist's brief:
104
110
 
105
111
  > Do not stage files (`git add`), create commits, or run the project test suite. Leave staging and committing to the orchestrator or caller.
106
112
 
107
113
  ## Result Synthesis
108
114
 
109
- After subagents complete, the orchestrator synthesizes results:
115
+ After specialists complete, the orchestrator synthesizes results:
110
116
 
111
- 1. **Wait for all** — in a parallel batch, wait for every subagent to finish before acting on any result.
112
- 2. **Check for file collisions** — compare actual files modified by all subagents in the batch (not just declared files). If 2+ subagents modified the same file, only the last writer's version survives. If the workflow owns git operations, resolve by staging non-colliding files first, then re-running the affected units serially; otherwise, report the collision list to the caller.
117
+ 1. **Wait for all** — in a parallel batch, wait for every specialist to finish before acting on any result.
118
+ 2. **Check for file collisions** — compare actual files modified by all specialists in the batch (not just declared files). If 2+ specialists modified the same file, only the last writer's version survives. If the workflow owns git operations, resolve by staging non-colliding files first, then re-running the affected units serially; otherwise, report the collision list to the caller.
113
119
  3. **Review each diff** — verify changes match the unit's declared scope.
114
120
  4. **Run targeted tests** — run the narrowest test command relevant to the changed files.
115
121
  5. **Stage and commit per unit (if the workflow owns git operations)** — in dependency order, stage only that unit's files and commit with a conventional message. If git operations belong to the caller or user, synthesize the result list and file inventory instead.
116
122
 
117
123
  ## Failure and Retry
118
124
 
119
- - If a subagent returns an error or its output is incomplete, diagnose before dispatching dependent units.
125
+ - If a specialist returns an error or its output is incomplete, diagnose before dispatching dependent units.
120
126
  - Do not dispatch dependent units on a broken tree.
121
- - Retry a failed unit by dispatching a new `task()` call with a corrected prompt, or resume the prior session with `task_id`.
122
- - For background tasks (when available): wait for the automatic completion notification (the result is injected into the parent session). Do not poll or sleep. Retry by dispatching a new `task()` with a corrected prompt, or resume with `task_id`.
127
+ - Retry a failed unit by re-dispatching with a corrected brief, or resume the prior specialist session where the harness supports session reuse.
128
+ - For background work (when available): wait for the automatic completion notification (the result is delivered into the parent session). Do not poll or sleep. Retry by re-dispatching with a corrected brief, or resume the prior specialist session where the harness supports session reuse.
123
129
 
124
130
  ## Quick Reference
125
131
 
@@ -127,18 +133,18 @@ After subagents complete, the orchestrator synthesizes results:
127
133
  |---|---|
128
134
  | Units have dependencies | Serial foreground dispatch |
129
135
  | Units share files | Serial foreground dispatch |
130
- | Units are independent, no file overlap | Parallel foreground dispatch |
131
- | Background available + long-running work | Parallel background dispatch; results are pushed back to the parent on completion (no polling) |
136
+ | Units are independent, no file overlap | Concurrent dispatch where supported; otherwise batched foreground dispatch |
137
+ | Background available + long-running work | Concurrent background dispatch; results are pushed back to the parent on completion (no polling) |
132
138
  | Background unavailable | Foreground only — serial or batched |
133
- | Subagent fails | Diagnose, fix prompt, retry with new `task()` or resume with `task_id` |
139
+ | Specialist fails | Diagnose, correct the brief, then re-dispatch or resume the prior session where supported |
134
140
  | File collision detected post-parallel | Stage non-colliding files (if workflow owns git ops), re-run colliding units serially |
135
141
 
136
142
  ## Common Mistakes
137
143
 
138
144
  | Mistake | Fix |
139
145
  |---|---|
140
- | Polling or sleeping to wait for a background subagent | Background results are pushed into the parent session automatically; never poll or sleep |
141
- | Parallel subagents staging or committing | Instruct subagents not to stage/commit; the current workflow owner handles git ops when applicable, otherwise synthesize file inventory and results for the caller or user |
146
+ | Polling or sleeping to wait for background work | Background results are pushed into the parent session automatically; never poll or sleep |
147
+ | Parallel specialists staging or committing | Instruct specialists not to stage/commit; the current workflow owner handles git ops when applicable, otherwise synthesize file inventory and results for the caller or user |
142
148
  | Dispatching dependent units without waiting | Always wait for prerequisites to complete and verify their output |
143
149
  | Ignoring file overlap in parallel batches | Run the Parallel Safety Check before every parallel dispatch |
144
- | Using `background: true` without the experimental flag enabled | Only use background when `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true`; otherwise dispatch foreground |
150
+ | Assuming background support without checking the active profile | Use background dispatch only when the active harness profile declares it available; otherwise dispatch in the foreground |
@@ -11,7 +11,7 @@ Report bugs encountered while using the Systematic plugin. This skill gathers st
11
11
 
12
12
  ## Step 1: Gather Bug Information
13
13
 
14
- Ask the user the following questions (using the platform's blocking question tool — e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini — or present numbered options and wait for a reply):
14
+ Ask the user the following questions (using the platform's blocking question tool — e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait — or present numbered options and wait for a reply):
15
15
 
16
16
  **Question 1: Bug Category**
17
17
  - What type of issue are you experiencing?
@@ -14,7 +14,7 @@ Fetch and analyze the bug report to extract structured information before touchi
14
14
 
15
15
  ### Fetch the issue
16
16
 
17
- If no issue number or URL was provided as an argument, ask the user for one before proceeding (using the platform's question tool -- e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini -- or present a prompt and wait for a reply).
17
+ If no issue number or URL was provided as an argument, ask the user for one before proceeding (using the platform's question tool -- e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait -- or present a prompt and wait for a reply).
18
18
 
19
19
  ```bash
20
20
  gh issue view $ARGUMENTS --json title,body,comments,labels,assignees
@@ -111,7 +111,7 @@ When the bug is reproduced:
111
111
  For bugs that require specific data conditions, user roles, external service state, or cannot be automated:
112
112
 
113
113
  1. Document what conditions are needed
114
- 2. Ask the user (using the platform's question tool -- e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini -- or present options and wait for a reply) whether they can set up the required conditions
114
+ 2. Ask the user (using the platform's question tool -- e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait -- or present options and wait for a reply) whether they can set up the required conditions
115
115
  3. Guide them through manual reproduction steps if needed
116
116
 
117
117
  ### If reproduction fails
@@ -327,7 +327,7 @@ Still pending from a previous run (count):
327
327
 
328
328
  If a blocking question tool is available, use it to ask about all pending decisions (both new `needs-human` and previous-run pending) together. If there are only pending decisions and no new work was done, the summary is just the pending items.
329
329
 
330
- If a blocking question tool is available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini), use it to present the decisions and wait for the user's response. After they decide, process the remaining items: fix the code, compose the reply, post it, and resolve the thread.
330
+ If a blocking question tool is available (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait), use it to present the decisions and wait for the user's response. After they decide, process the remaining items: fix the code, compose the reply, post it, and resolve the thread.
331
331
 
332
332
  If no question tool is available, present the decisions in the summary output and wait for the user to respond in conversation. If they don't respond, the items remain open on the PR for later handling.
333
333
 
@@ -48,7 +48,7 @@ If not installed, inform the user: "`agent-browser` is not installed. Install it
48
48
 
49
49
  ### 2. Ask Browser Mode
50
50
 
51
- Ask the user whether to run headed or headless (using the platform's question tool — e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini — or present options and wait for a reply):
51
+ Ask the user whether to run headed or headless (using the platform's question tool — e.g., `question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini; in Pi, use the blocking-question extension if available, otherwise present numbered options in chat and wait — or present options and wait for a reply):
52
52
 
53
53
  ```
54
54
  Do you want to watch the browser tests run?
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: using-systematic
3
3
  description: Use when starting any conversation - establishes how to find and use skills, requiring skill tool invocation before ANY response including clarifying questions
4
+ metadata:
5
+ harness-portability: neutral-v1
4
6
  ---
5
7
 
6
8
  <SUBAGENT-STOP>
@@ -27,8 +29,6 @@ If CLAUDE.md, GEMINI.md, or AGENTS.md says "don't use TDD" and a skill says "alw
27
29
 
28
30
  ## How to Access Skills
29
31
 
30
- Use the `systematic_skill` tool for Systematic bundled skills. Use the `skill` tool for non-Systematic skills. When you invoke a skill, its content is loaded and presented to you—follow it directly.
31
-
32
32
  # Using Skills
33
33
 
34
34
  ## The Rule
@@ -106,6 +106,10 @@ The skill itself tells you which.
106
106
 
107
107
  Instructions say WHAT, not HOW. "Add X" or "Fix Y" doesn't mean skip workflows.
108
108
 
109
- ## Skill Resolution
109
+ ## Capability Resolution
110
+
111
+ The four capabilities are subagent delegation, blocking user interaction, task tracking, and skill loading.
112
+
113
+ The bootstrap inlines the active harness profile naming the exact mechanisms—consult it. See `references/opencode-profile.md` and `references/pi-profile.md`.
110
114
 
111
- Systematic bundled skills are listed in the `systematic_skill` tool description. Use the `skill` tool for skills outside the Systematic plugin.
115
+ When a mechanism is unavailable, present numbered options in chat and wait for questions, maintain a visible list for task tracking, and dispatch delegation sequentially or do the work inline.
@@ -0,0 +1,57 @@
1
+ # OpenCode Capability Profile
2
+
3
+ Evidence registry: see [`HARNESSES.md`](../../../HARNESSES.md).
4
+
5
+ | Capability | Mechanism | Status | Fallback |
6
+ |---|---|---|---|
7
+ | Subagent delegation | `task()` tool; `subagent_type` selects a specialist, `task_id` resumes a session | supported; parallel and background dispatch may be available | Dispatch in the foreground, serially or in small batches |
8
+ | Blocking user interaction | `question` tool | supported | Present numbered options in chat and wait |
9
+ | Task tracking | `todowrite` | supported | Maintain a visible task list in responses |
10
+ | Skill loading | `systematic_skill` for bundled skills; `skill` tool for non-Systematic skills | supported | Read the skill instructions listed by the active harness |
11
+
12
+ ## Invocation examples
13
+
14
+ ### Subagent delegation
15
+
16
+ ```typescript
17
+ task({
18
+ subagent_type: "systematic-implementer",
19
+ description: "Implement auth module",
20
+ prompt: "Implement the auth module and return the changed files.",
21
+ })
22
+
23
+ // Background dispatch (run independent work concurrently; reconcile on completion):
24
+ task({
25
+ subagent_type: "explorer",
26
+ description: "Map fixture patterns",
27
+ prompt: "…",
28
+ background: true,
29
+ })
30
+
31
+ // Resume a prior specialist session:
32
+ task({ subagent_type: "fixer", task_id: "<prior-session-id>", description: "Resume fixer task", prompt: "…" })
33
+ ```
34
+
35
+ ### Blocking user interaction
36
+
37
+ ```typescript
38
+ question({
39
+ questions: [{ question: "Which deployment target should I use?", header: "Deployment target",
40
+ options: [{ label: "Staging", description: "Deploy to staging" }] }],
41
+ })
42
+ ```
43
+
44
+ ### Task tracking
45
+
46
+ ```typescript
47
+ todowrite({
48
+ todos: [{ content: "Run validation", status: "pending", priority: "high" }],
49
+ })
50
+ ```
51
+
52
+ ### Skill loading
53
+
54
+ ```typescript
55
+ systematic_skill({ name: "systematic:using-systematic" })
56
+ skill({ name: "external-skill" })
57
+ ```
@@ -0,0 +1,44 @@
1
+ # Pi Capability Profile
2
+
3
+ Evidence registry: see [`HARNESSES.md`](../../../HARNESSES.md).
4
+
5
+ | Capability | Mechanism | Status | Fallback |
6
+ |---|---|---|---|
7
+ | Subagent delegation | `systematic_delegate({agent, task})` with bundled personas | degraded; execution is sequential only | Dispatch sequentially in dependency order or do the work inline |
8
+ | Blocking user interaction | No native blocking tool | degraded | Present numbered options in chat and wait |
9
+ | Task tracking | No native task-tracking mechanism | unavailable | Maintain a visible task list in responses |
10
+ | Skill loading | `systematic_skill` tool or Pi-native skill activation | supported | Read the skill instructions listed by the active harness |
11
+
12
+ ## Invocation examples
13
+
14
+ ### Subagent delegation
15
+
16
+ ```typescript
17
+ systematic_delegate({
18
+ agent: "systematic-implementer",
19
+ task: "Implement the auth module and return the changed files.",
20
+ })
21
+ ```
22
+
23
+ ### Blocking user interaction
24
+
25
+ ```text
26
+ 1. Deploy to staging
27
+ 2. Deploy to production
28
+
29
+ Reply with the number of your choice.
30
+ ```
31
+
32
+ ### Task tracking
33
+
34
+ ```text
35
+ Task list:
36
+ - [ ] Implement the auth module
37
+ - [ ] Run validation
38
+ ```
39
+
40
+ ### Skill loading
41
+
42
+ ```typescript
43
+ systematic_skill({ name: "systematic:using-systematic" })
44
+ ```