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.
- package/.agents/skills/ck-search/SKILL.md +11 -87
- package/.agents/skills/cocoindex-search/SKILL.md +35 -0
- package/.agents/skills/harness-debate-plan/SKILL.md +44 -0
- package/.agents/skills/harness-decisions/SKILL.md +1 -1
- package/.agents/skills/harness-orchestration/SKILL.md +54 -28
- package/.agents/skills/harness-plan/SKILL.md +15 -20
- package/.pi/PACKAGING.md +1 -0
- package/.pi/SYSTEM.md +21 -20
- package/.pi/agents/harness/adversary.md +0 -1
- package/.pi/agents/harness/evaluator.md +0 -1
- package/.pi/agents/harness/executor.md +1 -2
- package/.pi/agents/harness/incident-recorder.md +0 -1
- package/.pi/agents/harness/meta-optimizer.md +0 -1
- package/.pi/agents/harness/planning/decompose.md +3 -4
- package/.pi/agents/harness/planning/execution-plan-author.md +30 -0
- package/.pi/agents/harness/planning/hypothesis-validator.md +23 -0
- package/.pi/agents/harness/planning/hypothesis.md +3 -4
- package/.pi/agents/harness/planning/plan-adversary.md +10 -42
- package/.pi/agents/harness/planning/plan-evaluator.md +18 -0
- package/.pi/agents/harness/planning/review-integrator.md +23 -0
- package/.pi/agents/harness/planning/scout-graphify.md +13 -5
- package/.pi/agents/harness/planning/scout-semantic.md +23 -11
- package/.pi/agents/harness/planning/scout-structure.md +12 -6
- package/.pi/agents/harness/planning/sprint-contract-auditor.md +18 -0
- package/.pi/agents/harness/planning/stack-researcher.md +24 -0
- package/.pi/agents/harness/tie-breaker.md +0 -1
- package/.pi/agents/harness/trace-librarian.md +0 -1
- package/.pi/extensions/debate-orchestrator.ts +90 -53
- package/.pi/extensions/harness-plan-approval.ts +2 -2
- package/.pi/extensions/harness-run-context.ts +150 -5
- package/.pi/extensions/harness-subagents.ts +17 -6
- package/.pi/extensions/lib/harness-cocoindex-refresh.ts +49 -0
- package/.pi/extensions/lib/harness-posthog.ts +6 -1
- package/.pi/extensions/lib/harness-spawn-budget.ts +75 -0
- package/.pi/extensions/lib/harness-subagent-auth.ts +123 -0
- package/.pi/extensions/lib/{harness-subagents/harness-subagent-policy.ts → harness-subagent-policy.ts} +8 -7
- package/.pi/extensions/lib/harness-subagent-precheck.ts +95 -0
- package/.pi/extensions/lib/harness-subagents-bridge.ts +122 -0
- package/.pi/extensions/lib/plan-approval/create-plan.ts +4 -7
- package/.pi/extensions/lib/plan-approval/plan-review.ts +1 -1
- package/.pi/extensions/lib/plan-approval/types.ts +7 -1
- package/.pi/extensions/lib/plan-debate-envelope.ts +84 -0
- package/.pi/extensions/lib/{harness-subagents/spawn-policy.ts → spawn-policy.ts} +1 -0
- package/.pi/extensions/policy-gate.ts +1 -1
- package/.pi/extensions/review-integrity.ts +48 -29
- package/.pi/harness/agents.manifest.json +37 -25
- package/.pi/harness/docs/adrs/0032-harness-command-orchestration.md +4 -3
- package/.pi/harness/docs/adrs/0033-parent-orchestrated-planning.md +2 -2
- package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +27 -0
- package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/review-round-r1.yaml +25 -0
- package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/review-round-r4.yaml +26 -0
- package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/artifacts/sprint-audit-r4.yaml +5 -0
- package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/plan-packet.yaml +196 -0
- package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/plan-review.md +14 -0
- package/.pi/harness/evals/smoke/fixtures/plan-phase/minimal-med/research-brief.yaml +32 -0
- package/.pi/harness/evals/smoke/run-context.fixture.json +1 -1
- package/.pi/harness/evals/smoke/smoke-harness-plan.mjs +88 -0
- package/.pi/harness/specs/harness-posthog-event.schema.json +6 -1
- package/.pi/harness/specs/plan-execution-plan-brief.schema.json +13 -0
- package/.pi/harness/specs/plan-execution-plan.schema.json +255 -0
- package/.pi/harness/specs/plan-packet.schema.json +14 -5
- package/.pi/harness/specs/plan-review-round-draft.schema.json +68 -0
- package/.pi/harness/specs/plan-sprint-audit-turn.schema.json +29 -0
- package/.pi/harness/specs/plan-stack-brief.schema.json +65 -0
- package/.pi/harness/specs/plan-validation-turn.schema.json +42 -0
- package/.pi/harness/specs/round-result.schema.json +16 -9
- package/.pi/lib/debate-orchestrator-types.ts +38 -0
- package/.pi/lib/harness-agent-discovery.mjs +81 -0
- package/.pi/lib/harness-run-context.ts +64 -38
- package/.pi/lib/harness-yaml.mjs +73 -0
- package/.pi/lib/harness-yaml.ts +90 -0
- package/.pi/prompts/harness-auto.md +13 -11
- package/.pi/prompts/harness-critic.md +2 -2
- package/.pi/prompts/harness-eval.md +3 -3
- package/.pi/prompts/harness-incident.md +2 -2
- package/.pi/prompts/harness-plan.md +83 -92
- package/.pi/prompts/harness-review.md +2 -2
- package/.pi/prompts/harness-router-tune.md +1 -1
- package/.pi/prompts/harness-run.md +2 -2
- package/.pi/prompts/harness-setup.md +30 -17
- package/.pi/prompts/harness-trace.md +2 -2
- package/.pi/scripts/README.md +1 -0
- package/.pi/scripts/harness-agents-manifest.mjs +1 -1
- package/.pi/scripts/harness-cli-verify.sh +24 -14
- package/.pi/scripts/harness-cocoindex-bootstrap.sh +182 -0
- package/.pi/scripts/harness-verify.mjs +38 -19
- package/.pi/scripts/validate-plan-dag.mjs +258 -0
- package/.pi/scripts/vendor-sync-pi-subagents.sh +19 -0
- package/.pi/skills/ast-grep/SKILL.md +2 -2
- package/.pi/skills/ccc/SKILL.md +142 -0
- package/.pi/skills/ccc/references/management.md +110 -0
- package/CHANGELOG.md +22 -0
- package/THIRD_PARTY_NOTICES.md +15 -0
- package/biome.json +2 -2
- package/package.json +7 -4
- package/vendor/pi-subagents/LICENSE +21 -0
- package/vendor/pi-subagents/UPSTREAM_PIN.md +11 -0
- package/vendor/pi-subagents/src/agents.ts +357 -0
- package/vendor/pi-subagents/src/subagents.ts +1463 -0
- package/.pi/agents/harness/planner.md +0 -13
- package/.pi/agents/harness/planning/hypothesis-eval.md +0 -59
- package/.pi/agents/harness/planning/planner.md +0 -20
- package/.pi/extensions/lib/harness-subagents/agent-loader.ts +0 -126
- package/.pi/extensions/lib/harness-subagents/agent-manifest.ts +0 -119
- package/.pi/extensions/lib/harness-subagents/agent-parser.ts +0 -87
- package/.pi/extensions/lib/harness-subagents/blackboard-tool.ts +0 -118
- package/.pi/extensions/lib/harness-subagents/blackboard.ts +0 -175
- package/.pi/extensions/lib/harness-subagents/parent-ask-user-bridge.ts +0 -10
- package/.pi/extensions/lib/harness-subagents/parent-harness-ui-bridge.ts +0 -137
- package/.pi/extensions/lib/harness-subagents/parent-harness-ui-hooks.ts +0 -77
- package/.pi/extensions/lib/harness-subagents/types-blackboard.ts +0 -27
- package/.pi/extensions/lib/harness-subagents/vendored/agent-manager.ts +0 -558
- package/.pi/extensions/lib/harness-subagents/vendored/agent-runner.ts +0 -666
- package/.pi/extensions/lib/harness-subagents/vendored/agent-types.ts +0 -175
- package/.pi/extensions/lib/harness-subagents/vendored/context.ts +0 -59
- package/.pi/extensions/lib/harness-subagents/vendored/cross-extension-rpc.ts +0 -134
- package/.pi/extensions/lib/harness-subagents/vendored/custom-agents.ts +0 -5
- package/.pi/extensions/lib/harness-subagents/vendored/default-agents.ts +0 -123
- package/.pi/extensions/lib/harness-subagents/vendored/env.ts +0 -43
- package/.pi/extensions/lib/harness-subagents/vendored/group-join.ts +0 -144
- package/.pi/extensions/lib/harness-subagents/vendored/index.ts +0 -2460
- package/.pi/extensions/lib/harness-subagents/vendored/invocation-config.ts +0 -52
- package/.pi/extensions/lib/harness-subagents/vendored/memory.ts +0 -182
- package/.pi/extensions/lib/harness-subagents/vendored/model-resolver.ts +0 -92
- package/.pi/extensions/lib/harness-subagents/vendored/output-file.ts +0 -115
- package/.pi/extensions/lib/harness-subagents/vendored/prompts.ts +0 -103
- package/.pi/extensions/lib/harness-subagents/vendored/schedule-store.ts +0 -177
- package/.pi/extensions/lib/harness-subagents/vendored/schedule.ts +0 -416
- package/.pi/extensions/lib/harness-subagents/vendored/settings.ts +0 -210
- package/.pi/extensions/lib/harness-subagents/vendored/skill-loader.ts +0 -108
- package/.pi/extensions/lib/harness-subagents/vendored/types.ts +0 -187
- package/.pi/extensions/lib/harness-subagents/vendored/ui/agent-widget.ts +0 -639
- package/.pi/extensions/lib/harness-subagents/vendored/ui/conversation-viewer.ts +0 -324
- package/.pi/extensions/lib/harness-subagents/vendored/ui/schedule-menu.ts +0 -110
- package/.pi/extensions/lib/harness-subagents/vendored/usage.ts +0 -71
- package/.pi/extensions/lib/harness-subagents/vendored/worktree.ts +0 -195
- /package/.pi/extensions/{00-ultimate-pi-system-prompt.ts → custom-system-prompt.ts} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://ultimate-pi.local/.pi/harness/specs/plan-packet.schema.json",
|
|
4
4
|
"title": "PlanPacket",
|
|
5
|
-
"description": "Plan-gated mutation contract emitted before execution.",
|
|
5
|
+
"description": "Plan-gated mutation contract emitted before execution (instance files: plan-packet.yaml).",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": [
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"assumptions",
|
|
15
15
|
"risk_level",
|
|
16
16
|
"acceptance_checks",
|
|
17
|
-
"rollback_plan"
|
|
17
|
+
"rollback_plan",
|
|
18
|
+
"execution_plan"
|
|
18
19
|
],
|
|
19
20
|
"properties": {
|
|
20
21
|
"schema_version": {
|
|
@@ -23,7 +24,7 @@
|
|
|
23
24
|
},
|
|
24
25
|
"contract_version": {
|
|
25
26
|
"type": "string",
|
|
26
|
-
"
|
|
27
|
+
"enum": ["1.0.0", "1.1.0"]
|
|
27
28
|
},
|
|
28
29
|
"plan_id": {
|
|
29
30
|
"type": "string",
|
|
@@ -52,8 +53,13 @@
|
|
|
52
53
|
"type": "array",
|
|
53
54
|
"minItems": 1,
|
|
54
55
|
"items": {
|
|
55
|
-
"type": "
|
|
56
|
-
"
|
|
56
|
+
"type": "object",
|
|
57
|
+
"additionalProperties": false,
|
|
58
|
+
"required": ["id", "description"],
|
|
59
|
+
"properties": {
|
|
60
|
+
"id": { "type": "string", "pattern": "^AC-[0-9]+$" },
|
|
61
|
+
"description": { "type": "string", "minLength": 1 }
|
|
62
|
+
}
|
|
57
63
|
}
|
|
58
64
|
},
|
|
59
65
|
"rollback_plan": {
|
|
@@ -85,6 +91,9 @@
|
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
93
|
}
|
|
94
|
+
},
|
|
95
|
+
"execution_plan": {
|
|
96
|
+
"$ref": "plan-execution-plan.schema.json"
|
|
88
97
|
}
|
|
89
98
|
}
|
|
90
99
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ultimate-pi.local/.pi/harness/specs/plan-review-round-draft.schema.json",
|
|
4
|
+
"title": "PlanReviewRoundDraft",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"round_index",
|
|
10
|
+
"round_summary",
|
|
11
|
+
"review_gate_ready",
|
|
12
|
+
"recommended_packet_patches"
|
|
13
|
+
],
|
|
14
|
+
"properties": {
|
|
15
|
+
"schema_version": { "type": "string", "const": "1.0.0" },
|
|
16
|
+
"round_index": { "type": "integer", "minimum": 1, "maximum": 4 },
|
|
17
|
+
"debate_round_focus": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": ["spec", "wbs", "schedule", "quality"]
|
|
20
|
+
},
|
|
21
|
+
"round_summary": { "type": "string", "minLength": 1 },
|
|
22
|
+
"validation_summary": { "type": "string" },
|
|
23
|
+
"adversary_summary": { "type": "string" },
|
|
24
|
+
"disputes": {
|
|
25
|
+
"type": "array",
|
|
26
|
+
"items": { "type": "string", "minLength": 1 }
|
|
27
|
+
},
|
|
28
|
+
"recommended_packet_patches": {
|
|
29
|
+
"type": "array",
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"required": ["path", "value"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"path": { "type": "string", "minLength": 1 },
|
|
35
|
+
"value": {}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"review_gate_ready": { "type": "boolean" },
|
|
40
|
+
"participants": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"items": { "type": "string", "minLength": 1 }
|
|
43
|
+
},
|
|
44
|
+
"claims": { "type": "array", "items": { "type": "string" } },
|
|
45
|
+
"rebuttals": { "type": "array", "items": { "type": "string" } },
|
|
46
|
+
"evidence_refs": { "type": "array", "items": { "type": "string" } },
|
|
47
|
+
"token_usage": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"properties": {
|
|
50
|
+
"per_agent": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"additionalProperties": { "type": "number" }
|
|
53
|
+
},
|
|
54
|
+
"round_total": { "type": "number" }
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"consensus_delta": { "type": "number" },
|
|
58
|
+
"severity_scores": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"properties": {
|
|
61
|
+
"correctness": { "type": "number" },
|
|
62
|
+
"security": { "type": "number" },
|
|
63
|
+
"architecture": { "type": "number" },
|
|
64
|
+
"test_integrity": { "type": "number" }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ultimate-pi.local/.pi/harness/specs/plan-sprint-audit-turn.schema.json",
|
|
4
|
+
"title": "PlanSprintAuditTurn",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["schema_version", "round_index", "gaps", "recommendation"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema_version": { "type": "string", "const": "1.0.0" },
|
|
10
|
+
"round_index": { "type": "integer", "minimum": 1, "maximum": 4 },
|
|
11
|
+
"gaps": {
|
|
12
|
+
"type": "array",
|
|
13
|
+
"items": { "type": "string", "minLength": 1 }
|
|
14
|
+
},
|
|
15
|
+
"checkpoint_issues": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"items": { "type": "string", "minLength": 1 }
|
|
18
|
+
},
|
|
19
|
+
"done_criteria_issues": {
|
|
20
|
+
"type": "array",
|
|
21
|
+
"items": { "type": "string", "minLength": 1 }
|
|
22
|
+
},
|
|
23
|
+
"recommendation": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"enum": ["proceed", "revise"]
|
|
26
|
+
},
|
|
27
|
+
"human_summary": { "type": "string" }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ultimate-pi.local/.pi/harness/specs/plan-stack-brief.schema.json",
|
|
4
|
+
"title": "PlanStackBrief",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"problem_framing",
|
|
10
|
+
"constraints",
|
|
11
|
+
"options",
|
|
12
|
+
"recommended_primary",
|
|
13
|
+
"rationale"
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"schema_version": { "type": "string", "const": "1.0.0" },
|
|
17
|
+
"problem_framing": { "type": "string", "minLength": 1 },
|
|
18
|
+
"constraints": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"items": { "type": "string", "minLength": 1 }
|
|
21
|
+
},
|
|
22
|
+
"options": {
|
|
23
|
+
"type": "array",
|
|
24
|
+
"minItems": 1,
|
|
25
|
+
"items": { "$ref": "#/$defs/stack_option" }
|
|
26
|
+
},
|
|
27
|
+
"recommended_primary": { "type": "string", "minLength": 1 },
|
|
28
|
+
"rationale": { "type": "string", "minLength": 1 },
|
|
29
|
+
"open_questions": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"items": { "type": "string", "minLength": 1 }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"$defs": {
|
|
35
|
+
"stack_option": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"additionalProperties": false,
|
|
38
|
+
"required": [
|
|
39
|
+
"name",
|
|
40
|
+
"category",
|
|
41
|
+
"fit_summary",
|
|
42
|
+
"tradeoffs",
|
|
43
|
+
"risks",
|
|
44
|
+
"evidence_refs",
|
|
45
|
+
"recommendation_rank"
|
|
46
|
+
],
|
|
47
|
+
"properties": {
|
|
48
|
+
"name": { "type": "string" },
|
|
49
|
+
"category": { "type": "string" },
|
|
50
|
+
"fit_summary": { "type": "string" },
|
|
51
|
+
"tradeoffs": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"required": ["pros", "cons"],
|
|
54
|
+
"properties": {
|
|
55
|
+
"pros": { "type": "array", "items": { "type": "string" } },
|
|
56
|
+
"cons": { "type": "array", "items": { "type": "string" } }
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"risks": { "type": "array", "items": { "type": "string" } },
|
|
60
|
+
"evidence_refs": { "type": "array", "items": { "type": "string" } },
|
|
61
|
+
"recommendation_rank": { "type": "integer", "minimum": 1 }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ultimate-pi.local/.pi/harness/specs/plan-validation-turn.schema.json",
|
|
4
|
+
"title": "PlanValidationTurn",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema_version",
|
|
9
|
+
"round_index",
|
|
10
|
+
"debate_round_focus",
|
|
11
|
+
"checks",
|
|
12
|
+
"overall_ready"
|
|
13
|
+
],
|
|
14
|
+
"properties": {
|
|
15
|
+
"schema_version": { "type": "string", "const": "1.0.0" },
|
|
16
|
+
"round_index": { "type": "integer", "minimum": 1, "maximum": 4 },
|
|
17
|
+
"debate_round_focus": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": ["spec", "wbs", "schedule", "quality"]
|
|
20
|
+
},
|
|
21
|
+
"checks": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"items": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": ["id", "status", "evidence"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"id": { "type": "string" },
|
|
28
|
+
"status": { "type": "string", "enum": ["pass", "warn", "fail"] },
|
|
29
|
+
"evidence": { "type": "string" },
|
|
30
|
+
"work_item_id": { "type": "string" },
|
|
31
|
+
"phase_id": { "type": "string" }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"mitigations": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"items": { "type": "string", "minLength": 1 }
|
|
38
|
+
},
|
|
39
|
+
"overall_ready": { "type": "boolean" },
|
|
40
|
+
"human_summary": { "type": "string" }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -46,7 +46,17 @@
|
|
|
46
46
|
"minItems": 2,
|
|
47
47
|
"items": {
|
|
48
48
|
"type": "string",
|
|
49
|
-
"enum": [
|
|
49
|
+
"enum": [
|
|
50
|
+
"EvaluatorAgent",
|
|
51
|
+
"AdversaryAgent",
|
|
52
|
+
"TieBreakerAgent",
|
|
53
|
+
"PlanEvaluatorAgent",
|
|
54
|
+
"PlanAdversaryAgent",
|
|
55
|
+
"HypothesisValidatorAgent",
|
|
56
|
+
"SprintContractAuditorAgent",
|
|
57
|
+
"ReviewIntegratorAgent",
|
|
58
|
+
"StackResearchAgent"
|
|
59
|
+
]
|
|
50
60
|
}
|
|
51
61
|
},
|
|
52
62
|
"claims": {
|
|
@@ -80,7 +90,7 @@
|
|
|
80
90
|
"additionalProperties": {
|
|
81
91
|
"type": "integer",
|
|
82
92
|
"minimum": 0,
|
|
83
|
-
"maximum":
|
|
93
|
+
"maximum": 35000
|
|
84
94
|
}
|
|
85
95
|
},
|
|
86
96
|
"round_total": {
|
|
@@ -101,19 +111,16 @@
|
|
|
101
111
|
"properties": {
|
|
102
112
|
"name": {
|
|
103
113
|
"type": "string",
|
|
104
|
-
"
|
|
114
|
+
"enum": ["aggressive", "plan"]
|
|
105
115
|
},
|
|
106
116
|
"max_rounds": {
|
|
107
|
-
"type": "integer"
|
|
108
|
-
"const": 6
|
|
117
|
+
"type": "integer"
|
|
109
118
|
},
|
|
110
119
|
"round_token_cap": {
|
|
111
|
-
"type": "integer"
|
|
112
|
-
"const": 2500
|
|
120
|
+
"type": "integer"
|
|
113
121
|
},
|
|
114
122
|
"debate_global_cap": {
|
|
115
|
-
"type": "integer"
|
|
116
|
-
"const": 35000
|
|
123
|
+
"type": "integer"
|
|
117
124
|
}
|
|
118
125
|
}
|
|
119
126
|
},
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Shared debate bus participant types (plan + post-execute). */
|
|
2
|
+
|
|
3
|
+
export type PostExecuteDebateParticipant =
|
|
4
|
+
| "EvaluatorAgent"
|
|
5
|
+
| "AdversaryAgent"
|
|
6
|
+
| "TieBreakerAgent";
|
|
7
|
+
|
|
8
|
+
export type PlanDebateParticipant =
|
|
9
|
+
| "PlanEvaluatorAgent"
|
|
10
|
+
| "PlanAdversaryAgent"
|
|
11
|
+
| "HypothesisValidatorAgent"
|
|
12
|
+
| "SprintContractAuditorAgent"
|
|
13
|
+
| "ReviewIntegratorAgent"
|
|
14
|
+
| "StackResearchAgent";
|
|
15
|
+
|
|
16
|
+
export type DebateParticipant =
|
|
17
|
+
| PostExecuteDebateParticipant
|
|
18
|
+
| PlanDebateParticipant;
|
|
19
|
+
|
|
20
|
+
export const PLAN_DEBATE_PARTICIPANTS: PlanDebateParticipant[] = [
|
|
21
|
+
"PlanEvaluatorAgent",
|
|
22
|
+
"PlanAdversaryAgent",
|
|
23
|
+
"HypothesisValidatorAgent",
|
|
24
|
+
"SprintContractAuditorAgent",
|
|
25
|
+
"ReviewIntegratorAgent",
|
|
26
|
+
"StackResearchAgent",
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export const POST_EXECUTE_DEBATE_PARTICIPANTS: PostExecuteDebateParticipant[] =
|
|
30
|
+
["EvaluatorAgent", "AdversaryAgent", "TieBreakerAgent"];
|
|
31
|
+
|
|
32
|
+
export function isPlanDebateId(debateId: string): boolean {
|
|
33
|
+
return debateId.startsWith("plan-");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function debatePhaseFromId(debateId: string): "plan" | "post_execute" {
|
|
37
|
+
return isPlanDebateId(debateId) ? "plan" : "post_execute";
|
|
38
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared agent discovery helpers (manifest + tests).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
7
|
+
import { join, relative } from "node:path";
|
|
8
|
+
|
|
9
|
+
export function isSafeAgentId(id) {
|
|
10
|
+
if (!id || id.includes("..") || id.startsWith("/") || id.includes("\\")) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return /^[a-zA-Z0-9][a-zA-Z0-9/_-]*$/.test(id);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function sha256Content(content) {
|
|
17
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function walkAgentsDir(rootDir, source, out) {
|
|
21
|
+
if (!existsSync(rootDir)) return;
|
|
22
|
+
const stack = [rootDir];
|
|
23
|
+
while (stack.length > 0) {
|
|
24
|
+
const dir = stack.pop();
|
|
25
|
+
let entries;
|
|
26
|
+
try {
|
|
27
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
28
|
+
} catch {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
const full = join(dir, entry.name);
|
|
33
|
+
if (entry.isDirectory()) {
|
|
34
|
+
stack.push(full);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!entry.name.endsWith(".md")) continue;
|
|
38
|
+
const rel = relative(rootDir, full).replace(/\\/g, "/");
|
|
39
|
+
const id = rel.replace(/\.md$/i, "");
|
|
40
|
+
if (!isSafeAgentId(id)) continue;
|
|
41
|
+
let content;
|
|
42
|
+
try {
|
|
43
|
+
content = readFileSync(full, "utf-8");
|
|
44
|
+
} catch {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
out.set(id, { id, path: full, source, content });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function discoverFromRoots(packageAgentsDir, projectAgentsDir, globalAgentsDir) {
|
|
53
|
+
const files = new Map();
|
|
54
|
+
walkAgentsDir(packageAgentsDir, "package", files);
|
|
55
|
+
if (globalAgentsDir) walkAgentsDir(globalAgentsDir, "global", files);
|
|
56
|
+
walkAgentsDir(projectAgentsDir, "project", files);
|
|
57
|
+
return files;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function getDriftReport(manifest, onDiskHashes) {
|
|
61
|
+
const items = [];
|
|
62
|
+
if (!manifest) {
|
|
63
|
+
return { ok: false, items: [{ id: "*", kind: "missing_on_disk" }] };
|
|
64
|
+
}
|
|
65
|
+
for (const [id, entry] of onDiskHashes) {
|
|
66
|
+
const expected = manifest.agents[id];
|
|
67
|
+
if (!expected) {
|
|
68
|
+
items.push({ id, kind: "missing_in_manifest" });
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (expected.sha256 !== entry.sha256) {
|
|
72
|
+
items.push({ id, kind: "hash_mismatch" });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const id of Object.keys(manifest.agents)) {
|
|
76
|
+
if (!onDiskHashes.has(id)) {
|
|
77
|
+
items.push({ id, kind: "missing_on_disk" });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { ok: items.length === 0, items };
|
|
81
|
+
}
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* harness-run-context — shared types and helpers for active harness runs.
|
|
3
3
|
*
|
|
4
4
|
* Session entry `harness-run-context` is the live source of truth; disk mirrors:
|
|
5
|
-
* - `.pi/harness/runs/<run_id>/run-context.
|
|
5
|
+
* - `.pi/harness/runs/<run_id>/run-context.yaml`
|
|
6
6
|
* - `.pi/harness/active-run.json` (cross-session pointer)
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { mkdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
10
10
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
11
|
+
import { readYamlFile, writeYamlFile } from "./harness-yaml.js";
|
|
11
12
|
|
|
12
13
|
export type HarnessPhase =
|
|
13
14
|
| "plan"
|
|
@@ -67,6 +68,7 @@ export interface PlanPacketLike {
|
|
|
67
68
|
risk_level?: string;
|
|
68
69
|
assumptions?: unknown[];
|
|
69
70
|
rollback_plan?: unknown;
|
|
71
|
+
execution_plan?: unknown;
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
interface SessionEntryLike {
|
|
@@ -107,11 +109,22 @@ export function activeRunPointerPath(projectRoot: string): string {
|
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
export function runContextDiskPath(runId: string, projectRoot: string): string {
|
|
110
|
-
return join(harnessRunsRoot(projectRoot), runId,
|
|
112
|
+
return join(harnessRunsRoot(projectRoot), runId, RUN_CONTEXT_BASENAME);
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
export function canonicalPlanPath(runId: string, projectRoot: string): string {
|
|
114
|
-
return join(harnessRunsRoot(projectRoot), runId,
|
|
116
|
+
return join(harnessRunsRoot(projectRoot), runId, PLAN_PACKET_BASENAME);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function canonicalResearchBriefPath(
|
|
120
|
+
runId: string,
|
|
121
|
+
projectRoot: string,
|
|
122
|
+
): string {
|
|
123
|
+
return join(harnessRunsRoot(projectRoot), runId, RESEARCH_BRIEF_BASENAME);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function runArtifactsDir(runId: string, projectRoot: string): string {
|
|
127
|
+
return join(harnessRunsRoot(projectRoot), runId, "artifacts");
|
|
115
128
|
}
|
|
116
129
|
|
|
117
130
|
export const PLAN_REVIEW_BASENAME = "plan-review.md";
|
|
@@ -123,7 +136,16 @@ export function canonicalPlanReviewPath(
|
|
|
123
136
|
return join(harnessRunsRoot(projectRoot), runId, PLAN_REVIEW_BASENAME);
|
|
124
137
|
}
|
|
125
138
|
|
|
126
|
-
const PLAN_PACKET_BASENAME = "plan-packet.
|
|
139
|
+
export const PLAN_PACKET_BASENAME = "plan-packet.yaml";
|
|
140
|
+
export const RUN_CONTEXT_BASENAME = "run-context.yaml";
|
|
141
|
+
export const RESEARCH_BRIEF_BASENAME = "research-brief.yaml";
|
|
142
|
+
|
|
143
|
+
const PLAN_RUN_SCOPED_ROOT_FILES = new Set([
|
|
144
|
+
PLAN_PACKET_BASENAME,
|
|
145
|
+
RESEARCH_BRIEF_BASENAME,
|
|
146
|
+
"plan-dag-validation.yaml",
|
|
147
|
+
PLAN_REVIEW_BASENAME,
|
|
148
|
+
]);
|
|
127
149
|
|
|
128
150
|
const MUTATING_FILE_TOOLS = new Set(["write", "edit"]);
|
|
129
151
|
|
|
@@ -208,7 +230,21 @@ export function extractWritePathFromToolInput(
|
|
|
208
230
|
return raw.trim();
|
|
209
231
|
}
|
|
210
232
|
|
|
211
|
-
/** True when absPath is
|
|
233
|
+
/** True when absPath is a plan-phase artifact under the active run directory. */
|
|
234
|
+
export function isPlanRunScopedRelativePath(rel: string): boolean {
|
|
235
|
+
if (rel.startsWith("..") || isAbsolute(rel)) return false;
|
|
236
|
+
const parts = rel.split(/[/\\]/);
|
|
237
|
+
if (parts.length === 2 && PLAN_RUN_SCOPED_ROOT_FILES.has(parts[1])) {
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
if (parts.length === 3 && parts[1] === "artifacts") {
|
|
241
|
+
const file = parts[2];
|
|
242
|
+
return file.endsWith(".yaml") || file.endsWith(".yml");
|
|
243
|
+
}
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** True when absPath is a writable plan-run artifact for the active run. */
|
|
212
248
|
export async function isPlanPhaseScopedWrite(
|
|
213
249
|
absPath: string,
|
|
214
250
|
runCtx: HarnessRunContext | null,
|
|
@@ -229,11 +265,9 @@ export async function isPlanPhaseScopedWrite(
|
|
|
229
265
|
runsReal = runsRoot;
|
|
230
266
|
}
|
|
231
267
|
const rel = relative(runsReal, resolved);
|
|
232
|
-
if (
|
|
268
|
+
if (!isPlanRunScopedRelativePath(rel)) return false;
|
|
233
269
|
const parts = rel.split(/[/\\]/);
|
|
234
|
-
|
|
235
|
-
if (parts[0] !== runCtx.run_id) return false;
|
|
236
|
-
return isCanonicalPlanPacketPath(resolved, projectRoot, runCtx.run_id);
|
|
270
|
+
return parts[0] === runCtx.run_id;
|
|
237
271
|
}
|
|
238
272
|
|
|
239
273
|
export function getLatestHarnessTurn(
|
|
@@ -497,19 +531,6 @@ export async function isPlanPhaseAllowedMutation(
|
|
|
497
531
|
'policy-gate: no active harness run. Run /harness-plan "<task>" first.',
|
|
498
532
|
};
|
|
499
533
|
}
|
|
500
|
-
if (
|
|
501
|
-
!hasPlanUserApproval(opts.entries, {
|
|
502
|
-
sincePlanCommand: true,
|
|
503
|
-
planId: runCtx.plan_id,
|
|
504
|
-
})
|
|
505
|
-
) {
|
|
506
|
-
return {
|
|
507
|
-
allowed: false,
|
|
508
|
-
isScopedPlanWrite: true,
|
|
509
|
-
reason:
|
|
510
|
-
"policy-gate: plan-packet.json write blocked until the user approves via approve_plan or ask_user (present the full plan, then Approve).",
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
534
|
if (opts.aborted) {
|
|
514
535
|
return { allowed: true, isScopedPlanWrite: true };
|
|
515
536
|
}
|
|
@@ -522,7 +543,7 @@ export async function isPlanPhaseAllowedMutation(
|
|
|
522
543
|
return {
|
|
523
544
|
allowed: false,
|
|
524
545
|
isScopedPlanWrite: true,
|
|
525
|
-
reason: `harness-run-context: plan-packet.
|
|
546
|
+
reason: `harness-run-context: plan-packet.yaml is read-only in phase '${phase}'.`,
|
|
526
547
|
};
|
|
527
548
|
}
|
|
528
549
|
|
|
@@ -530,7 +551,7 @@ export async function isPlanPhaseAllowedMutation(
|
|
|
530
551
|
return {
|
|
531
552
|
allowed: false,
|
|
532
553
|
reason:
|
|
533
|
-
"policy-gate: mutating tool blocked because harness-abort lock is active. Attach a new approved plan via plan-packet.
|
|
554
|
+
"policy-gate: mutating tool blocked because harness-abort lock is active. Attach a new approved plan via plan-packet.yaml first.",
|
|
534
555
|
};
|
|
535
556
|
}
|
|
536
557
|
|
|
@@ -548,7 +569,7 @@ export async function isPlanPhaseAllowedMutation(
|
|
|
548
569
|
|
|
549
570
|
const allowedPath = runCtx?.run_id
|
|
550
571
|
? canonicalPlanPath(runCtx.run_id, projectRoot)
|
|
551
|
-
:
|
|
572
|
+
: `.pi/harness/runs/<run_id>/${PLAN_PACKET_BASENAME}`;
|
|
552
573
|
return {
|
|
553
574
|
allowed: false,
|
|
554
575
|
reason: `policy-gate: ${toolName} blocked in phase '${phase}'. In plan phase only ${allowedPath} is writable after ask_user approval.`,
|
|
@@ -754,8 +775,11 @@ export async function loadRunContextFromDisk(
|
|
|
754
775
|
projectRoot: string,
|
|
755
776
|
): Promise<HarnessRunContext | null> {
|
|
756
777
|
try {
|
|
757
|
-
const
|
|
758
|
-
|
|
778
|
+
const doc = await readYamlFile(
|
|
779
|
+
runContextDiskPath(runId, projectRoot),
|
|
780
|
+
"run-context",
|
|
781
|
+
);
|
|
782
|
+
return normalizeRunContext(doc as Partial<HarnessRunContext>);
|
|
759
783
|
} catch {
|
|
760
784
|
return null;
|
|
761
785
|
}
|
|
@@ -766,11 +790,7 @@ export async function saveRunContextToDisk(
|
|
|
766
790
|
): Promise<void> {
|
|
767
791
|
const dir = join(harnessRunsRoot(ctx.project_root), ctx.run_id);
|
|
768
792
|
await mkdir(dir, { recursive: true });
|
|
769
|
-
await
|
|
770
|
-
runContextDiskPath(ctx.run_id, ctx.project_root),
|
|
771
|
-
`${JSON.stringify(ctx, null, 2)}\n`,
|
|
772
|
-
"utf-8",
|
|
773
|
-
);
|
|
793
|
+
await writeYamlFile(runContextDiskPath(ctx.run_id, ctx.project_root), ctx);
|
|
774
794
|
}
|
|
775
795
|
|
|
776
796
|
export async function loadProjectActiveRun(
|
|
@@ -828,8 +848,8 @@ export async function readPlanPacketFromPath(
|
|
|
828
848
|
planPath: string,
|
|
829
849
|
): Promise<PlanPacketLike | null> {
|
|
830
850
|
try {
|
|
831
|
-
const
|
|
832
|
-
return
|
|
851
|
+
const doc = await readYamlFile(planPath, planPath);
|
|
852
|
+
return doc as PlanPacketLike;
|
|
833
853
|
} catch {
|
|
834
854
|
return null;
|
|
835
855
|
}
|
|
@@ -844,8 +864,11 @@ export function validatePlanPacket(packet: PlanPacketLike | null): {
|
|
|
844
864
|
const errors: string[] = [];
|
|
845
865
|
if (packet.schema_version !== "1.0.0")
|
|
846
866
|
errors.push("schema_version must be 1.0.0");
|
|
847
|
-
if (
|
|
848
|
-
|
|
867
|
+
if (
|
|
868
|
+
packet.contract_version !== "1.0.0" &&
|
|
869
|
+
packet.contract_version !== "1.1.0"
|
|
870
|
+
)
|
|
871
|
+
errors.push("contract_version must be 1.0.0 or 1.1.0");
|
|
849
872
|
if (!packet.plan_id || typeof packet.plan_id !== "string")
|
|
850
873
|
errors.push("plan_id required");
|
|
851
874
|
if (!packet.task_id || typeof packet.task_id !== "string")
|
|
@@ -859,6 +882,9 @@ export function validatePlanPacket(packet: PlanPacketLike | null): {
|
|
|
859
882
|
errors.push("acceptance_checks required");
|
|
860
883
|
if (!packet.risk_level) errors.push("risk_level required");
|
|
861
884
|
if (!packet.rollback_plan) errors.push("rollback_plan required");
|
|
885
|
+
if (packet.contract_version === "1.1.0" && !packet.execution_plan) {
|
|
886
|
+
errors.push("execution_plan required for contract_version 1.1.0");
|
|
887
|
+
}
|
|
862
888
|
return { valid: errors.length === 0, errors };
|
|
863
889
|
}
|
|
864
890
|
|
|
@@ -957,7 +983,7 @@ export function formatActivePlanBlock(
|
|
|
957
983
|
);
|
|
958
984
|
} else {
|
|
959
985
|
lines.push(
|
|
960
|
-
"Plan is read-only in this phase. Do not edit plan-packet.
|
|
986
|
+
"Plan is read-only in this phase. Do not edit plan-packet.yaml.",
|
|
961
987
|
);
|
|
962
988
|
}
|
|
963
989
|
if (ctx.plan_packet_path) {
|
|
@@ -1016,7 +1042,7 @@ export function validatePlanOverridePath(
|
|
|
1016
1042
|
if (!isCanonicalPlanPacketPath(absPlan, projectRoot, runId)) {
|
|
1017
1043
|
return {
|
|
1018
1044
|
ok: false,
|
|
1019
|
-
reason: `--plan must be runs/${runId}
|
|
1045
|
+
reason: `--plan must be runs/${runId}/${PLAN_PACKET_BASENAME} (canonical plan packet only)`,
|
|
1020
1046
|
};
|
|
1021
1047
|
}
|
|
1022
1048
|
return { ok: true };
|