ultimate-pi 0.11.0 → 0.13.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.
Files changed (137) hide show
  1. package/.agents/skills/ck-search/SKILL.md +11 -87
  2. package/.agents/skills/cocoindex-search/SKILL.md +35 -0
  3. package/.agents/skills/harness-debate-plan/SKILL.md +44 -0
  4. package/.agents/skills/harness-decisions/SKILL.md +1 -1
  5. package/.agents/skills/harness-orchestration/SKILL.md +54 -28
  6. package/.agents/skills/harness-plan/SKILL.md +15 -20
  7. package/.pi/PACKAGING.md +1 -0
  8. package/.pi/SYSTEM.md +21 -20
  9. package/.pi/agents/harness/adversary.md +0 -1
  10. package/.pi/agents/harness/evaluator.md +0 -1
  11. package/.pi/agents/harness/executor.md +1 -2
  12. package/.pi/agents/harness/incident-recorder.md +0 -1
  13. package/.pi/agents/harness/meta-optimizer.md +0 -1
  14. package/.pi/agents/harness/planning/decompose.md +3 -4
  15. package/.pi/agents/harness/planning/execution-plan-author.md +30 -0
  16. package/.pi/agents/harness/planning/hypothesis-validator.md +23 -0
  17. package/.pi/agents/harness/planning/hypothesis.md +3 -4
  18. package/.pi/agents/harness/planning/plan-adversary.md +10 -42
  19. package/.pi/agents/harness/planning/plan-evaluator.md +18 -0
  20. package/.pi/agents/harness/planning/review-integrator.md +23 -0
  21. package/.pi/agents/harness/planning/scout-graphify.md +13 -5
  22. package/.pi/agents/harness/planning/scout-semantic.md +23 -11
  23. package/.pi/agents/harness/planning/scout-structure.md +12 -6
  24. package/.pi/agents/harness/planning/sprint-contract-auditor.md +18 -0
  25. package/.pi/agents/harness/planning/stack-researcher.md +24 -0
  26. package/.pi/agents/harness/tie-breaker.md +0 -1
  27. package/.pi/agents/harness/trace-librarian.md +0 -1
  28. package/.pi/extensions/debate-orchestrator.ts +90 -53
  29. package/.pi/extensions/harness-plan-approval.ts +2 -2
  30. package/.pi/extensions/harness-run-context.ts +150 -5
  31. package/.pi/extensions/harness-subagents.ts +17 -6
  32. package/.pi/extensions/lib/harness-cocoindex-refresh.ts +49 -0
  33. package/.pi/extensions/lib/harness-posthog.ts +6 -1
  34. package/.pi/extensions/lib/harness-spawn-budget.ts +75 -0
  35. package/.pi/extensions/lib/harness-subagent-auth.ts +123 -0
  36. package/.pi/extensions/lib/{harness-subagents/harness-subagent-policy.ts → harness-subagent-policy.ts} +8 -7
  37. package/.pi/extensions/lib/harness-subagent-precheck.ts +95 -0
  38. package/.pi/extensions/lib/harness-subagents-bridge.ts +122 -0
  39. package/.pi/extensions/lib/plan-approval/create-plan.ts +4 -7
  40. package/.pi/extensions/lib/plan-approval/plan-review.ts +1 -1
  41. package/.pi/extensions/lib/plan-approval/types.ts +7 -1
  42. package/.pi/extensions/lib/plan-debate-envelope.ts +84 -0
  43. package/.pi/extensions/lib/{harness-subagents/spawn-policy.ts → spawn-policy.ts} +1 -0
  44. package/.pi/extensions/policy-gate.ts +1 -1
  45. package/.pi/extensions/review-integrity.ts +48 -29
  46. package/.pi/harness/agents.manifest.json +37 -25
  47. package/.pi/harness/docs/adrs/0032-harness-command-orchestration.md +4 -3
  48. package/.pi/harness/docs/adrs/0033-parent-orchestrated-planning.md +2 -2
  49. package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +27 -0
  50. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/review-round-r1.yaml +25 -0
  51. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/review-round-r4.yaml +26 -0
  52. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/sprint-audit-r4.yaml +5 -0
  53. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/plan-packet.yaml +196 -0
  54. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/plan-review.md +14 -0
  55. package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/research-brief.yaml +32 -0
  56. package/.pi/harness/evals/smoke/run-context.fixture.json +1 -1
  57. package/.pi/harness/evals/smoke/smoke-harness-plan.mjs +88 -0
  58. package/.pi/harness/specs/harness-posthog-event.schema.json +6 -1
  59. package/.pi/harness/specs/plan-execution-plan-brief.schema.json +13 -0
  60. package/.pi/harness/specs/plan-execution-plan.schema.json +255 -0
  61. package/.pi/harness/specs/plan-packet.schema.json +14 -5
  62. package/.pi/harness/specs/plan-review-round-draft.schema.json +68 -0
  63. package/.pi/harness/specs/plan-sprint-audit-turn.schema.json +29 -0
  64. package/.pi/harness/specs/plan-stack-brief.schema.json +65 -0
  65. package/.pi/harness/specs/plan-validation-turn.schema.json +42 -0
  66. package/.pi/harness/specs/round-result.schema.json +16 -9
  67. package/.pi/lib/debate-orchestrator-types.ts +38 -0
  68. package/.pi/lib/harness-agent-discovery.mjs +81 -0
  69. package/.pi/lib/harness-run-context.ts +64 -38
  70. package/.pi/lib/harness-yaml.mjs +73 -0
  71. package/.pi/lib/harness-yaml.ts +90 -0
  72. package/.pi/prompts/harness-auto.md +13 -11
  73. package/.pi/prompts/harness-critic.md +2 -2
  74. package/.pi/prompts/harness-eval.md +3 -3
  75. package/.pi/prompts/harness-incident.md +2 -2
  76. package/.pi/prompts/harness-plan.md +83 -92
  77. package/.pi/prompts/harness-review.md +2 -2
  78. package/.pi/prompts/harness-router-tune.md +1 -1
  79. package/.pi/prompts/harness-run.md +2 -2
  80. package/.pi/prompts/harness-setup.md +30 -17
  81. package/.pi/prompts/harness-trace.md +2 -2
  82. package/.pi/scripts/README.md +1 -0
  83. package/.pi/scripts/harness-agents-manifest.mjs +1 -1
  84. package/.pi/scripts/harness-cli-verify.sh +24 -14
  85. package/.pi/scripts/harness-cocoindex-bootstrap.sh +182 -0
  86. package/.pi/scripts/harness-verify.mjs +38 -19
  87. package/.pi/scripts/validate-plan-dag.mjs +258 -0
  88. package/.pi/scripts/vendor-sync-pi-subagents.sh +19 -0
  89. package/.pi/skills/ast-grep/SKILL.md +2 -2
  90. package/.pi/skills/ccc/SKILL.md +142 -0
  91. package/.pi/skills/ccc/references/management.md +110 -0
  92. package/CHANGELOG.md +22 -0
  93. package/THIRD_PARTY_NOTICES.md +15 -0
  94. package/biome.json +2 -2
  95. package/package.json +7 -4
  96. package/vendor/pi-subagents/LICENSE +21 -0
  97. package/vendor/pi-subagents/UPSTREAM_PIN.md +11 -0
  98. package/vendor/pi-subagents/src/agents.ts +357 -0
  99. package/vendor/pi-subagents/src/subagents.ts +1463 -0
  100. package/.pi/agents/harness/planner.md +0 -13
  101. package/.pi/agents/harness/planning/hypothesis-eval.md +0 -59
  102. package/.pi/agents/harness/planning/planner.md +0 -20
  103. package/.pi/extensions/lib/harness-subagents/agent-loader.ts +0 -126
  104. package/.pi/extensions/lib/harness-subagents/agent-manifest.ts +0 -119
  105. package/.pi/extensions/lib/harness-subagents/agent-parser.ts +0 -87
  106. package/.pi/extensions/lib/harness-subagents/blackboard-tool.ts +0 -118
  107. package/.pi/extensions/lib/harness-subagents/blackboard.ts +0 -175
  108. package/.pi/extensions/lib/harness-subagents/parent-ask-user-bridge.ts +0 -10
  109. package/.pi/extensions/lib/harness-subagents/parent-harness-ui-bridge.ts +0 -137
  110. package/.pi/extensions/lib/harness-subagents/parent-harness-ui-hooks.ts +0 -77
  111. package/.pi/extensions/lib/harness-subagents/types-blackboard.ts +0 -27
  112. package/.pi/extensions/lib/harness-subagents/vendored/agent-manager.ts +0 -558
  113. package/.pi/extensions/lib/harness-subagents/vendored/agent-runner.ts +0 -666
  114. package/.pi/extensions/lib/harness-subagents/vendored/agent-types.ts +0 -175
  115. package/.pi/extensions/lib/harness-subagents/vendored/context.ts +0 -59
  116. package/.pi/extensions/lib/harness-subagents/vendored/cross-extension-rpc.ts +0 -134
  117. package/.pi/extensions/lib/harness-subagents/vendored/custom-agents.ts +0 -5
  118. package/.pi/extensions/lib/harness-subagents/vendored/default-agents.ts +0 -123
  119. package/.pi/extensions/lib/harness-subagents/vendored/env.ts +0 -43
  120. package/.pi/extensions/lib/harness-subagents/vendored/group-join.ts +0 -144
  121. package/.pi/extensions/lib/harness-subagents/vendored/index.ts +0 -2460
  122. package/.pi/extensions/lib/harness-subagents/vendored/invocation-config.ts +0 -52
  123. package/.pi/extensions/lib/harness-subagents/vendored/memory.ts +0 -182
  124. package/.pi/extensions/lib/harness-subagents/vendored/model-resolver.ts +0 -92
  125. package/.pi/extensions/lib/harness-subagents/vendored/output-file.ts +0 -115
  126. package/.pi/extensions/lib/harness-subagents/vendored/prompts.ts +0 -103
  127. package/.pi/extensions/lib/harness-subagents/vendored/schedule-store.ts +0 -177
  128. package/.pi/extensions/lib/harness-subagents/vendored/schedule.ts +0 -416
  129. package/.pi/extensions/lib/harness-subagents/vendored/settings.ts +0 -210
  130. package/.pi/extensions/lib/harness-subagents/vendored/skill-loader.ts +0 -108
  131. package/.pi/extensions/lib/harness-subagents/vendored/types.ts +0 -187
  132. package/.pi/extensions/lib/harness-subagents/vendored/ui/agent-widget.ts +0 -639
  133. package/.pi/extensions/lib/harness-subagents/vendored/ui/conversation-viewer.ts +0 -324
  134. package/.pi/extensions/lib/harness-subagents/vendored/ui/schedule-menu.ts +0 -110
  135. package/.pi/extensions/lib/harness-subagents/vendored/usage.ts +0 -71
  136. package/.pi/extensions/lib/harness-subagents/vendored/worktree.ts +0 -195
  137. /package/.pi/extensions/{00-ultimate-pi-system-prompt.ts → custom-system-prompt.ts} +0 -0
@@ -1,50 +1,18 @@
1
1
  ---
2
- description: Plan adversary (pre-approval) edge cases and acceptance gaps on a draft PlanPacket.
3
- tools: read, grep, find, ls, bash
4
- disallowed_tools: write, edit, ask_user, approve_plan, create_plan, Agent
2
+ description: Plan-phase adversarial verification on ExecutionPlan.
3
+ tools: read, grep, find, ls
4
+ disallowed_tools: write, edit, bash, ask_user, approve_plan, create_plan, subagent
5
5
  extensions: false
6
- thinking: high
7
- max_turns: 15
8
- inherit_context: false
6
+ thinking: medium
7
+ max_turns: 12
9
8
  ---
10
9
 
11
- You are the **Harness plan adversary (pre-approval)**. Not the post-run `harness/adversary`.
10
+ You are **plan-adversary** break the plan with reproducible counterexamples.
12
11
 
13
- ## Mission
12
+ Engage failed/warn checks from the same round's `plan-evaluator` first, then independent attacks. Cite `work_item_id` / `phase_id`.
14
13
 
15
- Pressure-test a **draft** `PlanPacket` for **execution risk** before the user approves. Surface edge cases, failure modes, and missing acceptance checks tied to hypothesis-derived `acceptance_checks`. Read-only — no mutations.
14
+ ## Output
16
15
 
