Skip to content

spec-workflow: DONE is not tied to landing — slices marked DONE strand on worktree branches while main says DRAFT #110

Description

@Kyarha

Third report in the series (#108 — capture misses what the owner says; #109 — capture suppresses what it catches). This one is about the other end of the lifecycle: DONE is jig's terminal state, and it is not tied to the code reaching main. Found while tracing why my decided changes keep "reverting" — some of them went through the full jig lifecycle and were still lost.

The concrete case — tabula spec 003 exists in three contradictory records

All on my disk right now, verifiable:

  1. The stranded branch claude/chord-sheet-features-5dd1f7 (+18 commits not on main) carries built features as proper slice commits: feat(003-03): capo helper, feat(003-04): save key per arrangement (persist transpose offset), feat(003-05): show key & capo pills + no-capo filter.
  2. Main's status board (docs/specs/README.md) lists all five 003 slices as DRAFT. Main's app code contains none of those features (a grep for the capo work on main hits only design docs).
  3. A session transcript (captured in my decision-scratch logs) asserts the opposite: spec 003's slices were "built and landed (all DONE)" and asks for the spec overview's stale framing to be retired to match.

So the same work is simultaneously DRAFT, DONE, and built-but-unreachable, depending on which jig-maintained record you read. The next session starts from main, sees DRAFT and no code, and to me it looks like the work was overwritten. That branch will never be merged by anything currently in the system.

The mechanism

  • Status lives in files, and every worktree carries its own copy. A transition … DONE inside a worktree updates that worktree's board — a silent fork of jig's memory. Nothing reconciles it with main's.
  • The review-evidence gate checks the wrong terminal condition. It gates REVIEWED/RECONCILED/DONE on recorded verdict artifacts (ADR-0014) — it never checks that the slice's commits are reachable from main.
  • slice-land performs exactly the right checks — when invoked. Nothing notices when it isn't. There is no surface anywhere that says "this branch holds N slice commits that never landed."

Scale, with an honest caveat

Across my 6 jig projects: 34 branches with commits not on main, plus 18 worktrees holding uncommitted edits right now. Not all of it is loss — in card-games I verified 004-03/004-05/012-01 did land on main as different commits, so several of its stranded branches are stale duplicates of landed work. But nothing distinguishes a stale duplicate from tabula-style stranded real work, or deliberately parked from forgotten. The tabula case is the one I've fully verified end-to-end.

Directions to react to (not a design)

  1. Tie DONE to landing. The same gate pattern that refuses DONE without a review verdict could refuse DONE unless the slice's commits are reachable from main — or route the transition through slice-land. Today DONE asserts nothing about where the code lives.
  2. Give status truth one home. Either boards are only authoritative on main, or a freshness check (the git-freshness session hook already exists as a precedent) flags a diverged board when read from a worktree.
  3. Surface stranded work. At Stop or session start: "this worktree/branch has N commits not on main — land, park with a note, or discard." Parked should be distinguishable from forgotten.

Happy to hand over the exact branch names, commit hashes, and grep commands for the tabula case — everything above reproduces on my machine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions