cc-devflow 4.5.8 → 4.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/.claude/skills/cc-act/CHANGELOG.md +27 -0
  2. package/.claude/skills/cc-act/PLAYBOOK.md +9 -4
  3. package/.claude/skills/cc-act/SKILL.md +62 -3
  4. package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_INDEX_TEMPLATE.md +30 -0
  5. package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_PRINCIPLES_TEMPLATE.md +29 -0
  6. package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_TEMPLATE.md +103 -0
  7. package/.claude/skills/cc-act/assets/PR_BRIEF_TEMPLATE.md +60 -4
  8. package/.claude/skills/cc-act/references/closure-contract.md +3 -0
  9. package/.claude/skills/cc-act/references/git-commit-guidelines.md +342 -37
  10. package/.claude/skills/cc-act/scripts/cc-act-common.sh +29 -1
  11. package/.claude/skills/cc-act/scripts/render-pr-brief.sh +164 -0
  12. package/.claude/skills/cc-act/scripts/sync-act-docs.sh +1 -1
  13. package/.claude/skills/cc-do/CHANGELOG.md +11 -0
  14. package/.claude/skills/cc-do/SKILL.md +19 -13
  15. package/.claude/skills/cc-do/scripts/build-task-context.sh +9 -5
  16. package/.claude/skills/cc-do/scripts/mark-task-complete.sh +0 -6
  17. package/.claude/skills/cc-investigate/CHANGELOG.md +17 -0
  18. package/.claude/skills/cc-investigate/PLAYBOOK.md +15 -0
  19. package/.claude/skills/cc-investigate/SKILL.md +46 -1
  20. package/.claude/skills/cc-investigate/assets/ANALYSIS_TEMPLATE.md +47 -0
  21. package/.claude/skills/cc-investigate/assets/TASKS_TEMPLATE.md +21 -2
  22. package/.claude/skills/cc-investigate/assets/TASK_MANIFEST_TEMPLATE.json +28 -58
  23. package/.claude/skills/cc-investigate/references/investigation-contract.md +14 -0
  24. package/.claude/skills/cc-next/CHANGELOG.md +6 -0
  25. package/.claude/skills/cc-next/PLAYBOOK.md +26 -4
  26. package/.claude/skills/cc-next/SKILL.md +39 -4
  27. package/.claude/skills/cc-plan/CHANGELOG.md +19 -0
  28. package/.claude/skills/cc-plan/PLAYBOOK.md +25 -20
  29. package/.claude/skills/cc-plan/SKILL.md +83 -22
  30. package/.claude/skills/cc-plan/assets/DESIGN_TEMPLATE.md +67 -0
  31. package/.claude/skills/cc-plan/assets/TASKS_TEMPLATE.md +59 -0
  32. package/.claude/skills/cc-plan/assets/TASK_MANIFEST_TEMPLATE.json +55 -228
  33. package/.claude/skills/cc-plan/assets/TINY_DESIGN_TEMPLATE.md +46 -0
  34. package/.claude/skills/cc-plan/references/planning-contract.md +41 -27
  35. package/.claude/skills/cc-roadmap/CHANGELOG.md +6 -0
  36. package/.claude/skills/cc-roadmap/PLAYBOOK.md +30 -0
  37. package/.claude/skills/cc-roadmap/SKILL.md +45 -8
  38. package/.claude/skills/cc-roadmap/assets/BACKLOG_TEMPLATE.md +8 -0
  39. package/.claude/skills/cc-roadmap/assets/ROADMAP_TEMPLATE.md +22 -0
  40. package/.claude/skills/cc-roadmap/assets/TRACKING_TEMPLATE.json +32 -1
  41. package/.claude/skills/cc-roadmap/references/roadmap-dialogue.md +14 -14
  42. package/CHANGELOG.md +12 -0
  43. package/README.md +37 -35
  44. package/README.zh-CN.md +37 -35
  45. package/docs/examples/example-bindings.json +7 -7
  46. package/docs/examples/full-design-blocked/BACKLOG.md +1 -1
  47. package/docs/examples/full-design-blocked/README.md +1 -1
  48. package/docs/examples/full-design-blocked/ROADMAP.md +1 -1
  49. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/design.md +1 -1
  50. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/task-manifest.json +27 -311
  51. package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/tasks.md +1 -1
  52. package/docs/examples/full-design-blocked/roadmap.json +1 -1
  53. package/docs/examples/local-handoff/BACKLOG.md +1 -1
  54. package/docs/examples/local-handoff/README.md +1 -1
  55. package/docs/examples/local-handoff/ROADMAP.md +1 -1
  56. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/design.md +1 -1
  57. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/task-manifest.json +25 -209
  58. package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/tasks.md +1 -1
  59. package/docs/examples/local-handoff/roadmap.json +1 -1
  60. package/docs/examples/pdca-loop/BACKLOG.md +1 -1
  61. package/docs/examples/pdca-loop/README.md +1 -1
  62. package/docs/examples/pdca-loop/ROADMAP.md +1 -1
  63. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/pr-brief.md +64 -0
  64. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/design.md +1 -1
  65. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json +25 -228
  66. package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/tasks.md +1 -1
  67. package/docs/examples/pdca-loop/roadmap.json +1 -1
  68. package/docs/examples/scripts/check-example-bindings.sh +9 -5
  69. package/docs/get-shit-done-strategy-audit.md +4 -4
  70. package/docs/guides/artifact-contract.md +44 -0
  71. package/docs/guides/project-postmortem.md +78 -0
  72. package/lib/skill-runtime/__tests__/planner.tdd.test.js +2 -2
  73. package/lib/skill-runtime/__tests__/schemas.test.js +33 -2
  74. package/lib/skill-runtime/planner.js +1 -2
  75. package/lib/skill-runtime/query.js +1 -1
  76. package/lib/skill-runtime/schemas.js +5 -3
  77. package/package.json +1 -1