17
- Do **not** re-score DARWIN novelty or duplicate hypothesis-eval work.
16
+ Valid **YAML only** `PlanAdversaryBrief` (`.pi/harness/specs/plan-adversary-brief.schema.json`).
18
17
 
19
- ## Input
20
-
21
- The spawn prompt includes:
22
-
23
- - `HarnessSpawnContext`
24
- - Draft `PlanPacket` JSON
25
- - Scout lane summaries (graphify, structure, semantic)
26
-
27
- ## Process
28
-
29
- 1. Assume the plan has hidden gaps until you justify `recommendation: proceed`.
30
- 2. Tie every finding to evidence (paths, APIs, or scout findings) — no speculation without a probe path.
31
- 3. Propose concrete `mitigations` the parent can merge into scope, assumptions, or `acceptance_checks`.
32
- 4. Empty arrays are allowed when no material gaps exist; say so in `human_summary`.
33
-
34
- ## Output (required JSON block)
35
-
36
- Match `PlanAdversaryBrief` (`.pi/harness/specs/plan-adversary-brief.schema.json`):
37
-
38
- ```json
39
- {
40
- "schema_version": "1.0.0",
41
- "edge_cases": ["…"],
42
- "failure_modes": ["…"],
43
- "acceptance_gaps": ["…"],
44
- "mitigations": ["…"],
45
- "recommendation": "proceed",
46
- "human_summary": "…"
47
- }
48
- ```
49
-
50
- Use `"recommendation": "revise"` when scope or acceptance must change before execution.
18
+ Bus label: `PlanAdversarysubagent`.
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Plan-phase Validation Checks evaluator (neutral pass/fail).
3
+ tools: read, grep, find, ls
4
+ disallowed_tools: write, edit, bash, ask_user, approve_plan, create_plan, subagent
5
+ extensions: false
6
+ thinking: medium
7
+ max_turns: 12
8
+ ---
9
+
10
+ You are **plan-evaluator** — score ExecutionPlan against Validation Checks (not an advocate).
11
+
12
+ Parent passes `debate_round_focus`: `spec` | `wbs` | `schedule` | `quality`.
13
+
14
+ ## Output
15
+
16
+ Valid **YAML only** — `PlanValidationTurn` (`.pi/harness/specs/plan-validation-turn.schema.json`). Fail if `dag_validation.status === "fail"`.
17
+
18
+ Bus label: `PlanEvaluatorsubagent`.
@@ -0,0 +1,23 @@
1
+ ---
2
+ description: Plan-phase Review Gate integrator (round → debate bus).
3
+ tools: read, grep, find, ls
4
+ disallowed_tools: write, edit, bash, ask_user, approve_plan, create_plan, subagent
5
+ extensions: false
6
+ thinking: medium
7
+ max_turns: 10
8
+ ---
9
+
10
+ You are **review-integrator** — merge evaluator, adversary, sprint audit, and hypothesis-validator outputs into a Review Gate draft.
11
+
12
+ ## Output
13
+
14
+ Valid **YAML only** — `PlanReviewRoundDraft` (`.pi/harness/specs/plan-review-round-draft.schema.json`) with:
15
+
16
+ - `round_summary`, `validation_summary`, `adversary_summary`
17
+ - `disputes[]`, `recommended_packet_patches[]` (JSON Pointer paths)
18
+ - `review_gate_ready` boolean
19
+ - `participants`, `claims`, `rebuttals`, `evidence_refs`, `token_usage`, `severity_scores`
20
+
21
+ Parent runs `buildPlanReviewRoundEnvelope` → `/harness-debate-round`.
22
+
23
+ Bus label: `ReviewIntegratorsubagent`.
@@ -1,11 +1,10 @@
1
1
  ---
