@haposoft/cafekit 0.16.7 → 0.18.0

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 (193) hide show
  1. package/README.md +14 -22
  2. package/bin/__tests__/codex-hooks-ownership.test.js +2 -2
  3. package/bin/__tests__/codex-hooks.test.js +0 -36
  4. package/bin/__tests__/codex-native.test.js +46 -88
  5. package/bin/__tests__/develop-contract.test.js +26 -57
  6. package/bin/__tests__/docs-sync-on-demand.test.js +93 -0
  7. package/bin/__tests__/grok-envelope.test.js +0 -56
  8. package/bin/__tests__/hook-payload.test.js +4 -6
  9. package/bin/__tests__/legacy-authority-decoupled.test.js +159 -0
  10. package/bin/__tests__/legacy-hooks-retired.test.js +221 -0
  11. package/bin/__tests__/omp-bridge.test.js +20 -17
  12. package/bin/__tests__/omp-hooks.test.js +0 -19
  13. package/bin/__tests__/optional-skill-inventory.test.js +112 -4
  14. package/bin/__tests__/orca-session.test.js +0 -2
  15. package/bin/__tests__/package-inventory.test.js +100 -541
  16. package/bin/__tests__/runtime-dir.test.js +0 -3
  17. package/bin/__tests__/runtime-schema.test.js +3 -2
  18. package/bin/__tests__/skill-routing-source.test.js +27 -15
  19. package/bin/__tests__/spec-narrowing.test.js +0 -27
  20. package/bin/__tests__/specs-v2-execution-closeout.test.js +4 -69
  21. package/bin/__tests__/ui-ux-skill.test.js +101 -0
  22. package/bin/__tests__/usage-hook-retired.test.js +114 -0
  23. package/bin/__tests__/validator-grounding.test.js +9 -28
  24. package/bin/phases/codex-runtime.js +24 -0
  25. package/bin/phases/omp-runtime.js +22 -0
  26. package/package.json +1 -1
  27. package/src/claude/CLAUDE.md +3 -10
  28. package/src/claude/agents/brainstormer.md +7 -3
  29. package/src/claude/agents/code-auditor.md +35 -50
  30. package/src/claude/agents/debugger.md +5 -79
  31. package/src/claude/agents/deployer.md +3 -5
  32. package/src/claude/agents/docs-keeper.md +2 -7
  33. package/src/claude/agents/implementer.md +6 -9
  34. package/src/claude/agents/inspector.md +2 -3
  35. package/src/claude/agents/project-manager.md +7 -15
  36. package/src/claude/agents/researcher.md +9 -3
  37. package/src/claude/agents/spec-maker.md +11 -11
  38. package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -1
  39. package/src/claude/hooks/__tests__/spec-gate.test.js +74 -3
  40. package/src/claude/hooks/__tests__/spec-state-touched.test.js +134 -0
  41. package/src/claude/hooks/__tests__/state.test.js +68 -0
  42. package/src/claude/hooks/__tests__/statusline.test.js +140 -11
  43. package/src/claude/hooks/agent.cjs +2 -1
  44. package/src/claude/hooks/lib/context.cjs +0 -89
  45. package/src/claude/hooks/lib/hook-payload.cjs +2 -2
  46. package/src/claude/hooks/rules.cjs +2 -1
  47. package/src/claude/hooks/session.cjs +0 -1
  48. package/src/claude/hooks/spec-gate.cjs +17 -28
  49. package/src/claude/hooks/spec-state.cjs +95 -1
  50. package/src/claude/hooks/state.cjs +21 -2
  51. package/src/claude/migration-manifest.json +30 -15
  52. package/src/claude/rules/ai-dev-rules.md +1 -1
  53. package/src/claude/rules/hook-protocols.md +8 -15
  54. package/src/claude/rules/manage-docs.md +9 -23
  55. package/src/claude/rules/orchestrator.md +3 -4
  56. package/src/claude/rules/review-audit-self-decision.md +3 -3
  57. package/src/claude/rules/skill-domain-routing.md +1 -3
  58. package/src/claude/rules/skill-workflow-routing.md +4 -5
  59. package/src/claude/rules/state-sync.md +3 -12
  60. package/src/claude/rules/workflow.md +10 -18
  61. package/src/claude/runtime.schema.json +5 -3
  62. package/src/claude/scripts/generate-skill-catalog.cjs +7 -6
  63. package/src/claude/scripts/provenance.cjs +23 -5
  64. package/src/claude/scripts/spec-receipt.cjs +24 -7
  65. package/src/claude/scripts/spec-resolver.cjs +1 -2
  66. package/src/claude/scripts/validate-spec-output.cjs +5 -32
  67. package/src/claude/settings/settings.json +1 -32
  68. package/src/claude/skills/{question → ask}/SKILL.md +9 -75
  69. package/src/claude/skills/brainstorm/SKILL.md +43 -131
  70. package/src/claude/skills/code-review/SKILL.md +48 -17
  71. package/src/claude/skills/code-review/references/spec-compliance-review.md +2 -3
  72. package/src/claude/skills/code-review/references/verification-gate.md +22 -27
  73. package/src/claude/skills/debug/SKILL.md +29 -149
  74. package/src/claude/skills/develop/SKILL.md +27 -36
  75. package/src/claude/skills/develop/references/parallel-waves.md +0 -8
  76. package/src/claude/skills/develop/references/quality-gate.md +15 -13
  77. package/src/claude/skills/docs/SKILL.md +2 -2
  78. package/src/claude/skills/docs/references/update-workflow.md +1 -1
  79. package/src/claude/skills/fix/SKILL.md +153 -0
  80. package/src/claude/skills/{hotfix → fix}/references/diagnosis-protocol.md +2 -2
  81. package/src/claude/skills/{hotfix → fix}/references/parallel-patterns.md +2 -2
  82. package/src/claude/skills/{hotfix → fix}/references/prevention-gate.md +3 -3
  83. package/src/claude/skills/{hotfix → fix}/references/review-cycle.md +1 -1
  84. package/src/claude/skills/git/SKILL.md +48 -9
  85. package/src/claude/skills/git/references/commit-protocols.md +35 -16
  86. package/src/claude/skills/git/references/worktree-blueprint.md +42 -6
  87. package/src/claude/skills/orca/SKILL.md +9 -8
  88. package/src/claude/skills/research/SKILL.md +2 -0
  89. package/src/claude/skills/scout/SKILL.md +61 -0
  90. package/src/claude/skills/{inspect → scout}/references/internal-inspection.md +26 -10
  91. package/src/claude/skills/specs/SKILL.md +22 -29
  92. package/src/claude/skills/specs/references/review.md +8 -6
  93. package/src/claude/skills/specs/references/templates.md +34 -41
  94. package/src/claude/skills/sync/SKILL.md +8 -15
  95. package/src/claude/skills/sync/references/rebind-and-audit.md +59 -0
  96. package/src/claude/skills/sync/references/sync-protocols.md +4 -13
  97. package/src/claude/skills/test/SKILL.md +22 -3
  98. package/src/claude/skills/test/references/execution-strategy.md +83 -0
  99. package/src/claude/skills/test/references/failure-triage.md +1 -1
  100. package/src/claude/skills/ui-ux/LICENSE +21 -0
  101. package/src/claude/skills/ui-ux/SKILL.md +497 -0
  102. package/src/claude/skills/ui-ux/references/brand-tokens.md +90 -0
  103. package/src/claude/skills/ui-ux/references/budgets.md +113 -0
  104. package/src/claude/skills/ui-ux/references/checklist.md +271 -0
  105. package/src/claude/skills/ui-ux/references/components/accordion.md +246 -0
  106. package/src/claude/skills/ui-ux/references/components/avatar.md +153 -0
  107. package/src/claude/skills/ui-ux/references/components/banner.md +43 -0
  108. package/src/claude/skills/ui-ux/references/components/breadcrumb.md +201 -0
  109. package/src/claude/skills/ui-ux/references/components/button.md +142 -0
  110. package/src/claude/skills/ui-ux/references/components/card.md +113 -0
  111. package/src/claude/skills/ui-ux/references/components/charts.md +376 -0
  112. package/src/claude/skills/ui-ux/references/components/chat.md +132 -0
  113. package/src/claude/skills/ui-ux/references/components/choice-controls.md +369 -0
  114. package/src/claude/skills/ui-ux/references/components/comment-thread.md +17 -0
  115. package/src/claude/skills/ui-ux/references/components/description-list.md +116 -0
  116. package/src/claude/skills/ui-ux/references/components/empty-state.md +98 -0
  117. package/src/claude/skills/ui-ux/references/components/file-upload.md +107 -0
  118. package/src/claude/skills/ui-ux/references/components/inline-edit.md +128 -0
  119. package/src/claude/skills/ui-ux/references/components/input.md +161 -0
  120. package/src/claude/skills/ui-ux/references/components/list-row.md +56 -0
  121. package/src/claude/skills/ui-ux/references/components/loading.md +198 -0
  122. package/src/claude/skills/ui-ux/references/components/logo.md +147 -0
  123. package/src/claude/skills/ui-ux/references/components/otp-input.md +43 -0
  124. package/src/claude/skills/ui-ux/references/components/quantity-input.md +100 -0
  125. package/src/claude/skills/ui-ux/references/components/range-slider.md +16 -0
  126. package/src/claude/skills/ui-ux/references/components/small-controls.md +340 -0
  127. package/src/claude/skills/ui-ux/references/components/sortable-header.md +86 -0
  128. package/src/claude/skills/ui-ux/references/components/tag-input.md +14 -0
  129. package/src/claude/skills/ui-ux/references/components/timeline.md +38 -0
  130. package/src/claude/skills/ui-ux/references/components/tree.md +30 -0
  131. package/src/claude/skills/ui-ux/references/design-process.md +650 -0
  132. package/src/claude/skills/ui-ux/references/layouts/app-kanban.html +303 -0
  133. package/src/claude/skills/ui-ux/references/layouts/app.md +1369 -0
  134. package/src/claude/skills/ui-ux/references/layouts/form.md +430 -0
  135. package/src/claude/skills/ui-ux/references/layouts/overlay.md +552 -0
  136. package/src/claude/skills/ui-ux/references/layouts/pricing.md +204 -0
  137. package/src/claude/skills/ui-ux/references/locked-rules.md +35 -0
  138. package/src/claude/skills/ui-ux/references/principles.md +408 -0
  139. package/src/claude/skills/ui-ux/references/refactor.md +245 -0
  140. package/src/claude/skills/ui-ux/references/responsive.md +195 -0
  141. package/src/claude/skills/ui-ux/references/review.md +528 -0
  142. package/src/claude/skills/ui-ux/references/rules-color.md +623 -0
  143. package/src/claude/skills/ui-ux/references/rules-form.md +235 -0
  144. package/src/claude/skills/ui-ux/references/rules-state.md +680 -0
  145. package/src/claude/skills/ui-ux/references/rules-type.md +369 -0
  146. package/src/claude/skills/ui-ux/references/styles.md +311 -0
  147. package/src/claude/skills/ui-ux/references/system.md +219 -0
  148. package/src/claude/skills/ui-ux/references/tailwind-v4-traps.md +237 -0
  149. package/src/claude/skills/ui-ux/references/tokens.css +362 -0
  150. package/src/claude/skills/ui-ux/scripts/lint-skill.mjs +216 -0
  151. package/src/claude/skills/ui-ux/scripts/package.json +9 -0
  152. package/src/claude/skills/ui-ux/scripts/probe.mjs +4447 -0
  153. package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
  154. package/src/claude/status.cjs +149 -144
  155. package/src/codex/AGENTS.md +8 -13
  156. package/src/codex/hooks/agent.cjs +2 -1
  157. package/src/codex/hooks/lib/spec-receipt.cjs +2 -2
  158. package/src/codex/hooks/lib/spec-utils.cjs +0 -7
  159. package/src/codex/hooks/rules.cjs +2 -1
  160. package/src/codex/hooks/session.cjs +0 -2
  161. package/src/codex/hooks/spec-gate.cjs +7 -18
  162. package/src/codex/hooks.json +0 -20
  163. package/src/codex/rules/state-sync.md +3 -12
  164. package/src/common/AGENTS.md +2 -2
  165. package/src/omp/extensions/cafekit-bridge.mjs +6 -6
  166. package/src/claude/hooks/__tests__/completion-authority.test.js +0 -990
  167. package/src/claude/hooks/__tests__/semantic-review-authority.test.js +0 -259
  168. package/src/claude/hooks/completion-authority-check.cjs +0 -56
  169. package/src/claude/hooks/completion-authority-state.cjs +0 -527
  170. package/src/claude/hooks/completion-authority.cjs +0 -163
  171. package/src/claude/hooks/semantic-review-authority.cjs +0 -154
  172. package/src/claude/hooks/task-scaffold-guard.cjs +0 -114
  173. package/src/claude/hooks/usage.cjs +0 -197
  174. package/src/claude/skills/delegate/SKILL.md +0 -124
  175. package/src/claude/skills/delegate/references/codex-delegation.md +0 -71
  176. package/src/claude/skills/delegate/references/grok-delegation.md +0 -84
  177. package/src/claude/skills/hotfix/SKILL.md +0 -289
  178. package/src/claude/skills/inspect/SKILL.md +0 -142
  179. package/src/claude/skills/loop/SKILL.md +0 -114
  180. package/src/claude/skills/loop/references/bounded-loop-protocol.md +0 -104
  181. package/src/claude/skills/loop/references/metric-and-guard-contract.md +0 -76
  182. package/src/claude/skills/route/SKILL.md +0 -94
  183. package/src/claude/skills/route/references/agent-timing.md +0 -46
  184. package/src/claude/skills/route/references/chaining-patterns.md +0 -53
  185. package/src/claude/skills/route/references/task-taxonomy.md +0 -48
  186. package/src/codex/hooks/completion-authority-check.cjs +0 -67
  187. package/src/codex/hooks/completion-authority-state.cjs +0 -527
  188. package/src/codex/hooks/completion-authority.cjs +0 -109
  189. package/src/codex/hooks/semantic-review-authority.cjs +0 -130
  190. package/src/codex/hooks/task-scaffold-guard.cjs +0 -63
  191. /package/src/claude/skills/{question → ask}/templates/question.md +0 -0
  192. /package/src/claude/skills/{hotfix → fix}/references/escalation-tactics.md +0 -0
  193. /package/src/claude/skills/{hotfix → fix}/references/workflow-specialized.md +0 -0
