Skip to content

afx spawn hands builders an unrelated old spec when the issue number collides with a zero-padded filename #65

Description

@pseudoseed

What happened

afx spawn 63 --protocol experiment pointed the builder at:

codev/specs/0063-tower-dashboard-improvements.md

That is a real, already-shipped spec about the Tower dashboard, SSH remote and ttyd. The builder's actual assignment was GitHub issue #63, which is a v2 UI dark-palette design task and shares nothing with it.

The builder read the spec, believed it, and spent about an hour producing a competent finding about the wrong subject: "Hypothesis holds: do not implement spec 0063 as written. One-row + Create are additive. SSH remote and ttyd are not."

Root cause

afx spawn <n> derives a spec path by zero-padding the issue number to four digits. This repo has two numbering conventions living side by side:

  • Old, zero-padded: codev/specs/0038-consult-pr-mode.md, 0039-codev-cli.md, 0063-tower-dashboard-improvements.md
  • Current, unpadded: codev/specs/469-..., 494-..., 52-v2-server-events.md

So any new issue whose number collides with an old zero-padded spec gets handed that spec as its assignment.

This is not the first time

Three builders hit it today:

Spawn Prompt pointed at Outcome
afx spawn 38 0038-consult-pr-mode.md (2025 TICK) Builder noticed and worked the issue
afx spawn 39 0039-codev-cli.md (shipped) Builder noticed and worked the issue
afx spawn 63 0063-tower-dashboard-improvements.md Builder did not notice. Wrong work delivered

Two out of three caught it. That is not a safety property — it is luck, and it depends on a builder being suspicious of its own assignment.

The failure is silent and confident: the file exists, it is a real spec, it is well written, and nothing signals that it belongs to different work.

Why it is worse than a wasted hour

A builder that trusts the named spec will produce a coherent, well-argued deliverable for the wrong problem, which is harder to spot in review than an obvious error. The two builders that caught it did so because the subject matter was visibly unrelated. Where an old spec is merely adjacent to the new issue, nobody would catch it at all.

Suggested fix

  1. The issue is the source of truth; make the spawn prompt say so. Reference the issue and let the builder resolve artifacts from it, rather than asserting a spec path that may not correspond to anything.
  2. Do not conjure a path that was not verified to belong to this work. If codev/specs/<n>-*.md does not exist for the unpadded number, say "no spec exists yet" rather than falling back to a zero-padded match. An absent spec is a fact worth stating; a wrong one is not.
  3. If a zero-padded file matches but an unpadded one does not, warn loudly at spawn: this path may belong to unrelated older work.

Point 2 is the same principle already load-bearing elsewhere in this codebase: "I could not tell" must never be spelled the same way as an answer. Right now "no spec for this issue" is spelled identically to "here is your spec."

Cost so far

One builder-hour on issue #63, plus the architect time to detect and redirect. Caught only because the wrong-subject output was obviously wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/towerTower, afx, terminals, messagingbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions