Spec: the swarm workflow definition — a dispatched multi-agent run that proposes one PR (moved from swarm/ting-dsh#74) #35
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Meta/Campaign
Meta/Epic
Meta/Session
Priority/Critical
Priority/High
Priority/Low
Priority/Medium
Reviewed/Confirmed
Reviewed/Curated
Reviewed/Duplicate
Reviewed/Invalid
Reviewed/Won't Fix
Scope/Campaign
Status/Abandoned
Status/Blocked
Status/Conflicted
Status/In Progress
Status/In Review
Status/Need Grooming
Status/Need More Info
Status/Ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
Reference
Ting/workflows#35
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Moved from swarm/ting-dsh#74 on 2026-09-10 (freeholder: "Move to Ting/workflows"). This is the spec of the
swarmworkflow definition for this executor: a catalog entry whose steps bind the seat cards (queen, vinculum, drone, probe, resistance; cards inlarandar/agents.larseats/), with AC3 as the gate: a dispatchedswarmrun decomposes work, delegates to seat-holders, and proposes one PR. Two rulings since it was written: ruling 10 (2026-09-06: Open Workflow Specification definitions, ting's own Rust executor, OpenSpec + Datalog gates) and 2026-09-10 (swarm/ting-dsh#115: "dispatch -> interface for the executor that will run using dsh as harness"). Read the body below in that layering: where it says the console mints a context or the queen interprets a pattern, the executor now does it through dsh sessions; the roster half stays in swarm/ting-dsh#32. The 2026-09-04 decision map it cites is in the ting-dsh wiki (DecisionMap-swarm-workflow).Spec (PRD) for the change
swarm-workflow. Grounded in~/openspec/ting-dsh-wiki/DecisionMap-swarm-workflow.md(the seven lockeddecisions, 2026-09-04 rulings) and the fixed seat charter
(
presets/swarm/skills/swarm/SKILL.md). Vocabulary isCONTEXT.mdand #72:a dispatch family is a workflow; one execution is a run — "pass" is
retired. AC3 is the acceptance bar.
Depends on #72 and the a2a-purity spec (#73).
Problem Statement
The estate can dispatch a single-session run of a workflow family, but it
cannot yet dispatch the
swarmworkflow: a run that decomposes work acrossthe seats of the swarm charter (queen, vinculum, drone, probe, resistance)
and proposes one PR as its proof of work. Today's dispatch mints one a2a
context and enqueues one brief; there is no queen that splits the work, no
durable seat sessions under it, no landing gate that reads real artifacts,
no curated single-PR outcome. The roster (
@ting/dsh-swarm,GET /ting/api/swarm) is the surface meant to show who holds which seat, butits
report/withdrawwriters are dead — nothing wires a spawned seat ontoit, so the roster is permanently empty and a swarm's membership is invisible.
The seat charter is written and fixed, yet no workflow drives it end to end.
The acceptance bar (AC3): a dispatched
swarmrun decomposes work, delegatesto seat-holders, and proposes one PR.
Solution
Build the
swarmworkflow as a multi-stage dispatched run, homed in thedomain bundle
@ting/dsh-swarm(a2a stays a pure A2A-spec implementation —that cut is the prerequisite change a2a-purity, #73). A run is minted by a
dispatch route — after a2a-purity's rename,
/swarm/api/runs— that binds ana2a context. Space setup is mechanical and scripted: a deterministic step
provisions the queen's tree for the chosen isolation mode FIRST, and only then
is the queen's first-turn brief composed (from the task, the bound workspace,
and the isolation mode) and the queen seat spawned into that ready tree.
The queen then delegates by INVOKING a sub-workflow per drone: each
sub-workflow provisions an isolated tree off the queen's tip, spawns and
briefs the drone on its deliverable, and returns the branch for the
vinculum's gate. Execution is hybrid:
probe(mechanical, no-thinking) runsas an in-session subagent (the swarm preset already mounts
subagent/subagent_fork); every complex-contract or recyclable seat — queen,vinculum, drone, resistance — runs as an A2A multi-session (a separate DSH
session per seat) so it is durable, visible on the roster, and recyclable.
The outcome flow is invariant: the vinculum LANDS (gates each member's real
artifact against the brief's acceptance and composes the collective result),
the queen CURATES the landed work — pulling each approved branch into its own
tree and reshaping git history into feature-sized commits — and the queen
PROPOSES the single PR. Every run ends in a proposed PR: there is no
--applygate and no dry-run swarm; the PR is the proof of work. Spawnedseats become visible by wiring the roster's
report/withdrawso a seatregisters on spawn and withdraws on exit.
User Stories
swarmrun with a task anda bound workspace, so that a queen decomposes the work and returns a single
PR I can review.
ad-hoc on my live worktree, or clean-room in a scratchpad clone — so that
the swarm either curates around my concurrent changes or works off a clean
fastlane@origintip.its id immediately, so that I can open the run's surface without waiting for
it to finish.
that I always have a concrete artifact to accept or reject — never a dry-run
with nothing to show.
so that a running swarm's membership is visible rather than empty.
and its folders/repos, and the isolation mode, so that I can decompose the
work knowing my context — the charter already carries my role behaviour.
worktree (ad-hoc) or a shallow
fastlane@originclone in a scratchpad(clean-room) — so that my base is correct before I delegate.
deliverable, so that each drone gets an isolated tree off my tip, is spawned
and briefed on its deliverable, and returns its branch — delegation is
composition, not a bare spawn.
whole plan, so that a drone ships precisely what it was asked for.
clone off my tip, so that a stuck drone does not stall the run.
branch into my own tree — so that composition lands under one hand.
the proposed PR carries feature-sized commits, not one commit per
deliverable.
(push to origin in clean-room; cut from the freeholder base in ad-hoc), so
that the run always ends in exactly one PR.
a test run — against the brief's acceptance items, so that I land work on
evidence and never on a claim of "done".
the evidence, so that repair is directed, never silent.
collective artifact the queen can accept whole, so that the queen curates a
landed result rather than raw member output.
by reading the real artifact and never by writing it.
naming my deliverable, so that I can ship it exactly as briefed without
colliding with another drone.
contradicts my brief, so that the queen reconciles it rather than my
guessing past it.
cwd, so that a mechanical, effectively read-only errand needs no isolated
tree.
clones with the probe's mechanical findings as ammunition, so that what
survives the gate deserves to.
withdraw when I exit, so that the roster reflects the live membership of the
swarm.
in the same seat, so that recycling a member is a new durable session, not a
lost run.
Implementation Decisions
Restating the seven locked decisions as module/interface decisions. No file
paths, no code snippets.
Charter fixed; identity deferred. The seats and their contracts are a
given from the preset charter; this change does NOT redefine them. Identity
assignment (named identities per seat) is OUT of v1 — a seat is held by a
nameless ad-hoc agent that takes the seat's contract. (Identity waits on the
seat-granting framework, #59.)
The dispatch route. The
swarmworkflow is dispatched by a domain route— after a2a-purity,
/swarm/api/runs— that mints an a2a context, composesthe queen's first-turn brief, writes the run's own domain document, and
answers the run id, without awaiting the run's completion. Brief composition
is one pure function of (task, workspace, isolation mode); the charter
carries role behaviour, the brief carries only task and context.
Hybrid execution.
probeis an in-session subagent spawned inside thespawner's own loop (the preset already mounts the delegation tools). Every
complex-contract or recyclable seat — queen, vinculum, drone, resistance —
is an A2A multi-session: a separate durable DSH session per seat, visible on
the roster and recyclable by replacement.
Isolation provisioning (mechanical, scripted — runs first). Space setup
is a deterministic scripted step, NOT agent work: within each stage the tree
is provisioned FIRST, then the agent is spawned and briefed into the ready
tree. A provisioning interface maps an isolation mode to a queen space: ad-hoc
= the freeholder's live worktree (curated around the freeholder's concurrent
changes); clean-room = a shallow clone of
fastlane@origintip into ascratchpad directory (a real scratchpad, never
/tmp). Drones always clonethe tip of the QUEEN's clone (isolated per drone) — again a scripted clone,
not an agent action. Vinculum and resistance are read-only on the drone
clones; probe shares the queen cwd (effectively read-only). This ties to
decision 2's "mechanical" framing: the deterministic script provisions the
space, the agent only inhabits it.
The multi-stage pipeline and the drone-space sub-workflow. The run is a
staged setup, each stage a scripted provision then a spawn: Stage 1 the
script provisions the queen space, THEN spawns the queen; Stage 2 the queen
delegates by INVOKING a sub-workflow per drone. The queen-callable
drone-space sub-workflow is the new primitive this change must build (the
research gap): it first provisions an isolated tree off the queen tip
(scripted), then spawns and briefs the drone's session into that ready tree
with its deliverable, and returns the branch for the vinculum's gate.
Delegation is nested composition, not a bare spawn call.
Domain home and roster wiring. All swarm concepts live in
@ting/dsh-swarm; a2a stays a pure A2A-spec implementation (the a2a-purityprerequisite moves the swarm surfaces out). Member visibility is the
@ting/dsh-swarmroster (/ting/api/swarm), whosereport/withdrawwriters — dead today — get wired so a spawned seat registers on the roster
and withdraws on exit. The membership/lineage link is ting-swarm's own
domain state, projected over a2a's generic context/task ledger, never a new
field in the a2a context record.
The queen merge + history curation, and the always-PR outcome. The
outcome flow is invariant: vinculum lands (gates each member's real artifact
against the brief's acceptance, composes) → queen curates (owns the
merge-write of approved branches into its tree, and reshapes git history into
feature-sized commits) → queen proposes the single PR. Every run ends in a
proposed PR — no
--apply, no dry-run. Clean-room mode pushes the curatedbranch to origin and opens the PR; ad-hoc mode cuts the curated branch from
the freeholder base and opens the PR (the curated commits may also remain on
the working copy). The queen owns the merge-write; the vinculum only gates.
Testing Decisions
Only external behaviour. Prior art is
scripts/verify.nuandscripts/check.nu(home-isolated under.dsh-check/). All seams below arePROPOSED, pending freeholder confirmation — they were not yet confirmed live.
and the one that runs FIRST in the pipeline: a mechanical, scripted,
deterministic setup step — not an agent turn. Given a mode, the queen space
is set up correctly (ad-hoc worktree vs shallow scratchpad clone) and drone
spaces clone off the queen tip — testable against a temporary git repo, no
agents at all, since space setup is a script.
composed from (task, workspace, isolation mode), assembled AFTER the tree is
provisioned and used to brief the agent into the ready tree. Prior art: the
BRIEFScomposer map in dispatch.just verify) — PROPOSED./ting/api/swarmreflectsspawned seats via the wired
report/withdraw.just verify) — PROPOSED./swarm/api/runsmints a runand returns its id.
outcome (decompose → drones → vinculum gate → queen curate → PR) is proven by
a LIVE dispatched run producing a PR plus a browser, NOT by a deterministic
test. Per AGENTS.md law 4, composed is not mounted and only the real run and
a browser prove the rendered, mounted outcome — a deterministic test cannot
stand in for it. This is stated explicitly as the acceptance method for AC3.
Out of Scope
seat-granting framework; v1 seats are nameless ad-hoc agents.
fixed; this change consumes them, it does not re-litigate them.
a2a is the separate prerequisite change (#73), not part of this one.
is dispatcher guidance only for now; the preset plane enforcing a model per
seat is future backlog.
Further Notes
a2a-purity spec (#73), which lands first to give this change a clean base with
the swarm surfaces homed in
@ting/dsh-swarmand the routes renamed/*/api/runs.seat-holders, and proposes one PR.
landing-gate mechanics (how the vinculum reads each member's real artifact
against acceptance and how a rejected landing bounces back); the recycling
mechanism (how the queen replaces a failing seat with a fresh clone off its
tip); and model tiers per seat (dispatcher guidance until the preset plane
enforces it).
that proved it —
--dump-configproves composition, a boot plus a route probeproves mounting, a browser proves rendering; AC3's outcome is proven live.
@deepseek-ai/dsh0.1.1-rc.2; an upgrade is a re-derivation, not a version bump.