2
2
  description: Plan-phase scout — graphify graph and wiki navigation (read-only).
3
- tools: read, grep, find, ls, bash
4
- disallowed_tools: write, edit, ask_user, approve_plan, create_plan, Agent
3
+ tools: read, bash, ls
4
+ disallowed_tools: write, edit, ask_user, approve_plan, create_plan, subagent, grep, find
5
5
  extensions: false
6
- thinking: medium
7
- max_turns: 12
8
- inherit_context: false
6
+ thinking: low
7
+ max_turns: 6
9
8
  ---
10
9
 
11
10
  You are the **Harness planning scout (graphify lane)**.
@@ -16,6 +15,8 @@ Explore the codebase via graphify for the task in `HarnessSpawnContext`. You do
16
15
 
17
16
  Findings should feed **constraints, prior art, and tensions** for the decompose agent (existing patterns, god nodes, surprising connections).
18
17
 
18
+ **Lane contract:** you own **relationships and architecture** (`graphify query`, `explain`, `path`). `scout-semantic` owns implementation-by-meaning via `ccc search` — do not duplicate semantic chunk search here.
19
+
19
20
  ## Spawn context
20
21
 
21
22
  Read `HarnessSpawnContext` in the spawn prompt (`task_summary`, `mode`, `plan_packet_path`, `risk_level`, `quick`). For `mode: revise`, read the existing plan at `plan_packet_path` first and focus findings on what changed or is at risk.