@@ -8,14 +8,14 @@ Use the CafeKit loop: **Understand -> Plan -> Execute -> Verify -> Sync**.
8
8
  - Read the active spec/task file when one exists.
9
9
  - Read and activate any CafeKit skill that likely applies before taking action.
10
10
  - Inspect only the code needed to understand the affected area.
11
- - Use `inspect` or focused search when structure is unclear.
11
+ - Use `cf:scout` or focused search when structure is unclear.
12
12
 
13
13
  ## 2. Plan
14
14
 
15
15
  - For non-trivial features, use `/cf:specs` to challenge the minimum scope,
16
- open C1, and create `specs/<feature>/plan.md` with flat
16
+ open GATE-SCOPE, and create `specs/<feature>/plan.md` with flat
17
17
  `task-NN-*.md` files beside it.
18
- - After adversarial review, open C2 and apply only the findings the user accepts
18
+ - After adversarial review, open GATE-REVIEW and apply only the findings the user accepts
19
19
  or revises. Specs never starts implementation.
20
20
  - Start implementation only after a new explicit `/cf:develop` invocation,
21
21
  then select one unblocked task at a time.
@@ -24,16 +24,18 @@ Use the CafeKit loop: **Understand -> Plan -> Execute -> Verify -> Sync**.
24
24
  - `Outcome`
