T-JOXA-task-kind-field-and-leaf-dispatch
Status: closed/done · Impact: high · Complexity: medium
D-VSLI-distributed-work-runner-architecture is accepted; its settled
orchestrator-selection rule is unbuilt. Ship the kind: field and
the two dispatch predicates: task next offers only leaves
(parents are rollups) whose kind is implementation (absent =
implementation).
| Location | Role today |
|---|---|
apps/sdlc/lib/model/entities/task/schema.ts | v5; no kind field. |
apps/sdlc/lib/model/entities/task/ops/create.ts | Create op; flags derive from the schema, so no --kind. |
apps/sdlc/lib/model/entities/task/ops/next.ts | No kind predicate, no leaf check — a parent task is offered like any other. |
apps/sdlc/skills/orchestrate/SKILL.md | Dispatch selection via task next; assumes every offer is dispatchable. |
Proposed
Section titled “Proposed”Optional kind: implementation | planning | research on the Task
schema (absent = implementation; immutable after creation in the
common case). sdlc task create --kind follows from the
schema-derived flags. task next gains the leaf predicate (skip
any task with children, derived via parent_key) and the kind
predicate (--kind implementation default for dispatch);
--explain names both skips. Design the predicates so relaxing
leaf-only into nested traversal later is a predicate change, not a
rewrite.
Approach
Section titled “Approach”- Add
kindto the schema (doc-comment: leaf-execution-only, never gates containers) and confirmcreate --kindappears. - Add leaf + kind predicates to
next.tswith--explainoutput. - Update orchestrate SKILL.md’s selection step to state the predicates.
- Tests: parent never offered;
planning-kind leaf not offered by default; absent kind treated asimplementation.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
apps/sdlc/lib/model/entities/task/schema.ts | modify | Optional kind enum. |
apps/sdlc/lib/model/entities/task/ops/next.ts | modify | Leaf + kind predicates. |
apps/sdlc/skills/orchestrate/SKILL.md | modify | Selection rule prose. |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: A task with children is never emitted by
task next. - AC-2: A
kind: planningleaf is excluded by the default dispatch predicate;--kind planningopts in. - AC-3: Every existing task (no
kind) remains dispatchable unchanged.
Out of scope
Section titled “Out of scope”- The runner registry and per-kind dispatchers — T-FTV3-runner-registry-v1.
- Nested orchestration traversal (parents decompose/fan-out) — the D-VSLI end-state, later.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”- D-VSLI accepted at v1 scope (PR #1123); this is the settled rule’s implementation.
Post-mortem
Section titled “Post-mortem”Captured by /sdlc:task-work on 2026-08-03. PR: pending.
Acceptance criteria coverage
Section titled “Acceptance criteria coverage”- AC-1: auto + agent-manual —
next-golden.test.ts“leaf predicate via sdlc task next” (4 cases: closed-only child, bare-idparent_key,--include-blocked,skipped_parentJSON shape). Also exercised directly against a fixture corpus: a parent whose only child isclosed/doneis withheld and reported asskipped-parent: … (has children: …). - AC-2: auto + agent-manual —
next-golden.test.ts“kind predicate via sdlc task next” (4 cases: default set,--kind planning, repeatability,skipped_kindJSON shape). Fixture run confirmed akind: planningleaf is withheld by default and returned under--kind planning. - AC-3: auto + agent-manual — every pre-existing golden fixture
carries no
kind:and still passes. Confirmed on the live corpus: pre-change and post-change binaries both emit the same 23 basenames, byte-identical.
What worked
Section titled “What worked”- The op registry derived
--kindfortask nextfrom the zod input schema with no CLI plumbing — only the repeatable-flag descriptor had to be declared. - The existing
skipped_blockedpair (structured output array +skipped-…:stderr line) was a clean template; the two new predicates copied its shape exactly rather than inventing one. --project-rootmade empirical AC verification cheap: a five-file fixture corpus in a temp dir exercised all three predicates end-to-end through the real CLI.
Friction and automation gaps
Section titled “Friction and automation gaps”- The Step 3a quality baseline took over 10 minutes (full
tscplus the wholebun test apps/sdlcsuite), exceeding the default Bash timeout and forcing a manual re-run in the background — the task-work baseline step should either background the capture by default or document that projects with multi-minute gates need an extended timeout. → T-89GV-task-work-backgrounds-baseline-capture - Step 7’s gate invocation resolved
--baseline-dirrelative to the worktree (where no baseline exists) and failed withbaseline not found, even though Step 3a wrote it under the main repo. The skill calls--baseline-dir“optional in spirit”; it is in fact required whenever the gate runs from a worktree, and the Step 7 snippet should pass it explicitly like the Step 3a snippet does. → T-OLTA-task-work-step7-worktree-baseline-dir --kinddid not appear onsdlc task createfrom the schema alone:create.tscarries an explicitfields:allowlist that must be edited in lockstep with every new schema field. A gate asserting the allowlist covers all creatable schema fields would catch the omission instead of leaving it to a manual--helpcheck. → T-DJ5G-gate-create-allowlist-covers-schema-fields- Adding a schema field required hand-auditing in-process callers of
nextOp.handler(services/orchestrator/ops/watch.tsneeded a matchingkind: []); nothing flags a caller whose literal args object drifts from an op’s input schema. → T-U1KI-typecheck-in-process-op-call-args - Schema-version-bump precedent was split across prior fields
(
prs/prioritybumped,autonomydid not) and had to be settled by reading git history — the entity schema docs should state the rule for optional, absent-defaulted fields outright. → T-VDHJ-document-schema-version-bump-rule
Spawned follow-up tasks
Section titled “Spawned follow-up tasks”- T-89GV-task-work-backgrounds-baseline-capture (https://github.com/sksizer/dev/pull/1155) [open/ready] — task-work backgrounds the Step 3a quality baseline capture by default; spawned.
- T-OLTA-task-work-step7-worktree-baseline-dir [open/ready] — Step 7 resolves the quality baseline dir from a worktree; linked (fourth independent report of the same gap).
- T-DJ5G-gate-create-allowlist-covers-schema-fields
(https://github.com/sksizer/dev/pull/1157) [open/ready] — gate that the
create op’s
fields:allowlist covers every creatable schema field; spawned. - T-U1KI-typecheck-in-process-op-call-args (https://github.com/sksizer/dev/pull/1162) [open/ready] — flag in-process op callers whose literal args drift from the op input schema; spawned.
- T-VDHJ-document-schema-version-bump-rule
(https://github.com/sksizer/dev/pull/1161) [open/ready] — entity schema
docs state the
schema_versionbump rule for optional fields; spawned.
Note for a reviewer: T-2T20-task-work-backgrounds-quality-gate is
closed/done with a completion note citing PR #970, but that PR’s only
changed file was the task file itself — no
apps/sdlc/skills/task-work/SKILL.md change ever landed, so both halves it
claimed (backgrounding the long steps and the explicit main-repo
--baseline-dir) are still open. That is why bullets 1 and 2 recurred here.