Skip to content

TECH — Task-list field discipline (ID-34.3)

TECH — Task-list field discipline (ID-34.3)

Section titled “TECH — Task-list field discipline (ID-34.3)”

Task: ID-34. This Subtask: {34.3} TECH — doc-location decision + skill-update map + soft-warning implementation. Predecessors: RESEARCH.md, PRODUCT.md.

Maps each PRODUCT invariant to a concrete proposed change, grounded in the installed code and skill bodies (verified at HEAD 73ffb2b4). Migration plan: zero schema migration — the only code change is additive warning logic.


§1 Doc-location decision (resolves OQ-34-1)

Section titled “§1 Doc-location decision (resolves OQ-34-1)”

Decision: new dedicated doc docs/reference/task-list-discipline.md. NOT an appended § to taskmaster-schema-reference.md.

Rationale:

  • taskmaster-schema-reference.md is a snapshot-dated empirical artefact (“Snapshot date: 2026-05-16. If the upstream Phoenix Bridges export changes shape, re-run the analysis”). It answers what the fields are. The discipline doc answers how to write them — an evolving policy with a different update cadence and a different audience (authors/Planners vs parser implementers). Co-locating couples two doc lifecycles and invites the discipline policy to inherit the schema-reference’s “re-run on upstream change” framing, which does not apply.
  • A dedicated doc is the natural cross_doc_links and skill-reference target (a single stable path), and the natural home the four skills point at (inv 9).
  • It registers cleanly in docs/reference/documentation-inventory.md as one new entry.

The discipline doc cross-links to taskmaster-schema-reference.md for the field shapes and to lib/validation/task-list-schema.ts for the enforced constraints, so the two are connected without being merged.


§2 Proposed changes, mapped to PRODUCT invariants

Section titled “§2 Proposed changes, mapped to PRODUCT invariants”
PRODUCT invProposed changeFile(s)
1, 2, 3, 4, 5, 6, 7Author docs/reference/task-list-discipline.md publishing the §2 per-field table + the canonical-ref-vs-traceability boundary rule + ≥3 worked examples.docs/reference/task-list-discipline.md (new)
1Register the new doc in the documentation inventory.docs/reference/documentation-inventory.md
8, 10, 11Extend parseTaskListWithWarnings with a per-field budget check emitting TaskListWarning entries; no schema .max(); logic stays inside the function body.lib/validation/task-list-schema.ts
8Unit test: over-budget fixture warns (not throws); 25-Subtask warning still fires; field/id/measured-vs-budget surfaced.__tests__/lib/validation/task-list-discipline-warnings.test.ts (new)
9Amend the 3 repo-local skills to cite the discipline doc..claude/skills/{workflow-orchestration,write-product-spec,write-tech-spec}/SKILL.md
9Amend planning-and-task-breakdown — see §4 (global-skill caveat / OQ-34-5).~/.claude/skills/planning-and-task-breakdown/SKILL.md (global — see OQ)
12, 13Sweep policy is in PRODUCT §4; {34.4} PLAN decomposes it as the lowest-priority Subtask with the OQ-first gate.PLAN.md + OQ-pending.md

§3 Soft-warning implementation design (inv 8/10/11)

Section titled “§3 Soft-warning implementation design (inv 8/10/11)”

Extend the existing parseTaskListWithWarnings loop. Add a small budget table and a per-Task / per-Subtask field scan that pushes warnings alongside the existing 25-Subtask check. No change to any *Schema definition.

// lib/validation/task-list-schema.ts — inside parseTaskListWithWarnings, after parse
const FIELD_BUDGETS = {
taskDescription: 1500,
taskStatusNote: 300,
subtaskDescription: 250,
subtaskTestStrategy: 300,
} as const;
// per Task:
if (task.description.length > FIELD_BUDGETS.taskDescription) {
warnings.push({ taskId: task.id, message:
`Task "${task.id}" description is ${task.description.length} chars ` +
`(>${FIELD_BUDGETS.taskDescription}). Move design rationale to docs/ and ` +
`reference it via cross_doc_links (see docs/reference/task-list-discipline.md).` });
}
if (task.status_note && task.status_note.length > FIELD_BUDGETS.taskStatusNote) { … }
// per Subtask: description / testStrategy budgets, same shape.

