maestro-flow 0.4.19 → 0.4.21
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/agents/workflow-collab-planner.md +4 -1
- package/.agents/agents/workflow-plan-checker.md +11 -1
- package/.agents/agents/workflow-planner.md +4 -1
- package/.agents/skills/maestro/SKILL.md +8 -5
- package/.agents/skills/maestro-analyze/SKILL.md +1 -1
- package/.agents/skills/maestro-brainstorm/SKILL.md +2 -1
- package/.agents/skills/maestro-companion/SKILL.md +533 -0
- package/.agents/skills/maestro-grill/SKILL.md +116 -0
- package/.agents/skills/maestro-plan/SKILL.md +4 -0
- package/.agents/skills/maestro-ralph/SKILL.md +11 -7
- package/.agents/skills/maestro-ralph-execute/SKILL.md +2 -1
- package/.agents/skills/maestro-swarm-workflow/SKILL.md +266 -0
- package/.agents/skills/maestro-universal-workflow/SKILL.md +563 -0
- package/.agents/skills/manage-codebase-rebuild/SKILL.md +13 -1
- package/.agents/skills/manage-codebase-refresh/SKILL.md +3 -0
- package/.agents/skills/spec-setup/SKILL.md +9 -5
- package/.agents/skills/team-adversarial-swarm/SKILL.md +235 -0
- package/.agents/skills/team-adversarial-swarm/scripts/aco.py +473 -0
- package/.agents/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
- package/.agents/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
- package/.agents/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
- package/.agents/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
- package/.agents/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
- package/.agents/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
- package/.agents/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
- package/.agents/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
- package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
- package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
- package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
- package/.agents/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
- package/.agy/agents/workflow-collab-planner.md +4 -1
- package/.agy/agents/workflow-plan-checker.md +11 -1
- package/.agy/agents/workflow-planner.md +4 -1
- package/.agy/skills/maestro/SKILL.md +8 -5
- package/.agy/skills/maestro-analyze/SKILL.md +1 -1
- package/.agy/skills/maestro-brainstorm/SKILL.md +2 -1
- package/.agy/skills/maestro-companion/SKILL.md +529 -0
- package/.agy/skills/maestro-grill/SKILL.md +116 -0
- package/.agy/skills/maestro-plan/SKILL.md +4 -0
- package/.agy/skills/maestro-ralph/SKILL.md +11 -7
- package/.agy/skills/maestro-ralph-execute/SKILL.md +2 -1
- package/.agy/skills/maestro-swarm-workflow/SKILL.md +263 -0
- package/.agy/skills/maestro-universal-workflow/SKILL.md +560 -0
- package/.agy/skills/manage-codebase-rebuild/SKILL.md +13 -1
- package/.agy/skills/manage-codebase-refresh/SKILL.md +3 -0
- package/.agy/skills/spec-setup/SKILL.md +9 -5
- package/.agy/skills/team-adversarial-swarm/SKILL.md +244 -0
- package/.agy/skills/team-adversarial-swarm/scripts/aco.py +473 -0
- package/.agy/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
- package/.agy/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
- package/.agy/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
- package/.agy/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
- package/.agy/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
- package/.agy/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
- package/.agy/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
- package/.agy/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
- package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
- package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
- package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
- package/.agy/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
- package/.claude/agents/workflow-collab-planner.md +4 -1
- package/.claude/agents/workflow-plan-checker.md +11 -1
- package/.claude/agents/workflow-planner.md +4 -1
- package/.claude/commands/maestro-analyze.md +1 -1
- package/.claude/commands/maestro-brainstorm.md +2 -1
- package/.claude/commands/maestro-companion.md +531 -0
- package/.claude/commands/maestro-grill.md +114 -0
- package/.claude/commands/maestro-plan.md +4 -0
- package/.claude/commands/maestro-ralph-execute.md +2 -1
- package/.claude/commands/maestro-ralph.md +11 -7
- package/.claude/commands/maestro-swarm-workflow.md +264 -0
- package/.claude/commands/maestro-universal-workflow.md +561 -0
- package/.claude/commands/maestro.md +8 -5
- package/.claude/commands/manage-codebase-rebuild.md +13 -1
- package/.claude/commands/manage-codebase-refresh.md +3 -0
- package/.claude/commands/spec-setup.md +9 -5
- package/.claude/skills/team-adversarial-swarm/SKILL.md +233 -0
- package/.claude/skills/team-adversarial-swarm/scripts/aco.py +473 -0
- package/.claude/skills/team-adversarial-swarm/scripts/pheromone.py +144 -0
- package/.claude/skills/team-adversarial-swarm/scripts/scoring.py +92 -0
- package/.claude/skills/team-adversarial-swarm/scripts/test_aco.py +475 -0
- package/.claude/skills/team-adversarial-swarm/specs/ant-output-schema.md +115 -0
- package/.claude/skills/team-adversarial-swarm/specs/convergence-criteria.md +75 -0
- package/.claude/skills/team-adversarial-swarm/specs/pheromone-schema.md +90 -0
- package/.claude/skills/team-adversarial-swarm/specs/swarm-config-template.json +66 -0
- package/.claude/skills/team-adversarial-swarm/specs/swarm-protocol.md +105 -0
- package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-converge.js +197 -0
- package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-explore.js +194 -0
- package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-score.js +188 -0
- package/.claude/skills/team-adversarial-swarm/workflows/wf-swarm-synthesize.js +248 -0
- package/.codex/skills/maestro/SKILL.md +7 -2
- package/.codex/skills/maestro-companion/SKILL.md +485 -0
- package/.codex/skills/maestro-grill/SKILL.md +111 -0
- package/.codex/skills/maestro-ralph/SKILL.md +11 -7
- package/.codex/skills/manage-codebase-rebuild/SKILL.md +6 -0
- package/.codex/skills/manage-codebase-refresh/SKILL.md +6 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.d.ts +36 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +138 -2
- package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js +13 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.d.ts +11 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +178 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +1 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +39 -23
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
- package/dashboard/dist-server/src/graph/types.d.ts +111 -0
- package/dashboard/dist-server/src/graph/types.js +2 -0
- package/dashboard/dist-server/src/graph/types.js.map +1 -0
- package/dist/src/cli.js +1 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/kg.d.ts +11 -0
- package/dist/src/commands/kg.d.ts.map +1 -0
- package/dist/src/commands/kg.js +486 -0
- package/dist/src/commands/kg.js.map +1 -0
- package/dist/src/graph/analyzers/fs-analyzer.d.ts +10 -0
- package/dist/src/graph/analyzers/fs-analyzer.d.ts.map +1 -0
- package/dist/src/graph/analyzers/fs-analyzer.js +959 -0
- package/dist/src/graph/analyzers/fs-analyzer.js.map +1 -0
- package/dist/src/graph/index.d.ts +6 -0
- package/dist/src/graph/index.d.ts.map +1 -0
- package/dist/src/graph/index.js +6 -0
- package/dist/src/graph/index.js.map +1 -0
- package/dist/src/graph/loader.d.ts +3 -0
- package/dist/src/graph/loader.d.ts.map +1 -0
- package/dist/src/graph/loader.js +12 -0
- package/dist/src/graph/loader.js.map +1 -0
- package/dist/src/graph/merger.d.ts +56 -0
- package/dist/src/graph/merger.d.ts.map +1 -0
- package/dist/src/graph/merger.js +896 -0
- package/dist/src/graph/merger.js.map +1 -0
- package/dist/src/graph/query.d.ts +7 -0
- package/dist/src/graph/query.d.ts.map +1 -0
- package/dist/src/graph/query.js +126 -0
- package/dist/src/graph/query.js.map +1 -0
- package/dist/src/graph/types.d.ts +112 -0
- package/dist/src/graph/types.d.ts.map +1 -0
- package/dist/src/graph/types.js +2 -0
- package/dist/src/graph/types.js.map +1 -0
- package/dist/src/tui/install-ui/KgVendorConfig.d.ts +7 -0
- package/dist/src/tui/install-ui/KgVendorConfig.d.ts.map +1 -0
- package/dist/src/tui/install-ui/KgVendorConfig.js +9 -0
- package/dist/src/tui/install-ui/KgVendorConfig.js.map +1 -0
- package/dist/src/utils/update-notices.js +23 -0
- package/dist/src/utils/update-notices.js.map +1 -1
- package/package.json +1 -1
- package/workflows/analyze.md +2 -1
- package/workflows/brainstorm.md +24 -1
- package/workflows/codebase-rebuild.md +141 -1
- package/workflows/codebase-refresh.md +20 -0
- package/workflows/finish-work.md +7 -2
- package/workflows/grill.md +513 -0
- package/workflows/plan.md +7 -4
- package/workflows/specs-setup.md +99 -3
- package/workflows/swarm/wf-analyze.js +347 -0
- package/workflows/swarm/wf-brainstorm.js +456 -0
- package/workflows/swarm/wf-execute.js +379 -0
- package/workflows/swarm/wf-grill.js +359 -0
- package/workflows/swarm/wf-milestone-audit.js +385 -0
- package/workflows/swarm/wf-plan.js +468 -0
- package/workflows/swarm/wf-review.js +341 -0
- package/workflows/swarm/wf-verify.js +395 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Convergence Criteria — Adversarial Edition
|
|
2
|
+
|
|
3
|
+
When does the swarm stop? Two-layer convergence: Python signal + adversarial debate.
|
|
4
|
+
|
|
5
|
+
## Two-Layer Convergence
|
|
6
|
+
|
|
7
|
+
Unlike team-swarm (Python-only), adversarial-swarm uses two layers:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Layer 1: Python aco.py converged → signal (data-driven)
|
|
11
|
+
Layer 2: wf-swarm-converge → adversarial debate (judgment-driven)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Python provides the raw signal (stagnation, entropy, budget). The Workflow module
|
|
15
|
+
runs a prosecutor/defender/judge debate to make the final call.
|
|
16
|
+
|
|
17
|
+
## Python Stop Conditions (any-of)
|
|
18
|
+
|
|
19
|
+
| Criterion | Default | Description |
|
|
20
|
+
|-----------|---------|-------------|
|
|
21
|
+
| `max_iterations` | 5 | Hard cap — always triggers |
|
|
22
|
+
| `stagnation` | patience=2 | Best score unchanged for N iterations |
|
|
23
|
+
| `entropy_floor` | 0.5 | Pheromone entropy below threshold |
|
|
24
|
+
| `budget_tokens` | 100000 | Total token cost exceeded |
|
|
25
|
+
| `target_score` | 0.95 | Best verified_score crosses target |
|
|
26
|
+
|
|
27
|
+
## Adversarial Override
|
|
28
|
+
|
|
29
|
+
The Python signal is an INPUT to the adversarial debate, not the final decision:
|
|
30
|
+
|
|
31
|
+
| Python says | Adversarial debate can |
|
|
32
|
+
|-------------|----------------------|
|
|
33
|
+
| converged=true | Override to CONTINUE if prosecutor makes strong case (rare) |
|
|
34
|
+
| converged=false | Override to STOP if defender makes strong case (quality sufficient) |
|
|
35
|
+
| max_iterations reached | MUST converge (no override — hard safety net) |
|
|
36
|
+
|
|
37
|
+
## Debate Decision Rules
|
|
38
|
+
|
|
39
|
+
From wf-swarm-converge.js:
|
|
40
|
+
|
|
41
|
+
1. `iteration >= max_iterations` → MUST converge (no debate needed)
|
|
42
|
+
2. `iteration == 1` → MUST NOT converge (too early)
|
|
43
|
+
3. Stagnation signal + defender confidence > 60% → converge
|
|
44
|
+
4. Prosecutor confidence > 80% + best score < 0.5 → continue (insufficient quality)
|
|
45
|
+
5. Defender concedes major points → continue
|
|
46
|
+
6. Prosecutor concedes major points → stop
|
|
47
|
+
7. Otherwise → weigh evidence quality
|
|
48
|
+
|
|
49
|
+
## Configuration
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"convergence": {
|
|
54
|
+
"max_iterations": 5,
|
|
55
|
+
"stagnation": { "enabled": true, "patience": 2, "min_delta": 0.01 },
|
|
56
|
+
"entropy_floor": { "enabled": true, "threshold": 0.5 },
|
|
57
|
+
"budget_tokens": { "enabled": false, "max": 100000 },
|
|
58
|
+
"target_score": { "enabled": true, "value": 0.95 }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Why Two-Layer
|
|
64
|
+
|
|
65
|
+
Single-layer convergence is fragile:
|
|
66
|
+
- Python-only misses qualitative signals (solution is "good enough" even if score plateau isn't reached)
|
|
67
|
+
- LLM-only is unreliable for numeric comparisons (misreads stagnation signals)
|
|
68
|
+
- Combined: Python provides hard data, adversarial debate provides judgment
|
|
69
|
+
|
|
70
|
+
## Anti-Patterns
|
|
71
|
+
|
|
72
|
+
- DO NOT disable `max_iterations` — runaway risk
|
|
73
|
+
- DO NOT use `stagnation.patience < 2` — noise triggers false stops
|
|
74
|
+
- DO NOT skip the adversarial debate for iteration 1 — just force the outcome
|
|
75
|
+
- DO NOT let prosecutor override `max_iterations` — hard cap is sacred
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Pheromone Schema
|
|
2
|
+
|
|
3
|
+
Pheromone matrix structure, update formula, evaporation rule.
|
|
4
|
+
Authoritative spec for `pheromone/current.json` and history snapshots.
|
|
5
|
+
|
|
6
|
+
Inherited from team-swarm — ACO math is identical.
|
|
7
|
+
|
|
8
|
+
## File Layout
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
<session>/pheromone/
|
|
12
|
+
├── current.json # latest state, overwritten each iteration
|
|
13
|
+
├── history/
|
|
14
|
+
│ ├── 1.json # snapshot after iteration 1
|
|
15
|
+
│ ├── 2.json
|
|
16
|
+
│ └── ...
|
|
17
|
+
└── init.json # snapshot of initial state (immutable)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Schema (pheromone/current.json)
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"version": "1.0",
|
|
25
|
+
"iteration": 3,
|
|
26
|
+
"n_nodes": 42,
|
|
27
|
+
"matrix_type": "edge_weighted_sparse",
|
|
28
|
+
"tau": {
|
|
29
|
+
"<node_a>::<node_b>": 0.85,
|
|
30
|
+
"<node_a>::<node_c>": 1.20
|
|
31
|
+
},
|
|
32
|
+
"node_tau": {
|
|
33
|
+
"<node_a>": 0.92,
|
|
34
|
+
"<node_b>": 1.05
|
|
35
|
+
},
|
|
36
|
+
"metadata": {
|
|
37
|
+
"alpha": 1.0,
|
|
38
|
+
"beta": 2.0,
|
|
39
|
+
"rho": 0.2,
|
|
40
|
+
"q": 1.0,
|
|
41
|
+
"tau_init": 1.0,
|
|
42
|
+
"tau_min": 0.01,
|
|
43
|
+
"tau_max": 10.0
|
|
44
|
+
},
|
|
45
|
+
"stats": {
|
|
46
|
+
"mean": 0.91,
|
|
47
|
+
"max": 2.34,
|
|
48
|
+
"min": 0.05,
|
|
49
|
+
"entropy": 3.21,
|
|
50
|
+
"n_edges_active": 87
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Update Formula
|
|
56
|
+
|
|
57
|
+
After iteration k, for each ant a:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
delta_tau_a(edge) = q * verified_score_a if edge in path_a, else 0
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Then:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
tau(edge) = (1 - rho) * tau(edge) + sum_over_ants(delta_tau_a(edge))
|
|
67
|
+
tau(edge) = clip(tau(edge), tau_min, tau_max)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Note**: In adversarial-swarm, `verified_score` comes from the 3-vote adversarial scoring
|
|
71
|
+
module (wf-swarm-score) rather than a single scorer. The pheromone math is identical —
|
|
72
|
+
only the score source changes.
|
|
73
|
+
|
|
74
|
+
## Selection Probability
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
p(i -> j) = (tau(i,j)^alpha * eta(i,j)^beta) / sum_{k in N(i)}(tau(i,k)^alpha * eta(i,k)^beta)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Path-Hints vs Full-Path
|
|
81
|
+
|
|
82
|
+
`aco.py select` returns weighted starting nodes + edge probabilities.
|
|
83
|
+
Ant agents make actual node-by-node choices with freedom to deviate.
|
|
84
|
+
|
|
85
|
+
## Entropy as Convergence Signal
|
|
86
|
+
|
|
87
|
+
Shannon entropy of normalized pheromone:
|
|
88
|
+
- High H → diverse exploration (early stage)
|
|
89
|
+
- Low H → concentrated on few paths (converging)
|
|
90
|
+
- Used by both Python `converged` check AND adversarial convergence debate
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Config template for team-adversarial-swarm. Generated by coordinator in Phase 1.",
|
|
3
|
+
|
|
4
|
+
"swarm": {
|
|
5
|
+
"n_ants": 5,
|
|
6
|
+
"max_iterations": 5,
|
|
7
|
+
"elite_keep": 3
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
"aco": {
|
|
11
|
+
"alpha": 1.0,
|
|
12
|
+
"beta": 2.0,
|
|
13
|
+
"rho": 0.2,
|
|
14
|
+
"q": 1.0,
|
|
15
|
+
"tau_init": 1.0,
|
|
16
|
+
"tau_min": 0.01,
|
|
17
|
+
"tau_max": 10.0
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
"task_space": {
|
|
21
|
+
"type": "graph",
|
|
22
|
+
"nodes": ["node_a", "node_b", "node_c"],
|
|
23
|
+
"_alt_auto_discover": "auto_discover_from: 'src/**/*.ts'",
|
|
24
|
+
"max_path_length": 5,
|
|
25
|
+
"start_nodes": "any",
|
|
26
|
+
"edges": "complete"
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
"scoring": {
|
|
30
|
+
"_comment": "mode: adversarial (3-vote per ant) | script | fallback",
|
|
31
|
+
"mode": "adversarial",
|
|
32
|
+
"rubric": "",
|
|
33
|
+
"self_score_discount": 0.5,
|
|
34
|
+
"_alt_script": "script_path: './my-scoring-rule.py'"
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"ant_prompt": {
|
|
38
|
+
"objective": "Find the file with the highest density of suspicious code patterns",
|
|
39
|
+
"evidence_requirements": [
|
|
40
|
+
"At least 1 file:line reference per node visited",
|
|
41
|
+
"Concrete code snippet showing the suspicious pattern"
|
|
42
|
+
],
|
|
43
|
+
"tools_hint": "Use Grep + Read for code-based exploration"
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
"convergence": {
|
|
47
|
+
"max_iterations": 5,
|
|
48
|
+
"stagnation": {
|
|
49
|
+
"enabled": true,
|
|
50
|
+
"patience": 2,
|
|
51
|
+
"min_delta": 0.01
|
|
52
|
+
},
|
|
53
|
+
"entropy_floor": {
|
|
54
|
+
"enabled": true,
|
|
55
|
+
"threshold": 0.5
|
|
56
|
+
},
|
|
57
|
+
"budget_tokens": {
|
|
58
|
+
"enabled": false,
|
|
59
|
+
"max": 100000
|
|
60
|
+
},
|
|
61
|
+
"target_score": {
|
|
62
|
+
"enabled": true,
|
|
63
|
+
"value": 0.95
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Swarm Protocol — Adversarial Edition
|
|
2
|
+
|
|
3
|
+
Defines how the SKILL.md coordinator, Python ACO controller, and modular Workflow scripts interface.
|
|
4
|
+
|
|
5
|
+
## Design Philosophy
|
|
6
|
+
|
|
7
|
+
| Principle | Rationale |
|
|
8
|
+
|-----------|-----------|
|
|
9
|
+
| **Outer loop = coordinator, inner loop = Workflow** | Coordinator drives iteration lifecycle; Workflow scripts handle multi-agent parallelism |
|
|
10
|
+
| **ACO math = Python script** | Optimization math is cheap and deterministic; kept in Python for correctness |
|
|
11
|
+
| **Exploration = Workflow agents** | LLM agents explore task space in parallel via `parallel()` |
|
|
12
|
+
| **Every decision = adversarial** | No single-agent verdicts — scoring, convergence, synthesis all use adversarial patterns |
|
|
13
|
+
| **Schema-locked ant output** | Same contract as team-swarm; LLM output → algorithm input via strict JSON |
|
|
14
|
+
| **Modular composition** | 4 independent Workflow scripts, composable in any order |
|
|
15
|
+
|
|
16
|
+
## Three-Component Architecture
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
+-----------------------------------------------------+
|
|
20
|
+
| SKILL.md Coordinator |
|
|
21
|
+
| - Parses user task → emits swarm-config.json |
|
|
22
|
+
| - Iteration loop: calls Python + Workflow modules |
|
|
23
|
+
| - Data bridge between Workflow calls |
|
|
24
|
+
+--------+--------------------------------------------+
|
|
25
|
+
| Bash subprocess | Workflow({scriptPath})
|
|
26
|
+
v v
|
|
27
|
+
+---------------------+ +--------------------------------+
|
|
28
|
+
| Python ACO | | Workflow Modules (4x) |
|
|
29
|
+
| scripts/aco.py | | wf-swarm-explore.js |
|
|
30
|
+
| - init/select/ | | wf-swarm-score.js |
|
|
31
|
+
| update/converge | | wf-swarm-converge.js |
|
|
32
|
+
| - Owns pheromone | | wf-swarm-synthesize.js |
|
|
33
|
+
+---------------------+ | - parallel()/pipeline() agents |
|
|
34
|
+
| - Adversarial decision gates |
|
|
35
|
+
+--------------------------------+
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Iteration Lifecycle
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
[Coordinator] Phase 1: generate swarm-config.json
|
|
42
|
+
[Coordinator] Phase 2: python aco.py init
|
|
43
|
+
|
|
44
|
+
[Coordinator] Phase 3: iteration k = 1..K
|
|
45
|
+
├─ python aco.py select --iter k → assignments
|
|
46
|
+
├─ Workflow(wf-swarm-explore, args={assignments...}) → ant_results
|
|
47
|
+
├─ Workflow(wf-swarm-score, args={ant_results...}) → verified_scores
|
|
48
|
+
├─ Write scores → python aco.py update --iter k → pheromone updated
|
|
49
|
+
├─ Workflow(wf-swarm-converge, args={best, history...}) → {converged}
|
|
50
|
+
└─ if converged: break
|
|
51
|
+
|
|
52
|
+
[Coordinator] Phase 4:
|
|
53
|
+
├─ python aco.py report → best + top_k + curve
|
|
54
|
+
└─ Workflow(wf-swarm-synthesize, args={best, top_k...}) → best-solution.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Script ↔ Coordinator Contract
|
|
58
|
+
|
|
59
|
+
Same as team-swarm. All scripts:
|
|
60
|
+
- Read from `<session>/...` (via `--session` flag)
|
|
61
|
+
- Emit JSON to stdout
|
|
62
|
+
- Exit 0 = success, 1 = error, 2 = config invalid
|
|
63
|
+
- Idempotent: calling update twice for same iteration is safe
|
|
64
|
+
|
|
65
|
+
| Subcommand | Input | Output (stdout JSON) | Side effects |
|
|
66
|
+
|------------|-------|---------------------|--------------|
|
|
67
|
+
| `init` | swarm-config.json | `{status, pheromone_path, n_nodes}` | writes pheromone/current.json, task-space.json |
|
|
68
|
+
| `select --iter k` | pheromone/current.json | `{assignments: [{ant_id, path_hints, ...}]}` | none |
|
|
69
|
+
| `update --iter k` | artifacts/ant-k-*.json, scores | `{mean_score, best_score, delta}` | writes pheromone + trails + best.json |
|
|
70
|
+
| `converged` | history/, best.json, config | `{converged, reason, metrics}` | none |
|
|
71
|
+
| `report` | best.json, history/ | full report JSON | none |
|
|
72
|
+
|
|
73
|
+
## Coordinator ↔ Workflow Contract
|
|
74
|
+
|
|
75
|
+
Each Workflow module receives `args` and returns structured JSON.
|
|
76
|
+
|
|
77
|
+
| Module | args (input) | return (output) |
|
|
78
|
+
|--------|-------------|-----------------|
|
|
79
|
+
| explore | `{iteration, assignments[], objective, session, config, task_space, wisdom}` | `{ant_results[], metadata}` |
|
|
80
|
+
| score | `{iteration, ant_results[], objective, rubric}` | `{votes, calibration, metadata}` |
|
|
81
|
+
| converge | `{iteration, best, history[], config}` | `{converged, reason, confidence, debate}` |
|
|
82
|
+
| synthesize | `{best, top_k[], convergence_story, objective, total_iterations, total_ants}` | `{perspectives, synthesis, metadata}` |
|
|
83
|
+
|
|
84
|
+
**Key rule**: Coordinator writes ant artifacts and scores to disk BETWEEN Workflow calls.
|
|
85
|
+
Workflow agents can read files but structured data flows through args/return.
|
|
86
|
+
|
|
87
|
+
## Adversarial Patterns by Module
|
|
88
|
+
|
|
89
|
+
| Module | Pattern | Agents per decision |
|
|
90
|
+
|--------|---------|-------------------|
|
|
91
|
+
| explore | Parallel ants + cross-validation | N ants + N validators |
|
|
92
|
+
| score | Prosecutor/Defender/Judge per ant | 3 × N ants + 1 calibrator |
|
|
93
|
+
| converge | Prosecutor(continue) / Defender(stop) / Judge | 3 agents |
|
|
94
|
+
| synthesize | 3-perspective (why-won/stability/caveats) + Arbitrator | 4 agents |
|
|
95
|
+
|
|
96
|
+
## vs team-swarm Protocol
|
|
97
|
+
|
|
98
|
+
| Aspect | team-swarm | team-adversarial-swarm |
|
|
99
|
+
|--------|-----------|----------------------|
|
|
100
|
+
| Worker spawning | delegate_subagent(team-worker) + callback | Workflow parallel()/pipeline() |
|
|
101
|
+
| Scoring | Single scorer OR script | 3-vote adversarial per ant |
|
|
102
|
+
| Convergence | Python script only | Python signal + adversarial debate |
|
|
103
|
+
| Synthesis | Single analyst | 3-perspective + arbitrator |
|
|
104
|
+
| Session management | create_team + team_msg | Coordinator direct file I/O |
|
|
105
|
+
| Data flow | Message bus + file artifacts | args → Workflow → return + files |
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'wf-swarm-converge',
|
|
3
|
+
description: 'Adversarial convergence decision — prosecutor(continue) vs defender(stop) vs judge resolves',
|
|
4
|
+
whenToUse: 'After each ACO iteration: adversarial debate on whether swarm has converged or should continue',
|
|
5
|
+
phases: [
|
|
6
|
+
{ title: 'Argue', detail: 'Prosecutor argues to continue, Defender argues to stop' },
|
|
7
|
+
{ title: 'Judge', detail: 'Judge resolves debate with evidence-weighted verdict' },
|
|
8
|
+
],
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const ARGUMENT_SCHEMA = {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
role: { type: 'string', enum: ['prosecutor', 'defender'] },
|
|
15
|
+
stance: { type: 'string', enum: ['continue', 'stop'] },
|
|
16
|
+
argument: { type: 'string' },
|
|
17
|
+
key_points: {
|
|
18
|
+
type: 'array',
|
|
19
|
+
items: {
|
|
20
|
+
type: 'object',
|
|
21
|
+
properties: {
|
|
22
|
+
point: { type: 'string' },
|
|
23
|
+
evidence: { type: 'string' },
|
|
24
|
+
strength: { type: 'string', enum: ['strong', 'moderate', 'weak'] },
|
|
25
|
+
},
|
|
26
|
+
required: ['point', 'evidence', 'strength'],
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
concessions: { type: 'array', items: { type: 'string' } },
|
|
30
|
+
confidence: { type: 'number', minimum: 0, maximum: 100 },
|
|
31
|
+
},
|
|
32
|
+
required: ['role', 'stance', 'argument', 'key_points', 'confidence'],
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const VERDICT_SCHEMA = {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
converged: { type: 'boolean' },
|
|
39
|
+
reason: { type: 'string' },
|
|
40
|
+
confidence: { type: 'number', minimum: 0, maximum: 100 },
|
|
41
|
+
adversarial_outcome: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
prosecutor_confidence: { type: 'number' },
|
|
45
|
+
defender_confidence: { type: 'number' },
|
|
46
|
+
decisive_factor: { type: 'string' },
|
|
47
|
+
prosecutor_concessions: { type: 'array', items: { type: 'string' } },
|
|
48
|
+
defender_concessions: { type: 'array', items: { type: 'string' } },
|
|
49
|
+
},
|
|
50
|
+
required: ['prosecutor_confidence', 'defender_confidence', 'decisive_factor'],
|
|
51
|
+
},
|
|
52
|
+
recommendation: { type: 'string' },
|
|
53
|
+
},
|
|
54
|
+
required: ['converged', 'reason', 'confidence', 'adversarial_outcome'],
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const iteration = args?.iteration || 1
|
|
58
|
+
const best = args?.best || {}
|
|
59
|
+
const history = args?.history || []
|
|
60
|
+
const config = args?.config || {}
|
|
61
|
+
const patience = config.patience || 2
|
|
62
|
+
const minImprovement = config.min_improvement || 0.01
|
|
63
|
+
const maxIterations = config.max_iterations || 5
|
|
64
|
+
|
|
65
|
+
const historyDigest = history.map((h, i) =>
|
|
66
|
+
`Iter ${i + 1}: best=${h.best_score} mean=${h.mean_score} delta=${h.delta || 'n/a'} ants=${h.completed_ants || 'n/a'}`
|
|
67
|
+
).join('\n')
|
|
68
|
+
|
|
69
|
+
const improvementTrend = history.length >= 2
|
|
70
|
+
? history.slice(-patience).map(h => h.delta || 0)
|
|
71
|
+
: []
|
|
72
|
+
const stagnating = improvementTrend.length >= patience && improvementTrend.every(d => Math.abs(d) < minImprovement)
|
|
73
|
+
|
|
74
|
+
// Phase 1: Adversarial Debate
|
|
75
|
+
phase('Argue')
|
|
76
|
+
log(`Iteration ${iteration}: adversarial convergence debate...`)
|
|
77
|
+
|
|
78
|
+
const debate = await parallel([
|
|
79
|
+
() => agent(
|
|
80
|
+
`You are the PROSECUTOR. Argue that the swarm should CONTINUE exploring.
|
|
81
|
+
|
|
82
|
+
## Current State
|
|
83
|
+
Iteration: ${iteration} of ${maxIterations}
|
|
84
|
+
Best score: ${best.score || 'unknown'}
|
|
85
|
+
Best ant: ${best.ant_id || 'unknown'}
|
|
86
|
+
|
|
87
|
+
## Score History
|
|
88
|
+
${historyDigest || 'No history yet'}
|
|
89
|
+
|
|
90
|
+
## Convergence Config
|
|
91
|
+
Patience: ${patience} (stop if no improvement for this many iterations)
|
|
92
|
+
Min improvement: ${minImprovement}
|
|
93
|
+
Max iterations: ${maxIterations}
|
|
94
|
+
|
|
95
|
+
## Stagnation Signal
|
|
96
|
+
${stagnating ? 'YES — last ' + patience + ' iterations show < ' + minImprovement + ' improvement' : 'NO — improvement still occurring or not enough data'}
|
|
97
|
+
|
|
98
|
+
## Your Job: Argue to CONTINUE
|
|
99
|
+
Build the strongest case that the swarm should keep going:
|
|
100
|
+
- Best score isn't good enough yet (absolute quality)
|
|
101
|
+
- Score variance across ants suggests unexplored promising regions
|
|
102
|
+
- Pheromone entropy is still high (many paths competitive)
|
|
103
|
+
- Budget allows more iterations
|
|
104
|
+
- Recent deviations from pheromone hints produced discoveries
|
|
105
|
+
|
|
106
|
+
Acknowledge when stopping would be reasonable — concessions add credibility.
|
|
107
|
+
Your confidence reflects how genuinely strong your case is.`,
|
|
108
|
+
{ label: 'prosecutor:continue', phase: 'Argue', schema: ARGUMENT_SCHEMA }
|
|
109
|
+
),
|
|
110
|
+
() => agent(
|
|
111
|
+
`You are the DEFENDER. Argue that the swarm should STOP and declare convergence.
|
|
112
|
+
|
|
113
|
+
## Current State
|
|
114
|
+
Iteration: ${iteration} of ${maxIterations}
|
|
115
|
+
Best score: ${best.score || 'unknown'}
|
|
116
|
+
Best ant: ${best.ant_id || 'unknown'}
|
|
117
|
+
|
|
118
|
+
## Score History
|
|
119
|
+
${historyDigest || 'No history yet'}
|
|
120
|
+
|
|
121
|
+
## Convergence Config
|
|
122
|
+
Patience: ${patience} (stop if no improvement for this many iterations)
|
|
123
|
+
Min improvement: ${minImprovement}
|
|
124
|
+
Max iterations: ${maxIterations}
|
|
125
|
+
|
|
126
|
+
## Stagnation Signal
|
|
127
|
+
${stagnating ? 'YES — last ' + patience + ' iterations show < ' + minImprovement + ' improvement' : 'NO — improvement still occurring or not enough data'}
|
|
128
|
+
|
|
129
|
+
## Your Job: Argue to STOP
|
|
130
|
+
Build the strongest case that the swarm has converged:
|
|
131
|
+
- Best score is stable across recent iterations
|
|
132
|
+
- Multiple ants converging on similar paths (low entropy)
|
|
133
|
+
- Diminishing returns — each iteration yields less improvement
|
|
134
|
+
- Best solution quality is sufficient for the objective
|
|
135
|
+
- Further iterations would waste budget without meaningful gain
|
|
136
|
+
|
|
137
|
+
Acknowledge when continuing might help — concessions add credibility.
|
|
138
|
+
Your confidence reflects how genuinely strong your case is.`,
|
|
139
|
+
{ label: 'defender:stop', phase: 'Argue', schema: ARGUMENT_SCHEMA }
|
|
140
|
+
),
|
|
141
|
+
])
|
|
142
|
+
|
|
143
|
+
const validDebate = debate.filter(Boolean)
|
|
144
|
+
const prosecutor = validDebate.find(a => a.role === 'prosecutor')
|
|
145
|
+
const defender = validDebate.find(a => a.role === 'defender')
|
|
146
|
+
|
|
147
|
+
const debateDigest = validDebate.map(a =>
|
|
148
|
+
`### ${a.role.toUpperCase()} (stance: ${a.stance}, confidence: ${a.confidence}%)\n${a.argument}\nKey points:\n${a.key_points.map(p => '- [' + p.strength + '] ' + p.point).join('\n')}\nConcessions: ${a.concessions.join('; ') || 'none'}`
|
|
149
|
+
).join('\n\n---\n\n')
|
|
150
|
+
|
|
151
|
+
log(`Prosecutor: ${prosecutor ? prosecutor.confidence : '?'}% for continue | Defender: ${defender ? defender.confidence : '?'}% for stop`)
|
|
152
|
+
|
|
153
|
+
// Phase 2: Judge resolves
|
|
154
|
+
phase('Judge')
|
|
155
|
+
log('Judge resolving convergence debate...')
|
|
156
|
+
|
|
157
|
+
const verdict = await agent(
|
|
158
|
+
`You are the JUDGE. Two advocates debated whether this swarm should continue or stop.
|
|
159
|
+
|
|
160
|
+
=== DEBATE ===
|
|
161
|
+
${debateDigest}
|
|
162
|
+
|
|
163
|
+
=== OBJECTIVE DATA ===
|
|
164
|
+
Iteration: ${iteration} of ${maxIterations}
|
|
165
|
+
Best score: ${best.score || 'unknown'}
|
|
166
|
+
Score history: ${historyDigest || 'none'}
|
|
167
|
+
Stagnation signal: ${stagnating ? 'YES' : 'NO'}
|
|
168
|
+
|
|
169
|
+
=== DECISION RULES ===
|
|
170
|
+
1. If iteration >= max_iterations → MUST converge (safety net)
|
|
171
|
+
2. If iteration == 1 → MUST NOT converge (need at least 2 iterations)
|
|
172
|
+
3. If stagnation signal AND defender confidence > 60% → converge
|
|
173
|
+
4. If prosecutor confidence > 80% AND best score < 0.5 → continue (insufficient quality)
|
|
174
|
+
5. If defender concedes major points → likely should continue
|
|
175
|
+
6. If prosecutor concedes major points → likely should stop
|
|
176
|
+
7. Otherwise → weigh evidence quality from both sides
|
|
177
|
+
|
|
178
|
+
Record the adversarial_outcome with both confidences, concessions, and the decisive factor.
|
|
179
|
+
Provide a recommendation for what to focus on if continuing.`,
|
|
180
|
+
{ label: 'judge', phase: 'Judge', schema: VERDICT_SCHEMA }
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
iteration: iteration,
|
|
185
|
+
converged: verdict ? verdict.converged : (iteration >= maxIterations),
|
|
186
|
+
reason: verdict ? verdict.reason : 'max_iterations_reached',
|
|
187
|
+
confidence: verdict ? verdict.confidence : 100,
|
|
188
|
+
adversarial_outcome: verdict ? verdict.adversarial_outcome : null,
|
|
189
|
+
debate: { prosecutor: prosecutor, defender: defender },
|
|
190
|
+
metadata: {
|
|
191
|
+
best_score: best.score,
|
|
192
|
+
stagnation_signal: stagnating,
|
|
193
|
+
iteration_of_max: iteration + '/' + maxIterations,
|
|
194
|
+
prosecutor_confidence: prosecutor ? prosecutor.confidence : null,
|
|
195
|
+
defender_confidence: defender ? defender.confidence : null,
|
|
196
|
+
},
|
|
197
|
+
}
|