T-TZD2-task-work-spawn-fast-path-no-op
Status: closed/done · Impact: medium · Complexity: small
Auto-generated from a /sdlc:task-work post-mortem. Review and
promote to open/ready before picking up.
/sdlc:task-work Step 8 unconditionally spawns a sub-agent to convert
post-mortem friction bullets into follow-up task files, even when the
friction section reads - none observed. For trivially empty or
single-line gap lists this is pure overhead — a round trip through
sub-agent dispatch, the spawn-from-post-mortem reference doc, and
the no-commit return path. In environments where the Agent tool
isn’t exposed (some Skill harness configurations), the runner ends
up inline-executing the procedure manually anyway. An inline
fast-path keeps the common case cheap and gives the runner a
fallback contract when sub-agent dispatch isn’t available. See
T-Y0SQ-task-work-emit-completion-marker for the originating
post-mortem.
Step 8 of plugin/skills/task-work/SKILL.md (subsection “Spawn
follow-up tasks from the friction list”) instructs the runner to
“Always invoke this sub-step — even if the gaps section reads - none observed, calling the sub-agent makes the ‘no-op’ explicit and gives
one consistent code path.” The reference doc at
plugin/entities/task/spawn-from-post-mortem.md handles the no-op
case at step 1 (“If the only bullet is - none observed, jump
straight to step 7 with a count of zero”), but step 7 still requires
a structured stdout report. There is no documented behavior for
“the Agent tool isn’t available in this environment” — the runner
silently inline-executes the procedure or skips, depending on its
own judgment.
Proposed
Section titled “Proposed”Step 8 gains two explicit shapes:
- An inline fast-path: when the runner can statically determine the
friction list is empty (only
- none observedor no bullets), skip the sub-agent dispatch and emit a one-line report (“SPAWNED: 0, LINKED-EXISTING: 0, SKIPPED: 0”) inline. - A documented fallback contract: when the
Agenttool isn’t available, the runner inlines the spawn-from-post-mortem procedure itself, following the same input/output contract. The SKILL.md states this explicitly so the runner doesn’t have to guess.
Approach
Section titled “Approach”- Edit
plugin/skills/task-work/SKILL.mdStep 8 “Spawn follow-up tasks from the friction list” subsection to add the two shapes above as explicit guidance. - Decide whether the inline fast-path is the runner’s responsibility (parse the friction list, branch) or the sub-agent’s (always dispatched, returns early). Bias toward the runner so the fast-path actually saves the dispatch round trip.
- Update
plugin/skills/task-work/invariants.yamlif the new prose warrants pinning a phrase (e.g. a literal fallback marker).
Files to touch
Section titled “Files to touch”plugin/skills/task-work/SKILL.md— Step 8 spawn subsection.plugin/skills/task-work/invariants.yaml— possibly pin new fast-path or fallback phrases.
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: Step 8’s “Spawn follow-up tasks” prose documents an
inline fast-path for
- none observedfriction lists. - AC-2: Step 8’s prose documents what to do when the
Agenttool is not available in the runner’s environment. - AC-3:
lint_skill_prose.pycontinues to pass against the edited SKILL.md.
Out of scope
Section titled “Out of scope”- Building a generic Skill-harness “is tool available” probe — this task only documents the fallback at the prose level.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”Spawned by /sdlc:task-work post-mortem of T-Y0SQ-task-work-emit-completion-marker on 2026-05-21.
Post-mortem
Section titled “Post-mortem”Captured by /sdlc:task-work on 2026-05-22. PR: pending.
Acceptance criteria coverage
Section titled “Acceptance criteria coverage”- AC-1: auto —
command grep "Fast-path: empty friction list"against the edited SKILL.md confirms the subsection landed; lint_skill_prose.py passes. - AC-2: auto —
command grep "Fallback: the .Agent. tool isn't available"confirms the subsection landed; lint_skill_prose.py passes. - AC-3: auto —
plugin/scripts/lint_skill_prose.py plugin/skills/task-work/SKILL.mdreports “1 skill(s) checked, 1 with invariants.yaml, no violations.” against the edited SKILL.md.
What worked
Section titled “What worked”- The relevance check found every cited path on first probe; no spec drift between authoring and pickup.
- The invariants pin (
SPAWNED-LOCAL: 0) was a natural extension of the existingspawn-from-post-mortem.mdpin — adding a second adjacent invariant kept the shape consistent with what was already there. - Quality checks ran cleanly except for a pre-existing audit_entities drift on
2026-05-21-pr-check-schema-promote.mdthat also fails on main and is unrelated to this change.
Friction and automation gaps
Section titled “Friction and automation gaps”- Quality-checks runner conflates pre-existing unrelated drift with new failures —
run_quality_checks.pyreturns FAIL wheneveraudit_entities.pyflags any drifted file, even when none of the drifted files were touched by the current branch. The runner could diff the audit output against the merge-base onorigin/mainand only fail on drift the current branch introduced; that would let task-work skills proceed without per-run manual triage of pre-existing failures. → spawned T-H69K-run-quality-checks-isolates-pre-existing-drift.