@haposoft/cafekit 0.16.0-rc.2 → 0.16.0-rc.4

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 (98) hide show
  1. package/bin/__tests__/codex-hooks.test.js +794 -21
  2. package/bin/__tests__/codex-native.test.js +228 -7
  3. package/bin/__tests__/develop-contract.test.js +1838 -112
  4. package/bin/__tests__/installer-safety.test.js +82 -29
  5. package/bin/__tests__/opencode-spec-gate.test.js +799 -0
  6. package/bin/__tests__/package-inventory.test.js +841 -10
  7. package/bin/__tests__/specs-v2-execution-closeout.test.js +421 -0
  8. package/bin/__tests__/specs-v2-policy-and-scaffold.test.js +601 -0
  9. package/bin/__tests__/specs-v2-validator-grounder-contract.test.js +952 -0
  10. package/bin/__tests__/test-runtime-dependency-closure.cjs +182 -0
  11. package/bin/__tests__/validator-grounding.test.js +2469 -71
  12. package/bin/lib/managed-writer.js +12 -3
  13. package/bin/phases/codex-runtime.js +17 -1
  14. package/package.json +1 -1
  15. package/src/claude/CLAUDE.md +6 -0
  16. package/src/claude/agents/code-auditor.md +20 -0
  17. package/src/claude/agents/spec-maker.md +153 -202
  18. package/src/claude/hooks/__tests__/completion-authority.test.js +953 -0
  19. package/src/claude/hooks/__tests__/privacy-block.test.js +172 -0
  20. package/src/claude/hooks/__tests__/semantic-review-authority.test.js +257 -0
  21. package/src/claude/hooks/__tests__/spec-gate.test.js +604 -56
  22. package/src/claude/hooks/completion-authority-check.cjs +56 -0
  23. package/src/claude/hooks/completion-authority-state.cjs +527 -0
  24. package/src/claude/hooks/completion-authority.cjs +154 -0
  25. package/src/claude/hooks/docs-sync.cjs +5 -2
  26. package/src/claude/hooks/lib/privacy-command-analysis.cjs +393 -0
  27. package/src/claude/hooks/lib/runtime-path-safety.cjs +119 -0
  28. package/src/claude/hooks/privacy-block.cjs +77 -30
  29. package/src/claude/hooks/semantic-review-authority.cjs +152 -0
  30. package/src/claude/hooks/session.cjs +33 -19
  31. package/src/claude/hooks/spec-gate.cjs +181 -139
  32. package/src/claude/hooks/spec-state.cjs +112 -47
  33. package/src/claude/migration-manifest.json +15 -2
  34. package/src/claude/rules/state-sync.md +52 -21
  35. package/src/claude/rules/workflow.md +17 -9
  36. package/src/claude/scripts/provenance.cjs +315 -0
  37. package/src/claude/scripts/spec-final-state.cjs +244 -0
  38. package/src/claude/scripts/spec-ground.cjs +535 -173
  39. package/src/claude/scripts/spec-readiness.cjs +118 -0
  40. package/src/claude/scripts/spec-receipt.cjs +162 -0
  41. package/src/claude/scripts/spec-resolver.cjs +501 -0
  42. package/src/claude/scripts/spec-scaffold.cjs +1945 -55
  43. package/src/claude/scripts/spec-semantic-model.cjs +396 -0
  44. package/src/claude/scripts/validate-spec-output.cjs +3204 -262
  45. package/src/claude/scripts/workflow-policy.cjs +1888 -203
  46. package/src/claude/settings/settings.json +12 -0
  47. package/src/claude/skills/code-review/SKILL.md +94 -66
  48. package/src/claude/skills/code-review/references/spec-compliance-review.md +10 -2
  49. package/src/claude/skills/code-review/references/verification-gate.md +13 -0
  50. package/src/claude/skills/develop/SKILL.md +138 -283
  51. package/src/claude/skills/develop/references/parallel-waves.md +9 -6
  52. package/src/claude/skills/develop/references/quality-gate.md +123 -148
  53. package/src/claude/skills/develop/references/subagent-patterns.md +42 -37
  54. package/src/claude/skills/specs/SKILL.md +192 -397
  55. package/src/claude/skills/specs/references/ask-user-question-gates.md +27 -18
  56. package/src/claude/skills/specs/references/cross-spec-dependency.md +8 -4
  57. package/src/claude/skills/specs/references/research-strategy.md +4 -1
  58. package/src/claude/skills/specs/references/review.md +200 -260
  59. package/src/claude/skills/specs/references/scope-inquiry.md +18 -5
  60. package/src/claude/skills/specs/rules/design-discovery-full.md +33 -81
  61. package/src/claude/skills/specs/rules/design-discovery-light.md +21 -42
  62. package/src/claude/skills/specs/rules/design-principles.md +136 -180
  63. package/src/claude/skills/specs/rules/design-review.md +42 -97
  64. package/src/claude/skills/specs/rules/ears-format.md +42 -50
  65. package/src/claude/skills/specs/rules/phase-decision-matrix.md +42 -41
  66. package/src/claude/skills/specs/rules/task-scoring-rubric.md +46 -46
  67. package/src/claude/skills/specs/rules/tasks-generation.md +189 -271
  68. package/src/claude/skills/specs/templates/design.md +49 -263
  69. package/src/claude/skills/specs/templates/requirements.md +26 -36
  70. package/src/claude/skills/specs/templates/research.md +9 -98
  71. package/src/claude/skills/specs/templates/spec-state.json +26 -67
  72. package/src/claude/skills/specs/templates/task.md +30 -82
  73. package/src/claude/skills/sync/SKILL.md +45 -15
  74. package/src/claude/skills/sync/references/sync-protocols.md +34 -16
  75. package/src/claude/skills/test/SKILL.md +151 -167
  76. package/src/codex/AGENTS.md +6 -0
  77. package/src/codex/hooks/completion-authority-check.cjs +63 -0
  78. package/src/codex/hooks/completion-authority-state.cjs +527 -0
  79. package/src/codex/hooks/completion-authority.cjs +106 -0
  80. package/src/codex/hooks/lib/hook-context.cjs +58 -4
  81. package/src/codex/hooks/lib/privacy-command-analysis.cjs +3 -0
  82. package/src/codex/hooks/lib/privacy-state.cjs +38 -16
  83. package/src/codex/hooks/lib/runtime-path-safety.cjs +3 -0
  84. package/src/codex/hooks/lib/spec-receipt.cjs +86 -115
  85. package/src/codex/hooks/lib/spec-utils.cjs +104 -27
  86. package/src/codex/hooks/privacy-approval.cjs +1 -1
  87. package/src/codex/hooks/privacy-block.cjs +67 -11
  88. package/src/codex/hooks/semantic-review-authority.cjs +130 -0
  89. package/src/codex/hooks/session.cjs +2 -0
  90. package/src/codex/hooks/spec-gate.cjs +151 -24
  91. package/src/codex/hooks/spec-state.cjs +65 -12
  92. package/src/codex/hooks/state.cjs +2 -0
  93. package/src/codex/hooks.json +16 -1
  94. package/src/codex/rules/state-sync.md +47 -27
  95. package/src/common/AGENTS.md +1 -1
  96. package/src/opencode/AGENTS.md +4 -2
  97. package/src/opencode/plugins/spec-gate.ts +296 -122
  98. package/src/opencode/plugins/spec-state.ts +183 -116
