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.
- package/.claude/skills/cc-act/CHANGELOG.md +27 -0
- package/.claude/skills/cc-act/PLAYBOOK.md +9 -4
- package/.claude/skills/cc-act/SKILL.md +62 -3
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_INDEX_TEMPLATE.md +30 -0
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_PRINCIPLES_TEMPLATE.md +29 -0
- package/.claude/skills/cc-act/assets/PROJECT_POSTMORTEM_TEMPLATE.md +103 -0
- package/.claude/skills/cc-act/assets/PR_BRIEF_TEMPLATE.md +60 -4
- package/.claude/skills/cc-act/references/closure-contract.md +3 -0
- package/.claude/skills/cc-act/references/git-commit-guidelines.md +342 -37
- package/.claude/skills/cc-act/scripts/cc-act-common.sh +29 -1
- package/.claude/skills/cc-act/scripts/render-pr-brief.sh +164 -0
- package/.claude/skills/cc-act/scripts/sync-act-docs.sh +1 -1
- package/.claude/skills/cc-do/CHANGELOG.md +11 -0
- package/.claude/skills/cc-do/SKILL.md +19 -13
- package/.claude/skills/cc-do/scripts/build-task-context.sh +9 -5
- package/.claude/skills/cc-do/scripts/mark-task-complete.sh +0 -6
- package/.claude/skills/cc-investigate/CHANGELOG.md +17 -0
- package/.claude/skills/cc-investigate/PLAYBOOK.md +15 -0
- package/.claude/skills/cc-investigate/SKILL.md +46 -1
- package/.claude/skills/cc-investigate/assets/ANALYSIS_TEMPLATE.md +47 -0
- package/.claude/skills/cc-investigate/assets/TASKS_TEMPLATE.md +21 -2
- package/.claude/skills/cc-investigate/assets/TASK_MANIFEST_TEMPLATE.json +28 -58
- package/.claude/skills/cc-investigate/references/investigation-contract.md +14 -0
- package/.claude/skills/cc-next/CHANGELOG.md +6 -0
- package/.claude/skills/cc-next/PLAYBOOK.md +26 -4
- package/.claude/skills/cc-next/SKILL.md +39 -4
- package/.claude/skills/cc-plan/CHANGELOG.md +19 -0
- package/.claude/skills/cc-plan/PLAYBOOK.md +25 -20
- package/.claude/skills/cc-plan/SKILL.md +83 -22
- package/.claude/skills/cc-plan/assets/DESIGN_TEMPLATE.md +67 -0
- package/.claude/skills/cc-plan/assets/TASKS_TEMPLATE.md +59 -0
- package/.claude/skills/cc-plan/assets/TASK_MANIFEST_TEMPLATE.json +55 -228
- package/.claude/skills/cc-plan/assets/TINY_DESIGN_TEMPLATE.md +46 -0
- package/.claude/skills/cc-plan/references/planning-contract.md +41 -27
- package/.claude/skills/cc-roadmap/CHANGELOG.md +6 -0
- package/.claude/skills/cc-roadmap/PLAYBOOK.md +30 -0
- package/.claude/skills/cc-roadmap/SKILL.md +45 -8
- package/.claude/skills/cc-roadmap/assets/BACKLOG_TEMPLATE.md +8 -0
- package/.claude/skills/cc-roadmap/assets/ROADMAP_TEMPLATE.md +22 -0
- package/.claude/skills/cc-roadmap/assets/TRACKING_TEMPLATE.json +32 -1
- package/.claude/skills/cc-roadmap/references/roadmap-dialogue.md +14 -14
- package/CHANGELOG.md +12 -0
- package/README.md +37 -35
- package/README.zh-CN.md +37 -35
- package/docs/examples/example-bindings.json +7 -7
- package/docs/examples/full-design-blocked/BACKLOG.md +1 -1
- package/docs/examples/full-design-blocked/README.md +1 -1
- package/docs/examples/full-design-blocked/ROADMAP.md +1 -1
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/design.md +1 -1
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/task-manifest.json +27 -311
- package/docs/examples/full-design-blocked/changes/REQ-002-bulk-invite-import/planning/tasks.md +1 -1
- package/docs/examples/full-design-blocked/roadmap.json +1 -1
- package/docs/examples/local-handoff/BACKLOG.md +1 -1
- package/docs/examples/local-handoff/README.md +1 -1
- package/docs/examples/local-handoff/ROADMAP.md +1 -1
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/design.md +1 -1
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/task-manifest.json +25 -209
- package/docs/examples/local-handoff/changes/REQ-003-audit-log-export/planning/tasks.md +1 -1
- package/docs/examples/local-handoff/roadmap.json +1 -1
- package/docs/examples/pdca-loop/BACKLOG.md +1 -1
- package/docs/examples/pdca-loop/README.md +1 -1
- package/docs/examples/pdca-loop/ROADMAP.md +1 -1
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/handoff/pr-brief.md +64 -0
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/design.md +1 -1
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json +25 -228
- package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/tasks.md +1 -1
- package/docs/examples/pdca-loop/roadmap.json +1 -1
- package/docs/examples/scripts/check-example-bindings.sh +9 -5
- package/docs/get-shit-done-strategy-audit.md +4 -4
- package/docs/guides/artifact-contract.md +44 -0
- package/docs/guides/project-postmortem.md +78 -0
- package/lib/skill-runtime/__tests__/planner.tdd.test.js +2 -2
- package/lib/skill-runtime/__tests__/schemas.test.js +33 -2
- package/lib/skill-runtime/planner.js +1 -2
- package/lib/skill-runtime/query.js +1 -1
- package/lib/skill-runtime/schemas.js +5 -3
- package/package.json +1 -1
package/docs/examples/pdca-loop/changes/REQ-001-copy-invite-link/planning/task-manifest.json
CHANGED
|
@@ -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.
|
|
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
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
|
|
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
|
}
|
|
@@ -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
|
-
.
|
|
106
|
-
.
|
|
107
|
-
(.
|
|
108
|
-
|
|
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 | `
|
|
131
|
-
| External doc conflict buckets | `
|
|
132
|
-
| Trust boundary | `
|
|
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` | `
|
|
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
|
|
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).
|
|
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).
|
|
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
|
|
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 =
|
|
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().
|
|
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
|
-
|
|
545
|
+
const manifest = parseWithSchema(ManifestSchema, input, 'Manifest');
|
|
546
|
+
delete manifest.activePhase;
|
|
547
|
+
return manifest;
|
|
546
548
|
}
|
|
547
549
|
|
|
548
550
|
function parseCheckpoint(input) {
|