@haposoft/cafekit 0.16.6 → 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 +112 -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 +18 -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 +52 -6
- package/src/claude/scripts/spec-resolver.cjs +1 -2
- package/src/claude/scripts/validate-spec-output.cjs +5 -32
- package/src/claude/scripts/workflow-policy.cjs +22 -10
- 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 +38 -44
- 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 +5 -0
- 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 +8 -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
|
@@ -22,10 +22,9 @@ Example prompt:
|
|
|
22
22
|
|
|
23
23
|
## Resource Constraints
|
|
24
24
|
|
|
25
|
-
- Each subagent has
|
|
26
|
-
- Spawning many parallel agents degrades system performance — check available CPU/memory before scaling out. For parallel implementation waves the cap is 3 concurrent agents by default, never more than 5 (each agent carries
|
|
25
|
+
- Each subagent has its own context window — scope tasks to fit comfortably within it
|
|
26
|
+
- Spawning many parallel agents degrades system performance — check available CPU/memory before scaling out. For parallel implementation waves the cap is 3 concurrent agents by default, never more than 5 (each agent carries its own context window)
|
|
27
27
|
- Prefer fewer, well-scoped agents over many overlapping ones
|
|
28
|
-
- Include system resource info (from hook injection) when delegating tasks so subagents can self-regulate
|
|
29
28
|
|
|
30
29
|
---
|
|
31
30
|
|
|
@@ -132,7 +131,7 @@ Docs: [docs path]
|
|
|
132
131
|
|
|
133
132
|
| ❌ Vague | ✅ Precise |
|
|
134
133
|
|----------|-----------|
|
|
135
|
-
| "Pick up where we left off" | "Add the `/users` POST endpoint per `
|
|
134
|
+
| "Pick up where we left off" | "Add the `/users` POST endpoint per `task-02-api.md`" |
|
|
136
135
|
| "Fix the issues we talked about" | "Add null-check in `auth.ts:45` — root cause: missing input validation" |
|
|
137
136
|
| "Explore the codebase" | "Read `src/api/routes.ts`, then add the missing handler" |
|
|
138
137
|
| Dumping 50+ lines of chat history | A 5-line summary with file paths |
|
|
@@ -12,10 +12,10 @@ When rejecting an audit concern, name the verification source briefly.
|
|
|
12
12
|
|
|
13
13
|
## User Decisions
|
|
14
14
|
|
|
15
|
-
Do not silently undo an explicit user decision. This covers the
|
|
16
|
-
|
|
15
|
+
Do not silently undo an explicit user decision. This covers the GATE-SCOPE scope choice,
|
|
16
|
+
GATE-REVIEW finding dispositions, and GATE-DONE completion judgement, along with thresholds,
|
|
17
17
|
selected libraries, feature scope, schema shape, pricing, timelines, compliance
|
|
18
|
-
choices, and UX trade-offs. Those gates are defined in `
|
|
18
|
+
choices, and UX trade-offs. Those gates are defined in `state-sync.md`; this rule
|
|
19
19
|
governs only how a later review may treat them.
|
|
20
20
|
|
|
21
21
|
If an audit suggests reversing a user decision, present:
|
|
@@ -27,6 +27,4 @@ an entry condition for the primary. If zero valid capabilities match, continue
|
|
|
27
27
|
inline when safe or name the gap. If multiple catalog entries expose the same
|
|
28
28
|
public identity, do not auto-route; require explicit user disambiguation.
|
|
29
29
|
|
|
30
|
-
Never infer an optional document capability from this rule.
|
|
31
|
-
explicit-only numeric optimization capability unless the user invokes it with
|
|
32
|
-
its required bounded metric/guard contract.
|
|
30
|
+
Never infer an optional document capability from this rule.
|
|
@@ -9,9 +9,9 @@ workflow.
|
|
|
9
9
|
1. If the user names a valid installed skill, use it directly.
|
|
10
10
|
2. If one obvious low-risk installed skill covers the intent, use it directly.
|
|
11
11
|
3. For direct factual conversation, answer directly or use the installed
|
|
12
|
-
evidence-answer capability; do not
|
|
13
|
-
4. For ambiguous, multi-step, multi-domain, or elevated/high-risk work,
|
|
14
|
-
|
|
12
|
+
evidence-answer capability; do not spawn agents for ceremony.
|
|
13
|
+
4. For ambiguous, multi-step, multi-domain, or elevated/high-risk work, classify
|
|
14
|
+
it yourself and compose the shortest valid chain below.
|
|
15
15
|
|
|
16
16
|
Resolve every abstract link against the current runtime catalog. An absent,
|
|
17
17
|
invalid, folder-mismatched, duplicate, or retired entry is not routable. Continue
|
|
@@ -28,5 +28,4 @@ owner, entry condition, and observable exit per retained link. Diagnosis does
|
|
|
28
28
|
not authorize repair; implementation does not authorize commit, push, deploy,
|
|
29
29
|
publish, or release; no route expands the user's existing authority.
|
|
30
30
|
|
|
31
|
-
Use `skill-domain-routing.md` to resolve domain capability slots.
|
|
32
|
-
optimization capability remains explicit-only and must never be auto-routed.
|
|
31
|
+
Use `skill-domain-routing.md` to resolve domain capability slots.
|
|
@@ -51,19 +51,10 @@ proves only the boundary it executed.
|
|
|
51
51
|
|
|
52
52
|
## Human gates and workflow ownership
|
|
53
53
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
54
|
+
- GATE-SCOPE records the user's scope decision before the plan is written.
|
|
55
|
+
- GATE-REVIEW records the user's disposition of deduplicated adversarial findings.
|
|
56
56
|
- Develop starts only after a new explicit user invocation and executes one
|
|
57
57
|
unblocked task at a time.
|
|
58
58
|
- Sync changes only observed file state and never starts implementation.
|
|
59
|
-
-
|
|
59
|
+
- GATE-DONE occurs after current receipts and limitations are shown; the user decides
|
|
60
60
|
whether the requested feature is complete.
|
|
61
|
-
|
|
62
|
-
## Legacy compatibility
|
|
63
|
-
|
|
64
|
-
Existing packets containing `spec.json`, nested `tasks/task-R*.md`, or other
|
|
65
|
-
legacy kernel artifacts stay on their installed adapters. Preserve their
|
|
66
|
-
`task_registry`, `semantic_model`, `planning_depth`, lane,
|
|
67
|
-
`execution_tier`, typed topology, separate receipts, and feature closeout
|
|
68
|
-
contract. Do not migrate that machine authority or storage shape while syncing
|
|
69
|
-
an unrelated process-first packet.
|
|
@@ -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,
|
|
@@ -113,7 +113,10 @@ function hasNonEmptyFencedBlock(body) {
|
|
|
113
113
|
|
|
114
114
|
function fieldValues(body, name) {
|
|
115
115
|
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
116
|
-
|
|
116
|
+
// A leading list marker is accepted: every neighbouring section of a task file writes
|
|
117
|
+
// its fields as list items, so continuing that style inside the Receipt is the
|
|
118
|
+
// natural mistake rather than a malformed receipt.
|
|
119
|
+
const matcher = new RegExp(`^\\s*(?:[-*+]\\s+)?${escaped}\\s*:\\s*(.*?)\\s*$`, 'i');
|
|
117
120
|
return String(body || '').split('\n').map((line) => line.match(matcher)).filter(Boolean).map((match) => match[1]);
|
|
118
121
|
}
|
|
119
122
|
|
|
@@ -146,11 +149,18 @@ function workflowVerificationCommand(taskText) {
|
|
|
146
149
|
if (current) current.push(line);
|
|
147
150
|
}
|
|
148
151
|
if (sections.length !== 1) return null;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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))
|
|
152
159
|
.map((match) => normalizedCommand(match[1]));
|
|
153
|
-
|
|
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;
|
|
154
164
|
}
|
|
155
165
|
|
|
156
166
|
function workflowCommandFailures(taskText, body) {
|
|
@@ -335,6 +345,41 @@ function checkWorkflowTaskReceipt(featureDir, taskPath, runtimeContext, policy)
|
|
|
335
345
|
};
|
|
336
346
|
}
|
|
337
347
|
|
|
348
|
+
// The gate used to answer every receipt failure with the same sentence — write a
|
|
349
|
+
// runtime-bound Receipt — which is the wrong instruction whenever the Receipt is
|
|
350
|
+
// present and one field simply could not be read. Name what to change instead.
|
|
351
|
+
const RECEIPT_FIX_HINTS = Object.freeze([
|
|
352
|
+
['missing_receipt', 'add exactly one `## Receipt` section at the end of the file'],
|
|
353
|
+
['task_status', 'the file needs exactly one `Status: done` line outside any fence'],
|
|
354
|
+
['verification_state', 'add a `Verification: PASS` line'],
|
|
355
|
+
['command', 'add a `Command:` line holding the exact command that was run'],
|
|
356
|
+
['command_identity', 'the `Command:` line must match the Verification Plan command exactly'],
|
|
357
|
+
['exit_result', 'add `Exit: 0`; a non-zero exit or a failure marker does not close a task'],
|
|
358
|
+
['command_output', 'add a non-empty fenced block holding the real command output'],
|
|
359
|
+
['placeholder', 'replace the placeholder values with real ones'],
|
|
360
|
+
['provenance', 'add runtime-derived `Base:` and `Head:` lines matching the current runtime'],
|
|
361
|
+
]);
|
|
362
|
+
|
|
363
|
+
/**
|
|
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.
|
|
368
|
+
*/
|
|
369
|
+
function receiptFixHint(failures, body) {
|
|
370
|
+
const codes = new Set(Array.isArray(failures) ? failures : []);
|
|
371
|
+
const hints = RECEIPT_FIX_HINTS.filter(([code]) => codes.has(code)).map(([, hint]) => hint);
|
|
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
|
+
}
|
|
380
|
+
return hints.length === 1 ? hints[0] : `${hints.slice(0, -1).join('; ')}; and ${hints[hints.length - 1]}`;
|
|
381
|
+
}
|
|
382
|
+
|
|
338
383
|
function workflowProofSignature(taskPath, proof) {
|
|
339
384
|
const hash = crypto.createHash('sha256');
|
|
340
385
|
hash.update('cafekit-workflow-proof-v1\0');
|
|
@@ -381,7 +426,7 @@ function checkWorkflowReceiptSet(candidates, projectRoot, runtimeSession, policy
|
|
|
381
426
|
for (const taskPath of doneTasks) {
|
|
382
427
|
const proof = checkWorkflowTaskReceipt(candidate.featureDir, taskPath, runtimeContext, policy);
|
|
383
428
|
if (proof.failures.length > 0) {
|
|
384
|
-
failures.push({ featureName: candidate.featureName, taskPath, failures: proof.failures });
|
|
429
|
+
failures.push({ featureName: candidate.featureName, taskPath, failures: proof.failures, body: proof.body });
|
|
385
430
|
}
|
|
386
431
|
}
|
|
387
432
|
}
|
|
@@ -404,6 +449,7 @@ module.exports = {
|
|
|
404
449
|
checkTaskReceipt,
|
|
405
450
|
checkWorkflowReceiptSet,
|
|
406
451
|
checkWorkflowTaskReceipt,
|
|
452
|
+
receiptFixHint,
|
|
407
453
|
evidenceBody,
|
|
408
454
|
readTaskProof,
|
|
409
455
|
safeRead,
|
|
@@ -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) {
|
|
@@ -1884,6 +1884,18 @@ function flashState(taskRegistry = {}) {
|
|
|
1884
1884
|
.map(([taskPath]) => taskPath);
|
|
1885
1885
|
}
|
|
1886
1886
|
|
|
1887
|
+
// Every other section of a task file writes its fields as list items — the Verification
|
|
1888
|
+
// Plan's own `- Command:` sits a few lines above the Receipt — so continuing that house
|
|
1889
|
+
// style inside the Receipt is the natural mistake, and it used to fail five checks at
|
|
1890
|
+
// once with a message that pointed at the content instead of the dash. Accept either
|
|
1891
|
+
// form. The receipt body is cut to its own `## Receipt` section, so this cannot pick up
|
|
1892
|
+
// the Verification Plan's fields.
|
|
1893
|
+
const RECEIPT_FIELD_PREFIX = '\\s*(?:[-*+]\\s+)?';
|
|
1894
|
+
|
|
1895
|
+
function receiptFieldPattern(name, tail = '\\s*:', flags = '') {
|
|
1896
|
+
return new RegExp(`^${RECEIPT_FIELD_PREFIX}${name}${tail}`, flags);
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1887
1899
|
function validateCanonicalReceipt(body, options = {}) {
|
|
1888
1900
|
if (typeof body !== 'string') return ['verification_state'];
|
|
1889
1901
|
const failures = [];
|
|
@@ -1900,15 +1912,15 @@ function validateCanonicalReceipt(body, options = {}) {
|
|
|
1900
1912
|
addFailure('verification_state');
|
|
1901
1913
|
}
|
|
1902
1914
|
// Unambiguous verification state: must be Verification: PASS exactly
|
|
1903
|
-
if (
|
|
1915
|
+
if (!receiptFieldPattern('Verification', '\\s*:\\s*PASS\\s*$', 'm').test(body)) {
|
|
1904
1916
|
addFailure('verification_state');
|
|
1905
1917
|
}
|
|
1906
1918
|
// Command must be present with non-empty concrete value on same line, not placeholder
|
|
1907
|
-
const cmdLine = body.split('\n').find((l) =>
|
|
1908
|
-
if (!cmdLine ||
|
|
1919
|
+
const cmdLine = body.split('\n').find((l) => receiptFieldPattern('Command(?:\\(s\\))?', '\\s*:', 'm').test(l)) || null;
|
|
1920
|
+
if (!cmdLine || !receiptFieldPattern('Command(?:\\(s\\))?', '\\s*:[ \\t]*\\S', 'm').test(cmdLine)) {
|
|
1909
1921
|
addFailure('command');
|
|
1910
1922
|
} else {
|
|
1911
|
-
const m = cmdLine.match(
|
|
1923
|
+
const m = cmdLine.match(receiptFieldPattern('Command(?:\\(s\\))?', '\\s*:[ \\t]*(.*)$', 'm'));
|
|
1912
1924
|
const val = m ? m[1].trim() : '';
|
|
1913
1925
|
if (isPlaceholderToken(val)) {
|
|
1914
1926
|
addFailure('command');
|
|
@@ -1921,15 +1933,15 @@ function validateCanonicalReceipt(body, options = {}) {
|
|
|
1921
1933
|
const exitValues = [];
|
|
1922
1934
|
const resultValues = [];
|
|
1923
1935
|
for (const line of lines) {
|
|
1924
|
-
if (
|
|
1925
|
-
const m = line.match(
|
|
1936
|
+
if (receiptFieldPattern('Exit', '\\s*:', 'i').test(line)) {
|
|
1937
|
+
const m = line.match(receiptFieldPattern('Exit', '\\s*:\\s*(.*)$', 'i'));
|
|
1926
1938
|
exitValues.push(m ? m[1].trim() : '');
|
|
1927
1939
|
} else if (/exit\s+code\s*[:=]/i.test(line)) {
|
|
1928
1940
|
const m = line.match(/exit\s+code\s*[:=]\s*(.*)$/i);
|
|
1929
1941
|
if (m) exitValues.push(m[1].trim());
|
|
1930
1942
|
}
|
|
1931
|
-
if (
|
|
1932
|
-
const m = line.match(
|
|
1943
|
+
if (receiptFieldPattern('Result', '\\s*:', 'i').test(line)) {
|
|
1944
|
+
const m = line.match(receiptFieldPattern('Result', '\\s*:\\s*(.+?)\\s*$', 'i'));
|
|
1933
1945
|
resultValues.push(m ? m[1].trim() : '');
|
|
1934
1946
|
}
|
|
1935
1947
|
}
|
|
@@ -1954,8 +1966,8 @@ function validateCanonicalReceipt(body, options = {}) {
|
|
|
1954
1966
|
// Without expected values this validates schema only; it does not claim identity binding.
|
|
1955
1967
|
const receiptLines = body.split('\n');
|
|
1956
1968
|
const readField = (name) => receiptLines
|
|
1957
|
-
.filter((line) =>
|
|
1958
|
-
.map((line) => line.replace(
|
|
1969
|
+
.filter((line) => receiptFieldPattern(name, '\\s*:', 'i').test(line))
|
|
1970
|
+
.map((line) => line.replace(receiptFieldPattern(name, '\\s*:\\s*', 'i'), '').trim());
|
|
1959
1971
|
const baseValues = readField('Base');
|
|
1960
1972
|
const headValues = readField('Head');
|
|
1961
1973
|
const baseShaValues = readField('base_sha');
|
|
@@ -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\""
|