Summary
A WU produces: entry that is a bare filename (or any path not resolvable from the repo root) silently fails the driver's presence gate and spins to a 3-attempt blocked state — even when the file is actually produced, just in a subdirectory. The failure is only discoverable at runtime (after 3 wasted opus sessions), not at lint time.
Observed on DRIVER_VERSION = "0.2.0".
Concrete incident
A close-adjacent WU declared:
produces:
- GATE-02-REVIEW.md # file actually lives at .specfuse/features/FEAT-XXXX-.../GATE-02-REVIEW.md
The WU did its work correctly (the file was written/updated in the feature dir, external side effects done), but the presence gate resolves produces relative to the repo root, where GATE-02-REVIEW.md does not exist. Result:
DELIVERABLE MISSING attempt 1/3 — declared deliverable absent: GATE-02-REVIEW.md
DELIVERABLE MISSING attempt 2/3 — declared deliverable absent: GATE-02-REVIEW.md
DELIVERABLE MISSING attempt 3/3 — declared deliverable absent: GATE-02-REVIEW.md
BLOCKED after 3 attempts — escalated (spinning_detected)
~3 opus sessions burned on an unsatisfiable check; the fix was a one-line path correction (.specfuse/features/FEAT-XXXX-.../GATE-02-REVIEW.md). Nothing the agent did would ever satisfy it — the path was wrong in the WU frontmatter, so every attempt fails identically.
Why it's worth a guard
- The error message ("declared deliverable absent: GATE-02-REVIEW.md") looks like the agent failed to produce the file, sending the operator to debug the agent's work — when the real cause is a frontmatter path. (Same diagnosis-misdirection family as the
files_changed_mismatch ambiguity.)
- It's a pure authoring mistake that a static check can catch before dispatch, for free.
Suggested fix (1 is the high-value one)
- Lint-time guard (
lint_plan.py): warn (or error) when a produces: path is not repo-root-resolvable in an obvious way — at minimum, flag a bare filename with no / (almost always wrong, since WU deliverables live under .specfuse/, modules/, environments/, etc.), or a path that doesn't match any plausible tracked location. Catch it at lint, not after a 3-attempt runtime spin.
- Runtime clarity: when the presence gate fails, make the message name the resolved absolute path it looked for (e.g. "looked for
<repo_root>/GATE-02-REVIEW.md — produces paths are repo-root-relative") so the misdirection is obvious. Optionally, if a bare filename matches exactly one file under the WU's feature dir, resolve it there (lenient) rather than failing.
Workaround (today)
Always write produces: as a repo-root-relative path (e.g. .specfuse/features/FEAT-XXXX-<slug>/GATE-02-REVIEW.md), never a bare filename. Related: a deletion-deliverable WU must omit produces entirely (a deleted path can never satisfy a presence gate).
Summary
A WU
produces:entry that is a bare filename (or any path not resolvable from the repo root) silently fails the driver's presence gate and spins to a 3-attempt blocked state — even when the file is actually produced, just in a subdirectory. The failure is only discoverable at runtime (after 3 wasted opus sessions), not at lint time.Observed on
DRIVER_VERSION = "0.2.0".Concrete incident
A
close-adjacent WU declared:The WU did its work correctly (the file was written/updated in the feature dir, external side effects done), but the presence gate resolves
producesrelative to the repo root, whereGATE-02-REVIEW.mddoes not exist. Result:~3 opus sessions burned on an unsatisfiable check; the fix was a one-line path correction (
.specfuse/features/FEAT-XXXX-.../GATE-02-REVIEW.md). Nothing the agent did would ever satisfy it — the path was wrong in the WU frontmatter, so every attempt fails identically.Why it's worth a guard
files_changed_mismatchambiguity.)Suggested fix (1 is the high-value one)
lint_plan.py): warn (or error) when aproduces:path is not repo-root-resolvable in an obvious way — at minimum, flag a bare filename with no/(almost always wrong, since WU deliverables live under.specfuse/,modules/,environments/, etc.), or a path that doesn't match any plausible tracked location. Catch it at lint, not after a 3-attempt runtime spin.<repo_root>/GATE-02-REVIEW.md—producespaths are repo-root-relative") so the misdirection is obvious. Optionally, if a bare filename matches exactly one file under the WU's feature dir, resolve it there (lenient) rather than failing.Workaround (today)
Always write
produces:as a repo-root-relative path (e.g..specfuse/features/FEAT-XXXX-<slug>/GATE-02-REVIEW.md), never a bare filename. Related: a deletion-deliverable WU must omitproducesentirely (a deleted path can never satisfy a presence gate).