Skip to content

feat(orchestrate): mid-run task splitting + release v1.4.2 (PR 2/2) - #60

Merged
choiyounggi merged 8 commits into
mainfrom
feat/orchestrate-task-split
Aug 7, 2026
Merged

feat(orchestrate): mid-run task splitting + release v1.4.2 (PR 2/2)#60
choiyounggi merged 8 commits into
mainfrom
feat/orchestrate-task-split

Conversation

@choiyounggi

Copy link
Copy Markdown
Owner

Completes the pair started in #59. A worker that finds its task far larger than the brief assumed can now propose splitting it instead of silently running long — and this branch carries the README sync and the v1.4.2 bump for both.

Spec: docs/superpowers/specs/2026-08-07-orchestrate-ready-set-scheduler-design.md §3.5, §4 · Plan: docs/superpowers/plans/2026-08-07-orchestrate-task-split.md

The decision is one overlap test

The worker proposes; the coordinator decides and replies either way. A rejection that is never sent is indistinguishable from silence, and a worker that hears nothing decides for itself — the failure mode fixed in v1.4.1.

pieces' files what happens what it buys
no overlap new node via graph-add.sh; enters the ready set and the next free slot takes it parallelism
overlap node with deps: ["<parent>"], handed to the same worker in the same worktree when the parent settles a smaller review and rework unit — not parallelism, and the report says so

The overlap branch deliberately does not create a second worktree: the parent's code is not on the integration branch until Phase 6, so a second checkout would be editing files it cannot see.

graph-add.sh (new) — the only writer of graph.json after Phase 2

It validates the resulting graph, not the node alone, because every defect that matters is relational: a duplicate id, a dependency naming an undefined task, a split_of pointing at a node that is itself a split child, an output with two producers, a cycle. On any rejection it exits 3 with the reason and leaves the file byte-identical — a half-applied graph would make re-entry read a state that never existed. Exit 4 means the graph itself could not be read, which is a different problem from a bad proposal and is reported as such.

Depth is capped at 1. A piece that came from a split can never itself be split. That stops a worker from deferring work by subdivision, and keeps graph.json readable by a person. A depth-2 attempt is a signal that Phase 2's decomposition was wrong, so it goes to the user rather than being worked around.

The proposal must carry its file scope. templates/brief.md now requires per-piece files, outputs, and split_of, because without them the overlap test cannot run at all and the worker sits idle through an extra round trip.

Tests

423 passing, 0 failing (407 before). 14 new on graph-add.sh covering each rejection with a byte-identical assertion, the exit 3/4 boundary, and an integration test that feeds a graph it just wrote to ready-set.sh — so the two scripts' contracts are pinned together rather than separately.

Review

Per-task reviews plus a whole-branch review. One Critical was caught and fixed: graph-add.sh exit 4 had no defined coordinator action on either branch, leaving the proposing worker waiting for a reply nothing told the coordinator to send. Same class as the hang caught in #59 — a branch that reads fine and ends nowhere. All seven coordinator branches now terminate in a concrete action.

One finding is on record rather than fixed: the final reviewer judged 1.5.0 semantically more accurate than the 1.4.2 shipped here, since the pair adds two scripts, a CLI option, and replaces the execution model. Patch was chosen deliberately; noting it so the next release is not surprised.

🤖 Generated with Claude Code

task 3개: graph-add.sh 신규(검증된 원자적 확장, bats 14), brief 템플릿에
파일 범위 필수화, SKILL.md 코디네이터 판정 절차.

핵심은 graph-add.sh가 결과 그래프 전체를 검증하고 하나라도 걸리면 파일을
건드리지 않는 것 — 반쯤 적용된 그래프는 재진입을 깨뜨린다.
분할 제안이 승인됐을 때 graph.json을 늘리는 유일한 경로. 결과 그래프 전체를
검증한다(중복 id, 미정의 의존, 분할 깊이 1, 중복 output, 사이클). 하나라도
걸리면 파일을 건드리지 않는다 — 반쯤 적용된 그래프는 재진입을 깨뜨린다.
코디네이터의 판정은 파일 겹침 검사다. 범위 없는 제안은 판정 불가라 왕복이
한 번 더 생기고 그 사이 워커는 멈춰 있다. 워커가 읽는 자리에 요구사항을 둔다.
워커가 제안하고 코디네이터가 겹침 판정으로 결정한다. 안 겹치면 새 노드로
병렬, 겹치면 같은 워커에 순차 부착(파일이 통합 브랜치에 없으므로 두 번째
워크트리를 만들 수 없다). 거절도 반드시 reply — 침묵은 워커의 자체 판단을 부른다.
Exit 4 (graph I/O error) now has explicit coordinator replies and escalation
path. Restored bold formatting to 'same worker' and 'same worktree' for
readability. Updated test to match formatted text via grep -E.
웨이브 배리어가 사라지고 의존 그래프 + 슬롯 회계가 그 자리를 대신한다는 것,
슬롯 수가 Gate 1에서 제안·승인되고 LO_MAX_SESSIONS가 상한이라는 것,
실패한 의존이 조용한 대기가 아니라 보고되는 교착으로 드러난다는 것,
워커가 실행 중 분할을 제안할 수 있다는 것 — 네 가지를 양쪽 README에 반영.
PR #59와 이 브랜치의 분할 경로를 함께 낸다. plugin.json과 marketplace.json을
같이 올린다 — 릴리즈 워크플로는 plugin.json만 게이트하므로 marketplace.json은
빠뜨리면 조용히 드리프트한다.
[가-힣] 문자 범위는 이식 가능하지 않다. GNU grep 3.12 실측(2026-08-07):
C 로케일에서 이 범위를 바이트 범위로 읽어 UTF-8 문장부호의 연속 바이트에
매칭된다 — SKILL.md의 em-dash만으로 136줄이 잡힌다. C.UTF-8에서는 아예
'Invalid collation character'로 거부한다. BSD grep은 반대로 아무것도
매칭하지 않아서, 깨진 assertion이 macOS에서는 초록으로 통과했다.

대신 UTF-8 선행 바이트 EA-ED를 센다. 한글 음절 블록 U+AC00-U+D7A3이 정확히
그 선행 바이트로 인코딩되고, 라틴 문자나 그 문장부호에는 없다. macOS와
Ubuntu에서 바이트 단위로 동일함을 확인했다(영어 파일 0, README.ko.md 2782).

네거티브 컨트롤을 함께 넣는다. 원래 assertion은 '== 0'이라 아무것도 찾지
못하는 검출기도 만족시킨다 — 이번 실패가 정확히 그 모양이었다. 한국어 파일이
0보다 커야 한다는 반대 방향을 함께 고정한다.

ubuntu 컨테이너에서 main 기준선과 대조: 브랜치 고유 실패 0건.
@choiyounggi
choiyounggi merged commit 18b9eee into main Aug 7, 2026
2 checks passed
@choiyounggi
choiyounggi deleted the feat/orchestrate-task-split branch August 7, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant