Repository navigation
Drop the orchestrate sub-coordinator - #28
Conversation
A Droid subagent cannot call Task, so each track stays with the coordinator. Briefs inline store facts, and a chain rebase still loads this computer. Co-authored-by: Kaitian Xie <caelaxie@users.noreply.github.com>
caelaxie
left a comment
There was a problem hiding this comment.
verdict: changes requested (proof only).
content passes. L17 and L81 are exactly #16's smallest fix. the track rewrite answers #16's question the way the factory custom droids docs force it (subagents can't call Task), and every knock-on line (L55 brief, L57 audit, step 4, restart line) is consistent. no other sub-coordinator, depth 3, or nested-spawn refs left in the 31 poteto-mode md files at f48501a. Closes #16 is right, not a draft.
missing: harness proof. Validate plugin was still running at review time. please post, on f48501a (or the final head):
droid plugin marketplace addof this branch +droid plugin install pstack@droid-pstack+droid plugin list- the installed
skills/poteto-mode/playbooks/orchestrate.mdgrepped forTrack (coordinator-owned)andThere is no separate machine for a chain rebase(or acmpagainst the PR head copy) - green
Validate plugin
if a live model turn is blocked by droid auth, install+list plus the installed copy is enough for this text-only change. i'll merge once that lands.
|
Harness proof. Command output is unedited. |
caelaxie
left a comment
There was a problem hiding this comment.
verdict: changes requested (comment review, same account). not merging.
proof is fine now: validate plugin is green at f48501a. L17 and L81 match #16's smallest fix word for word, and the no-nested-spawn claim matches custom droids ("a subagent cannot spawn its own subagents"). Closes #16, not a draft.
i'm walking back the earlier "every knock-on line is consistent". the track bullet keeps upstream sentences that only made sense with a separate drainer per track:
- L16: upstream's cap is "what one drain can process, roughly ten" per sub-coordinator, and each sub-coordinator had its own drain. now the coordinator is the only drain, so ten per track means N tracks put N×10 children on one drain, which breaks the rule's own reason. the threshold "only when the program exceeds what one coordinator's drains can manage" has the same problem: a track no longer takes any drain load off the coordinator.
- L55: a "track brief the coordinator keeps" with a spawn budget, drain protocol, and rollup format has no reader. those were instructions to the sub-coordinator agent.
- L16 rewording beyond the fix: "always local, durable, one per track" -> "one per cut", "needs no middle layer" -> "needs no separate board".
smallest way out is up to you: make the cap total across tracks and drop the threshold, rollup, and L55 brief clauses, or drop the role and keep tracks only as a label for decomposition (L19 already says that).
caelaxie
left a comment
There was a problem hiding this comment.
line comments for the review above.
| - **Coordinator (this chat).** Local. Frames, authors briefs, drains the inbox, owns the human report, makes judgment calls. It never authors or edits code. Conflicted merges, chain rebases, and code changes are always tasks. Mechanically landing a verified unit (fast-forward or clean cherry-pick of a worker's commit, then push) is bookkeeping the coordinator may do itself on repos where local git is cheap. Queueing finished work behind an idle stacker is how a deadline harvests nothing. The loop is agentic end to end. Agents are spawned, resumed, and drained only through the Task tool. Pick each subagent's complexity for the job, per the Subagents section. State reads and writes go through `scripts/orch/orch.ts` at drain points, one command in and one line out. The CLI never spawns, waits, or wakes anything. | ||
| - **Sub-coordinator.** Always local, durable, one per track, and only when the program exceeds what one coordinator's drains can manage. A track the coordinator can drain itself needs no middle layer. Each nested layer re-pays a full orientation preamble, and a blocking sub-coordinator hides its children while the parent idles. Owns its track's units and boards, authors its workers' briefs, spawns its own workers and verifiers (nesting works to depth 3, and a nested spawn has the full Task schema). Rolls up aggregates at wave boundaries. Never forwards raw child reports. Cap in-flight children at what one drain can process, roughly ten, as a rolling window. Never as blocking batches, which cost the slowest child of every batch. | ||
| - **Worker / verifier.** Always spawned with `run_in_background: true` in its own git worktree, unless the task needs this machine: `control-ui` or `control-cli` runtime verification. Reading local session transcripts under `~/.factory/sessions/`. Simulators and local IDE state. Auth that exists only here. Subagents cannot see the parent chat, so their briefs inline what they need or point at repo paths. Prefer fewer, broader workers. One writer per worktree or branch (principle-separate-before-serializing-shared-state). Run a unit's verifier on a different seat from its worker. | ||
| - **Track (coordinator-owned).** One per cut, and only when the program exceeds what one coordinator's drains can manage. A track the coordinator can drain itself needs no separate board. A subagent cannot call Task, so the coordinator owns the track's units and boards, authors its workers' briefs, and spawns that track's workers and verifiers. There is no nested spawn and no depth-3 tree. Rolls up aggregates at wave boundaries. Never forwards raw child reports. Cap in-flight children at what one drain can process, roughly ten, as a rolling window. Never as blocking batches, which cost the slowest child of every batch. |
There was a problem hiding this comment.
the cap and the threshold both assume each track has its own drainer. with the coordinator as the only drain, "roughly ten" per track gives N×10 children on one drain, and "only when the program exceeds what one coordinator's drains can manage" no longer describes what a track does. either make the cap total across tracks or drop the role. also keep upstream's wording where it still holds: "one per cut" and "needs no separate board" are rewrites of "one per track" and "needs no middle layer".
| Size the brief to the unit. A one-command unit gets the template collapsed to a paragraph that still names goal, scope, the verify command, and the report shape. A 4KB scaffold around a two-line edit costs more to write and obey than the edit. Local spawns may reference the standing-orders file by store path. Verbatim paste is for background spawns and every resume. | ||
|
|
||
| A sub-coordinator brief adds its track boundary and unit list, its spawn budget with the background default and the local exception list, the drain protocol, and the rollup format (per child: name, status, PR, head SHA, verdict, one line, plus track status and frontier delta). | ||
| A track brief the coordinator keeps adds its track boundary and unit list, its spawn budget with the background default and the local exception list, the drain protocol, and the rollup format (per child: name, status, PR, head SHA, verdict, one line, plus track status and frontier delta). |
There was a problem hiding this comment.
no agent reads this brief now. spawn budget, drain protocol, and rollup format were instructions to the sub-coordinator. drop the paragraph, or say what the coordinator keeps it for in one line.
The coordinator-owned track kept a per-track cap that assumes each track has its own drainer. The sub-coordinator bullet and its brief stay, and the only new wording is the store-access and machine-load warnings. Co-authored-by: Kaitian Xie <caelaxie@users.noreply.github.com>
Co-authored-by: Kaitian Xie <caelaxie@users.noreply.github.com>
|
Harness proof for 2d1d1b8. Command output is unedited. |
caelaxie
left a comment
There was a problem hiding this comment.
verdict: changes requested (comment review, same account). not merging.
what passes: validate plugin is green at 2d1d1b8, and the proof comment is at the same sha. L17 and L81 are exactly #16's smallest fix. L53 and L55 differ from upstream only by background for cloud, and that swap is needed: droid Task has run_in_background and no environment. Closes #16, not a draft.
blocking: the restore brings back the claim #16 was filed for. L16 still says the sub-coordinator "spawns its own workers and verifiers (nesting works to depth 3, and a nested spawn has the full Task schema)". custom droids says "a subagent cannot spawn its own subagents (the Task tool is not available to it)". a sub-coordinator is a Task subagent, so on droid it can't spawn anything. merging this would close #16 with its L16 half unfixed, and the text that depends on it is still in the file and still contradicts the docs: the L55 brief's spawn budget, step 4's "spawn track sub-coordinators" (L64), and "respawn one sub-coordinator per track" (L102).
my last review asked you to either fix the per-track cap or drop the role. restoring upstream fixes the cap, but it puts the nesting claim back. the narrowest fix that's true on droid is to drop the sub-coordinator role: delete the L16 bullet and the L55 brief, and cut "spawn track sub-coordinators" (L64) and "respawn one sub-coordinator per track" (L102) down to what the coordinator does itself. the coordinator then drains every track, under one cap.
| @@ -14,7 +14,7 @@ Three rules carry the rest. | |||
|
|
|||
| - **Coordinator (this chat).** Local. Frames, authors briefs, drains the inbox, owns the human report, makes judgment calls. It never authors or edits code. Conflicted merges, chain rebases, and code changes are always tasks. Mechanically landing a verified unit (fast-forward or clean cherry-pick of a worker's commit, then push) is bookkeeping the coordinator may do itself on repos where local git is cheap. Queueing finished work behind an idle stacker is how a deadline harvests nothing. The loop is agentic end to end. Agents are spawned, resumed, and drained only through the Task tool. Pick each subagent's complexity for the job, per the Subagents section. State reads and writes go through `scripts/orch/orch.ts` at drain points, one command in and one line out. The CLI never spawns, waits, or wakes anything. | |||
| - **Sub-coordinator.** Always local, durable, one per track, and only when the program exceeds what one coordinator's drains can manage. A track the coordinator can drain itself needs no middle layer. Each nested layer re-pays a full orientation preamble, and a blocking sub-coordinator hides its children while the parent idles. Owns its track's units and boards, authors its workers' briefs, spawns its own workers and verifiers (nesting works to depth 3, and a nested spawn has the full Task schema). Rolls up aggregates at wave boundaries. Never forwards raw child reports. Cap in-flight children at what one drain can process, roughly ten, as a rolling window. Never as blocking batches, which cost the slowest child of every batch. | |||
There was a problem hiding this comment.
blocking: droid subagents can't call Task (docs.factory.ai custom droids: "a subagent cannot spawn its own subagents"), so "spawns its own workers and verifiers (nesting works to depth 3, and a nested spawn has the full Task schema)" is false on droid. this is the L16 half of #16. drop the role here, along with the L55 brief and the L64 and L102 references.
A Droid subagent cannot spawn subagents, so the coordinator drains every track under the one in-flight cap. The store-access and rebase sentences stay. Co-authored-by: Kaitian Xie <caelaxie@users.noreply.github.com>
|
Harness proof for 214c69e. Command output is unedited. |
caelaxie
left a comment
There was a problem hiding this comment.
verdict: pass at 214c69e, merging.
- the sub-coordinator role is gone. upstream's cap sentences move verbatim onto the coordinator bullet after "It drains every track itself." depth is now "coordinator and worker". the L55 brief and step 4's sub-coordinator sentence are deleted. the audit line and the restart line say track/coordinator/workers where upstream said sub-coordinator. nothing else is reworded.
- L17 and L81 are still #16's fix. L52 differs from upstream only by
backgroundforcloud, which is needed because droid Task has noenvironment. - at 214c69e, no file in the repo mentions sub-coordinators, nesting, depth 3, or a middle layer. that now matches custom droids (subagents can't call Task).
validate pluginis green at 214c69e, and the proof comment is at the same sha. the proof'sdiff origin/mainlists README and claude-code.md only because the branch predates #29. the pr's own diff is orchestrate.md only, so the squash leaves #29 alone.Closes #16, not a draft.
Closes #16
Should the sub-coordinator be dropped, or turned into a coordinator-owned track?
Dropped. A Droid subagent cannot call Task, so it cannot spawn a track's workers. A coordinator-owned track that kept a per-track cap would put every track's children on the one drain.
The coordinator drains every track itself. The cap stays one drain, roughly ten, on the coordinator. The sub-coordinator brief is gone. The audit samples one worker brief per track, and a bad brief is fixed in the coordinator's instructions. After a restart the coordinator respawns that track's workers from their stored briefs.
The store and rebase sentences stay. A subagent gets only its brief, so the brief inlines what it needs from the store or points at repo paths. A chain rebase has no separate machine, so it still loads this computer and runs in one background subagent, never beside other heavy work. "Background" stays where upstream said "cloud" on the verbatim-paste sentence. The brief's "background default" went away with the brief.