@@ -25,11 +26,18 @@ Read `HarnessSpawnContext` in the spawn prompt (`task_summary`, `mode`, `plan_pa
25
26
  1. Read `graphify-out/GRAPH_REPORT.md` when present; use `graphify query`, `graphify path`, or `graphify explain` for the task (read-only CLI only).
26
27
  2. If `graphify-out/` is missing, say so in `findings` and `open_questions` — do not run `graphify update` or installs.
27
28
  3. Do not read `.pi/harness/specs/*.schema.json` from disk.
29
+ 4. **Stop early** — target ≤6 tool calls when possible.
28
30
 
29
31
  ## Bash guardrails
30
32
 
31
33
  Read-only only: no `graphify update`, `graphify extract`, `pip install`, redirects (`>`, `>>`), or file creation. Allowed: `graphify query`, `graphify path`, `graphify explain`, `ls`, `cat`, `head`.
32
34
 
35
+ ## Output limits
36
+
37
+ - `findings`: at most **8** bullets, each ≤2 sentences
38
+ - `key_paths`: at most **10** absolute paths
39
+ - `open_questions`: at most **5** items
40
+
33
41
  ## Output (required JSON block)
34
42
 
35
43
  End with one fenced `json` block:
@@ -1,18 +1,19 @@
1
1
  ---
2
- description: Plan-phase scout — ck semantic code search (read-only).
3
- tools: read, grep, find, ls, bash
4
- disallowed_tools: write, edit, ask_user, approve_plan, create_plan, Agent
2
+ description: Plan-phase scout — CocoIndex semantic code search (read-only).
3
+ tools: read, bash, ls
4
+ disallowed_tools: write, edit, ask_user, approve_plan, create_plan, subagent, grep, find
5
5
  extensions: false
6
- thinking: medium
7
- max_turns: 12
8
- inherit_context: false
6
+ thinking: low
7
+ max_turns: 6
9
8
  ---
10
9
 
11
10
  You are the **Harness planning scout (semantic lane)**.
12
11
 
13
12
  ## Mission
14
13
 
15
- Find conceptually related code via ck semantic search for the task in `HarnessSpawnContext`. You do **not** build the PlanPacket or mutate files.
14
+ Find conceptually related **implementation** via CocoIndex (`ccc search`) for the task in `HarnessSpawnContext`. You do **not** build the PlanPacket or mutate files.
15
+
16
+ **Lane contract:** `scout-graphify` owns relationships, callers, and communities. You own **meaning** — functions, classes, and chunks that implement the task.
16
17
 
17
18
  ## Spawn context
18
19
 
@@ -20,13 +21,24 @@ Read `HarnessSpawnContext` in the spawn prompt. For `mode: revise`, bias searche
20
21
 
21
22
  ## Process
22
23
 
23
- 1. Use `ck search` or `ck query` (or project-documented ck CLI) with task-focused queries.
24
- 2. If ck is unavailable, set `status: partial` and document in `findings`.
25
- 3. Cap output prefer the top 5–10 most relevant paths.
24
+ 1. Run **2–3** task-focused queries: `ccc search "<query>" --limit 5` (add `--path` when spawn context names a directory).
25
+ 2. The harness runs incremental `ccc index` before scouts spawn — **do not** run `ccc index`, `ccc init`, or `ccc search --refresh`.
26
+ 3. If `ccc` is missing or the index is empty: `status: partial` and document in `findings`.
27
+ 4. **Stop early** — top **5** most relevant paths only.
26
28
 
27
29
  ## Bash guardrails
28
30
 
29
- Read-only only: no installs, index rebuilds that mutate disk, or redirects.
31
+ Read-only only: no installs, indexing, daemon control, or redirects.
32
+
33
+ **Allowed:** `ccc search`, `ccc status`, `ls`, `head`, `cat`, `sed -n` (read slices).
34
+
35
+ **Forbidden:** `ccc index`, `ccc init`, `ccc reset`, `ccc daemon`, `ccc search --refresh`, package installs.
36
+
37
+ ## Output limits
38
+
39
+ - `findings`: at most **6** bullets
40
+ - `key_paths`: at most **8** absolute paths
41
+ - `open_questions`: at most **4** items
30
42
 
31
43
  ## Output (required JSON block)
32
44
 
@@ -1,11 +1,10 @@
1
1
  ---
2
2
  description: Plan-phase scout — ast-grep structural code search (read-only).
3
- tools: read, grep, find, ls, bash
4
- disallowed_tools: write, edit, ask_user, approve_plan, create_plan, Agent
3
+ tools: read, bash, ls
4
+ disallowed_tools: write, edit, ask_user, approve_plan, create_plan, subagent, grep, find
5
5
  extensions: false
6
- thinking: medium
7
- max_turns: 12
8
- inherit_context: false
6
+ thinking: low
7
+ max_turns: 6
9
8
  ---
10
9
 
11
10
  You are the **Harness planning scout (structure lane)**.
@@ -22,14 +21,21 @@ Read `HarnessSpawnContext` in the spawn prompt. For `mode: revise`, read the exi
22
21
 
23
22
  ## Process
24
23
 
25
- 1. Run `sg -p '…'` with patterns tied to the task (handlers, types, exports, call sites).
24
+ 1. Run `sg -p '…'` with patterns tied to the task (handlers, types, exports, call sites). **Do not use `find` or `grep`.**
26
25
  2. Prefer absolute paths in `key_paths`.
27
26
  3. If `sg` is not on PATH, set `status: partial` and note the tooling gap in `findings`.
27
+ 4. **Stop early** — target ≤6 tool calls when possible.
28
28
 
29
29
  ## Bash guardrails
30
30
 
31
31
  Read-only only: no installs, redirects, or mutating git/npm commands.
32
32
 
33
+ ## Output limits
34
+
35
+ - `findings`: at most **8** bullets
36
+ - `key_paths`: at most **10** absolute paths
37
+ - `open_questions`: at most **5** items
38
+
33
39
  ## Output (required JSON block)
34
40
 
35
41
  ```json
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Plan-phase ADR-020 sprint contract auditor.
3
+ tools: read, grep, find, ls
4
+ disallowed_tools: write, edit, bash, ask_user, approve_plan, create_plan, subagent
5
+ extensions: false
6
+ thinking: medium
7
+ max_turns: 10
8
+ ---
9
+
10
+ You are **sprint-contract-auditor** — ADR-020 Sprint Contract, Done Criteria Types, checkpoints, Keep Quality Left.
11
+
12
+ Required on debate **round 4**; optional spot-check round 2 if done_criteria sparse.
13
+
14
+ ## Output
15
+
16
+ Valid **YAML only** — `PlanSprintAuditTurn` (`.pi/harness/specs/plan-sprint-audit-turn.schema.json`).
17
+
18
+ Bus label: `SprintContractAuditorsubagent`.
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Plan-phase stack research (ctx7 + web, read-only file writes via parent).
3
+ tools: read, grep, find, ls, bash, web_search, web_fetch
4
+ disallowed_tools: write, edit, ask_user, approve_plan, create_plan, subagent
5
+ extensions: false
6
+ thinking: medium
7
+ max_turns: 14
8
+ ---
9
+
10
+ You are **stack-researcher** — evidence-backed stack recommendations for harness planning.
11
+
12
+ ## Mission
13
+
14
+ Produce `PlanStackBrief` with ranked options. For brownfield tasks, always include **extend current stack** as one ranked option.
15
+
16
+ ## Protocol
17
+
18
+ 1. **Libraries / APIs:** `ctx7 library` → `ctx7 docs` (read context7-cli skill). Cite library IDs in `evidence_refs`.
19
+ 2. **Comparisons / landscape:** `web_search` + `web_fetch` (`.web/` artifacts).
20
+ 3. **Greenfield:** ≥3 distinct options with pros/cons/risks.
21
+
22
+ ## Output
23
+
24
+ Return valid **YAML only** (no fences) matching `PlanStackBrief` (`.pi/harness/specs/plan-stack-brief.schema.json`). Parent writes `artifacts/stack.yaml`.
@@ -5,7 +5,6 @@ extensions: false
5
5
  disallowed_tools: ask_user
6
6
  thinking: high
7
7
  max_turns: 15
8
- inherit_context: false
9
8
  ---
10
9
 
11
10
  You are the Harness Tie-Breaker.
@@ -4,7 +4,6 @@ tools: read, grep, find, ls
4
4
  extensions: false
5
5
  thinking: medium
6
6
  max_turns: 20
7
- inherit_context: false
8
7
  ---
9
8
 
10
9
  You are the Harness Trace Librarian.
@@ -14,16 +14,20 @@
14
14
  * }
15
15
  */
16
16
 
17
- import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
17
+ import { appendFile, mkdir, writeFile } from "node:fs/promises";
18
18
  import { join } from "node:path";
19
19
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
20
+ import {
21
+ type DebateParticipant,
22
+ debatePhaseFromId,
23
+ isPlanDebateId,
24
+ PLAN_DEBATE_PARTICIPANTS,
25
+ POST_EXECUTE_DEBATE_PARTICIPANTS,
26
+ } from "../lib/debate-orchestrator-types.js";
20
27
  import { getRunIdFromSession } from "../lib/harness-run-context.js";
21
28
 
22
- type DebateParticipant =
23
- | "EvaluatorAgent"
24
- | "AdversaryAgent"
25
- | "TieBreakerAgent";
26
29
  type PolicyDecision = "pass" | "conditional_pass" | "block" | "human_required";
30
+ type DebatePhase = "plan" | "post_execute";
27
31
 
28
32
  interface RoundPayload {
29
33
  participants: DebateParticipant[];
@@ -46,11 +50,13 @@ interface RoundPayload {
46
50
  interface DebateState {
47
51
  run_id: string;
48
52
  debate_id: string;
53
+ debate_phase: DebatePhase;
49
54
  round_count: number;
50
55
  budget_used: number;
51
56
  max_rounds: number;
52
57
  round_token_cap: number;
53
58
  debate_global_cap: number;
59
+ last_review_gate_ready?: boolean;
54
60
  }
55
61
 
56
62
  interface BusEnvelope<T = unknown> {
@@ -104,46 +110,39 @@ function getRunId(ctx: {
104
110
  );
105
111
  }
106
112
 
107
- async function readRoundCapsFromSchema(): Promise<{
113
+ const PLAN_BUDGET = {
114
+ max_rounds: 4,
115
+ round_token_cap: 2000,
116
+ debate_global_cap: 12000,
117
+ } as const;
118
+
119
+ const AGGRESSIVE_BUDGET = {
120
+ max_rounds: 6,
121
+ round_token_cap: 2500,
122
+ debate_global_cap: 35000,
123
+ } as const;
124
+
125
+ function capsForDebate(debateId: string): {
126
+ name: "plan" | "aggressive";
108
127
  max_rounds: number;
109
128
  round_token_cap: number;
110
129
  debate_global_cap: number;
111
- }> {
112
- try {
113
- const roundSchemaPath = join(
114
- process.cwd(),
115
- ".pi",
116
- "harness",
117
- "specs",
118
- "round-result.schema.json",
130
+ } {
131
+ if (isPlanDebateId(debateId)) {
132
+ return { name: "plan", ...PLAN_BUDGET };
133
+ }
134
+ return { name: "aggressive", ...AGGRESSIVE_BUDGET };
135
+ }
136
+
137
+ function participantAllowed(participant: string, phase: DebatePhase): boolean {
138
+ if (phase === "plan") {
139
+ return (PLAN_DEBATE_PARTICIPANTS as readonly string[]).includes(
140
+ participant,
119
141
  );
120
- const parsed = JSON.parse(await readFile(roundSchemaPath, "utf-8")) as {
121
- properties?: {
122
- budget_profile?: {
123
- properties?: {
124
- max_rounds?: { const?: number };
125
- round_token_cap?: { const?: number };
126
- debate_global_cap?: { const?: number };
127
- };
128
- };
129
- };
130
- };
131
- return {
132
- max_rounds: Number(
133
- parsed?.properties?.budget_profile?.properties?.max_rounds?.const ?? 6,
134
- ),
135
- round_token_cap: Number(
136
- parsed?.properties?.budget_profile?.properties?.round_token_cap
137
- ?.const ?? 2500,
138
- ),
139
- debate_global_cap: Number(
140
- parsed?.properties?.budget_profile?.properties?.debate_global_cap
141
- ?.const ?? 35000,
142
- ),
143
- };
144
- } catch {
145
- return { max_rounds: 6, round_token_cap: 2500, debate_global_cap: 35000 };
146
142
  }
143
+ return (POST_EXECUTE_DEBATE_PARTICIPANTS as readonly string[]).includes(
144
+ participant,
145
+ );
147
146
  }
148
147
 
149
148
  async function writeDebateEvent(
@@ -197,13 +196,18 @@ export default function debateOrchestrator(pi: ExtensionAPI) {
197
196
  let lastSeverity = defaultSeverity();
198
197
 
199
198
  async function openDebate(runId: string, debateId: string): Promise<void> {
200
- const caps = await readRoundCapsFromSchema();
199
+ const caps = capsForDebate(debateId);
200
+ const debate_phase = debatePhaseFromId(debateId);
201
201
  state = {
202
202
  run_id: runId,
203
203
  debate_id: debateId,
204
+ debate_phase,
204
205
  round_count: 0,
205
206
  budget_used: 0,
206
- ...caps,
207
+ max_rounds: caps.max_rounds,
208
+ round_token_cap: caps.round_token_cap,
209
+ debate_global_cap: caps.debate_global_cap,
210
+ last_review_gate_ready: false,
207
211
  };
208
212
  pi.appendEntry("harness-debate-state", state);
209
213
  const envelope: BusEnvelope = {
@@ -216,7 +220,8 @@ export default function debateOrchestrator(pi: ExtensionAPI) {
216
220
  },
217
221
  payload: {
218
222
  opened_at: nowIso(),
219
- budget_profile: "aggressive",
223
+ debate_phase,
224
+ budget_profile: caps.name,
220
225
  },
221
226
  };
222
227
  pi.appendEntry("harness-debate-envelope", envelope);
@@ -267,6 +272,15 @@ export default function debateOrchestrator(pi: ExtensionAPI) {
267
272
  return { ok: false, reason: "debate id mismatch" };
268
273
  }
269
274
 
275
+ for (const p of envelope.payload.participants ?? []) {
276
+ if (!participantAllowed(p, state.debate_phase)) {
277
+ return {
278
+ ok: false,
279
+ reason: `participant ${p} invalid for debate_phase=${state.debate_phase}`,
280
+ };
281
+ }
282
+ }
283
+
270
284
  const nextRound = state.round_count + 1;
271
285
  if (nextRound > state.max_rounds) {
272
286
  await emitBudgetExhausted("max_rounds_reached");
@@ -310,6 +324,11 @@ export default function debateOrchestrator(pi: ExtensionAPI) {
310
324
  };
311
325
  }
312
326
 
327
+ const profileName =
328
+ state.debate_phase === "plan"
329
+ ? ("plan" as const)
330
+ : ("aggressive" as const);
331
+
313
332
  const roundRecord = {
314
333
  schema_version: "1.0.0",
315
334
  contract_version: "1.0.0",
@@ -322,7 +341,7 @@ export default function debateOrchestrator(pi: ExtensionAPI) {
322
341
  evidence_refs: envelope.payload.evidence_refs,
323
342
  token_usage: envelope.payload.token_usage,
324
343
  budget_profile: {
325
- name: "aggressive",
344
+ name: profileName,
326
345
  max_rounds: state.max_rounds,
327
346
  round_token_cap: state.round_token_cap,
328
347
  debate_global_cap: state.debate_global_cap,
@@ -354,12 +373,20 @@ export default function debateOrchestrator(pi: ExtensionAPI) {
354
373
  ),
355
374
  );
356
375
  const decision = decidePolicy(lastSeverity, evidenceScore);
376
+ const planPhase = state.debate_phase === "plan";
377
+ const evaluatorPassed = planPhase
378
+ ? Boolean(state.last_review_gate_ready)
379
+ : true;
380
+ const debateComplete = planPhase
381
+ ? state.round_count >= state.max_rounds
382
+ : state.round_count > 0;
357
383
 
358
384
  const consensus = {
359
385
  schema_version: "1.0.0",
360
386
  contract_version: "1.0.0",
361
387
  run_id: state.run_id,
362
388
  debate_id: state.debate_id,
389
+ debate_phase: state.debate_phase,
363
390
  round_count: state.round_count,
364
391
  budget_used: state.budget_used,
365
392
  severity_scores: lastSeverity,
@@ -371,15 +398,25 @@ export default function debateOrchestrator(pi: ExtensionAPI) {
371
398
  },
372
399
  confidence_weights: WEIGHTS,
373
400
  evidence_refs: [],
374
- strict_gate_prerequisites: {
375
- plan_gate_passed: true,
376
- execution_completed: true,
377
- evaluator_passed: true,
378
- adversarial_debate_completed: state.round_count > 0,
379
- severity_policy_ok: decision !== "block",
380
- benchmark_delta_checks_passed: false,
381
- rollback_artifacts_generated: false,
382
- },
401
+ strict_gate_prerequisites: planPhase
402
+ ? {
403
+ plan_gate_passed: false,
404
+ execution_completed: false,
405
+ evaluator_passed: evaluatorPassed,
406
+ adversarial_debate_completed: debateComplete,
407
+ severity_policy_ok: decision !== "block",
408
+ benchmark_delta_checks_passed: false,
409
+ rollback_artifacts_generated: false,
410
+ }
411
+ : {
412
+ plan_gate_passed: true,
413
+ execution_completed: true,
414
+ evaluator_passed: true,
415
+ adversarial_debate_completed: debateComplete,
416
+ severity_policy_ok: decision !== "block",
417
+ benchmark_delta_checks_passed: false,
418
+ rollback_artifacts_generated: false,
419
+ },
383
420
  policy_decision: decision,
384
421
  rationale,
385
422
  };
@@ -236,7 +236,7 @@ export default function harnessPlanApproval(pi: ExtensionAPI) {
236
236
  name: "create_plan",
237
237
  label: "Create Plan",
238
238
  description:
239
- "Write the approved PlanPacket to plan-packet.json for this harness run. Call only after approve_plan (Approve). Do not use write/edit.",
239
+ "Write the approved PlanPacket to plan-packet.yaml for this harness run. Call only after approve_plan (Approve). Do not use write/edit.",
240
240
  promptSnippet: CREATE_PLAN_SNIPPET,
241
241
  promptGuidelines: CREATE_PLAN_GUIDELINES,
242
242
  parameters: CreatePlanParamsSchema,
@@ -298,7 +298,7 @@ export default function harnessPlanApproval(pi: ExtensionAPI) {
298
298
  return new Text(
299
299
  theme.fg(
300
300
  "success",
301
- `Wrote ${details?.plan_path ?? "plan-packet.json"}`,
301
+ `Wrote ${details?.plan_path ?? "plan-packet.yaml"}`,
302
302
  ),
303
303
  0,
304
304
  0,