feat(cli): --criterion on create epictask, and file the reconciliation follow-ups
Merges the Epic reconciliation (task 170) and closes the gap that made it inert from the terminal. `mcpctl create epictask` had no `--criterion` flag while `create epic` did, so a roadmap built from the CLI had no criteria on its nodes. The reconciliation attributes a criterion to a node by id, so every criterion would have reported as `unowned` and both mismatch lists would always have been empty — the feature would have looked like it worked and detected nothing. Files two follow-ups the reconciliation surfaced: - 175: criteria and roadmap nodes are linked only by a free-form id convention that nothing enforces. EpicTaskService never validates ids against the parent Epic, ids can repeat across nodes, and a node can carry an id the Epic never had. The reconciliation reports those as `unowned` rather than guessing an owner, which is right, but the convention should become an invariant before more is built on it. - 176: `get epic -o yaml` now emits computed `completeness`/`reconciliation`, which are not settable. apply tolerates them, but the round-trip rule says get output is apply input. Local: build clean, workspace 2499 passed, lint unchanged at 794 errors. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4wNHWf7xSwnZCWpJcyv9p
This commit is contained in:
@@ -3358,9 +3358,9 @@
|
||||
"131",
|
||||
"126"
|
||||
],
|
||||
"status": "pending",
|
||||
"status": "done",
|
||||
"subtasks": [],
|
||||
"updatedAt": "2026-08-09T19:36:34.052Z"
|
||||
"updatedAt": "2026-08-09T21:09:27.647Z"
|
||||
},
|
||||
{
|
||||
"id": "171",
|
||||
@@ -3415,16 +3415,44 @@
|
||||
"status": "pending",
|
||||
"subtasks": [],
|
||||
"updatedAt": "2026-08-09T20:50:38.660Z"
|
||||
},
|
||||
{
|
||||
"id": "175",
|
||||
"title": "Give criteria a real link to the roadmap node that delivers them",
|
||||
"description": "Epic.doneCriteria and EpicTask.doneCriteria are connected only by a free-form id convention that nothing enforces. The reconciliation added in 170 depends on it.",
|
||||
"details": "Found while building the reconciliation. EpicTaskService.create/update never validates criterion ids against the parent Epic; ids can be duplicated across nodes, and a node can carry an id the Epic never had. Every failure of the convention currently surfaces as `unowned`.\n\nOptions:\n- an EpicCriterion table with a real FK (strongest, biggest change);\n- validate on epictask write that each doneCriteria[].id exists on the parent Epic, turning the convention into an invariant, plus a startup check for existing rows (cheapest honest fix).\n\nDecide before more is built on top of the convention.",
|
||||
"testStrategy": "See details.",
|
||||
"priority": "high",
|
||||
"dependencies": [
|
||||
"170"
|
||||
],
|
||||
"status": "pending",
|
||||
"subtasks": [],
|
||||
"updatedAt": "2026-08-09T21:09:27.819Z"
|
||||
},
|
||||
{
|
||||
"id": "176",
|
||||
"title": "Keep computed fields out of the get -o yaml round-trip",
|
||||
"description": "`get epic X -o yaml` now emits `completeness` and `reconciliation`, which are computed, not settable. apply -f tolerates them (zod ignores unknown keys) but the round-trip rule says get output is apply input.",
|
||||
"details": "Stripping them in stripInternalFields was tried and reverted: an existing smoke assertion reads `completeness` out of `get epics -o json`, and stripping would also hide the new mismatch from the CLI entirely.\n\nThe real fix is probably to keep computed fields in -o json but drop them from -o yaml, and surface the mismatch in `describe epic` (task 167) rather than in the apply document.",
|
||||
"testStrategy": "See details.",
|
||||
"priority": "medium",
|
||||
"dependencies": [
|
||||
"167"
|
||||
],
|
||||
"status": "pending",
|
||||
"subtasks": [],
|
||||
"updatedAt": "2026-08-09T21:09:27.819Z"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"version": "1.0.0",
|
||||
"lastModified": "2026-08-09T20:55:31.468Z",
|
||||
"lastModified": "2026-08-09T21:09:27.647Z",
|
||||
"taskCount": 174,
|
||||
"completedCount": 129,
|
||||
"completedCount": 130,
|
||||
"tags": [
|
||||
"master"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user