@@ -1,201 +1,185 @@
1
1
  ---
2
2
  name: hapo:test
3
- description: "Run and verify project tests across all scopes: unit, integration, e2e, and UI. Blast-radius scoping for speed, chrome-devtools for UI verification, structured verdicts for downstream automation."
3
+ description: "Execute the smallest adequate verification scope and own the canonical execution proof."
4
4
  user-invocable: true
5
- when_to_use: "Invoke to run and verify unit, integration, e2e, and UI tests."
5
+ when_to_use: "Use after implementation, for a feature scope, or for an explicit test request."
6
6
  category: testing
7
- keywords: [test, unit, integration, e2e]
7
+ keywords: [test, unit, integration, e2e, proof]
8
8
  argument-hint: "[scope|--full|--ui <url>|--ui-auth <url>|--ui-flow <url>]"
9
9
  metadata:
10
10
  author: haposoft
11
11
  version: "2.0.0"
12
12
  ---
13
- # Test — Verify Implementation Quality
13
+ # Test — execution proof owner
14
14
 
15
- Run the project's test suite, analyze results, and return a structured verdict.
16
- Designed to work **after `hapo:develop`**. Standalone `/hapo:test` uses the same `test-runner` contract that `hapo:develop` relies on during its Quality Gate, and may run **in parallel with `hapo:code-review`**.
17
-
18
- **Principles:** Fail-fast | Blast-radius scoping | Zero hidden failures | No mocking to pass
15
+ `hapo:test` is the sole owner of canonical execution proof. It runs real
16
+ commands, records what ran, and emits the receipt consumed by closeout and
17
+ review. Review may consume that receipt but must not run tests, create a second
18
+ receipt, or claim execution proof.
19
19
 
20
20
  ## Usage
21
21
 
22
- ```bash
23
- /hapo:test # Blast-radius mode: only tests affected by recent changes
24
- /hapo:test --full # Run full test suite regardless of changes
25
- /hapo:test <scope> # Test a specific module or path
26
- /hapo:test <feature-name> # Spec-aware test: load specs/<feature-name> and verify scope/task evidence
27
- /hapo:test specs/<feature> # Spec-aware test by spec directory
28
- /hapo:test --ui <url> # UI verification via chrome-devtools (public pages)
29
- /hapo:test --ui-auth <url> # UI verification with auth injection (protected pages)
30
- /hapo:test --ui-flow <url> # UI testing with User Journey (form fill/submit simulation)
22
+ ```text
23
+ /hapo:test
24
+ /hapo:test --full
25
+ /hapo:test <scope-or-path>
26
+ /hapo:test <feature-name>
27
+ /hapo:test specs/<feature>
28
+ /hapo:test --ui <url>
29
+ /hapo:test --ui-auth <url>
30
+ /hapo:test --ui-flow <url>
31
31
  ```
32
32
 
33
- <HARD-GATE>
34
- NEVER claim tests pass when they were NOT actually executed.
35
- NEVER mock, stub, or skip a failing test to produce a green result.
36
- If no test command is detected, report NO_TESTS — do not fabricate results.
37
- If a test command exits 0 but runs 0 tests, report NO_TESTS — this is a green lie, not a PASS.
38
- If tests fail, list every failure explicitly — do not summarize failures away.
39
- </HARD-GATE>
33
+ ## Hard gates
40
34
 
41
- <SCOPE-GATE>
42
- When a feature name or `specs/<feature>` path is supplied, testing is spec-aware.
43
- Load `spec.json`, `requirements.md`, `design.md`, active/recent task files, and task `Evidence` / test-plan proof.
44
- The verdict MUST compare executed/reachable behavior against `scope_lock`, requirements, design contracts, task Completion Criteria, and runtime reachability obligations.
45
- Build/typecheck success without scoped runtime proof is not PASS.
46
- ## Flash promotion contract
47
-
48
- Executable policy source: `.claude/scripts/workflow-policy.cjs` (source: `src/claude/scripts/workflow-policy.cjs`). Its `consumeReviewVerdict` and `promoteFlashTask` functions are sole source for PASS/FAIL/BLOCKED handling and task-scoped promotion.
49
-
50
- When `/hapo:test <feature>` finds a task with `status: "in_progress"` and receipt `FLASH_UNVERIFIED`, evaluate that task's exact Evidence and runtime reachability only:
51
-
52
- - PASS → replace receipt with concrete proof while keeping `status: "in_progress"`, `dependencyBlocked: true`, `unblocks: false`, and `readyForSync: true`; only explicit `/hapo:sync ... sync-finalize` may set `done` and unblock dependents.
53
- - FAIL, BLOCKED, or NO_TESTS → keep `status: "in_progress"`, keep or update blocker, and do not promote any other flash task.
54
- - Never blanket-promote every flash task in a feature because one task passed.
55
-
56
-
57
-
58
- ```mermaid
59
- flowchart TD
60
- A["/hapo:test"] --> B[Phase 1: Detect]
61
- B --> C{Test runner found?}
62
- C -->|No| Z[STOP: Verdict = NO_TESTS]
63
- C -->|Yes| D[Phase 2: Execute]
64
- D --> E{--ui / auth / flow?}
65
- E -->|Yes| F["UI Verification (Parallel Subagents)"]
66
- E -->|No| G[Code Tests (Blast Radius)]
67
- F --> H[Phase 3: Verdict]
68
- G --> H
69
- H --> I[Phase 4: Sync Memory]
70
- I -->|PASS| J[Hand off to hapo:code-review]
71
- I -->|FAIL| K[Load failure-triage.md → classify → escalate]
72
- ```
35
+ - Never claim a pass without executing the relevant command.
36
+ - Never mock, stub, delete, weaken, or skip a failing assertion to obtain green.
37
+ - A missing runner, missing required command, or zero executed tests is not
38
+ `PASS`; report the blocker and keep closeout unfinished.
39
+ - A compile/typecheck failure is a precheck failure even if no test command is
40
+ available.
41
+ - Preserve the exact command, exit result, provenance, and artifact hashes
42
+ required by the canonical receipt schema.
73
43
 
74
- ### Phase 1 — Detect
75
-
76
- Auto-detect the test runner from project files:
77
- - `package.json` → npm/yarn/pnpm/bun test, jest, vitest, mocha
78
- - `pyproject.toml` / `setup.cfg` → pytest
79
- - `go.mod` → go test
80
- - `Cargo.toml` → cargo test
81
- - `pubspec.yaml` → flutter test
82
-
83
- Unless `--full` is specified: apply **Blast Radius scoping** to run only tests
84
- affected by recent file changes. See `references/execution-strategy.md` Phase A.
85
-
86
- If the argument resolves to `specs/<feature>` or a feature directory under `specs/`, enter **Spec-Aware Mode**:
87
- - Load `spec.json`, `requirements.md`, `design.md`, and task files referenced by `task_registry`
88
- - Identify tasks marked `done`, `in_progress`, or recently changed
89
- - Extract exact commands, runtime/artifact proof, runtime reachability proof, and negative-path checks
90
- - Scope test selection by affected task files, but do not skip any mandatory task evidence
91
-
92
- ### Phase 2 — Execute
93
-
94
- **Code testing (default):**
95
- 1. Pre-flight: run typecheck/lint to catch compile errors first
96
- 2. Execute test command with coverage flags
97
- 3. Collect test counts, coverage percentages, and fail stack traces
98
- 4. Treat 0 executed tests as `NO_TESTS`, even if the command exits 0
99
- 5. In Spec-Aware Mode, inspect runtime reachability from declared entrypoints/callers and fail if scoped surfaces are missing or orphaned
100
-
101
- **Spec-aware test type escalation:**
102
- - Unit tests are mandatory when task evidence covers pure logic, transforms, validators, sorting/filtering, or regressions.
103
- - Component/integration tests are expected when task evidence covers stateful UI, context/store wiring, API/service boundaries, or persistence.
104
- - E2E/UI flow tests are expected once a complete user-facing workflow exists, not for isolated foundation tasks.
105
- - Visual/responsive checks are expected for layout, theme, dashboard, and style tasks.
106
- - Accessibility checks are expected for interactive UI surfaces where focus, roles, labels, keyboard navigation, or ARIA can regress.
107
- - Smoke checks are enough for scaffold/config tasks unless the task requires deeper proof.
108
- - Performance/security checks are only mandatory when the requirement, design risk, or touched runtime boundary calls for them.
109
-
110
- **UI verification (`--ui` / `--ui-auth` / `--ui-flow`):**
111
- Execute multi-page discovery, then spawn **Parallel UI Subagents** (test-runner instances) to handle Smoke, Core-Vitals, Accessibility, SEO, Security, and User Flows simultaneously.
112
- See `references/execution-strategy.md` Phase C for full phase breakdown.
113
-
114
- Delegate execution to `test-runner` agent:
115
- ```
116
- Agent(subagent_type="test-runner",
117
- prompt="Run tests. Scope: [blast-radius|full|ui|spec-aware]. Target: [path|url|feature]. Load specs when target is a feature. Return structured verdict with scope/spec coverage and runtime reachability.",
118
- description="Test [feature]")
119
- ```
44
+ ## Scope and policy
45
+
46
+ For a feature target, load `spec.json`, `requirements.md`, `design.md`, and
47
+ the active task's exact seven v2.1 sections and typed coordination boundaries
48
+ when that target exists. Compare actual execution against
49
+ `scope_lock`, contracts, completion criteria, runtime reachability, and
50
+ negative-path obligations.
51
+
52
+ Choose depth from `assurance_level`, risk, and blast radius. Lane is derived:
120
53
 
121
- ### Phase 3 — Verdict
54
+ - Direct: targeted commands and diff/runtime self-check;
55
+ - Standard: bounded affected suite and feature receipt;
56
+ - Critical: strict commands plus the independent evidence required by the
57
+ persisted obligations.
122
58
 
123
- Return a **structured verdict** (required format — not free-form prose):
59
+ Do not infer depth from file count or from the legacy `execution_tier`. That
60
+ field is a read-only compatibility adapter. A task bundle is not required for a
61
+ small Standard feature.
62
+
63
+ ## Spec-Aware Mode
64
+
65
+ <SCOPE-GATE>
66
+ For a feature target, test only the active scope, requirements, completion
67
+ criteria, and reachable runtime surfaces. A missing or orphaned runtime surface
68
+ is a failure even when the command exits successfully.
69
+ </SCOPE-GATE>
70
+
71
+ Use blast-radius selection by default; `--full` overrides selection, not proof
72
+ requirements. Use UI checks only when a reachable UI surface is in scope.
73
+
74
+ ## Execution
75
+
76
+ 1. Detect the project runner and exact commands from repository files and task
77
+ evidence. Do not invent commands.
78
+ 2. Run a cheap compile/typecheck precheck where the project provides one.
79
+ 3. Execute the smallest adequate unit, integration, UI, E2E, accessibility,
80
+ performance, or security proof for the changed surface.
81
+ 4. Inspect runtime reachability and declared artifacts when the task creates
82
+ runtime-facing or generated output.
83
+ 5. Preserve raw outcomes and, only after real execution, write one canonical
84
+ receipt. For a task use `receipts/<task-basename>.md`; never append execution
85
+ evidence to the task plan. A receipt must not contain secrets or placeholder
86
+ provenance.
87
+
88
+ Required proof type follows the behavior, not ceremony:
89
+
90
+ | Surface | Adequate proof |
91
+ |---|---|
92
+ | pure logic/parser/validator | unit plus negative path |
93
+ | stateful UI or module wiring | component/integration and mounted path |
94
+ | API, persistence, provider, or process boundary | real contract/state handoff |
95
+ | complete user workflow | E2E or UI flow |
96
+ | layout or responsive behavior | viewport/visual check |
97
+ | interactive focus/labels/keyboard | accessibility check |
98
+ | regression | reproduction before fix plus passing regression |
99
+ | security/performance | only when requirement, risk, or boundary requires it |
100
+
101
+ ## Canonical receipt
102
+
103
+ The receipt is execution evidence, not a status marker. It must contain the
104
+ task identity and canonical `tasks/task-*.md` path for task receipts, the actual
105
+ command, a successful exit/result, expected versus observed behavior, applicable
106
+ negative-path and reachability proof, both provenance anchors (`Base` and
107
+ `Head`, or their canonical aliases), and any declared artifact SHA-256. Reject
108
+ `Exit: 1`, conflicting outcomes, empty commands, placeholders, missing
109
+ provenance, zero execution, and failure summaries. No-artifact tasks remain
110
+ compatible; declared artifacts require hashes.
111
+
112
+ Closeout and flash callers must also provide an explicit runtime binding; a
113
+ valid-length `Base`/`Head` pair alone is not identity proof. The minimal adapter
114
+ contract is `const binding = policy.createReceiptBinding({ base, head })`, then
115
+ pass `receipt_binding: binding` to `completionDecision` or include the binding's
116
+ `expectedProvenance` in the flash task. The policy requires that binding and
117
+ compares both receipt anchors before completion or flash promotion.
118
+
119
+ For a normal closeout, emit a receipt that the shared policy validator accepts.
120
+ Legacy task `## Evidence` remains readable, but prefer the separate receipt. If
121
+ both exist and their proof identities conflict, report `FAIL` and do not choose
122
+ one. After all task receipts pass, execute final integration and create
123
+ `feature-receipt.md` exactly once. Taskless Compact/Full specs create that file
124
+ only at final closeout; absence before closeout is normal.
125
+ For `--flash`, emit proof for the current `FLASH_UNVERIFIED` task only. Only explicit trusted sync-finalize may promote it. The
126
+ receipt may make the task eligible for trusted sync-finalize, but it must not
127
+ promote the task, unblock dependents, or fabricate a done state.
128
+
129
+ ## Verdict and handoff
130
+
131
+ The shared workflow surface is:
132
+
133
+ `PASS | PASS_WITH_WARNINGS | FAIL | BLOCKED`
134
+
135
+ Warnings describe residual, non-blocking concerns; they never replace missing
136
+ execution proof. A legacy diagnostic result such as `NO_TESTS` is normalized by
137
+ the shared adapter to an unfinished outcome and is never treated as `PASS`.
124
138
 
125
139
  ```markdown
126
140
  ## Test Verdict
127
141
 
128
- **Status:** PASS | FAIL | PARTIAL | NO_TESTS
129
- **Scope:** blast-radius (N/M tests) | full-suite (N tests) | ui-check
130
- **Duration:** Xs
142
+ **Status:** PASS | PASS_WITH_WARNINGS | FAIL | BLOCKED
143
+ **Scope:** [target and selection]
144
+ **Commands:** [exact commands]
145
+ **Exit:** [actual result]
146
+ **Duration:** [measured time]
147
+ **Receipt:** [path or inline canonical receipt]
131
148
 
132
149
  ### Results
133
- - Passed: N | Failed: N | Skipped: N
134
-
135
- ### Coverage (if applicable)
136
- | Metric | Result | Threshold | Status |
137
- |-----------|--------|-----------|-----------|
138
- | Lines | X% | 80% | PASS/FAIL |
139
- | Branches | X% | 70% | PASS/FAIL |
140
- | Functions | X% | 80% | PASS/FAIL |
141
-
142
- ### Failures (if any)
143
- 1. `path/to/file.test.ts:42` — AssertionError: expected X but got Y — Category: Logic Error
144
-
145
- ### UI Results (if --ui)
146
- - Console errors: N found | none
147
- - Network errors (4xx/5xx): N found | none
148
- - Performance: LCP Xms | CLS X | FCP Xms
149
- - Accessibility issues: N found | none
150
- - Screenshots: [paths]
151
-
152
- ### Scope / Spec Coverage (if feature scope)
153
- - Requirements covered: N/N
154
- - Task evidence checks: PASS | FAIL | UNVERIFIED
155
- - Runtime reachability: PASS | FAIL | UNVERIFIED
156
- - Out-of-scope behavior detected: none | [list]
157
-
158
- ### Test Regression Check
159
- - **Comparison:** Compare current test count and assertion depth against previous runs.
160
- - **Result:** OK | REGRESSION (tests deleted/weakened)
150
+ - Passed: N | Failed: N | Skipped: N | Executed: N
151
+
152
+ ### Scope / reachability
153
+ - Requirements: [covered/uncovered]
154
+ - Runtime reachability: PASS | FAIL | BLOCKED
155
+ - Artifact/provenance checks: PASS | FAIL | BLOCKED
161
156
 
162
157
  ### Action
163
- - PASS → Proceed. Hand off to hapo:code-review.
164
- - FAIL → [list specific fixes needed] → Return to implementer. (If REGRESSION: label "Test Regression — tests were deleted or weakened to produce green result")
165
- - PARTIAL → [list uncovered areas] → Consider adding tests.
166
- - NO_TESTS → No test runner detected. User must configure tests first.
167
-
168
- <lessons_learned>
169
- {
170
- "flaky_tests_added": []
171
- }
172
- </lessons_learned>
158
+ - PASS → give the receipt to the single closeout owner; only literal `PASS` can
159
+ complete a task.
160
+ - PASS_WITH_WARNINGS → give the receipt to the closeout owner, but keep the
161
+ task unfinished until a literal `PASS` decision is recorded.
162
+ - FAIL → list exact failures; implementation remains unfinished.
163
+ - BLOCKED → state the changed prerequisite; do not blind-retry.
173
164
  ```
