Task — engineering-spec@1

Task-id allocation rule + next-id helper

doneTASK-IMP-105
module improvement · class product · priority p2 · created 2026-07-17 · shipped null
depends on none · blocks none

TASK-IMP-105: Task-id allocation rule + next-id helper

Summary

task-author has no rule for choosing a task id - the model picks, and the only safety net is backlog-mutate's uniqueness gate, which fires at INSERT after the spec folder is already on disk. Two authoring runs against one module can therefore both pick the same id, write two folders, and leave an orphan when the second insert refuses. State the allocation rule in the skill and make it executable as backlog-mutate next-id <module>.

Problem

grep for an allocation rule in task-author/SKILL.md finds nothing: no "scan existing ids", no "next available". The uniqueness pre-image gate in backlog-mutate.mjs:258 refuses with exit 7 (row already present ... uniqueness pre-image violated) - correct, but late: the spec files exist by then, and the operator is left with a half-landed task and no instruction.

Authoring is usually serial, which is why this has not bitten. This run interleaved five batches and got lucky. The pattern this run keeps re-learning is that every mechanical rule left in prose gets re-derived wrongly eventually, and every one moved into a tool stops being a question.

Proposed Solution

Add the rule to task-author: allocate by scanning docs/tasks/<module>/ for the highest existing stem and taking the next, and re-scan immediately before writing rather than trusting an id chosen at PLAN time. Add backlog-mutate next-id <module> so the rule is executable rather than remembered - it reads the same corpus the insert gate reads, so allocation and admission cannot disagree. The gate stays exactly as it is: this narrows the window, it does not replace the check.

Alternatives Considered

Success Metrics

Scope

In scope: the allocation rule in task-author/SKILL.md, backlog-mutate next-id <module>, suite arms.

Out of scope / Non-Goals

Dependencies

None logically.

Serialisation note: touches backlog-mutate.mjs (shared with TASK-IMP-108, which adds entered_via to the same writer). Parent-serialised per §11a.

AI Authorship Disclosure

1. Description (normative)

2. Acceptance criteria

3. Edge cases

Audit

§1 - Verdict summary

Spec is 79 lines, 6 §1 clauses, 5 ACs, 5 edge cases. Gap verified on main: task-author states no allocation rule; backlog-mutate.mjs:258 is the late net. Passes after 6 findings.

§2 - Findings (all resolved)

ISS-001 - Allocation could race between PLAN and write

An id chosen at PLAN time may be taken by the time files land. Resolved: §1 #1.1 requires a re-scan immediately before writing; AC 5 verifies the rule is stated.

ISS-002 - Half-landed folder with no row would be skipped

Counting rows rather than folders re-issues the exact colliding id this task prevents. Resolved: §3 edge case makes the folder authoritative.

ISS-003 - Gap reuse would make two tasks share a name in history

Taking the lowest free number recycles a retired id. Resolved: §1 #1.5 requires highest+1; AC 3 asserts it against a gapped corpus.

ISS-004 - Could be read as replacing the uniqueness gate

It narrows the window; it does not close it. Resolved: §1 #1.6 keeps the gate authoritative, AC 4 asserts exit-7 still fires, and §3 names the residual race honestly.

ISS-005 - Module argument is a path component - a traversal surface

next-id ../../etc would walk out of the corpus. Resolved: §3 security-class requires the relUnderRoot confinement the batch-5 review forced onto task-reconcile.

ISS-006 - Empty module could be treated as an error

A module's first task must be allocatable. Resolved: §1 #1.4 makes empty legal; AC 2 covers it.

§3 - Resolution

All 6 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-105 audit.