@@ -3,63 +3,33 @@
3
3
  "goal": "Add a one-click copy action to the existing share dialog without changing backend contracts.",
4
4
  "createdAt": "2026-04-15T10:00:00.000Z",
5
5
  "updatedAt": "2026-04-15T11:10:00.000Z",
6
- "status": "verified",
7
6
  "requirementId": "REQ-001",
8
7
  "requirementVersion": "REQ-001.v1",
9
- "sourceRoadmap": {
10
- "itemId": "RM-001",
11
- "roadmapVersion": "roadmap.v1",
12
- "roadmapSkillVersion": "5.2.0",
13
- "sourceStage": "Stage 1",
14
- "successSignal": "Users can copy the invite link with one click",
15
- "killSignal": "The patch requires backend or permission changes",
16
- "dependencies": [
17
- "Existing share dialog stays intact"
18
- ],
19
- "nonGoals": [
20
- "No invite role redesign",
21
- "No share analytics"
22
- ]
23
- },
24
8
  "planningMeta": {
25
- "reqPlanSkillVersion": "3.8.2",
9
+ "reqPlanSkillVersion": "3.8.5",
26
10
  "designVersion": "design.v1",
27
11
  "approvedAt": "2026-04-15T10:05:00.000Z",
28
- "approvedBy": "user",
29
12
  "basedOnOption": "Tiny design card",
30
- "requirementBrief": {
31
- "problemStatement": "Users can see the invite URL, but copying it still requires manual selection.",
32
- "solutionSummary": "Add a one-click copy action with lightweight confirmation inside the existing share dialog.",
33
- "actors": [
34
- "workspace member sharing an invite"
35
- ],
36
- "userStories": [
37
- {
38
- "id": "US-001",
39
- "actor": "workspace member",
40
- "want": "copy the invite link with one click",
41
- "benefit": "share it without manually selecting text",
42
- "acceptance": [
43
- "Dialog behavior test proves the current invite URL is copied"
44
- ]
45
- }
46
- ],
47
- "edgeOrRecoveryStories": [],
48
- "implementationDecisions": [
49
- "Reuse the existing invite URL source and dialog props"
50
- ],
51
- "testingDecisions": [
52
- "Test through the share dialog behavior, not an internal helper"
53
- ],
54
- "outOfScope": [
55
- "invite generation",
56
- "role controls",
57
- "analytics",
58
- "clipboard fallback redesign"
59
- ],
60
- "furtherNotes": [
61
- "Richer copied-state feedback is a separate UX requirement"
62
- ]
13
+ "aiLeverageDecisionLens": {
14
+ "realUserOrOperator": "workspace member sharing an invite",
15
+ "statusQuoWorkaround": "manual selection and copy of the visible invite URL",
16
+ "humanTeamEffortForFullScope": "about half a day for one engineer including test and review",
17
+ "ccAgentEffortForFullScope": "about 20 minutes for a targeted UI patch plus test update",
18
+ "aiCompressionRatio": "roughly 10x for this bounded UI slice",
19
+ "completeLakeBoundary": "copy action, current invite URL source, copied-state feedback, and dialog behavior test",
20
+ "oceanBoundary": "invite generation, permissions, analytics, or clipboard fallback redesign",
21
+ "scopeRecommendation": "boil-lake",
22
+ "costModel": {
23
+ "agentTime": "low",
24
+ "humanReviewTime": "low",
25
+ "verificationCost": "targeted dialog test",
26
+ "maintenanceCost": "low while scoped to the dialog",
27
+ "failureCost": "sharing friction remains",
28
+ "reversibility": "reversible UI patch"
29
+ },
30
+ "verdict": "boil-lake",
31
+ "missingEvidenceOrPivotReason": "",
32
+ "impactOnApprovedDirection": "cover the full same-dialog copy lake instead of only a happy-path button render"
63
33
  },
64
34
  "externalBestPractice": {
65
35
  "needed": false,
@@ -105,31 +75,9 @@
105
75
  "impact": "cc-do keeps implementation inside the share dialog and avoids backend or permission work",
106
76
  "status": "answered"
107
77
  }
108
- ],
109
- "aiLeverageDecisionLens": {
110
- "realUserOrOperator": "workspace member sharing an invite",
111
- "statusQuoWorkaround": "manual selection and copy of the visible invite URL",
112
- "humanTeamEffortForFullScope": "about half a day for one engineer including test and review",
113
- "ccAgentEffortForFullScope": "about 20 minutes for a targeted UI patch plus test update",
114
- "aiCompressionRatio": "roughly 10x for this bounded UI slice",
115
- "completeLakeBoundary": "copy action, current invite URL source, copied-state feedback, and dialog behavior test",
116
- "oceanBoundary": "invite generation, permissions, analytics, or clipboard fallback redesign",
117
- "scopeRecommendation": "boil-lake",
118
- "costModel": {
119
- "agentTime": "low",
120
- "humanReviewTime": "low",
121
- "verificationCost": "targeted dialog test",
122
- "maintenanceCost": "low while scoped to the dialog",
123
- "failureCost": "sharing friction remains",
124
- "reversibility": "reversible UI patch"
125
- },
126
- "verdict": "boil-lake",
127
- "missingEvidenceOrPivotReason": "",
128
- "impactOnApprovedDirection": "cover the full same-dialog copy lake instead of only a happy-path button render"
129
- }
78
+ ]
130
79
  },