174
165
 
175
- ### Phase 4 — Sync Memory
166
+ The closeout owner calls this workflow once for the current task or feature.
167
+ Do not trigger review from inside the test workflow and do not run a duplicate
168
+ test pass merely because review is requested. Review evaluates correctness,
169
+ security, and spec compliance against this proof.
176
170
 
177
- After receiving the verdict from `test-runner`, the orchestrator (`hapo:test`) intercepts the `<lessons_learned>` block.
178
- It merges the JSON data into `.hapo/test-memory.json` per `references/test-memory.md` to ensure that future runs remember flaky tests or environment setup requirements without modifying the codebase.
171
+ ## Flash proof
179
172
 
180
- ## Skill Interconnections
181
-
182
- | Skill / Agent | Direction | Role |
183
- |---|---|---|
184
- | `hapo:code-review` | runs in parallel | Both run at Quality Gate Step 4 |
185
- | `hapo:develop` | orchestrates | Spawns hapo:test at Step 4 |
186
- | `inspector` agent | hapo:test → | Scout test file locations when structure is unfamiliar |
187
- | `implementer` agent | hapo:test → | FAIL verdicts route back here for fixing |
188
- | `test-runner` agent | hapo:test → | Primary executor, spawned via the `Agent` tool |
189
- | chrome-devtools scripts | test-runner → | UI verification (navigate, screenshot, console, network, performance, aria-snapshot, inject-auth) |
173
+ When the target contains an in-progress `FLASH_UNVERIFIED` task, test only its
174
+ exact Verification Plan and reachability obligations. On pass, keep the task
175
+ `in_progress`, keep `FLASH_UNVERIFIED`, `dependencyBlocked: true`, and
176
+ `unblocks: false`; return canonical proof to trusted sync-finalize. On failure,
177
+ blocker, or no tests, do not promote any task.
190
178
 
