Skip to content

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).

LocationRole today
apps/sdlc/lib/model/entities/task/schema.tsv5; no kind field.
apps/sdlc/lib/model/entities/task/ops/create.tsCreate op; flags derive from the schema, so no --kind.
apps/sdlc/lib/model/entities/task/ops/next.tsNo kind predicate, no leaf check — a parent task is offered like any other.
apps/sdlc/skills/orchestrate/SKILL.mdDispatch selection via task next; assumes every offer is dispatchable.

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.

  1. Add kind to the schema (doc-comment: leaf-execution-only, never gates containers) and confirm create --kind appears.
  2. Add leaf + kind predicates to next.ts with --explain output.
  3. Update orchestrate SKILL.md’s selection step to state the predicates.
  4. Tests: parent never offered; planning-kind leaf not offered by default; absent kind treated as implementation.
LocationKindChange
apps/sdlc/lib/model/entities/task/schema.tsmodifyOptional kind enum.
apps/sdlc/lib/model/entities/task/ops/next.tsmodifyLeaf + kind predicates.
apps/sdlc/skills/orchestrate/SKILL.mdmodifySelection rule prose.
  • AC-1: A task with children is never emitted by task next.
  • AC-2: A kind: planning leaf is excluded by the default dispatch predicate; --kind planning opts in.
  • AC-3: Every existing task (no kind) remains dispatchable unchanged.
  • 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.
  • none
  • D-VSLI accepted at v1 scope (PR #1123); this is the settled rule’s implementation.

Captured by /sdlc:task-work on 2026-08-03. PR: pending.

  • AC-1: auto + agent-manual — next-golden.test.ts “leaf predicate via sdlc task next” (4 cases: closed-only child, bare-id parent_key, --include-blocked, skipped_parent JSON shape). Also exercised directly against a fixture corpus: a parent whose only child is closed/done is withheld and reported as skipped-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_kind JSON shape). Fixture run confirmed a kind: planning leaf 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.
  • The op registry derived --kind for task next from the zod input schema with no CLI plumbing — only the repeatable-flag descriptor had to be declared.
  • The existing skipped_blocked pair (structured output array + skipped-…: stderr line) was a clean template; the two new predicates copied its shape exactly rather than inventing one.
  • --project-root made empirical AC verification cheap: a five-file fixture corpus in a temp dir exercised all three predicates end-to-end through the real CLI.
  • The Step 3a quality baseline took over 10 minutes (full tsc plus the whole bun test apps/sdlc suite), 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-dir relative to the worktree (where no baseline exists) and failed with baseline 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
  • --kind did not appear on sdlc task create from the schema alone: create.ts carries an explicit fields: 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 --help check. → 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.ts needed a matching kind: []); 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/priority bumped, autonomy did 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

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.


← Back to Tasks