131
80
  "currentTaskId": null,
132
- "activePhase": null,
133
81
  "tasks": [
134
82
  {
135
83
  "id": "T001",
@@ -194,45 +142,7 @@
194
142
  "type": "automated-test",
195
143
  "determinism": "deterministic",
196
144
  "expectedFailure": "Fails before the behavior exists"
197
- },
198
- "allowedMocks": [
199
- "clipboard boundary"
200
- ],
201
- "testQuality": {
202
- "usesPublicInterface": true,
203
- "describesBehavior": true,
204
- "specStyleName": true,
205
- "oneLogicalBehavior": true,
206
- "verifiesThroughPublicPath": true,
207
- "survivesInternalRefactor": true,
208
- "mocksOnlySystemBoundaries": true,
209
- "noBulkRed": true
210
- },
211
- "greenMinimality": {
212
- "guard": "Keep the task scoped to its stated verification evidence",
213
- "noSpeculativeBranches": true
214
- },
215
- "completion": {
216
- "command": "SCRIPT_ROOT=\".claude/skills/cc-do/scripts\"; if [[ ! -d \"$SCRIPT_ROOT\" && -d \".codex/skills/cc-do/scripts\" ]]; then SCRIPT_ROOT=\".codex/skills/cc-do/scripts\"; fi; bash \"$SCRIPT_ROOT\"/mark-task-complete.sh --manifest docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json --tasks docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/tasks.md --task T001",
217
- "requiredBeforeCompletion": [
218
- "verification evidence captured",
219
- "checkpoint written",
220
- "spec review gate recorded",
221
- "code review gate recorded"
222
- ],
223
- "forbiddenShortcuts": [
224
- "manual checkbox edit",
225
- "manual manifest status edit",
226
- "leaving currentTaskId stale"
227
- ]
228
- },
229
- "refactorCandidates": [
230
- "duplication",
231
- "long method",
232
- "primitive obsession",
233
- "naming",
234
- "more than three nested branches"
235
- ]
145
+ }
236
146
  },
