@haposoft/cafekit 0.8.10 → 0.8.11
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/README.md +2 -1
- package/bin/install.js +4 -3
- package/package.json +1 -1
- package/src/claude/gitignore +3 -1
- package/src/claude/migration-manifest.json +1 -0
- package/src/claude/scripts/validate-spec-output.cjs +35 -5
- package/src/claude/skills/specs/SKILL.md +11 -7
- package/src/claude/skills/specs/references/review.md +3 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Claude Code-first spec-driven workflow and runtime bundle for AI coding assistants.
|
|
4
4
|
|
|
5
|
-
[](https://github.com/haposoft/cafekit)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](https://claude.ai/code)
|
|
8
8
|
|
|
@@ -46,6 +46,7 @@ Claude Code install targets:
|
|
|
46
46
|
|
|
47
47
|
```text
|
|
48
48
|
.claude/
|
|
49
|
+
├── .gitignore
|
|
49
50
|
├── skills/
|
|
50
51
|
├── agents/
|
|
51
52
|
├── hooks/
|
package/bin/install.js
CHANGED
|
@@ -751,7 +751,8 @@ function copyClaudeRuntimeFiles(platformKey, results, options = {}) {
|
|
|
751
751
|
|
|
752
752
|
manifest.runtime.files.forEach(relPath => {
|
|
753
753
|
const srcPath = path.join(srcBase, relPath);
|
|
754
|
-
const
|
|
754
|
+
const targetRelPath = relPath === 'gitignore' ? '.gitignore' : relPath;
|
|
755
|
+
const targetPath = path.join(targetBase, targetRelPath);
|
|
755
756
|
|
|
756
757
|
if (!fs.existsSync(srcPath)) {
|
|
757
758
|
console.log(` ⚠ Runtime file not found: ${relPath}`);
|
|
@@ -767,10 +768,10 @@ function copyClaudeRuntimeFiles(platformKey, results, options = {}) {
|
|
|
767
768
|
fs.copyFileSync(srcPath, targetPath);
|
|
768
769
|
|
|
769
770
|
if (targetExists) {
|
|
770
|
-
console.log(` ↻ Runtime updated: ${
|
|
771
|
+
console.log(` ↻ Runtime updated: ${targetRelPath}`);
|
|
771
772
|
results.updated++;
|
|
772
773
|
} else {
|
|
773
|
-
console.log(` ✓ Runtime installed: ${
|
|
774
|
+
console.log(` ✓ Runtime installed: ${targetRelPath}`);
|
|
774
775
|
results.copied++;
|
|
775
776
|
}
|
|
776
777
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haposoft/cafekit",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.11",
|
|
4
4
|
"description": "Claude Code-first spec-driven workflow for AI coding assistants. Bundles CafeKit hapo: skills, runtime hooks, agents, and installer scaffolding.",
|
|
5
5
|
"author": "Haposoft <nghialt@haposoft.com>",
|
|
6
6
|
"license": "MIT",
|
package/src/claude/gitignore
CHANGED
|
@@ -86,23 +86,31 @@ function extractRequirementIds(requirementsText) {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
function validateTaskSections(taskPath, content, errors) {
|
|
89
|
-
const hasContext =
|
|
90
|
-
|
|
91
|
-
hasHeading(content, 'Objective') ||
|
|
92
|
-
hasHeading(content, 'Goal');
|
|
89
|
+
const hasContext = hasHeading(content, 'Context');
|
|
90
|
+
const hasConstraints = hasHeading(content, 'Constraints');
|
|
93
91
|
const hasSteps =
|
|
94
92
|
hasHeading(content, 'Steps') || hasHeading(content, 'Implementation Steps');
|
|
95
93
|
const hasRequirements =
|
|
96
94
|
hasHeading(content, 'Requirements') || /_Requirements:\s*[^_\n]+_/i.test(content);
|
|
95
|
+
const hasRelatedFiles = hasHeading(content, 'Related Files');
|
|
96
|
+
const hasCompletionCriteria = hasHeading(content, 'Completion Criteria');
|
|
97
97
|
const hasEvidence =
|
|
98
98
|
hasHeading(content, 'Evidence') ||
|
|
99
99
|
hasHeading(content, 'Task Test Plan & Verification Evidence') ||
|
|
100
100
|
hasHeading(content, 'Verification & Evidence');
|
|
101
|
+
const hasRiskAssessment = hasHeading(content, 'Risk Assessment');
|
|
101
102
|
|
|
102
|
-
if (!hasContext) errors.push(`${taskPath}: missing Context
|
|
103
|
+
if (!hasContext) errors.push(`${taskPath}: missing Context`);
|
|
104
|
+
if (!hasConstraints) errors.push(`${taskPath}: missing Constraints`);
|
|
103
105
|
if (!hasSteps) errors.push(`${taskPath}: missing Steps/Implementation Steps`);
|
|
104
106
|
if (!hasRequirements) errors.push(`${taskPath}: missing Requirements mapping`);
|
|
107
|
+
if (!hasRelatedFiles) errors.push(`${taskPath}: missing Related Files`);
|
|
108
|
+
if (!hasCompletionCriteria) errors.push(`${taskPath}: missing Completion Criteria`);
|
|
105
109
|
if (!hasEvidence) errors.push(`${taskPath}: missing Evidence or task test plan`);
|
|
110
|
+
if (!hasRiskAssessment) errors.push(`${taskPath}: missing Risk Assessment`);
|
|
111
|
+
if (hasEvidence && !/Runtime reachability verification/i.test(content)) {
|
|
112
|
+
errors.push(`${taskPath}: missing Runtime reachability verification`);
|
|
113
|
+
}
|
|
106
114
|
}
|
|
107
115
|
|
|
108
116
|
function validateSpec(specDir) {
|
|
@@ -187,6 +195,28 @@ function validateSpec(specDir) {
|
|
|
187
195
|
errors.push('tasks/: feature work cannot be entirely R0; reserve R0 for shared foundation tasks');
|
|
188
196
|
}
|
|
189
197
|
|
|
198
|
+
const validationRecommended = spec.design_context?.validation_recommended === true;
|
|
199
|
+
if (taskFiles.length >= 5 && !validationRecommended) {
|
|
200
|
+
errors.push('spec.json.design_context.validation_recommended: must be true for specs with 5+ task files');
|
|
201
|
+
}
|
|
202
|
+
if (
|
|
203
|
+
(validationRecommended || taskFiles.length >= 5) &&
|
|
204
|
+
spec.ready_for_implementation === true &&
|
|
205
|
+
spec.validation?.status !== 'completed'
|
|
206
|
+
) {
|
|
207
|
+
errors.push(
|
|
208
|
+
'spec.json.ready_for_implementation: cannot be true when validation is recommended but validation.status is not completed',
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
if (spec.validation?.status === 'completed') {
|
|
212
|
+
if (!spec.timestamps?.validation_done) {
|
|
213
|
+
errors.push('spec.json.timestamps.validation_done: required when validation.status is completed');
|
|
214
|
+
}
|
|
215
|
+
if (taskFiles.length >= 5 && !spec.timestamps?.review_done) {
|
|
216
|
+
errors.push('spec.json.timestamps.review_done: required for 5+ task specs after validation');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
190
220
|
const requirementsPath = path.join(specDir, 'requirements.md');
|
|
191
221
|
const designPath = path.join(specDir, 'design.md');
|
|
192
222
|
const researchPath = path.join(specDir, 'research.md');
|
|
@@ -322,12 +322,15 @@ Each task file MUST be **self-contained and implementation-ready** — detailed
|
|
|
322
322
|
|
|
323
323
|
**Structure per task file:**
|
|
324
324
|
1. **Context** — why this task exists, current state, target outcome, relevant exact files.
|
|
325
|
-
2. **
|
|
326
|
-
3. **
|
|
327
|
-
4. **
|
|
328
|
-
5. **
|
|
329
|
-
6. **
|
|
330
|
-
7. **
|
|
325
|
+
2. **Constraints** — MUST / SHOULD / MUST NOT / SCOPE guardrails.
|
|
326
|
+
3. **Steps** — concise implementation checklist with business intent and code-level detail.
|
|
327
|
+
4. **Requirements** — list requirement IDs and acceptance criteria covered by this task.
|
|
328
|
+
5. **Related Files** — table with exact paths, action type, and descriptions when paths are known; otherwise run scout first.
|
|
329
|
+
6. **Completion Criteria** — observable, testable criteria.
|
|
330
|
+
7. **Evidence** — automated command(s), artifact/runtime proof, negative-path proof, and runtime reachability proof.
|
|
331
|
+
8. **Risk Assessment** — table with risk, severity, mitigation.
|
|
332
|
+
|
|
333
|
+
**Template fidelity is mandatory:** preserve the task template headings exactly. Do NOT rename `## Context` to `## Objective`, do NOT replace `## Completion Criteria` with prose, do NOT remove `## Related Files`, `## Constraints`, or `## Risk Assessment`, and do NOT collapse `## Evidence` into generic QA scenarios. Compact wording is fine; missing sections are invalid.
|
|
331
334
|
|
|
332
335
|
**Parallel markers:** Append `(P)` to tasks that can run concurrently (no data dependency, no shared files, no prerequisite approval from another task). Tasks serving DIFFERENT requirements are often parallelizable.
|
|
333
336
|
|
|
@@ -368,6 +371,7 @@ Load: `references/review.md` + `rules/design-review.md`
|
|
|
368
371
|
- FAIL if a task creates runtime-facing artifacts but neither proves reachability from an entrypoint/caller nor names a later integration task responsible for wiring them.
|
|
369
372
|
- FAIL if a UI/app/runtime spec has multiple user-facing task outputs but no final integration/reachability task or final integration section.
|
|
370
373
|
- FAIL if accepted validation decisions exist in reports but are not reflected in the implementation-facing sections of affected artifacts (`Context`, `Steps`, `Requirements`, `Completion Criteria`, `Evidence`, canonical contracts, or requirements text).
|
|
374
|
+
- FAIL if any generated task replaces the required task template with a reduced `Objective` / `Steps` / `Evidence` shape. `Context`, `Constraints`, `Related Files`, `Completion Criteria`, `Evidence`, and `Risk Assessment` must all remain present.
|
|
371
375
|
- FAIL if the spec scope/provider was switched away from Anthropic/Claude but `requirements.md`, `design.md`, or `tasks/*.md` still contain stale provider-specific strings such as `Claude API`, `Haiku`, or `haiku_reachable`. `research.md` is the only allowed place for historical cost comparisons.
|
|
372
376
|
- FAIL if privacy/delete-data work lacks a single canonical deletion policy. The design MUST explicitly choose either:
|
|
373
377
|
1. hard-delete with no re-registration lock, or
|
|
@@ -439,7 +443,7 @@ Task paths that omit the `task-` prefix or use non-padded sequence numbers (for
|
|
|
439
443
|
6. `task_registry` matches the real filesystem and does not omit any task file
|
|
440
444
|
7. If `design_context.validation_recommended = true`, `validation.status = "completed"` (or another explicit user-accepted risk state that is recorded)
|
|
441
445
|
|
|
442
|
-
If any approval is `false`, `ready_for_implementation` MUST remain `false`.
|
|
446
|
+
If any approval is `false`, `ready_for_implementation` MUST remain `false`. If the spec has 5+ task files, `ready_for_implementation` MUST remain `false` until `/hapo:specs <feature> --validate` completes Red Team + Validate and writes `validation.status = "completed"`.
|
|
443
447
|
|
|
444
448
|
## Output Structure
|
|
445
449
|
|
|
@@ -27,6 +27,7 @@ Required behavior:
|
|
|
27
27
|
4. The final report MUST include the validator command and the final PASS/FAIL result.
|
|
28
28
|
5. If the validator exits non-zero, final verdict is **FAIL / BLOCKED**, `validation.status` MUST NOT become `completed`, `ready_for_implementation` MUST remain `false`, and the output MUST NOT suggest `/hapo:develop`.
|
|
29
29
|
6. A markdown checklist, manual QA table, or "all required sections present" claim cannot override validator failure.
|
|
30
|
+
7. For specs with 5+ task files, a pre-review validator PASS only proves artifact shape. It does not mean implementation can start until Red Team + Validate finish, accepted fixes are propagated, and `spec.json.validation.status` is written as `completed`.
|
|
30
31
|
|
|
31
32
|
## Auto-Decision: When to Red Team vs Validate
|
|
32
33
|
|
|
@@ -261,6 +262,8 @@ Before declaring validation complete:
|
|
|
261
262
|
|
|
262
263
|
#### Step 8: Final Status Write-Back
|
|
263
264
|
- Update `spec.json.updated_at` to the reconciliation time
|
|
265
|
+
- On final PASS, set `spec.json.validation.status = "completed"`, `spec.json.timestamps.validation_done`, and, when Red Team ran, `spec.json.timestamps.review_done`
|
|
266
|
+
- On final PASS, set `spec.json.ready_for_implementation = true` only after the deterministic validator passes on the final physical artifacts
|
|
264
267
|
- Ensure `red-team-report.md` and `validate-log.md` do not contradict `spec.json`
|
|
265
268
|
- If reconciliation or deterministic validation fails, keep `validation.status` as `not-run` or `in_progress`, keep `ready_for_implementation = false`, list blockers explicitly, and do not provide an implementation handoff.
|
|
266
269
|
|