25
25
  - `Scope`
26
26
  - `Ownership`
27
+ - `Steps`
27
28
  - `Acceptance`
28
29
  - `Dependencies`
29
30
  - `Verification Plan`
31
+ - `Failure Protocol`
30
32
  - If these are missing or too vague to verify, route back to spec correction.
31
33
 
32
34
  ## 3. Execute
33
35
 
34
36
  - Implement only the active scope.
35
37
  - Modify existing files directly; do not create duplicate "enhanced" variants.
36
- - Keep named contracts from `design.md` intact.
38
+ - Keep named contracts from the plan and task intact.
37
39
  - Do not use placeholder wiring, process-local stand-ins, or fake adapters as completion proof.
38
40
 
39
41
  ## 4. Verify
@@ -53,16 +55,15 @@ Use the CafeKit loop: **Understand -> Plan -> Execute -> Verify -> Sync**.
53
55
  sole writer of task Status and proof.
54
56
  - Keep exactly one `Status:` field. Write or replace the task's final inline
55
57
  `## Receipt` before setting `Status: done`.
56
- - A canonical Receipt contains the exact command, `Exit: 0`,
57
- `Verification: PASS`, runtime-derived Base and Head values, and non-empty
58
- fenced current output. Never invent, copy, or infer missing proof.
58
+ - The canonical Receipt is defined in `state-sync.md`. Never invent, copy, or
59
+ infer missing proof.
59
60
  - When the binding to Base and Head applies, and what the gate does and does not