237
147
  {
238
148
  "id": "T002",
@@ -299,45 +209,7 @@
299
209
  "type": "automated-test",
300
210
  "determinism": "deterministic",
301
211
  "expectedFailure": ""
302
- },
303
- "allowedMocks": [
304
- "clipboard boundary"
305
- ],
306
- "testQuality": {
307
- "usesPublicInterface": true,
308
- "describesBehavior": true,
309
- "specStyleName": true,
310
- "oneLogicalBehavior": true,
311
- "verifiesThroughPublicPath": true,
312
- "survivesInternalRefactor": true,
313
- "mocksOnlySystemBoundaries": true,
314
- "noBulkRed": true
315
- },
316
- "greenMinimality": {
317
- "guard": "Implement only the code needed to pass the current red behavior",
318
- "noSpeculativeBranches": true
319
- },
320
- "completion": {
321
- "command": "SCRIPT_ROOT=\".claude/skills/cc-do/scripts\"; if [[ ! -d \"$SCRIPT_ROOT\" && -d \".codex/skills/cc-do/scripts\" ]]; then SCRIPT_ROOT=\".codex/skills/cc-do/scripts\"; fi; bash \"$SCRIPT_ROOT\"/mark-task-complete.sh --manifest docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json --tasks docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/tasks.md --task T002",
322
- "requiredBeforeCompletion": [
323
- "verification evidence captured",
324
- "checkpoint written",
325
- "spec review gate recorded",
326
- "code review gate recorded"
327
- ],
328
- "forbiddenShortcuts": [
329
- "manual checkbox edit",
330
- "manual manifest status edit",
331
- "leaving currentTaskId stale"
332
- ]
333
- },
334
- "refactorCandidates": [
335
- "duplication",
336
- "long method",
337
- "primitive obsession",
338
- "naming",
339
- "more than three nested branches"
340
- ]
212
+ }
341
213
  },
342
214
  {
343
215
  "id": "T003",
@@ -408,87 +280,12 @@
408
280
  "type": "automated-test",
409
281
  "determinism": "deterministic",
410
282
  "expectedFailure": ""
411
- },
412
- "allowedMocks": [
413
- "clipboard boundary"
414
- ],
415
- "testQuality": {
416
- "usesPublicInterface": true,
417
- "describesBehavior": true,
418
- "specStyleName": true,
419
- "oneLogicalBehavior": true,
420
- "verifiesThroughPublicPath": true,
421
- "survivesInternalRefactor": true,
422
- "mocksOnlySystemBoundaries": true,
423
- "noBulkRed": true
424
- },
425
- "greenMinimality": {
426
- "guard": "Keep the task scoped to its stated verification evidence",
427
- "noSpeculativeBranches": true
428
- },
429
- "completion": {
430
- "command": "SCRIPT_ROOT=\".claude/skills/cc-do/scripts\"; if [[ ! -d \"$SCRIPT_ROOT\" && -d \".codex/skills/cc-do/scripts\" ]]; then SCRIPT_ROOT=\".codex/skills/cc-do/scripts\"; fi; bash \"$SCRIPT_ROOT\"/mark-task-complete.sh --manifest docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json --tasks docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/tasks.md --task T003",
431
- "requiredBeforeCompletion": [
432
- "verification evidence captured",
433
- "checkpoint written",
434
- "spec review gate recorded",
435
- "code review gate recorded"
436
- ],
437
- "forbiddenShortcuts": [
438
- "manual checkbox edit",
439
- "manual manifest status edit",
440
- "leaving currentTaskId stale"
441
- ]
442
- },
443
- "refactorCandidates": [
444
- "duplication",
445
- "long method",
446
- "primitive obsession",
447
- "naming",
448
- "more than three nested branches"
449
- ]
283
+ }
450
284
  }
451
285
  ],
452
286
  "metadata": {
453
287
  "source": "tasks.md",
454
288
  "generatedBy": "docs-example",
455
289
  "planVersion": 1
456
- },
457
- "deferredQuestions": [
458
- "If users still miss the copied-state confirmation, open RM-002 for richer feedback."
459
- ],
460
- "executionProtocol": {
461
- "templateCompliance": {
462
- "required": true,
463
- "sourceTemplate": "assets/TASKS_TEMPLATE.md",
464
- "taskBlockMustInclude": [
465
- "Goal",
466
- "TDD phase",
467
- "Files",
468
- "Read first",
469
- "Verification",
470
- "Evidence",
471
- "Test seam",
472
- "Public verification path",
473
- "Allowed mocks",
474
- "Completion"
475
- ],
476
- "titleOnlyTasks": "forbidden"
477
- },
478
- "selection": {
479
- "sourceOfTruth": "planning/task-manifest.json.currentTaskId",
480
- "commandTemplate": "SCRIPT_ROOT=\".claude/skills/cc-do/scripts\"; if [[ ! -d \"$SCRIPT_ROOT\" && -d \".codex/skills/cc-do/scripts\" ]]; then SCRIPT_ROOT=\".codex/skills/cc-do/scripts\"; fi; bash \"$SCRIPT_ROOT\"/select-ready-tasks.sh --manifest docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json"
481
- },
482
- "completion": {
483
- "manualStatusEdit": "forbidden",
484
- "commandTemplate": "SCRIPT_ROOT=\".claude/skills/cc-do/scripts\"; if [[ ! -d \"$SCRIPT_ROOT\" && -d \".codex/skills/cc-do/scripts\" ]]; then SCRIPT_ROOT=\".codex/skills/cc-do/scripts\"; fi; bash \"$SCRIPT_ROOT\"/mark-task-complete.sh --manifest docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json --tasks docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/tasks.md --task <task-id>",
485
- "failurePolicy": "Do not hand-edit status; fix missing checkpoint, review gate, or dependency evidence and rerun the script.",
486
- "updates": [
487
- "planning/task-manifest.json.tasks[].status",
488
- "planning/task-manifest.json.currentTaskId",
489
- "planning/task-manifest.json.status",
490
- "planning/tasks.md checkbox"
491
- ]
492
- }
493
290
  }
