Task — engineering-spec@1

Split the statuses doing two jobs

doneTASK-IMP-108
module improvement · class product · priority p1 · created 2026-07-17 · shipped 2026-07-17
depends on none · blocks none

TASK-IMP-108: Split the statuses doing two jobs

Summary

Three findings are one defect: draft means four different things, ready_to_implement means two, and routed_back_count is written eighteen times and read as a limit zero times. Each is a word doing more than one job, and the fix in every case is to record the reason rather than mint a status. Add draft_reason, add entered_via, and give the route-back a ceiling that halts for the operator instead of grinding.

Problem

Verified on merged main:

The consequence is shared: work that keeps failing cannot be told from work that has not started, and nothing escalates.

Proposed Solution

Record reasons, do not mint statuses. draft_reason (enum: authoring, migrated_stub, needs_spec, parked_idea) says which kind of draft this is. entered_via (enum: audit, rework, spec_rejected) says which kind of ready_to_implement this is - and spec_rejected gives a wrong SPEC somewhere to go other than back to an implementer who will build the same wrong thing. At routed_back_count >= 3 ship-tasks HALTS at an operator gate presenting the route-back reasons side by side, with the verdicts re-enter / split / on_hold / closed.

Three is a judgment call and the spec says so: it is the point at which "the same task failed three different ways" is evidence about the spec, not the implementation.

Alternatives Considered

Success Metrics

Scope

In scope: draft_reason and entered_via frontmatter fields + their FM rules, the route-back ceiling in ship-tasks, the staleness report on the status page, suite arms.

Out of scope / Non-Goals

Dependencies

None logically. Fields are additive and optional.

Serialisation note: touches STATUS-REFERENCE.md (shared with TASK-IMP-109), ship-tasks.md (109, 113, 114, 115), backlog-mutate.mjs (105), render-status-hub.mjs (114), test_workflow_evolution.py (115). Different sections in each, but §11a forbids concurrent shared-tree writes: the parent serialises these, and they MUST NOT be swarm members of one round.

AI Authorship Disclosure

1. Description (normative)

2. Acceptance criteria

3. Edge cases

Audit

§1 - Verdict summary

Spec is 104 lines, 7 §1 clauses, 6 ACs, 7 edge cases. Merges three handoff findings the handoff itself asks to be treated as one batch. Every claim verified on main (336 draft rows; 18 routed_back_count references, 0 reading it as a limit). Passes after 8 findings.

§2 - Findings (all resolved)

ISS-001 - Scope could be read as re-opening the rename decision

The operator decided 2026-07-17 to keep implement; a task touching status semantics must not relitigate it. Resolved: Non-Goals state the 12-value enum is unchanged and name the decision; Alternatives records why removing draft was rejected.

ISS-002 - Backfilling draft_reason across 336 drafts would fabricate reasons

Inventing a reason for a task this run did not author is the # UNREVIEWED mistake with better manners. Resolved: explicit Non-Goal; §3 requires absent to render as unknown.

ISS-003 - entered_via may be redundant with routed_back_count

The counter already separates fresh from rework; only spec_rejected needs a new value. Resolved: Alternatives records the fallback explicitly so review can collapse the field - the cheaper option stays live rather than being argued away.

ISS-004 - A ceiling of 3 is a judgment, not a derivation

Presenting it as a fact would be false precision. Resolved: the Proposed Solution says so plainly; AC 5 pins that 2 still re-enters, making the number testable rather than asserted.

ISS-005 - spec_rejected routing to ready_to_implement would loop forever

Handing an unchanged wrong spec to an implementer rebuilds the same wrong thing. Resolved: §1 #1.5 routes to draft for re-authoring and re-audit; AC 3 asserts the landing status.

ISS-006 - Ceiling could be resolved by a swarm sub-agent

The verdict is the operator's, and §11a says shared gates belong to the parent. Resolved: §3 edge case makes the halt the parent's.

ISS-007 - Shared-file conflicts with five sibling tasks were unrecorded

Touches STATUS-REFERENCE, ship-tasks, backlog-mutate, render-status-hub, and test_workflow_evolution - all contended. Resolved: Dependencies carries a §11a serialisation note; these MUST NOT be swarm members of one round.

ISS-008 - Staleness report could be read as licence to auto-close

A report that ages drafts is one step from a job that closes them. Resolved: §1 #1.7 forbids status change; Alternatives rejects auto-close as an operator's decision.

§3 - Resolution

All 8 concerns addressed. The machine floor (task-lint) ran FIRST and was clean before any judgment family was applied, per TASK-IMP-084. Score = 10/10.


End of TASK-IMP-108 audit.