feat(swarm): SP2 — real collaboration (data-flow, role-aware personas, permissions, self-healing)#13
Closed
New1Direction wants to merge 6 commits into
Closed
Conversation
…-flow, permissions, self-healing)
…ake-crash from decomposition
role_marker now recognizes all 5 personas from their Prompts/*.md role titles
(Captain=Swarm Orchestrator & Planner, Harper=Adversarial Researcher & Reviewer,
Benjamin=Builder & Implementer, Lucas=Synthesizer & Reconciler,
Evaluator=Guardrail Evaluator & Critic), with persona names as fallback.
For the fixture-class task (add bug on src/lib.rs) each persona emits a real,
deterministic, role-shaped JSON artifact matching its documented schema:
captain->work_packages/acceptance_criteria, harper->concerns/risk_assessment,
benjamin->applyable mutations (unchanged), lucas->resolutions,
evaluator->passed_rubrics/recommended_action. Any non-fixture task ->
honest-null (empty role-shaped artifact + 0.2 confidence), never fabricated.
complete() stays pure/deterministic. Adds role-aware fixture + honest-null tests.
De-theater: decompose_into_persona_packages no longer bakes 'simulate-crash'
into Benjamin's package (now 'Implement: {root_task}'); the harness handler is
retained for explicit fault-injection. Adds a unit test asserting the default
benjamin package description does not contain 'simulate-crash'.
…(real data-flow) dispatch_concurrent now makes packages_map mutable and, after each DAG level completes, rewrites every still-pending downstream node whose dependencies include a just-completed node so its worker payload carries the real upstream PersonaResult.output (Captain+Harper -> Benjamin; Benjamin -> Lucas). The reverse dependency map is read from the DAG node .dependencies; the next level's dispatch_level reads pkg.description as the worker payload, so the flow is real (not a no-op). The payload rewrite lives in a pure helper compose_downstream_payload(base, upstream) in workers.rs: upstream entries are sorted by (persona, node_id) for determinism, and the appended upstream context is capped at UPSTREAM_CONTEXT_BUDGET (8000 chars) with an explicit …[truncated] marker on a UTF-8 char boundary. Adds unit tests proving the downstream payload carries upstream content (captain plan -> benjamin, benjamin output -> lucas), order-independence, the size cap, and the empty-upstream no-op.
…ver mutate Add a permission policy module (permissions_for / may_write): benjamin & lucas get fs:write:worktree; harper, captain, evaluator (and any unknown persona) get fs:read and are analyze-only. - session.rs: SubprocessBackend::spawn now derives RouteWork.permissions from permissions_for(&spec.persona) instead of hardcoding fs:write:worktree. - harness.rs: handle_route_work stops ignoring permissions (_permissions -> permissions) and threads them into run_task_in_worktree, which gates apply_mutations on may_write(). A read-only persona that emits mutations is analyzed (numstat/cargo_check on the existing tree), never applied, and records files_changed = 0 honestly, with a one-line log note. TDD: 8 policy tests + an apply-gate integration test proving benjamin's real fixture patch is blocked under fs:read (file unchanged, files_changed == 0) but applied under fs:write:worktree (src/lib.rs rewritten to a + b). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ount after heal) run_self_healing_loop previously never re-plumbed files_changed after a heal, so the leader's real_files_changed sum (leader.rs ~1484) missed healed changes. - After a real heal (direct heal-success or a speculative repair that mutated the worktree), re-run observation::numstat on the heal target and set current_result.files_changed to the re-measured count. Gated on a healed_this_loop flag so a no-op pass never re-measures or clobbers the worker's reported count — no fabrication. - Made the honest no-op explicit: when no worktree exists (clean run — the worker already cleaned up), return the worker's result unchanged. TDD: - test_self_healing_loop_success now sets up a git worktree with a committed missing-semicolon error so the heal path actually runs (non-vacuous), and asserts the re-measured files_changed == 1 (the healed src/main.rs; build artifacts gitignored, not counted). - Added test_self_healing_loop_no_op_preserves_count_when_no_worktree: with no worktree, the worker's reported count (5) is preserved, not re-measured. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ewrite The Slice-2 data-flow wiring previously had only the pure compose_downstream_payload helper under test — the per-level rewrite loop in dispatch_concurrent had no regression test. Extract that loop into a pure, testable workers::apply_upstream_to_pending(packages_map, node_dependencies, completed_outputs, just_completed_ids) and call it from dispatch_concurrent (behavior unchanged — the inline loop is now a single call). Add an integration test on the canonical 4-node DAG that asserts the REAL rewrite (not a tautology): - After captain+harper complete, benjamin's payload contains BOTH 'work_packages' / 'Upstream from Captain (pkg-captain)' AND 'concerns' / 'Upstream from Harper', while lucas (dep not yet done) is untouched and L1 peers are not rewritten. - After benjamin completes, lucas's payload contains 'mutations' / 'src/lib.rs' / 'Upstream from Benjamin (pkg-benjamin)', and benjamin is not re-rewritten. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New1Direction
added a commit
that referenced
this pull request
Jun 15, 2026
…ssions) Lands the stacked branch 'feat/swarm-collaboration' (PR #13) onto main.
Owner
Author
|
Landed on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Track B SP2: make the swarm actually collaborate
The DAG already encoded the collaboration graph (benjamin depends on captain+harper; lucas on benjamin) but never passed data; permissions were plumbed yet ignored; Benjamin's worker was deliberately crash-simulated (
"Implement (simulate-crash)"); and self-healing was a no-op. SP2 makes the collaboration mechanism genuinely real.Slices (each independently reviewed)
1 — Role-aware provider + de-theater (
52fbddd)DeterministicProvidernow recognizes all 5 personas (markers sourced 1:1 fromPrompts/*.md) and emits a real role-shaped artifact each for the fixture task (captain→work_packages, harper→concerns, benjamin→applyable patch, lucas→resolutions, evaluator→passed_rubrics); honest-null for any other task — never fabricated.(simulate-crash)directive from the default decomposition (the fault handler stays for explicit fault tests).2 — Real upstream→downstream data-flow (
d632657,27f66b7)dispatch_concurrentnow rewrites each downstream node's payload with its DAG-upstream personas' output (Captain+Harper→Benjamin, Benjamin→Lucas) before it dispatches — carried in the existingRouteWork.payload, 8000-char capped, deterministically ordered. Verified end-to-end: the rewrittenpkg.descriptionis the load-bearing worker payload (workers.rs:200).apply_upstream_to_pendingextracted + an integration test asserting the real rewrite (with pending-only gating).3 — Per-persona permissions (
85b90f6)permissions_for: benjamin/lucas write, harper/captain/evaluator read (least-privilege default). Enforced inrun_task_in_worktreeviamay_write— a read-only persona's mutations are not applied andfiles_changedis honestly 0. Proven on-disk: Benjamin's real patch is blocked underfs:read, applies underfs:write.4 — Self-healing re-plumb (
1d9a4fa)numstatand updatesfiles_changedso the ledger count stays truthful; a clean run still fabricates no heal. Test made non-vacuous (real compile error → heal runs →files_changed==1).Honesty boundary (stated, not hidden)
Offline real collaboration is demonstrated on fixture-class tasks via the role-aware deterministic stub; arbitrary campaign tasks honestly honest-null offline and need
--provider ollama. No claim that "all personas do real work on any task."Test plan
cargo test --workspace— 32 binaries, 0 failures (korg-runtime 132 lib + korg-llm 20 + keystone + run_once)Honest limitation
No live multi-subprocess
dispatch_concurrentcampaign was run end-to-end (it spawns real worker processes + worktrees — heavy/non-deterministic). Coverage targets the deterministic seams (data-flow pure-fn, permissions on-disk, self-healing orchestrator-level); the live-loop wiring is verified by construction + trace, not an end-to-end run.Stacked on
feat/swarm-honest-demo(SP4). For review — not for merge ahead of the stack.Spec:
docs/superpowers/specs/2026-06-14-korg-swarm-sp2-collaboration-design.md