494
291
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  - Requirement version: `REQ-001.v1`
6
6
  - Design version: `design.v1`
7
- - CC-Plan skill version: `3.8.2`
7
+ - CC-Plan skill version: `3.8.5`
8
8
  - Source roadmap item: `RM-001`
9
9
  - Source roadmap version: `roadmap.v1`
10
10
 
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "meta": {
7
7
  "roadmapVersion": "roadmap.v1",
8
- "skillVersion": "5.2.0",
8
+ "skillVersion": "5.3.0",
9
9
  "status": "active",
10
10
  "lastUpdated": "2026-04-19",
11
11
  "currentFocusStage": "Stage 1"
@@ -100,12 +100,16 @@ while IFS= read -r encoded; do
100
100
  assert_contains "$planning_dir/tasks.md" "- CC-Plan skill version: \`$REQ_PLAN_VERSION\`"
101
101
 
102
102
  jq -er --arg roadmap "$ROADMAP_VERSION" --arg reqplan "$REQ_PLAN_VERSION" '
103
- (.sourceRoadmap.roadmapSkillVersion // $roadmap) == $roadmap and
104
103
  (.planningMeta.reqPlanSkillVersion // $reqplan) == $reqplan and
105
- .executionProtocol.templateCompliance.required == true and
106
- .executionProtocol.completion.manualStatusEdit == "forbidden" and
107
- (.executionProtocol.completion.commandTemplate | contains("mark-task-complete.sh")) and
108
- all(.tasks[]; (.completion.command | contains("mark-task-complete.sh")) and (.tddPhase | type == "string") and (.testSeam.publicVerificationPath | type == "string"))
104
+ (.status? == null) and
105
+ (.activePhase? == null) and
106
+ (.sourceRoadmap? == null) and
107
+ (.spec? == null) and
108
+ (.executionProtocol? == null) and
109
+ (.planningMeta.requirementBrief? == null) and
110
+ (.planningMeta.ambiguityGate? == null) and
111
+ (.planningMeta.reviewLoop? == null) and
112
+ all(.tasks[]; (.completion? == null) and (.tddPhase | type == "string") and (.testSeam.publicVerificationPath | type == "string"))
109
113
  ' "$planning_dir/task-manifest.json" >/dev/null
110
114
 
111
115
  assert_contains "$planning_dir/tasks.md" "## Execution Protocol"
@@ -127,9 +127,9 @@ Codebase Map 七件套只作为按需缓存:
127
127
  | --- | --- | --- | --- |
128
128
  | WHAT/WHY ambiguity score | `task-manifest.json.planningMeta` + `planning/design.md` | score above threshold blocks task manifest approval | unit fixture: ambiguous input blocks; clear input passes |
129
129
  | Assumptions preview | `planning/design.md` decision log | user-visible assumptions before approval | fixture: hidden assumption fails review |
130
- | Bounded review loop | `task-manifest.json.planningMeta.reviewLoop` | max attempts and stall detection reroute to `cc-roadmap` or user question | hostile fixture: repeated issue count blocks |
131
- | External doc conflict buckets | `task-manifest.json.languageAndDecisions` | imported docs classified as auto-resolved, competing, unresolved | fixture: conflicting ADR/PRD creates blocker |
132
- | Trust boundary | `task-manifest.json.sourceEvidence[]` | external text is evidence/source only, never instruction | hostile fixture: prompt injection remains evidence-only |
130
+ | Bounded review loop | `planning/design.md` | max attempts and stall detection reroute to `cc-roadmap` or user question | hostile fixture: repeated issue count blocks |
131
+ | External doc conflict buckets | `planning/design.md` | imported docs classified as auto-resolved, competing, unresolved | fixture: conflicting ADR/PRD creates blocker |
132
+ | Trust boundary | `planning/design.md` | external text is evidence/source only, never instruction | hostile fixture: prompt injection remains evidence-only |
133
133
 
134
134
  `cc-plan` must keep design decisions readable in Markdown and machine truth in JSON.
135
135
  No separate GSD-style `.planning/` tree.
@@ -209,7 +209,7 @@ default planning path.
209
209
  | Data | Owner | Human view | Machine truth |
210
210
  | --- | --- | --- | --- |
211
211
  | Ambiguity and assumptions | `cc-plan` | `planning/design.md` | `task-manifest.json.planningMeta` |
212
- | Imported doc trust classification | `cc-plan` | `planning/design.md` | `task-manifest.json.sourceEvidence[]` |
212
+ | Imported doc trust classification | `cc-plan` | `planning/design.md` | `planning/design.md` |
213
213
  | Task graph and waves | `cc-plan` / `cc-do` | `planning/tasks.md` | `task-manifest.json.tasks[]` |
214
214
  | Quick lane state | `cc-do` | checkpoint summary | `task-manifest.json.metadata`, `checkpoint.json` |
215
215
  | Debug hypotheses and probes | `cc-investigate` | `planning/analysis.md` | optional `task-manifest.json.investigation` |
@@ -0,0 +1,44 @@
1
+ # Artifact Contract
2
+
3
+ cc-devflow artifacts follow two rules: progressive disclosure and one state owner.
4
+
5
+ ## Progressive Disclosure
6
+
7
+ Every skill output should have a default path and deeper layers.
8
+
9
+ - Default layer: the next actor can see the current state, next action, and proof source quickly.
10
+ - Conditional layer: open only when scope, dependency, review, or conflict questions arise.
11
+ - Deep layer: full evidence, reasoning, or historical review, opened only for audit or recovery.
12
+
13
+ If a field has no clear opener and no downstream consumer, remove it.
14
+
15
+ ## State Owners
16
+
17
+ | State | Owner artifact | Projection / derived readers |
18
+ | --- | --- | --- |
19
+ | Roadmap item status and progress | `devflow/roadmap.json` | `devflow/ROADMAP.md`, `devflow/BACKLOG.md`, handoff summaries |
20
+ | Capability/spec sync state | `devflow/changes/<change-key>/change-meta.json` | `planning/tasks.md`, `review/report-card.json`, handoff summaries |
21
+ | Execution task status | `planning/task-manifest.json.tasks[].status` | `planning/tasks.md` checkboxes, recovery summaries |
22
+ | Ready task / phase | derived from `tasks[].status`, `tasks[].phase`, and `tasks[].dependsOn` | `currentTaskId` cache, ready-task selector output |
23
+ | Runtime checkpoint state | `execution/tasks/<task-id>/checkpoint.json` | `events.jsonl`, recovery summaries |
24
+ | Review verdict | `review/report-card.json.verdict` | PR brief, release note, act gate |
25
+ | PR / remote queue truth | live GitHub API / `gh` output | local review notes and handoff summaries |
26
+ | Project postmortem facts and principles | `devflow/postmortems/` | planning recall, investigation hypotheses, task guardrails |
27
+
28
+ ## Duplication Rules
29
+
30
+ - Machine artifacts may reference another owner by id or path, but must not copy its status lifecycle.
31
+ - Markdown projections must state their source instead of becoming editable truth.
32
+ - Derived fields must be described as derived/cache and must be recomputable.
33
+ - A skill must not create a new status field unless it also names the owner, lifecycle, projection readers, and validation gate.
34
+ - Task manifests must not duplicate PRD narrative, review-loop prose, source-trust details, completion shell commands, roadmap progress, or spec sync status.
35
+ - Project postmortems must cite stronger owner artifacts and Git evidence; they do not own roadmap progress, task status, review verdicts, or spec sync state.
36
+
37
+ ## Required Check
38
+
39
+ Before changing any skill output, answer:
40
+
41
+ 1. Who owns this state?
42
+ 2. Is this field consumed directly, or is it a projection?
43
+ 3. Can it be recomputed from a stronger source?
44
+ 4. What validation fails if this state diverges?
@@ -0,0 +1,78 @@
1
+ # Project Postmortem Contract
2
+
3
+ cc-devflow treats project postmortems as a durable AI memory surface. They are not
4
+ chat summaries. They are repo-owned evidence that future agents can search before
5
+ planning, investigating, or executing work.
6
+
7
+ ## Storage Layout
8
+
9
+ Project-level postmortems live under `devflow/postmortems/`:
10
+
11
+ | Path | Owner | Purpose |
12
+ | --- | --- | --- |
13
+ | `INDEX.md` | `cc-act` | Progressive entry point, latest incidents, tags, and search hints |
14
+ | `principles.md` | `cc-act` | Generalized lessons about recurring model, process, and engineering mistakes |
15
+ | `incidents/<date>-<change-key>.md` | `cc-act` | Immutable-ish factual record for one incident, bug, or repeated AI failure |
16
+
17
+ `cc-act` owns writes because it has verified closeout, Git state, review state, and
18
+ ship facts. Earlier skills only read and project the relevant reminders into their
19
+ own artifacts.
20
+
21
+ ## Progressive Disclosure
22
+
23
+ - Default layer: `INDEX.md` gives tags, one-line lessons, severity, affected
24
+ surfaces, and links to deeper incident files.
25
+ - Principle layer: `principles.md` gives reusable rules such as model failure
26
+ modes, domain-specific judgment traps, and required countermeasures.
27
+ - Incident layer: `incidents/*.md` gives the detailed facts, Git evidence,
28
+ timeline, root cause, detection gap, repair, follow-ups, and search terms.
29
+
30
+ Agents should start with keyword search over the default and principle layers, then
31
+ open incident files only when the tags or failure class match the current task.
32
+
33
+ ## Required Incident Evidence
34
+
35
+ Every incident file should include:
36
+
37
+ - Symptom and impact.
38
+ - Trigger and timeline.
39
+ - Confirmed root cause and rejected near-causes.
40
+ - Why the failure escaped planning, investigation, execution, review, or ship.
41
+ - Git evidence: branch, base, head SHA, PR if any, relevant commits, review range,
42
+ and dirty-tree notes when they matter.
43
+ - Verification evidence: commands, exit status, key output, and artifact paths.
44
+ - Follow-up actions: root-cause fixes, detection improvements, and backlog items.
45
+ - AI failure mode: model limitation, pattern-matching trap, missing evidence habit,
46
+ over-broad abstraction, fake compatibility, test-seam mistake, or other reusable
47
+ class.
48
+ - Search terms future agents should use before repeating similar work.
49
+
50
+ ## Redaction Guard
51
+
52
+ Postmortems are durable repo artifacts, so they must never preserve secrets,
53
+ tokens, private customer data, personal machine paths, or raw private logs unless
54
+ the repository already treats that exact artifact as public source truth.
55
+
56
+ - Record the command, file path, commit, or artifact pointer that proves the fact.
57
+ - Quote only the minimal output needed to prove the incident.
58
+ - Replace sensitive values with `<redacted>` and add a short redaction summary.
59
+ - If the only available proof is sensitive, cite the owner artifact and describe
60
+ the observed shape instead of copying the raw value.
61
+
62
+ ## Read Gates
63
+
64
+ `cc-plan`, `cc-investigate`, and `cc-do` must run a quick local search before they
65
+ freeze direction or touch code:
66
+
67
+ ```bash
68
+ rg -n "<capability|module|error|failure-class|model-risk>" devflow/postmortems
69
+ ```
70
+
71
+ If `devflow/postmortems/` does not exist, record `no-project-postmortems-yet`.
72
+ If a match exists, load only `INDEX.md`, `principles.md`, and the one or two
73
+ incident files most relevant to the current work.
74
+
75
+ ## State Ownership
76
+
77
+ Postmortems do not own task status, roadmap progress, review verdicts, or spec sync
78
+ state. They cite those stronger owners by path, commit, or command output.
@@ -120,7 +120,7 @@ describe('TDD Order Validation', () => {
120
120
  });
121
121
  });
122
122
 
123
- test('should write currentTaskId and activePhase into manifest', async () => {
123
+ test('should write currentTaskId while deriving activePhase from the task graph', async () => {
124
124
  const repoRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'cc-devflow-planner-'));
125
125
  const changeId = 'REQ-321';
126
126
  const tasksPath = path.join(repoRoot, 'devflow', 'changes', `${changeId}-change`, 'planning', 'tasks.md');
@@ -146,7 +146,7 @@ describe('TDD Order Validation', () => {
146
146
  overwrite: true
147
147
  });
148
148
 
149
- expect(manifest.activePhase).toBe(1);
149
+ expect(manifest.activePhase).toBeUndefined();
150
150
  expect(manifest.currentTaskId).toBe('T002');
151
151
  expect(manifest.tasks[1].reviews).toEqual({ spec: 'pending', code: 'pending' });
152
152
  });
@@ -8,7 +8,6 @@ describe('Manifest schema hard constraints', () => {
8
8
  createdAt: '2026-04-10T01:00:00.000Z',
9
9
  updatedAt: '2026-04-10T01:05:00.000Z',
10
10
  currentTaskId: 'T001',
11
- activePhase: 1,
12
11
  tasks: [
13
12
  {
14
13
  id: 'T001',
@@ -73,7 +72,39 @@ describe('Manifest schema hard constraints', () => {
73
72
  });
74
73
 
75
74
  expect(manifest.currentTaskId).toBe('T001');
76
- expect(manifest.activePhase).toBe(1);
75
+ expect(manifest.activePhase).toBeUndefined();
76
+ });
77
+
78
+ test('accepts legacy activePhase input without preserving the retired field', () => {
79
+ const manifest = parseManifest({
80
+ changeId: 'REQ-560',
81
+ goal: 'Validate legacy manifest compatibility',
82
+ createdAt: '2026-04-10T01:00:00.000Z',
83
+ updatedAt: '2026-04-10T01:05:00.000Z',
84
+ currentTaskId: 'T001',
85
+ activePhase: 1,
86
+ tasks: [
87
+ {
88
+ id: 'T001',
89
+ title: '[TEST] Counter behavior',
90
+ type: 'OTHER',
91
+ phase: 1,
92
+ dependsOn: [],
93
+ run: ['echo ok'],
94
+ status: 'pending',
95
+ attempts: 0,
96
+ maxRetries: 1
97
+ }
98
+ ],
99
+ metadata: {
100
+ source: 'default',
101
+ generatedBy: 'test',
102
+ planVersion: 1
103
+ }
104
+ });
105
+
106
+ expect(manifest.currentTaskId).toBe('T001');
107
+ expect(manifest.activePhase).toBeUndefined();
77
108
  });
78
109
 
79
110
  test('rejects invalid currentTaskId for tasks.md manifest', () => {
@@ -480,7 +480,7 @@ function deriveManifestExecutionState(tasks) {
480
480
  function applyManifestExecutionState(manifest, updatedAt = nowIso()) {
481
481
  const executionState = deriveManifestExecutionState(manifest.tasks || []);
482
482
  manifest.currentTaskId = executionState.currentTaskId;
483
- manifest.activePhase = executionState.activePhase;
483
+ delete manifest.activePhase;
484
484
  manifest.updatedAt = updatedAt;
485
485
  return manifest;
486
486
  }
@@ -504,7 +504,6 @@ async function createTaskManifest({ repoRoot, changeId, goal, overwrite = false
504
504
  createdAt: previous?.createdAt || nowIso(),
505
505
  updatedAt: nowIso(),
506
506
  currentTaskId: null,
507
- activePhase: null,
508
507
  tasks,
509
508
  metadata: {
510
509
  source: hasTasksFile ? 'tasks.md' : 'default',
@@ -81,7 +81,7 @@ async function getNextTask(repoRoot, changeId, options = {}) {
81
81
  const manifestPath = getTaskManifestPath(repoRoot, changeId, options);
82
82
  const manifest = await readQueryArtifact(manifestPath);
83
83
  const executionState = deriveManifestExecutionState(manifest.tasks || []);
84
- const activePhase = manifest.activePhase ?? executionState.activePhase;
84
+ const activePhase = executionState.activePhase;
85
85
  const completedIds = new Set(
86
86
  (manifest.tasks || [])
87
87
  .filter((task) => isTaskCompletedStatus(task.status))
@@ -107,7 +107,7 @@ const ManifestSchema = z.object({
107
107
  createdAt: z.string().datetime(),
108
108
  updatedAt: z.string().datetime(),
109
109
  currentTaskId: z.string().regex(TASK_ID_PATTERN).nullable().default(null),
110
- activePhase: z.number().int().min(1).nullable().default(null),
110
+ activePhase: z.number().int().min(1).nullable().optional(),
111
111
  tasks: z.array(TaskSchema),
112
112
  metadata: z.object({
113
113
  source: z.enum(['tasks.md', 'default']).default('default'),
@@ -161,7 +161,7 @@ const ManifestSchema = z.object({
161
161
  ? Math.min(...unfinished.map((task) => task.phase || 1))
162
162
  : null;
163
163
 
164
- if (manifest.activePhase !== null && manifest.activePhase !== derivedActivePhase) {
164
+ if (manifest.activePhase !== undefined && manifest.activePhase !== null && manifest.activePhase !== derivedActivePhase) {
165
165
  ctx.addIssue({
166
166
  code: z.ZodIssueCode.custom,
167
167
  path: ['activePhase'],
@@ -542,7 +542,9 @@ function parseWithSchema(schema, input, label) {
542
542
  }
543
543
 
544
544
  function parseManifest(input) {
545
- return parseWithSchema(ManifestSchema, input, 'Manifest');
545
+ const manifest = parseWithSchema(ManifestSchema, input, 'Manifest');
546
+ delete manifest.activePhase;
547
+ return manifest;
546
548
  }
547
549
 
548
550
  function parseCheckpoint(input) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-devflow",
3
- "version": "4.5.8",
3
+ "version": "4.5.9",
4
4
  "description": "Multi-platform CLI and skill pack for agent coding",
5
5
  "main": "bin/cc-devflow.js",
6
6
  "bin": {