@haposoft/cafekit 0.8.9 → 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 +10 -1
- package/bin/install.js +57 -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 +36 -6
- package/src/claude/skills/specs/SKILL.md +13 -7
- package/src/claude/skills/specs/references/review.md +28 -3
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,9 +46,11 @@ Claude Code install targets:
|
|
|
46
46
|
|
|
47
47
|
```text
|
|
48
48
|
.claude/
|
|
49
|
+
├── .gitignore
|
|
49
50
|
├── skills/
|
|
50
51
|
├── agents/
|
|
51
52
|
├── hooks/
|
|
53
|
+
├── cafekit.json
|
|
52
54
|
├── status.cjs
|
|
53
55
|
├── runtime.json
|
|
54
56
|
├── settings.json
|
|
@@ -61,6 +63,13 @@ Managed runtime features include:
|
|
|
61
63
|
- rule/context injection
|
|
62
64
|
- spec state awareness
|
|
63
65
|
- safe settings merge on reinstall
|
|
66
|
+
- installed CafeKit version tracking in `.claude/cafekit.json`
|
|
67
|
+
|
|
68
|
+
To check the installed CafeKit package version:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
cat .claude/cafekit.json
|
|
72
|
+
```
|
|
64
73
|
|
|
65
74
|
## Core Skills
|
|
66
75
|
|
package/bin/install.js
CHANGED
|
@@ -20,6 +20,7 @@ const os = require('os');
|
|
|
20
20
|
const readline = require('readline');
|
|
21
21
|
const { execSync } = require('child_process');
|
|
22
22
|
const packageJson = require('../package.json');
|
|
23
|
+
const INSTALL_COMMAND = `npx ${packageJson.name}@${packageJson.version}`;
|
|
23
24
|
|
|
24
25
|
function validateManifestV2(manifest) {
|
|
25
26
|
if (!manifest || manifest.version !== 2) return false;
|
|
@@ -339,6 +340,55 @@ function ensureWorkflowDependencies(platformKey, platform, results, options = {}
|
|
|
339
340
|
});
|
|
340
341
|
}
|
|
341
342
|
|
|
343
|
+
function readJsonFile(filePath) {
|
|
344
|
+
if (!fs.existsSync(filePath)) {
|
|
345
|
+
return {};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
try {
|
|
349
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
350
|
+
} catch {
|
|
351
|
+
return {};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function writePlatformVersionMetadata(platformKey, results) {
|
|
356
|
+
const platform = PLATFORMS[platformKey];
|
|
357
|
+
const targetPath = path.join(platform.folder, 'cafekit.json');
|
|
358
|
+
const targetExists = fs.existsSync(targetPath);
|
|
359
|
+
const existingMetadata = readJsonFile(targetPath);
|
|
360
|
+
const now = new Date().toISOString();
|
|
361
|
+
const previousVersion = typeof existingMetadata.version === 'string'
|
|
362
|
+
? existingMetadata.version
|
|
363
|
+
: null;
|
|
364
|
+
|
|
365
|
+
const metadata = {
|
|
366
|
+
schemaVersion: 1,
|
|
367
|
+
packageName: packageJson.name,
|
|
368
|
+
version: packageJson.version,
|
|
369
|
+
platform: platform.id,
|
|
370
|
+
platformName: platform.name,
|
|
371
|
+
installedAt: existingMetadata.installedAt || now,
|
|
372
|
+
lastInstalledAt: now,
|
|
373
|
+
installCommand: INSTALL_COMMAND
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
if (previousVersion && previousVersion !== packageJson.version) {
|
|
377
|
+
metadata.previousVersion = previousVersion;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
381
|
+
fs.writeFileSync(targetPath, `${JSON.stringify(metadata, null, 2)}\n`, 'utf8');
|
|
382
|
+
|
|
383
|
+
if (targetExists) {
|
|
384
|
+
console.log(` ↻ Version metadata updated: ${targetPath}`);
|
|
385
|
+
results.updated++;
|
|
386
|
+
} else {
|
|
387
|
+
console.log(` ✓ Version metadata installed: ${targetPath}`);
|
|
388
|
+
results.copied++;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
342
392
|
function getPlatformSpecFiles(platformKey) {
|
|
343
393
|
if (platformKey === 'claude') {
|
|
344
394
|
const manifestCommands = CLAUDE_MIGRATION_MANIFEST?.commands?.core;
|
|
@@ -701,7 +751,8 @@ function copyClaudeRuntimeFiles(platformKey, results, options = {}) {
|
|
|
701
751
|
|
|
702
752
|
manifest.runtime.files.forEach(relPath => {
|
|
703
753
|
const srcPath = path.join(srcBase, relPath);
|
|
704
|
-
const
|
|
754
|
+
const targetRelPath = relPath === 'gitignore' ? '.gitignore' : relPath;
|
|
755
|
+
const targetPath = path.join(targetBase, targetRelPath);
|
|
705
756
|
|
|
706
757
|
if (!fs.existsSync(srcPath)) {
|
|
707
758
|
console.log(` ⚠ Runtime file not found: ${relPath}`);
|
|
@@ -717,10 +768,10 @@ function copyClaudeRuntimeFiles(platformKey, results, options = {}) {
|
|
|
717
768
|
fs.copyFileSync(srcPath, targetPath);
|
|
718
769
|
|
|
719
770
|
if (targetExists) {
|
|
720
|
-
console.log(` ↻ Runtime updated: ${
|
|
771
|
+
console.log(` ↻ Runtime updated: ${targetRelPath}`);
|
|
721
772
|
results.updated++;
|
|
722
773
|
} else {
|
|
723
|
-
console.log(` ✓ Runtime installed: ${
|
|
774
|
+
console.log(` ✓ Runtime installed: ${targetRelPath}`);
|
|
724
775
|
results.copied++;
|
|
725
776
|
}
|
|
726
777
|
} else {
|
|
@@ -1065,6 +1116,8 @@ async function main() {
|
|
|
1065
1116
|
copyGeminiFile(platformKey, results, installerOptions);
|
|
1066
1117
|
}
|
|
1067
1118
|
|
|
1119
|
+
writePlatformVersionMetadata(platformKey, results);
|
|
1120
|
+
|
|
1068
1121
|
results.targets.push(platform.commandsDir);
|
|
1069
1122
|
console.log();
|
|
1070
1123
|
}
|
|
@@ -1085,6 +1138,7 @@ async function main() {
|
|
|
1085
1138
|
console.log();
|
|
1086
1139
|
console.log(` Copied Files: ${results.copied}`);
|
|
1087
1140
|
console.log(` Updated Files: ${results.updated}`);
|
|
1141
|
+
console.log(` CafeKit Version: ${packageJson.version}`);
|
|
1088
1142
|
console.log(` Skipped Files: ${results.skipped}`);
|
|
1089
1143
|
console.log(` Installed Skills: ${results.installedSkills > 0 ? 'Yes ✓' : 'No'}`);
|
|
1090
1144
|
console.log(` Dependency Checks: ${results.dependencyChecks}`);
|
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
|
-
hasHeading(content, 'Requirements') ||
|
|
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');
|
|
@@ -137,6 +137,7 @@ The system MUST NOT execute Steps 1-8. Instead, load `references/review.md` and
|
|
|
137
137
|
5. **MUST NOT create implementation code files** (`.ts`, `.js`, `.py`, etc.). The validate workflow produces ONLY markdown spec documents and reports. If a fix requires a new shared module, describe it in the relevant task file instead of creating the actual code file.
|
|
138
138
|
6. **MUST NOT over-engineer fixes.** Apply YAGNI — if user says "configure later", add an abstraction note to the task, do NOT generate 4 concrete provider implementations.
|
|
139
139
|
7. **MUST follow auto-decision table exactly.** Count task files + scan for keywords → pick mode. No self-justification to override the table result.
|
|
140
|
+
8. **MUST run deterministic validator.** Before reporting validation PASS, run `node .claude/scripts/validate-spec-output.cjs specs/<feature>`. If it exits non-zero, validation is FAIL/BLOCKED, `ready_for_implementation` remains `false`, and output MUST NOT suggest `/hapo:develop`.
|
|
140
141
|
|
|
141
142
|
## Workflow Diagram
|
|
142
143
|
|
|
@@ -321,12 +322,15 @@ Each task file MUST be **self-contained and implementation-ready** — detailed
|
|
|
321
322
|
|
|
322
323
|
**Structure per task file:**
|
|
323
324
|
1. **Context** — why this task exists, current state, target outcome, relevant exact files.
|
|
324
|
-
2. **
|
|
325
|
-
3. **
|
|
326
|
-
4. **
|
|
327
|
-
5. **
|
|
328
|
-
6. **
|
|
329
|
-
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.
|
|
330
334
|
|
|
331
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.
|
|
332
336
|
|
|
@@ -350,6 +354,7 @@ Load: `references/review.md` + `rules/design-review.md`
|
|
|
350
354
|
- **PROHIBITION:** The system MUST NOT skip Red Team because of a prior code-auditor review. Code review ≠ Spec review.
|
|
351
355
|
- **PROHIBITION:** The system MUST NOT create `.ts`, `.js`, `.py` or any implementation files during validation. Spec-only outputs.
|
|
352
356
|
- **Reconciliation Rule:** `validation.status = "completed"` is forbidden until all accepted findings and validation decisions are physically propagated into `requirements.md`, `design.md`, `tasks/*.md`, and `spec.json` where applicable.
|
|
357
|
+
- **Deterministic Gate:** Run `node .claude/scripts/validate-spec-output.cjs specs/<feature>` after all fixes and before final output. Script failure overrides any LLM checklist result and blocks `ready_for_implementation = true`.
|
|
353
358
|
|
|
354
359
|
### Step 9.5: Finalization Audit (MANDATORY)
|
|
355
360
|
- Re-scan the `tasks/` directory and rebuild `spec.json.task_files` from the real filesystem (sorted, relative paths)
|
|
@@ -366,6 +371,7 @@ Load: `references/review.md` + `rules/design-review.md`
|
|
|
366
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.
|
|
367
372
|
- FAIL if a UI/app/runtime spec has multiple user-facing task outputs but no final integration/reachability task or final integration section.
|
|
368
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.
|
|
369
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.
|
|
370
376
|
- FAIL if privacy/delete-data work lacks a single canonical deletion policy. The design MUST explicitly choose either:
|
|
371
377
|
1. hard-delete with no re-registration lock, or
|
|
@@ -437,7 +443,7 @@ Task paths that omit the `task-` prefix or use non-padded sequence numbers (for
|
|
|
437
443
|
6. `task_registry` matches the real filesystem and does not omit any task file
|
|
438
444
|
7. If `design_context.validation_recommended = true`, `validation.status = "completed"` (or another explicit user-accepted risk state that is recorded)
|
|
439
445
|
|
|
440
|
-
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"`.
|
|
441
447
|
|
|
442
448
|
## Output Structure
|
|
443
449
|
|
|
@@ -10,6 +10,25 @@ Review a spec before implementation. The system auto-decides the review depth ba
|
|
|
10
10
|
2. If not → check active spec (spec with `in_progress` status; accept legacy `in-progress` when reading existing files)
|
|
11
11
|
3. If nothing found → ask user to specify path
|
|
12
12
|
|
|
13
|
+
## Deterministic Validator Gate (MANDATORY)
|
|
14
|
+
|
|
15
|
+
This gate is the hard source of truth for `hapo:specs --validate`. LLM red-team tables and markdown validation reports are advisory until this script passes.
|
|
16
|
+
|
|
17
|
+
After resolving the spec path, run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
node .claude/scripts/validate-spec-output.cjs specs/<feature>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Required behavior:
|
|
24
|
+
1. Run the validator once before the final PASS decision. If it fails, copy the exact failing categories into the validation findings/blockers and fix the physical spec artifacts.
|
|
25
|
+
2. Red Team and Validate may continue while fixing issues, but they cannot approve the spec while validator errors remain.
|
|
26
|
+
3. Run the validator again after every accepted Red Team / Validate fix set and before any final verdict.
|
|
27
|
+
4. The final report MUST include the validator command and the final PASS/FAIL result.
|
|
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
|
+
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`.
|
|
31
|
+
|
|
13
32
|
## Auto-Decision: When to Red Team vs Validate
|
|
14
33
|
|
|
15
34
|
The system evaluates the spec and picks the appropriate review mode:
|
|
@@ -45,6 +64,7 @@ These rules override any self-reasoning or optimization the system may attempt:
|
|
|
45
64
|
7. **Implementation-facing propagation is mandatory.** A decision that affects implementation is NOT considered applied if it only appears in `Risk Assessment`, `validate-log.md`, or `red-team-report.md`. It must update at least one of: `requirements.md`, `Canonical Contracts & Invariants`, `Context`, `Steps`, `Requirements`, `Completion Criteria`, or `Evidence`.
|
|
46
65
|
8. **CafeKit command dialect only.** Validation output MUST use `/hapo:develop <feature>` as the implementation handoff. Never mention `/sdd:execute-spec`, `/sdd:*`, `/work`, `/code`, `/specs <feature> --approve`, `/hapo:specs <feature> --approve`, or non-CafeKit aliases.
|
|
47
66
|
9. **CafeKit task filename convention only.** Task files MUST use `tasks/task-R{N}-{SEQ}-<slug>.md` with two-digit `SEQ` (for example `tasks/task-R0-01-project-scaffolding.md`). Files like `tasks/R0-1-project-scaffolding.md` are legacy/foreign format; rename them and update `spec.json.task_files`, `spec.json.task_registry`, and dependency references before passing validation.
|
|
67
|
+
10. **Deterministic validator is mandatory.** The final validation verdict MUST be derived from `node .claude/scripts/validate-spec-output.cjs specs/<feature>`. If that command fails, report FAIL/BLOCKED and list the script output. Do NOT report PASS.
|
|
48
68
|
|
|
49
69
|
---
|
|
50
70
|
|
|
@@ -226,13 +246,15 @@ Save to `reports/validate-log.md`:
|
|
|
226
246
|
Before declaring validation complete:
|
|
227
247
|
1. Re-read `spec.json`, `requirements.md`, `design.md`, and all `tasks/task-*.md`
|
|
228
248
|
2. Verify every accepted red-team finding and every validation action item is reflected in the correct physical file(s)
|
|
229
|
-
3.
|
|
249
|
+
3. Run `node .claude/scripts/validate-spec-output.cjs specs/<feature>` and keep the raw result visible
|
|
250
|
+
4. Fail the audit if:
|
|
230
251
|
- a report says "applied" but the file still contains the old text
|
|
231
252
|
- stale provider strings remain after a provider change
|
|
232
253
|
- delete-data/privacy artifacts mix multiple canonical policies
|
|
233
254
|
- any task path fails the CafeKit `tasks/task-R{N}-{SEQ}-<slug>.md` naming convention
|
|
234
255
|
- `spec.json.updated_at`, `timestamps.review_done`, or `timestamps.validation_done` do not reflect the final reviewed state
|
|
235
|
-
|
|
256
|
+
- deterministic validator exits non-zero
|
|
257
|
+
5. Only after the audit passes may you:
|
|
236
258
|
- set `spec.json.validation.status = "completed"`
|
|
237
259
|
- set `spec.json.timestamps.validation_done`
|
|
238
260
|
- set `spec.json.timestamps.review_done`
|
|
@@ -240,8 +262,10 @@ Before declaring validation complete:
|
|
|
240
262
|
|
|
241
263
|
#### Step 8: Final Status Write-Back
|
|
242
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
|
|
243
267
|
- Ensure `red-team-report.md` and `validate-log.md` do not contradict `spec.json`
|
|
244
|
-
- If reconciliation fails, keep `validation.status` as `not-run` or `in_progress`
|
|
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.
|
|
245
269
|
|
|
246
270
|
---
|
|
247
271
|
|
|
@@ -256,6 +280,7 @@ Red Team: {N} findings ({A} accepted, {R} rejected)
|
|
|
256
280
|
Validate: {Q} questions asked, {D} decisions confirmed
|
|
257
281
|
|
|
258
282
|
Files modified: {list}
|
|
283
|
+
Deterministic validator: PASS via `node .claude/scripts/validate-spec-output.cjs specs/<feature>`
|
|
259
284
|
|
|
260
285
|
📌 Next step: /hapo:develop <feature> (ONLY if reconciliation audit passed)
|
|
261
286
|
```
|