60
61
  detect, are stated once in `state-sync.md`.
61
62
  - Re-read each edited task and reconcile its plan row, dependencies, acceptance
62
63
  mapping, status, and receipt without rewriting unrelated bytes.
63
- - Run docs checkpoint when a completed task affects public docs or architecture docs.
64
+ - Update affected existing docs when a completed task changes public or architecture docs.
64
65
  - After all requested work has current proof, show evidence and limitations at
65
- C3. The user decides whether the feature is complete.
66
+ GATE-DONE. The user decides whether the feature is complete.
66
67
 
67
68
  ## Production Or CI Issues
68
69
 
@@ -73,12 +74,3 @@ Use the CafeKit loop: **Understand -> Plan -> Execute -> Verify -> Sync**.
73
74
  5. Review before syncing or shipping.
74
75
 
75
76
  Do not patch symptoms before diagnosis unless the issue is a trivial syntax/type/lint failure with an obvious local cause.
76
-
77
- ## Legacy compatibility
78
-
79
- When an existing feature contains `spec.json`, nested `tasks/task-R*.md`, or
80
- other legacy kernel artifacts, keep using the installed adapter. Preserve its
81
- `task_registry`, `semantic_model`, `planning_depth`, lane,
82
- `execution_tier`, typed boundaries, separate receipts, and final feature
83
- receipt. Do not project that machine authority or storage shape into a new
84
- process-first packet.
@@ -58,7 +58,8 @@
58
58
  "scaffold_guard": {
59
59
  "type": "boolean",
60
60
  "default": true,
61
- "description": "Require task files to be generated by the scaffold script. Set false to write them by hand."
61
+ "deprecated": true,
62
+ "description": "Not honoured. The task-scaffold guard that read this key was removed; the key is kept so existing runtime.json files stay valid."
62
63
  },