Why this is safe (inv 10/11):

  • TaskListSchema.parse() is untouched — the live over-budget ledger still parses. The warning is additive and non-fatal (matches the 25-Subtask-ceiling precedent exactly).
  • No *Schema field-shape change: the exported SubtaskSchema / TaskSchema / TaskListSchema field definitions are untouched, so there is no schema rejection, no enum change, and no logical divergence of the validated shape from task-view’s packages/schemas/src/task-list-schema.ts. Caveat (post-Checker correction): the new module-level FIELD_BUDGETS const + the extended parseTaskListWithWarnings body are NOT stripped by the drift workflow’s normalise() (it strips comments/imports/re-exports/ regex-consts only), so they WILL appear in the schema-step normalised diff and emit a non-blocking ::warning:: until task-view re-vendors KH’s schema. That is the workflow working as intended (a re-vendor reminder), acceptable per OQ-T2 — not a hard cap, not a CI failure.
  • The TaskListWarning interface already exists ({taskId, message}) — no new type. (A later enhancement could add an optional field/severity, but inv 8 only requires the id + field + measured-vs-budget to appear in message, so the minimal change keeps the interface stable and avoids touching consumers.)

ID-35 consumption (the audit §5 contract): the ID-35 CLI parses via parseTaskListWithWarnings and prints warnings[] to stderr on every mutating command, so discipline drift surfaces to the orchestrator-operator at write time without hard-failing. No additional ID-35-side work — the warnings flow for free.


SkillPathClassInsertion pointAmendment
workflow-orchestration.claude/skills/workflow-orchestration/SKILL.mdrepo-local ✓## Ledger field-discipline (line ~270) — the table already existsAdd a lead pointer: “Canonical reference: docs/reference/task-list-discipline.md.” Align the table’s budgets with the doc (≤1500 description, ≤300 status_note, ≤250 subtask description, one-line testStrategy).
write-product-spec.claude/skills/write-product-spec/SKILL.mdrepo-local ✓## Keep the spec current (line ~202)Add: canonical rationale/behaviour belongs in this PRODUCT.md; the task-list description carries a compact what+why + a cross_doc_links pointer here, never a copy. Link the discipline doc.
write-tech-spec.claude/skills/write-tech-spec/SKILL.mdrepo-local ✓## Keep the spec current (line ~158)Same shape: REJECTED-alternatives + migration rationale live here; task-list description points, does not inline. Link the discipline doc.
planning-and-task-breakdown~/.claude/skills/planning-and-task-breakdown/SKILL.mdglobal ✗### Step 4: Write Tasks (line ~79) + ## Task Sizing GuidelinesWhen emitting Subtask records: details = dispatch brief + append-only journal (uncapped); testStrategy = one-line acceptance the Checker gates against; description = one sentence. Link the discipline doc. See OQ-34-5.

OQ-34-5 — planning-and-task-breakdown is a GLOBAL skill (uncommittable)

Section titled “OQ-34-5 — planning-and-task-breakdown is a GLOBAL skill (uncommittable)”

planning-and-task-breakdown lives at ~/.claude/skills/, not in the KH repo, so an edit to it cannot be committed to this worker branch or cherry-picked to main by the parent. The cmux brief’s Files list assumed it was repo-local (.claude/skills/…).

Provisional default (applied): amend the three repo-local skills (committable, the load-bearing pair being workflow-orchestration + the two write-*-spec skills) and surface OQ-34-5 to the parent via OQ-pending.md. The global planning-and-task-breakdown edit is deferred to the parent’s decision: either (a) vendor planning-and-task-breakdown into .claude/skills/ (so the discipline amendment is committable + shared), or (b) the parent applies the global-skill edit out-of-band on the host. The CLI/discipline-doc deliverables do not depend on this skill edit, so deferral does not block ID-34 or ID-35.

Per the cmux brief: ID-34 skill updates go via the update-skill skill; the workflow-security hook may block the FIRST raw .claude/skills/ edit once — retry succeeds.


PRODUCT invTECH changeVerification
1§2 discipline doc + inventory entryfile exists + inventory grep
2,3,7doc boundary rules + examplesdoc content
4,5,6doc field designationsdoc content
8§3 warning loop + testunit test green
9§4 skill amendments (3 repo-local)grep each SKILL.md
10no .max() addedschema diff
11warning in function body, schema shape intactschema field-export diff + vendor-drift check
12,13sweep policy → PLAN + OQ-first gatePLAN.md + OQ-pending.md

1-to-1 mapping holds. New T-OQ: OQ-34-5 (global-skill). Migration plan: zero.