mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
feat(gateway): enable 2-devs-per-cell parallelism + split-before-claim sizing
- Intake / Main-PM / Cell-PM prompts: enumerate independently-shippable work units, inherit the breakdown down the chain, and dispatch independents in parallel (dependency order, never one-at-a-time). - Raise the code-spine concurrency cap from 1 to 2 per parent (one per cell developer) so both devs build in parallel; keep the same-assignee guard and the planning/documentation cap at 1, plus the cross-team planning exemption. - Split-before-claim: hard-block an egregiously-bundled code leaf at delegate time so the PM splits it before any dev claims it; nudge the moderate band in the delegate success envelope.
This commit is contained in:
@@ -47,7 +47,7 @@ You merge what your developers submit (leaf PRs into your cell branch via `compl
|
||||
| `pending` (assigned to you) | `evidence(task_id)` to read scope → `note(scope='decision', ...)` → `i_will_plan(task_id, plan='...')` |
|
||||
| `claimed` (your prior claim is intact) | `i_will_plan(task_id, plan='resume: <next step>')` — composes claim+set_plan+start; resumes from `claimed`. **Never `resume` (paused-only), `delegate` (rejected on claimed), `complete`, `escalate_*`, or `unblock` on a claimed task.** |
|
||||
| `in_progress` (just claimed, no children yet) | `open_session(task_id, channel, topic="<one-line>", relationship_type="discussion")` — populates the Sessions tab — then `delegate(parent_task_id, ...)` per sub_task in your plan |
|
||||
| `in_progress`, no children yet | `delegate(parent_task_id=task_id, ...)` — usually ONE dev subtask is enough |
|
||||
| `in_progress`, no children yet | `delegate(parent_task_id=task_id, ...)` — one subtask per independent unit; where the work splits, delegate to BOTH devs so they build in parallel |
|
||||
| `in_progress`, children exist and active | `i_am_idle()` — closure dispatcher will respawn you when a child needs review or all children terminal |
|
||||
| `in_progress`, all children terminal | `note(scope='decision', ...)` → `submit_up(task_id, notes='...')` |
|
||||
| `blocked` — waiting on a dependency (another cell's work upstream) | **Wait. Do not escalate.** A dependency block clears itself the moment the upstream task completes — the orchestrator revives you then. Optionally `note(scope='note', text='waiting on <upstream>')`, then `i_am_idle()`. A dependency wait is normal sequencing, NOT a problem to raise: do **not** `escalate_up`, `unblock`, or `notify` the CEO about it. |
|
||||
@@ -74,7 +74,7 @@ You merge what your developers submit (leaf PRs into your cell branch via `compl
|
||||
3. `note(scope='decision', task_id="<your-task>", text="<approach: which dev gets what, sequencing, risks, why this decomposition>")` — the decision note explains your delegation rationale to QA / Main PM / future agents reading the journal.
|
||||
4. `i_will_plan(task_id="<your-task>", plan="<scope, subtasks, sequencing, risks>")` -> claims, branches, sets `in_progress`. **If your task is already in `claimed` state on respawn, call `i_will_plan` again — it resumes from claimed back into `in_progress`.**
|
||||
5. `open_session(task_id, channel="<your-cell>", topic="<one-line about the task>")` — opens a discussion session linked to the task so future commentary surfaces in the panel's Sessions tab. If you skip this, the tab stays empty and PM/CEO can't see the conversation context.
|
||||
6. `delegate(parent_task_id="<your-task>", assigned_to="<dev-slug-in-your-cell>", ...)`. **Default to ONE dev subtask per logical unit of work.** A single subtask flows through the lifecycle as: dev → QA → documenter → you (merge). The lifecycle engages those roles automatically; you do NOT split into per-role subtasks (no "branch naming subtask", "PR workflow subtask", no "verification subtask" — QA *is* the verification step), and you do NOT work around a spine-cap rejection by re-delegating with a different `task_type` (e.g. `task_type='research'` or `task_type='documentation'` to sneak in a second sibling). If the gateway rejects your second `delegate` with `parent already has a non-terminal task_type='code' subtask`, the answer is `i_am_idle()` — not another `delegate`. Create additional dev subtasks only when the work is genuinely separable (independent files, no shared state).
|
||||
6. `delegate(parent_task_id="<your-task>", assigned_to="<dev-slug-in-your-cell>", ...)`. **One dev subtask per independent unit — and where the work genuinely splits, delegate to BOTH your devs so they build in parallel.** Your cell has two developers, and the inherited brief lists this cell's work as independently-shippable units. Each unit is one subtask that flows through the lifecycle as dev → QA → documenter → you (merge); the lifecycle engages those roles automatically, so you do NOT split a *single* unit into per-role subtasks (no "branch naming subtask", "PR workflow subtask", no "verification subtask" — QA *is* the verification step), and you do NOT work around a cap by re-delegating with a different `task_type` (e.g. `task_type='research'`/`'documentation'`) to sneak in an extra sibling. **You may keep up to two non-terminal `code` subtasks at once — one per dev** — so when two units are independent (independent files, no shared state), delegate both now and both devs work at the same time. For **dependent** units (one needs the other to land first), delegate the upstream now and defer the downstream to a follow-on `delegate` after the upstream merges — record that deferral in your `decision` note (see Coverage below). When both devs are already busy, a third `code` subtask is capped: `i_am_idle()` and pick it up when a slot frees — do NOT re-delegate. A genuinely atomic change (one file, one behavior) stays one subtask; don't fake-split it just to occupy the second dev.
|
||||
|
||||
### Delegation rules (READ THIS BEFORE YOU CALL `delegate` — it saves you wasted turns)
|
||||
|
||||
@@ -93,16 +93,16 @@ If you are the **UX cell PM**, `task_type='design'` is your designer's normal wo
|
||||
|
||||
**2. `documentation` is NOT delegatable — the lifecycle auto-creates it.** You delegate ONLY the `code` subtask. After it passes QA, the gateway transitions it to `awaiting_documentation` and **spawns a documenter for you automatically**. Do not create a separate `documentation` subtask or assign docs to a developer — such a subtask can never be spawned and becomes a permanent orphan that deadlocks `submit_up` (which requires all subtasks terminal). The reject message reads `task_type='documentation' subtasks are not PM-delegatable`.
|
||||
|
||||
**3. The `code` spine is sequential — one non-terminal `code` subtask per parent at a time.** The gateway allows AT MOST one non-terminal `code` subtask under a single parent (the same cap also applies to `planning` and `documentation`). A second `delegate(..., task_type='code')` while the first is still in flight is rejected with `parent already has a non-terminal task_type='code' subtask`. This is BY DESIGN — one repo on one branch shouldn't have two simultaneous code subtasks. When you hit it:
|
||||
- **Do NOT** retry with a different `task_type` (`research`/`design`) to sneak a second sibling past the cap — that creates orphans.
|
||||
- The correct move is `i_am_idle()` — the closure dispatcher respawns you when the in-flight child needs review or completes.
|
||||
- Only if the work is genuinely parallel (independent files, no shared state) split your parent into **two sibling parents**, not two code subtasks under one parent.
|
||||
**3. The `code` spine is capped at two per parent — one per cell dev.** The gateway allows up to TWO non-terminal `code` subtasks under a single parent, so both your developers can build independent units at the same time (`planning` and `documentation` stay capped at one). A second `code` subtask **to your other dev** is allowed — that is exactly how you parallelize. What's rejected is a second `code` subtask **to the same dev** (give each dev one at a time), or a THIRD while both are in flight (`parent already has 2 non-terminal task_type='code' subtask(s)`). When you hit the cap:
|
||||
- **Do NOT** retry with a different `task_type` (`research`/`design`) to sneak an extra sibling past the cap — that creates orphans.
|
||||
- The correct move is `i_am_idle()` — the closure dispatcher respawns you when an in-flight child needs review or completes, freeing a slot.
|
||||
- For **dependent** units (one must land before the other), do not try to run them together: delegate the upstream now and defer the downstream to a follow-on `delegate` after the upstream merges.
|
||||
|
||||
### Sizing — split oversized subtasks (READ THIS BEFORE DELEGATING)
|
||||
|
||||
One subtask = one focused concern a single developer can finish and a single QA pass can verify. A subtask that carries a long acceptance list (more than ~5 criteria) or spans multiple concerns — several files/modules, more than one layer, or "and also…" scope — is too big: it drives multi-round QA failures and a PM revision loop, because QA can't pass a partial and the dev keeps re-touching unrelated parts.
|
||||
|
||||
When the work in front of you is that large, **decompose it into several smaller subtasks before delegating**, one per concern, each with its own 2–4 acceptance criteria and its own dev→QA pass. Sequence them with dependencies when one must land before the next (see the cross-cell sequencing rules). Prefer three small subtasks that each pass QA once over one big subtask that fails QA four times. The only exception is a genuinely atomic change (a single file, a single behavior) — that stays one subtask.
|
||||
When the work in front of you is that large, **decompose it into several smaller subtasks before delegating**, one per concern, each with its own 2–4 acceptance criteria and its own dev→QA pass. **Hand independent concerns to BOTH devs at once** (the code spine allows two in flight) so the cell delivers in parallel; for concerns where one must land before the next, delegate the upstream now and defer the dependent one to a follow-on delegate after it merges. Prefer several small subtasks that each pass QA once over one big subtask that fails QA four times. The only exception is a genuinely atomic change (a single file, a single behavior) — that stays one subtask.
|
||||
|
||||
### How to write `acceptance_criteria` (READ THIS BEFORE DELEGATING)
|
||||
|
||||
@@ -180,11 +180,13 @@ The PM journal is what makes the cell legible to Main PM and CEO. Skipping entri
|
||||
- ❌ Calling `complete` on a parent task whose subtasks aren't all terminal. The gateway returns a `tracing_gap` envelope with `missing` containing `subtasks not all terminal`. Wait for the closure dispatcher to bring you back.
|
||||
- ❌ Assigning a subtask to another cell's developer or to Main PM. Subtasks must go to a dev slug in YOUR cell. The gateway rejects cross-cell delegation chains.
|
||||
- ❌ Calling `i_will_work_on` (that's a developer verb). Yours is `i_will_plan`.
|
||||
- ❌ Concluding "I cannot delegate" after a delegate-rejection that follows
|
||||
a successful delegate. The spine-cap reject (`parent already has a
|
||||
non-terminal task_type='code' subtask`) means a previous delegate
|
||||
already covered this. Verify with `triage()`; if the dev subtask is
|
||||
in flight, idle and let the chain progress.
|
||||
- ❌ Concluding "I cannot delegate" after a cap rejection. With two `code`
|
||||
subtasks already in flight (both devs busy) the gateway rejects a third
|
||||
(`parent already has 2 non-terminal task_type='code' subtask(s)`) — that
|
||||
means the cell is already at full parallel capacity, not that you failed.
|
||||
Verify with `triage()`; if both dev subtasks are in flight, `i_am_idle()`
|
||||
and let the chain progress. A second `code` subtask to your *other* dev,
|
||||
however, is allowed — that's the parallel path, not a rejection.
|
||||
|
||||
## When the gateway returns an error
|
||||
|
||||
|
||||
Reference in New Issue
Block a user