191
179
  ## References
192
180
 
193
- - `references/execution-strategy.md` — Blast-radius algorithm, auto-detect logic, UI verification phases (A–E)
194
- - `references/failure-triage.md` — Failure categories, triage decision tree, escalation rules
195
- - `references/test-memory.md` — `.hapo/test-memory.json` schema and merge rules
196
-
197
- ## Related
198
-
199
- - Previous skill: `hapo:develop`
200
- - Parallel skill: `hapo:code-review`
201
- - Parent workflow: `hapo:develop` Step 4 Quality Gate
181
+ - `references/execution-strategy.md` — blast-radius and UI selection, loaded
182
+ only when the default strategy needs detail.
183
+ - `references/failure-triage.md` — failure classification, loaded on failure.
184
+ - `references/test-memory.md` — optional historical context; current receipt
185
+ evidence always wins.
@@ -8,6 +8,12 @@
8
8
  - CafeKit agents live in `.codex/agents/*.toml` and are auto-discovered after the repository is trusted.
9
9
  - Runtime support lives in `.codex/rules/`, `.codex/scripts/`, `.codex/references/`, and `.codex/runtime.json`.
10
10
  - Project hooks live in `.codex/hooks.json`; review trusted hooks with `/hooks`.
11
+ - Specs v2 keeps `planning_depth` (`None`/`Compact`/`Full`) independent from `assurance_level` (`Routine`/`Elevated`/`Strict`). Any risk has an Elevated automatic floor; Strict is opt-in only for an explicit user/project independent-audit requirement or a user-confirmed scope-specific audit decision, never a keyword or severity label. Run the artifact router before discovery: None has no durable spec; Compact/Full share the bounded `spec.json` + `requirements.md` + `design.md` core. Research requires material unresolved uncertainty, an external-current fact, or an explicit request; tasks require typed coordination topology. Full/Strict never create either automatically.
12
+ - In v2.1, `spec.json` is machine authority and Markdown is a human projection. Task plans have exactly seven sections: `Outcome`, `Scope`, `Anchors and Ownership`, `Changes`, `Acceptance`, `Dependencies`, `Verification Plan`; the only ownership table is `ID | Type | Target | Role | Access | Action`.
13
+ - Promote canonical `semantic_model` only through the explicit installed machine semantic-sync step. A semantic Markdown edit requires resynchronization and round-trip validation; never hand-author the machine shape.
14
+ - `coordination.boundaries` typed as ownership/dependency/transition/proof/parallel is topology authority. Legacy trigger fields, priority markers, related-file lists, approval fields, and prose are inert compatibility inputs, never canonical authoring.
15
+ - Canonical lifecycle is exactly `in_progress`, `paused`, `blocked`, or `done`. Technical readiness differs from closeout; authors cannot self-declare readiness, review authority, execution proof, or final `done`.
16
+ - Validator exit 0 proves implemented structural checks only, not semantic quality or execution PASS.
11
17
 
