@haposoft/cafekit 0.8.9 → 0.8.10

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 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
- [![Version](https://img.shields.io/badge/version-0.8.0-blue.svg)](https://github.com/haposoft/cafekit)
5
+ [![Version](https://img.shields.io/badge/version-0.8.10-blue.svg)](https://github.com/haposoft/cafekit)
6
6
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
7
7
  [![Claude%20Code](https://img.shields.io/badge/Claude%20Code-Primary-orange.svg)](https://claude.ai/code)
8
8
 
@@ -49,6 +49,7 @@ Claude Code install targets:
49
49
  ├── skills/
50
50
  ├── agents/
51
51
  ├── hooks/
52
+ ├── cafekit.json
52
53
  ├── status.cjs
53
54
  ├── runtime.json
54
55
  ├── settings.json
@@ -61,6 +62,13 @@ Managed runtime features include:
61
62
  - rule/context injection
62
63
  - spec state awareness
63
64
  - safe settings merge on reinstall
65
+ - installed CafeKit version tracking in `.claude/cafekit.json`
66
+
67
+ To check the installed CafeKit package version:
68
+
69
+ ```bash
70
+ cat .claude/cafekit.json
71
+ ```
64
72
 
65
73
  ## Core Skills
66
74
 
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;
@@ -1065,6 +1115,8 @@ async function main() {
1065
1115
  copyGeminiFile(platformKey, results, installerOptions);
1066
1116
  }
1067
1117
 
1118
+ writePlatformVersionMetadata(platformKey, results);
1119
+
1068
1120
  results.targets.push(platform.commandsDir);
1069
1121
  console.log();
1070
1122
  }
@@ -1085,6 +1137,7 @@ async function main() {
1085
1137
  console.log();
1086
1138
  console.log(` Copied Files: ${results.copied}`);
1087
1139
  console.log(` Updated Files: ${results.updated}`);
1140
+ console.log(` CafeKit Version: ${packageJson.version}`);
1088
1141
  console.log(` Skipped Files: ${results.skipped}`);
1089
1142
  console.log(` Installed Skills: ${results.installedSkills > 0 ? 'Yes ✓' : 'No'}`);
1090
1143
  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.9",
3
+ "version": "0.8.10",
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",
@@ -93,7 +93,7 @@ function validateTaskSections(taskPath, content, errors) {
93
93
  const hasSteps =
94
94
  hasHeading(content, 'Steps') || hasHeading(content, 'Implementation Steps');
95
95
  const hasRequirements =
96
- hasHeading(content, 'Requirements') || /^\*\*Requirement:\*\*/m.test(content);
96
+ hasHeading(content, 'Requirements') || /_Requirements:\s*[^_\n]+_/i.test(content);
97
97
  const hasEvidence =
98
98
  hasHeading(content, 'Evidence') ||
99
99
  hasHeading(content, 'Task Test Plan & Verification Evidence') ||
@@ -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
 
@@ -350,6 +351,7 @@ Load: `references/review.md` + `rules/design-review.md`
350
351
  - **PROHIBITION:** The system MUST NOT skip Red Team because of a prior code-auditor review. Code review ≠ Spec review.
351
352
  - **PROHIBITION:** The system MUST NOT create `.ts`, `.js`, `.py` or any implementation files during validation. Spec-only outputs.
352
353
  - **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.
354
+ - **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
355
 
354
356
  ### Step 9.5: Finalization Audit (MANDATORY)
355
357
  - Re-scan the `tasks/` directory and rebuild `spec.json.task_files` from the real filesystem (sorted, relative paths)
@@ -10,6 +10,24 @@ 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
+
13
31
  ## Auto-Decision: When to Red Team vs Validate
14
32
 
15
33
  The system evaluates the spec and picks the appropriate review mode:
@@ -45,6 +63,7 @@ These rules override any self-reasoning or optimization the system may attempt:
45
63
  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
64
  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
65
  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.
66
+ 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
67
 
49
68
  ---
50
69
 
@@ -226,13 +245,15 @@ Save to `reports/validate-log.md`:
226
245
  Before declaring validation complete:
227
246
  1. Re-read `spec.json`, `requirements.md`, `design.md`, and all `tasks/task-*.md`
228
247
  2. Verify every accepted red-team finding and every validation action item is reflected in the correct physical file(s)
229
- 3. Fail the audit if:
248
+ 3. Run `node .claude/scripts/validate-spec-output.cjs specs/<feature>` and keep the raw result visible
249
+ 4. Fail the audit if:
230
250
  - a report says "applied" but the file still contains the old text
231
251
  - stale provider strings remain after a provider change
232
252
  - delete-data/privacy artifacts mix multiple canonical policies
233
253
  - any task path fails the CafeKit `tasks/task-R{N}-{SEQ}-<slug>.md` naming convention
234
254
  - `spec.json.updated_at`, `timestamps.review_done`, or `timestamps.validation_done` do not reflect the final reviewed state
235
- 4. Only after the audit passes may you:
255
+ - deterministic validator exits non-zero
256
+ 5. Only after the audit passes may you:
236
257
  - set `spec.json.validation.status = "completed"`
237
258
  - set `spec.json.timestamps.validation_done`
238
259
  - set `spec.json.timestamps.review_done`
@@ -241,7 +262,7 @@ Before declaring validation complete:
241
262
  #### Step 8: Final Status Write-Back
242
263
  - Update `spec.json.updated_at` to the reconciliation time
243
264
  - 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` and list blockers explicitly
265
+ - 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
266
 
246
267
  ---
247
268
 
@@ -256,6 +277,7 @@ Red Team: {N} findings ({A} accepted, {R} rejected)
256
277
  Validate: {Q} questions asked, {D} decisions confirmed
257
278
 
258
279
  Files modified: {list}
280
+ Deterministic validator: PASS via `node .claude/scripts/validate-spec-output.cjs specs/<feature>`
259
281
 
260
282
  📌 Next step: /hapo:develop <feature> (ONLY if reconciliation audit passed)
261
283
  ```