/develop: dispatch work units by declared dependency, not in list order #39

Open
opened 2026-08-14 13:01:45 +00:00 by jbr870 · 1 comment
Owner

Rank 2 of 13 in #37 · est. saving ~1h per multi-unit feature

Evidence

/develop on #230 decomposed the feature into six work units and ran them strictly one after
another
, 12:57 → 17:14 (4h 17m):

Unit What Depends on
WU-1 shared block contract, markdown splitter, content loader
WU-2 release_notes_seen table, migration, backfill
WU-3 service, routes, API wiring WU-1, WU-2
WU-4 page, block renderers, nav indicator WU-3
WU-5 static guards + Dockerfile copy
WU-6 e2e fixtures and specs WU-4

WU-1, WU-2 and WU-5 have no dependency on each other. Only WU-3 → WU-4 → WU-6 is a real chain.
Critical path with the independent units run concurrently: ~199 min instead of 257.

What happens now

The decomposition step produces an ordered list, and the lead walks it. Nothing in the skill text
asks for the dependency edges between units, so there is no basis on which to start two at once.

Proposed change

  • Require the WU plan to declare each unit's predecessors (possibly empty).
  • Change the dispatch rule from "next in the list" to "every unit whose predecessors are recorded
    complete and whose file boundaries do not overlap a running unit".
  • Keep the existing per-unit verification unchanged — this changes scheduling, not gating.

Note the interaction with #43: concurrent units share the test database, so lane ownership
has to land with or before this.

Acceptance

  • The WU plan comment carries a predecessor list per unit.
  • A feature with independent units shows overlapping unit windows in its Phase Outcome trail.
  • No unit starts while a running unit declares an overlapping file boundary.
**Rank 2 of 13** in #37 · est. saving **~1h per multi-unit feature** ## Evidence `/develop` on #230 decomposed the feature into six work units and ran them **strictly one after another**, 12:57 → 17:14 (4h 17m): | Unit | What | Depends on | |---|---|---| | WU-1 | shared block contract, markdown splitter, content loader | — | | WU-2 | `release_notes_seen` table, migration, backfill | — | | WU-3 | service, routes, API wiring | WU-1, WU-2 | | WU-4 | page, block renderers, nav indicator | WU-3 | | WU-5 | static guards + Dockerfile copy | — | | WU-6 | e2e fixtures and specs | WU-4 | WU-1, WU-2 and WU-5 have **no dependency on each other**. Only WU-3 → WU-4 → WU-6 is a real chain. Critical path with the independent units run concurrently: **~199 min instead of 257**. ## What happens now The decomposition step produces an ordered list, and the lead walks it. Nothing in the skill text asks for the dependency edges between units, so there is no basis on which to start two at once. ## Proposed change - Require the WU plan to declare each unit's predecessors (possibly empty). - Change the dispatch rule from "next in the list" to "every unit whose predecessors are recorded complete and whose file boundaries do not overlap a running unit". - Keep the existing per-unit verification unchanged — this changes scheduling, not gating. Note the interaction with #43: concurrent units share the test database, so lane ownership has to land with or before this. ## Acceptance - The WU plan comment carries a predecessor list per unit. - A feature with independent units shows overlapping unit windows in its Phase Outcome trail. - No unit starts while a running unit declares an overlapping file boundary.
Author
Owner
{"status":"active","from_issue":"43","finding_ref":"F-PO-43-2-10","decision":"D-PO-43-2-10","category":"in-scope-deferrable","summary":"A slot declaring exactly one test database serializes every wave, capping #39 concurrency gain at one suite","original_scope_note":"Raised as blocking by the performance review and carried in the SREQ Technical Risks. The concurrency buy-back needs disjoint identities to hand out; slot-isolation already supports several via derived_suffixes, so the lever exists, but widening a project pool is a project declaration change this feature does not make. Recommend a follow-up issue paired with #39, since #39 is what makes the ceiling bite.","disposition_rationale":"The finding is a direct constraint on #39's payoff: with one declared test database per slot, dispatch serializes and #39's concurrency gain caps at one suite until a project widens its pool via slot-isolation derived_suffixes. #39 is filed and pre-PREQ, so its requirements round is exactly where that trade-off must be weighed — a confident topical fold per the autonomous-folding rule."}
<!-- folded-finding:v1 issue=39 from_issue=43 finding_ref=F-PO-43-2-10 status=active decision=D-PO-43-2-10 --> ```json {"status":"active","from_issue":"43","finding_ref":"F-PO-43-2-10","decision":"D-PO-43-2-10","category":"in-scope-deferrable","summary":"A slot declaring exactly one test database serializes every wave, capping #39 concurrency gain at one suite","original_scope_note":"Raised as blocking by the performance review and carried in the SREQ Technical Risks. The concurrency buy-back needs disjoint identities to hand out; slot-isolation already supports several via derived_suffixes, so the lever exists, but widening a project pool is a project declaration change this feature does not make. Recommend a follow-up issue paired with #39, since #39 is what makes the ceiling bite.","disposition_rationale":"The finding is a direct constraint on #39's payoff: with one declared test database per slot, dispatch serializes and #39's concurrency gain caps at one suite until a project widens its pool via slot-isolation derived_suffixes. #39 is filed and pre-PREQ, so its requirements round is exactly where that trade-off must be weighed — a confident topical fold per the autonomous-folding rule."} ```
Sign in to join this conversation.
No description provided.