12
18
  ## Codex caveats
13
19
 
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const STATE = require('./completion-authority-state.cjs');
6
+ const { checkFeatureReceipt, checkReceiptDetails } = require('./lib/spec-receipt.cjs');
7
+ const RESOLVER = require('./lib/spec-utils.cjs');
8
+
9
+ const installedScripts = path.join(__dirname, '..', 'scripts');
10
+ const scripts = fs.existsSync(path.join(installedScripts, 'spec-final-state.cjs'))
11
+ ? installedScripts
12
+ : path.resolve(__dirname, '..', '..', 'claude', 'scripts');
13
+
14
+ function runtimeModule(root, name) {
15
+ const target = path.join(root, name);
16
+ const stat = fs.lstatSync(target);
17
+ if (stat.isSymbolicLink() || !stat.isFile()) throw new Error(`runtime dependency must be a regular non-symlink file: ${name}`);
18
+ const canonicalRoot = fs.realpathSync(root);
19
+ const canonical = fs.realpathSync(target);
20
+ const relative = path.relative(canonicalRoot, canonical);
21
+ if (relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) throw new Error(`runtime dependency escaped scripts root: ${name}`);
22
+ return require(canonical);
23
+ }
24
+
25
+ const FINAL_STATE = runtimeModule(scripts, 'spec-final-state.cjs');
26
+
27
+ function explicitTarget(payload) {
28
+ for (const key of ['featureName', 'feature', 'explicitFeature']) {
29
+ if (Object.prototype.hasOwnProperty.call(payload, key)) return { explicitFeature: payload[key] };
30
+ }
31
+ for (const key of ['specPath', 'spec_path', 'featurePath']) {
32
+ if (Object.prototype.hasOwnProperty.call(payload, key)) return { explicitPath: payload[key] };
33
+ }
34
+ return null;
35
+ }
36
+
37
+ function resolveCandidate({ projectRoot, runtime, payload }) {
38
+ const target = explicitTarget(payload);
39
+ if (target) return RESOLVER.resolveActiveSpec({ projectRoot, runtime, ...target });
40
+ const candidates = RESOLVER.findAllSpecCandidates(projectRoot, runtime);
41
+ if (candidates.length > 1) return { error: 'multiple_persisted', candidates: candidates.map((candidate) => candidate.featureName) };
42
+ return candidates[0] || null;
43
+ }
44
+
45
+ function dependencies(overrides = {}) {
46
+ if (!overrides.grounder) runtimeModule(scripts, 'spec-semantic-model.cjs');
47
+ const grounder = overrides.grounder || runtimeModule(scripts, 'spec-ground.cjs');
48
+ return {
49
+ validator: overrides.validator || runtimeModule(scripts, 'validate-spec-output.cjs'),
50
+ grounder,
51
+ semanticAuthority: overrides.semanticAuthority || require('./semantic-review-authority.cjs'),
52
+ };
53
+ }
54
+
55
+ module.exports = FINAL_STATE.createAuthority({
56
+ state: STATE,
57
+ resolveCandidate,
58
+ dependencies,
59
+ receipts: {
60
+ task: (featureDir, taskPath, task, context) => checkReceiptDetails(featureDir, taskPath, task, context),
61
+ feature: (featureDir, context) => checkFeatureReceipt(featureDir, context),
62
+ },
63
+ });