@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.
- package/README.md +14 -22
- package/bin/__tests__/codex-hooks-ownership.test.js +2 -2
- package/bin/__tests__/codex-hooks.test.js +0 -36
- package/bin/__tests__/codex-native.test.js +46 -88
- package/bin/__tests__/develop-contract.test.js +26 -57
- package/bin/__tests__/docs-sync-on-demand.test.js +93 -0
- package/bin/__tests__/grok-envelope.test.js +0 -56
- package/bin/__tests__/hook-payload.test.js +4 -6
- package/bin/__tests__/legacy-authority-decoupled.test.js +159 -0
- package/bin/__tests__/legacy-hooks-retired.test.js +221 -0
- package/bin/__tests__/omp-bridge.test.js +20 -17
- package/bin/__tests__/omp-hooks.test.js +0 -19
- package/bin/__tests__/optional-skill-inventory.test.js +112 -4
- package/bin/__tests__/orca-session.test.js +0 -2
- package/bin/__tests__/package-inventory.test.js +100 -541
- package/bin/__tests__/runtime-dir.test.js +0 -3
- package/bin/__tests__/runtime-schema.test.js +3 -2
- package/bin/__tests__/skill-routing-source.test.js +27 -15
- package/bin/__tests__/spec-narrowing.test.js +0 -27
- package/bin/__tests__/specs-v2-execution-closeout.test.js +4 -69
- package/bin/__tests__/ui-ux-skill.test.js +101 -0
- package/bin/__tests__/usage-hook-retired.test.js +114 -0
- package/bin/__tests__/validator-grounding.test.js +9 -28
- package/bin/phases/codex-runtime.js +24 -0
- package/bin/phases/omp-runtime.js +22 -0
- package/package.json +1 -1
- package/src/claude/CLAUDE.md +3 -10
- package/src/claude/agents/brainstormer.md +7 -3
- package/src/claude/agents/code-auditor.md +35 -50
- package/src/claude/agents/debugger.md +5 -79
- package/src/claude/agents/deployer.md +3 -5
- package/src/claude/agents/docs-keeper.md +2 -7
- package/src/claude/agents/implementer.md +6 -9
- package/src/claude/agents/inspector.md +2 -3
- package/src/claude/agents/project-manager.md +7 -15
- package/src/claude/agents/researcher.md +9 -3
- package/src/claude/agents/spec-maker.md +11 -11
- package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -1
- package/src/claude/hooks/__tests__/spec-gate.test.js +74 -3
- package/src/claude/hooks/__tests__/spec-state-touched.test.js +134 -0
- package/src/claude/hooks/__tests__/state.test.js +68 -0
- package/src/claude/hooks/__tests__/statusline.test.js +140 -11
- package/src/claude/hooks/agent.cjs +2 -1
- package/src/claude/hooks/lib/context.cjs +0 -89
- package/src/claude/hooks/lib/hook-payload.cjs +2 -2
- package/src/claude/hooks/rules.cjs +2 -1
- package/src/claude/hooks/session.cjs +0 -1
- package/src/claude/hooks/spec-gate.cjs +17 -28
- package/src/claude/hooks/spec-state.cjs +95 -1
- package/src/claude/hooks/state.cjs +21 -2
- package/src/claude/migration-manifest.json +30 -15
- package/src/claude/rules/ai-dev-rules.md +1 -1
- package/src/claude/rules/hook-protocols.md +8 -15
- package/src/claude/rules/manage-docs.md +9 -23
- package/src/claude/rules/orchestrator.md +3 -4
- package/src/claude/rules/review-audit-self-decision.md +3 -3
- package/src/claude/rules/skill-domain-routing.md +1 -3
- package/src/claude/rules/skill-workflow-routing.md +4 -5
- package/src/claude/rules/state-sync.md +3 -12
- package/src/claude/rules/workflow.md +10 -18
- package/src/claude/runtime.schema.json +5 -3
- package/src/claude/scripts/generate-skill-catalog.cjs +7 -6
- package/src/claude/scripts/provenance.cjs +23 -5
- package/src/claude/scripts/spec-receipt.cjs +24 -7
- package/src/claude/scripts/spec-resolver.cjs +1 -2
- package/src/claude/scripts/validate-spec-output.cjs +5 -32
- package/src/claude/settings/settings.json +1 -32
- package/src/claude/skills/{question → ask}/SKILL.md +9 -75
- package/src/claude/skills/brainstorm/SKILL.md +43 -131
- package/src/claude/skills/code-review/SKILL.md +48 -17
- package/src/claude/skills/code-review/references/spec-compliance-review.md +2 -3
- package/src/claude/skills/code-review/references/verification-gate.md +22 -27
- package/src/claude/skills/debug/SKILL.md +29 -149
- package/src/claude/skills/develop/SKILL.md +27 -36
- package/src/claude/skills/develop/references/parallel-waves.md +0 -8
- package/src/claude/skills/develop/references/quality-gate.md +15 -13
- package/src/claude/skills/docs/SKILL.md +2 -2
- package/src/claude/skills/docs/references/update-workflow.md +1 -1
- package/src/claude/skills/fix/SKILL.md +153 -0
- package/src/claude/skills/{hotfix → fix}/references/diagnosis-protocol.md +2 -2
- package/src/claude/skills/{hotfix → fix}/references/parallel-patterns.md +2 -2
- package/src/claude/skills/{hotfix → fix}/references/prevention-gate.md +3 -3
- package/src/claude/skills/{hotfix → fix}/references/review-cycle.md +1 -1
- package/src/claude/skills/git/SKILL.md +48 -9
- package/src/claude/skills/git/references/commit-protocols.md +35 -16
- package/src/claude/skills/git/references/worktree-blueprint.md +42 -6
- package/src/claude/skills/orca/SKILL.md +9 -8
- package/src/claude/skills/research/SKILL.md +2 -0
- package/src/claude/skills/scout/SKILL.md +61 -0
- package/src/claude/skills/{inspect → scout}/references/internal-inspection.md +26 -10
- package/src/claude/skills/specs/SKILL.md +22 -29
- package/src/claude/skills/specs/references/review.md +8 -6
- package/src/claude/skills/specs/references/templates.md +34 -41
- package/src/claude/skills/sync/SKILL.md +8 -15
- package/src/claude/skills/sync/references/rebind-and-audit.md +59 -0
- package/src/claude/skills/sync/references/sync-protocols.md +4 -13
- package/src/claude/skills/test/SKILL.md +22 -3
- package/src/claude/skills/test/references/execution-strategy.md +83 -0
- package/src/claude/skills/test/references/failure-triage.md +1 -1
- package/src/claude/skills/ui-ux/LICENSE +21 -0
- package/src/claude/skills/ui-ux/SKILL.md +497 -0
- package/src/claude/skills/ui-ux/references/brand-tokens.md +90 -0
- package/src/claude/skills/ui-ux/references/budgets.md +113 -0
- package/src/claude/skills/ui-ux/references/checklist.md +271 -0
- package/src/claude/skills/ui-ux/references/components/accordion.md +246 -0
- package/src/claude/skills/ui-ux/references/components/avatar.md +153 -0
- package/src/claude/skills/ui-ux/references/components/banner.md +43 -0
- package/src/claude/skills/ui-ux/references/components/breadcrumb.md +201 -0
- package/src/claude/skills/ui-ux/references/components/button.md +142 -0
- package/src/claude/skills/ui-ux/references/components/card.md +113 -0
- package/src/claude/skills/ui-ux/references/components/charts.md +376 -0
- package/src/claude/skills/ui-ux/references/components/chat.md +132 -0
- package/src/claude/skills/ui-ux/references/components/choice-controls.md +369 -0
- package/src/claude/skills/ui-ux/references/components/comment-thread.md +17 -0
- package/src/claude/skills/ui-ux/references/components/description-list.md +116 -0
- package/src/claude/skills/ui-ux/references/components/empty-state.md +98 -0
- package/src/claude/skills/ui-ux/references/components/file-upload.md +107 -0
- package/src/claude/skills/ui-ux/references/components/inline-edit.md +128 -0
- package/src/claude/skills/ui-ux/references/components/input.md +161 -0
- package/src/claude/skills/ui-ux/references/components/list-row.md +56 -0
- package/src/claude/skills/ui-ux/references/components/loading.md +198 -0
- package/src/claude/skills/ui-ux/references/components/logo.md +147 -0
- package/src/claude/skills/ui-ux/references/components/otp-input.md +43 -0
- package/src/claude/skills/ui-ux/references/components/quantity-input.md +100 -0
- package/src/claude/skills/ui-ux/references/components/range-slider.md +16 -0
- package/src/claude/skills/ui-ux/references/components/small-controls.md +340 -0
- package/src/claude/skills/ui-ux/references/components/sortable-header.md +86 -0
- package/src/claude/skills/ui-ux/references/components/tag-input.md +14 -0
- package/src/claude/skills/ui-ux/references/components/timeline.md +38 -0
- package/src/claude/skills/ui-ux/references/components/tree.md +30 -0
- package/src/claude/skills/ui-ux/references/design-process.md +650 -0
- package/src/claude/skills/ui-ux/references/layouts/app-kanban.html +303 -0
- package/src/claude/skills/ui-ux/references/layouts/app.md +1369 -0
- package/src/claude/skills/ui-ux/references/layouts/form.md +430 -0
- package/src/claude/skills/ui-ux/references/layouts/overlay.md +552 -0
- package/src/claude/skills/ui-ux/references/layouts/pricing.md +204 -0
- package/src/claude/skills/ui-ux/references/locked-rules.md +35 -0
- package/src/claude/skills/ui-ux/references/principles.md +408 -0
- package/src/claude/skills/ui-ux/references/refactor.md +245 -0
- package/src/claude/skills/ui-ux/references/responsive.md +195 -0
- package/src/claude/skills/ui-ux/references/review.md +528 -0
- package/src/claude/skills/ui-ux/references/rules-color.md +623 -0
- package/src/claude/skills/ui-ux/references/rules-form.md +235 -0
- package/src/claude/skills/ui-ux/references/rules-state.md +680 -0
- package/src/claude/skills/ui-ux/references/rules-type.md +369 -0
- package/src/claude/skills/ui-ux/references/styles.md +311 -0
- package/src/claude/skills/ui-ux/references/system.md +219 -0
- package/src/claude/skills/ui-ux/references/tailwind-v4-traps.md +237 -0
- package/src/claude/skills/ui-ux/references/tokens.css +362 -0
- package/src/claude/skills/ui-ux/scripts/lint-skill.mjs +216 -0
- package/src/claude/skills/ui-ux/scripts/package.json +9 -0
- package/src/claude/skills/ui-ux/scripts/probe.mjs +4447 -0
- package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
- package/src/claude/status.cjs +149 -144
- package/src/codex/AGENTS.md +8 -13
- package/src/codex/hooks/agent.cjs +2 -1
- package/src/codex/hooks/lib/spec-receipt.cjs +2 -2
- package/src/codex/hooks/lib/spec-utils.cjs +0 -7
- package/src/codex/hooks/rules.cjs +2 -1
- package/src/codex/hooks/session.cjs +0 -2
- package/src/codex/hooks/spec-gate.cjs +7 -18
- package/src/codex/hooks.json +0 -20
- package/src/codex/rules/state-sync.md +3 -12
- package/src/common/AGENTS.md +2 -2
- package/src/omp/extensions/cafekit-bridge.mjs +6 -6
- package/src/claude/hooks/__tests__/completion-authority.test.js +0 -990
- package/src/claude/hooks/__tests__/semantic-review-authority.test.js +0 -259
- package/src/claude/hooks/completion-authority-check.cjs +0 -56
- package/src/claude/hooks/completion-authority-state.cjs +0 -527
- package/src/claude/hooks/completion-authority.cjs +0 -163
- package/src/claude/hooks/semantic-review-authority.cjs +0 -154
- package/src/claude/hooks/task-scaffold-guard.cjs +0 -114
- package/src/claude/hooks/usage.cjs +0 -197
- package/src/claude/skills/delegate/SKILL.md +0 -124
- package/src/claude/skills/delegate/references/codex-delegation.md +0 -71
- package/src/claude/skills/delegate/references/grok-delegation.md +0 -84
- package/src/claude/skills/hotfix/SKILL.md +0 -289
- package/src/claude/skills/inspect/SKILL.md +0 -142
- package/src/claude/skills/loop/SKILL.md +0 -114
- package/src/claude/skills/loop/references/bounded-loop-protocol.md +0 -104
- package/src/claude/skills/loop/references/metric-and-guard-contract.md +0 -76
- package/src/claude/skills/route/SKILL.md +0 -94
- package/src/claude/skills/route/references/agent-timing.md +0 -46
- package/src/claude/skills/route/references/chaining-patterns.md +0 -53
- package/src/claude/skills/route/references/task-taxonomy.md +0 -48
- package/src/codex/hooks/completion-authority-check.cjs +0 -67
- package/src/codex/hooks/completion-authority-state.cjs +0 -527
- package/src/codex/hooks/completion-authority.cjs +0 -109
- package/src/codex/hooks/semantic-review-authority.cjs +0 -130
- package/src/codex/hooks/task-scaffold-guard.cjs +0 -63
- /package/src/claude/skills/{question → ask}/templates/question.md +0 -0
- /package/src/claude/skills/{hotfix → fix}/references/escalation-tactics.md +0 -0
- /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 `
|
|
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
|
|
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
|
|
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
|
|
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
|
-
-
|
|
57
|
-
|
|
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
|
-
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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": "
|
|
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:${
|
|
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 =
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
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
|
|
728
|
-
*
|
|
729
|
-
*
|
|
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'
|
|
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'
|
|
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/
|
|
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
|
-
##
|
|
61
|
+
## Standards
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
**Unclear questions.** If `unclear`, ask one focused follow-up with the minimum choices needed.
|
|
66
64
|
|
|
67
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|