63
64
  "tollgate": {
64
65
  "type": "boolean",
@@ -75,12 +76,13 @@
75
76
  "usage": {
76
77
  "type": "object",
77
78
  "additionalProperties": false,
78
- "description": "Usage and quota reporting.",
79
+ "deprecated": true,
80
+ "description": "Not honoured. The usage hook that read this key was removed; the statusline takes quota from the rate_limits Claude Code sends. Kept so existing runtime.json files stay valid.",
79
81
  "properties": {
80
82
  "enabled": {
81
83
  "type": "boolean",
82
84
  "default": true,
83
- "description": "Set false to stop fetching quota data for the statusline."
85
+ "description": "Not honoured. Nothing fetches quota data any more."
84
86
  }
85
87
  }
86
88
  },
@@ -15,12 +15,13 @@ const RETIRED_DIRECTORIES = new Set([
15
15
  'mobile-development',
16
16
  'devops',
17
17
  'react-best-practices',
18
+ 'inspect',
19
+ 'hotfix',
20
+ 'question',
21
+ 'loop',
22
+ 'route',
23
+ 'delegate',
18
24
  ]);
19
- const PUBLIC_SUFFIX_BY_DIRECTORY = {
20
- hotfix: 'fix',
21
- inspect: 'scout',
22
- question: 'ask',
23
- };
24
25
 
25
26
  function usage() {
26
27
  console.log(`Usage:
@@ -124,7 +125,7 @@ function publicIdentity(name) {
124
125
  }
125
126
 
126
127
  function expectedIdentity(directory) {
127
- return `cf:${PUBLIC_SUFFIX_BY_DIRECTORY[directory] || directory}`;
128
+ return `cf:${directory}`;
128
129
  }
129
130
 
130
131
  function diagnostic(code, directory, message) {
@@ -228,13 +228,30 @@ function identity(input) {
228
228
  return { root, specsRoot, specFile, feature, session, mode };
229
229
  }
230
230
 
231
+ // A Stop hook checks every done receipt against one checkout. Without a memo each
232
+ // receipt re-read the whole repository twice, so the gate grew with the number of
233
+ // done tasks (minutes on a large specs root). The memo is opt-in and lives only in
234
+ // the enabling process; every other caller still captures a fresh snapshot.
235
+ const snapshotMemo = new Map();
236
+ let snapshotMemoEnabled = false;
237
+ function enableSnapshotMemo() { snapshotMemoEnabled = true; }
238
+
239
+ function captureSnapshot(root, specsRoot) {
240
+ const key = `${root}\0${specsRoot}`;
241
+ if (snapshotMemoEnabled && snapshotMemo.has(key)) return snapshotMemo.get(key);
242
+ const base = gitBase(root, specsRoot);
243
+ const first = manifest(root, specsRoot);
244
+ const head = manifestDigest(first);
245
+ const second = manifest(root, specsRoot);
246
+ if (JSON.stringify(first) !== JSON.stringify(second) || gitBase(root, specsRoot) !== base) fail('worktree_race', 'checkout changed during provenance capture');
247
+ const snapshot = { base, head };
248
+ if (snapshotMemoEnabled) snapshotMemo.set(key, snapshot);
249
+ return snapshot;
250
+ }
251
+
231
252
  function deriveRuntimeProvenance(input) {
232
253
  const current = identity(input);
233
- const base = gitBase(current.root, current.specsRoot);
234
- const first = manifest(current.root, current.specsRoot);
235
- const head = manifestDigest(first);
236
- const second = manifest(current.root, current.specsRoot);
237
- if (JSON.stringify(first) !== JSON.stringify(second) || gitBase(current.root, current.specsRoot) !== base) fail('worktree_race', 'checkout changed during provenance capture');
254
+ const { base, head } = captureSnapshot(current.root, current.specsRoot);
238
255
  const stable = {
239
256
  schema_version: CONTEXT_SCHEMA_VERSION,
240
257
  project_root: current.root,
@@ -328,6 +345,7 @@ module.exports = {
328
345
  createReceiptBinding,
329
346
  deriveRuntimeContext: deriveRuntimeProvenance,
330
347
  deriveRuntimeProvenance,
348
+ enableSnapshotMemo,
331
349
  isTrustedRuntimeContext,
332
350
  recomputeRuntimeContext: recomputeRuntimeProvenance,
333
351
  recomputeRuntimeProvenance,
@@ -149,11 +149,18 @@ function workflowVerificationCommand(taskText) {
149
149
  if (current) current.push(line);
150
150
  }
151
151
  if (sections.length !== 1) return null;
152
- const commands = sections[0]
153
- .map((line) => line.match(/^\s*-\s+(?:\*\*Command\*\*|Command)\s*:\s*(.*?)\s*$/i))
154
- .filter(Boolean)
152
+ // Only a top-level `- Command:` counts: an indented one belongs to another field such as a
153
+ // Counterexample, and one under a `###` sub-heading is a side step that must not outrank
154
+ // the main block. When commands exist only under sub-headings, they are used as before.
155
+ const commandOf = (line) => line.match(/^-\s+(?:\*\*Command\*\*|Command)\s*:\s*(.*?)\s*$/i);
156
+ const firstSub = sections[0].findIndex((line) => /^###\s+/.test(line));
157
+ const main = (firstSub === -1 ? sections[0] : sections[0].slice(0, firstSub)).map(commandOf).filter(Boolean);
158
+ const commands = (main.length ? main : sections[0].map(commandOf).filter(Boolean))
155
159
  .map((match) => normalizedCommand(match[1]));
156
- return commands.length === 1 ? commands[0] : null;
160
+ // A plan may declare several commands when its proof takes more than one step. The last
161
+ // is canonical: earlier ones are prerequisites, and binding the Receipt to any of them
162
+ // would let a task close on its cheapest step. None declared still fails closed.
163
+ return commands.length >= 1 ? commands[commands.length - 1] : null;
157
164
  }
158
165
 
159
166
  function workflowCommandFailures(taskText, body) {
@@ -354,12 +361,22 @@ const RECEIPT_FIX_HINTS = Object.freeze([
354
361
  ]);
355
362
 
356
363
  /**
357
- * Turn receipt check codes into one instruction naming what to change.
364
+ * Turn receipt check codes into one instruction naming what to change. When the receipt
365
+ * body is available, a provenance failure is refined: telling someone to add lines they
366
+ * already wrote sends them looking in the wrong place, and the common cause is a pair
367
+ * typed by hand — git short SHAs — rather than the pair this runtime derives.
358
368
  */
359
- function receiptFixHint(failures) {
369
+ function receiptFixHint(failures, body) {
360
370
  const codes = new Set(Array.isArray(failures) ? failures : []);
361
371
  const hints = RECEIPT_FIX_HINTS.filter(([code]) => codes.has(code)).map(([, hint]) => hint);
362
372
  if (hints.length === 0) return null;
373
+ if (codes.has('provenance') && typeof body === 'string'
374
+ && fieldValues(body, 'Base').length > 0 && fieldValues(body, 'Head').length > 0) {
375
+ const index = hints.length - 1;
376
+ hints[index] = 'the `Base:` and `Head:` lines are present but are not the pair this runtime derives'
377
+ + ' — re-derive them (`Base` is a 40-character commit id, `Head` a 64-character tree digest);'
378
+ + ' git short SHAs typed by hand never match';
379
+ }
363
380
  return hints.length === 1 ? hints[0] : `${hints.slice(0, -1).join('; ')}; and ${hints[hints.length - 1]}`;
364
381
  }
365
382
 
@@ -409,7 +426,7 @@ function checkWorkflowReceiptSet(candidates, projectRoot, runtimeSession, policy
409
426
  for (const taskPath of doneTasks) {
410
427
  const proof = checkWorkflowTaskReceipt(candidate.featureDir, taskPath, runtimeContext, policy);
411
428
  if (proof.failures.length > 0) {
412
- failures.push({ featureName: candidate.featureName, taskPath, failures: proof.failures });
429
+ failures.push({ featureName: candidate.featureName, taskPath, failures: proof.failures, body: proof.body });
413
430
  }
414
431
  }
415
432
  }
@@ -860,8 +860,7 @@ function explicitWorkflowFeatureName({ projectRoot, specsDir, explicitFeature, e
860
860
 
861
861
  /**
862
862
  * Resolve the authoring/execution workflow visible to prompt and Stop hooks.
863
- * Persisted spec resolution remains unchanged; process-v3 is an additive adapter
864
- * and never becomes completion-authority input by way of findAllSpecCandidates.
863
+ * Persisted spec resolution remains unchanged; process-v3 is an additive adapter.
865
864
  */
866
865
  function resolveWorkflowCandidate({ projectRoot, runtime, explicitFeature, explicitPath, target, includeCompleted = false } = {}) {
867
866
  if (!projectRoot) throw new TypeError('projectRoot required');
@@ -724,11 +724,9 @@ function taskDeclaresParallel(content, taskPath, errors) {
724
724
  }
725
725
 
726
726
  /**
727
- * Task files are created from the scaffold template (the scaffold-guard hook
728
- * forces creation through it), so every task starts as a stub full of `{{...}}`
729
- * placeholders. The hook guarantees the stub is CREATED via scaffold, but
730
- * nothing guaranteed the model FILLED it. An unfilled `{{...}}` is an
731
- * incomplete task — SKILL.md: "Leave NO {{...}} placeholder ... fails DoCT" —
727
+ * Task files are usually created from the scaffold template, so a task can start as
728
+ * a stub full of `{{...}}` placeholders, and nothing guarantees the model FILLED it.
729
+ * An unfilled `{{...}}` is an incomplete task — SKILL.md: "Leave NO {{...}} placeholder ... fails DoCT" —
732
730
  * so it is a hard error here. A `.../` path fragment is a not-yet-resolved path
733
731
  * placeholder; it is only a warning, because it usually survives in prose Steps
734
732
  * while the Related Files table (which spec-ground.cjs does verify) is already
@@ -2471,23 +2469,7 @@ function validateSemanticReview(specDir, spec, context, subCriteriaIds, designTe
2471
2469
  errors.push('spec.json.validation.semantic_review.reviewed_artifact_digest: stale or does not match final artifacts and canonical state');
2472
2470
  }
2473
2471
  }
2474
- if (context.policy?.assurance_level === 'Strict' && SHA256_RE.test(review.reviewed_artifact_digest || '')) {
2475
- try {
2476
- const authority = require('../hooks/semantic-review-authority.cjs');
2477
- const canonicalSpecDir = fs.realpathSync(specDir);
2478
- let root = fs.realpathSync(process.cwd());
2479
- if (!isPathInside(root, canonicalSpecDir)) root = path.dirname(path.dirname(canonicalSpecDir));
2480
- const attestation = authority.verifyAttestation(
2481
- root,
2482
- path.join(canonicalSpecDir, 'spec.json'),
2483
- spec.feature_name,
2484
- review.reviewed_artifact_digest,
2485
- );
2486
- if (!attestation.ok) errors.push(`spec.json.validation.semantic_review: Strict assurance requires matching host-observed reviewer PASS attestation (${attestation.reason})`);
2487
- } catch (error) {
2488
- errors.push(`spec.json.validation.semantic_review: Strict assurance attestation is unavailable (${error.message})`);
2489
- }
2490
- }
2472
+ if (context.policy?.assurance_level === 'Strict') errors.push('spec.json.validation.semantic_review: Strict assurance is no longer supported (its reviewer attestation hook was removed); move the packet to plan.md with flat task files');
2491
2473
 
2492
2474
  const criteria = Array.isArray(review.reviewed_criteria) ? review.reviewed_criteria : [];
2493
2475
  const criterionSet = new Set(criteria);
@@ -2901,16 +2883,7 @@ function validateSemanticReview21(specDir, spec, criteria, designIds, verificati
2901
2883
  }
2902
2884
  }
2903
2885
  for (const criterion of criteria) if (!covered.has(criterion)) errors.push(`semantic review counterexamples missing criterion ${criterion}`);
2904
- if (spec.workflow_policy?.assurance_level === 'Strict' && SHA256_RE.test(review.semantic_digest || '')) {
2905
- try {
2906
- const authority = require('../hooks/semantic-review-authority.cjs');
2907
- const root = canonicalProjectRoot(specDir);
2908
- const attestation = authority.verifyAttestation(root, path.join(specDir, 'spec.json'), spec.feature_name, review.semantic_digest);
2909
- if (!attestation.ok) errors.push(`spec.json.validation.semantic_review: Strict readiness requires matching allowlisted host-observed reviewer PASS attestation (${attestation.reason})`);
2910
- } catch (error) {
2911
- errors.push(`spec.json.validation.semantic_review: Strict readiness attestation is unavailable (${error.message})`);
2912
- }
2913
- }
2886
+ if (spec.workflow_policy?.assurance_level === 'Strict') errors.push('spec.json.validation.semantic_review: Strict assurance is no longer supported (its reviewer attestation hook was removed); move the packet to plan.md with flat task files');
2914
2887
  }
2915
2888
 
2916
2889
  function computeLineageId(featureName, createdAt) {
@@ -14,10 +14,6 @@
14
14
  "type": "command",
15
15
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/session.cjs\""
16
16
  },
17
- {
18
- "type": "command",
19
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/docs-sync.cjs\""
20
- },
21
17
  {
22
18
  "type": "command",
23
19
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/state.cjs\""
@@ -58,18 +54,9 @@
58
54
  "type": "command",
59
55
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/rules.cjs\""
60
56
  },
61
- {
62
- "type": "command",
63
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/completion-authority.cjs\""
64
- },
65
57
  {
66
58
  "type": "command",
67
59
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/spec-state.cjs\""
68
- },
69
- {
70
- "type": "command",
71
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/usage.cjs\"",
72
- "timeout": 30
73
60
  }
74
61
  ]
75
62
  }
@@ -87,15 +74,6 @@
87
74
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/inspect-block.cjs\""
88
75
  }
89
76
  ]
90
- },
91
- {
92
- "matcher": "Write",
93
- "hooks": [
94
- {
95
- "type": "command",
96
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/task-scaffold-guard.cjs\""
97
- }
98
- ]
99
77
  }
100
78
  ],
101
79
  "PostToolUse": [
@@ -113,8 +91,7 @@
113
91
  "hooks": [
114
92
  {
115
93
  "type": "command",
116
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/usage.cjs\"",
117
- "timeout": 30
94
+ "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/spec-state.cjs\""
118
95
  }
119
96
  ]
120
97
  }
@@ -126,10 +103,6 @@
126
103
  "type": "command",
127
104
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/spec-gate.cjs\""
128
105
  },
129
- {
130
- "type": "command",
131
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/completion-authority.cjs\""
132
- },
133
106
  {
134
107
  "type": "command",
135
108
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/state.cjs\""
@@ -140,10 +113,6 @@
140
113
  "SubagentStop": [
141
114
  {
142
115
  "hooks": [
143
- {
144
- "type": "command",
145
- "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/semantic-review-authority.cjs\""
146
- },
147
116
  {
148
117
  "type": "command",
149
118
  "command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/state.cjs\""
@@ -24,6 +24,7 @@ metadata:
24
24
 
25
25
  <ANSWER-ONLY-GATE>
26
26
  Do NOT implement, scaffold, refactor, modify files, generate full specs, or make final architecture decisions.
27
+ This holds even when the question itself asks for a change ("and fix it", "rồi đổi luôn cho tôi"): answer the cause with evidence, edit nothing, and point to `cf:fix` for the change, or to `cf:debug` when the cause is not yet known.
27
28
  The output is an answer, evidence, confidence, and a follow-up only when needed.
28
29
  </ANSWER-ONLY-GATE>
29
30
 
@@ -43,10 +44,7 @@ Do not use it when:
43
44
  - The user asks to implement, fix, debug, test, commit, or publish.
44
45
  - The user wants ideation/tradeoff exploration; use `cf:brainstorm`.
45
46
  - The user wants a formal spec; use `cf:specs`.
46
- - The user wants full legacy documentation reconstruction: use
47
- `cf:docs --reconstruct` when the optional document bundle is installed;
48
- otherwise use `cf:scout` plus source evidence, or explain how to install the
49
- bundle with `npx @haposoft/cafekit --with-document-skills`.
47
+ - The user wants full legacy documentation reconstruction: use `cf:docs --reconstruct` when the optional document bundle is installed; otherwise use `cf:scout` plus source evidence, or explain how to install the bundle with `npx @haposoft/cafekit --with-document-skills`.
50
48
  - The user wants root-cause diagnosis for a failure; use `cf:debug`.
51
49
 
52
50
  ## Modes
@@ -60,50 +58,19 @@ Do not use it when:
60
58
 
61
59
  If modes conflict, prefer the most explicit source mode in this order: `--both`, `--repo`, `--web`, then default. Apply `--brief` or `--deep` as output depth modifiers.
62
60
 
63
- ## Workflow
61
+ ## Standards
64
62
 
65
- ### 1. Classify The Question
63
+ **Unclear questions.** If `unclear`, ask one focused follow-up with the minimum choices needed.
66
64
 
67
- Pick one primary answer type:
65
+ **Repo evidence priority:** `README.md`, `AGENTS.md`, `CLAUDE.md`; then relevant `docs/`, `specs/`, `.claude/`; then source files, tests, scripts, package manifests, config files; git history only when the question asks about changes or provenance. Use focused search (`rg`, targeted file reads) instead of broad scans. Use `cf:scout` when the user asks where something lives or the source surface is unclear.
68
66
 
69
- ```text
70
- source-code behavior | config/version | spec/docs consistency | dependency/library | workflow/process | external/current knowledge | unclear
71
- ```
72
-
73
- If `unclear`, ask one focused follow-up with the minimum choices needed.
74
-
75
- ### 2. Gather Evidence
76
-
77
- Repo evidence priority:
78
- 1. `README.md`, `AGENTS.md`, `CLAUDE.md`
79
- 2. relevant `docs/`, `specs/`, `.claude/`
80
- 3. source files, tests, scripts, package manifests, config files
81
- 4. git history only when the question asks about changes or provenance
82
-
83
- Use focused search (`rg`, targeted file reads) instead of broad scans. Use `cf:scout` when the user asks where something lives or the source surface is unclear.
84
-
85
- External evidence:
86
- - Use external/current docs when repo evidence is absent, stale, or not authoritative.
87
- - Prefer official docs, standards, source repositories, or primary vendor docs.
88
- - State clearly when an answer is inferred from external docs rather than confirmed in the repo.
67
+ **External evidence.** Use external/current docs when repo evidence is absent, stale, or not authoritative. Prefer official docs, standards, source repositories, or primary vendor docs. State clearly when an answer is inferred from external docs rather than confirmed in the repo.
89
68
 
90
- ### 3. Decide Whether To Answer Or Ask Back
69
+ **Broad questions.** When the question names no aspect or target — "Is this system stable?", "Is the code good?" — ask back before gathering evidence, offering 2-3 aspects (for example code and tests, runtime reliability, deploy readiness), even when a cautious answer would be possible.
91
70
 
92
- Answer directly when at least one of these is true:
93
- - repo evidence answers the question,
94
- - external/current evidence answers the non-project part,
95
- - a cautious answer can separate known facts from inference.
71
+ **Answer or ask back.** Answer directly when at least one of these is true: repo evidence answers the question, external/current evidence answers the non-project part, or a cautious answer can separate known facts from inference. Ask back when the target system/module is not named and multiple targets are plausible, the needed file/source is blocked or private, the question requires business/domain judgment not present in source, the answer would require guessing customer intent, or the question bundles multiple unrelated topics. Ask only one follow-up question. Include 2-3 concrete options if helpful.
96
72
 
97
- Ask back when:
98
- - the target system/module is not named and multiple targets are plausible,
99
- - the needed file/source is blocked or private,
100
- - the question requires business/domain judgment not present in source,
101
- - the answer would require guessing customer intent,
102
- - the question bundles multiple unrelated topics.
103
-
104
- Ask only one follow-up question. Include 2-3 concrete options if helpful.
105
-
106
- ### 4. Output Contract
73
+ ## Output Contract
107
74
 
108
75
  Default output:
109
76
 
@@ -135,36 +102,3 @@ Use `templates/question.md` when the user asks to save or document the answer.
135
102
  - Keep the answer proportional: concise for simple questions, structured for complex ones.
136
103
  - If external sources were used, include source links or names.
137
104
  - If no evidence exists, say "no evidence found in the current source" and explain what was checked.
138
-
139
- ## Examples
140
-
141
- ### Source Question
142
-
143
- ```text
144
- /cf:ask "In this system, which file does cafekit use to toggle skill routing?"
145
- ```
146
-
147
- Expected behavior:
148
- - read runtime/config/install files,
149
- - answer with exact config file and relevant keys,
150
- - say whether it is runtime-driven or hard-coded.
151
-
152
- ### Mixed Source + Web Question
153
-
154
- ```text
155
- /cf:ask "Which React version does this project use, and does that version still match current best practice?" --both
156
- ```
157
-
158
- Expected behavior:
159
- - read `package.json` or lockfile,
160
- - check current React docs/release info if needed,
161
- - separate local version from external recommendation.
162
-
163
- ### Ask Back
164
-
165
- ```text
166
- /cf:ask "Is this system stable?"
167
- ```
168
-
169
- Expected behavior:
170
- - ask one narrowing question because "stable" could mean architecture, security, performance, UX, tests, or deploy readiness.