@haposoft/cafekit 0.16.7 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +14 -22
  2. package/bin/__tests__/codex-hooks-ownership.test.js +2 -2
  3. package/bin/__tests__/codex-hooks.test.js +0 -36
  4. package/bin/__tests__/codex-native.test.js +46 -88
  5. package/bin/__tests__/develop-contract.test.js +26 -57
  6. package/bin/__tests__/docs-sync-on-demand.test.js +93 -0
  7. package/bin/__tests__/grok-envelope.test.js +0 -56
  8. package/bin/__tests__/hook-payload.test.js +4 -6
  9. package/bin/__tests__/legacy-authority-decoupled.test.js +159 -0
  10. package/bin/__tests__/legacy-hooks-retired.test.js +221 -0
  11. package/bin/__tests__/omp-bridge.test.js +20 -17
  12. package/bin/__tests__/omp-hooks.test.js +0 -19
  13. package/bin/__tests__/optional-skill-inventory.test.js +112 -4
  14. package/bin/__tests__/orca-session.test.js +0 -2
  15. package/bin/__tests__/package-inventory.test.js +100 -541
  16. package/bin/__tests__/runtime-dir.test.js +0 -3
  17. package/bin/__tests__/runtime-schema.test.js +3 -2
  18. package/bin/__tests__/skill-routing-source.test.js +27 -15
  19. package/bin/__tests__/spec-narrowing.test.js +0 -27
  20. package/bin/__tests__/specs-v2-execution-closeout.test.js +4 -69
  21. package/bin/__tests__/ui-ux-skill.test.js +101 -0
  22. package/bin/__tests__/usage-hook-retired.test.js +114 -0
  23. package/bin/__tests__/validator-grounding.test.js +9 -28
  24. package/bin/phases/codex-runtime.js +24 -0
  25. package/bin/phases/omp-runtime.js +22 -0
  26. package/package.json +1 -1
  27. package/src/claude/CLAUDE.md +3 -10
  28. package/src/claude/agents/brainstormer.md +7 -3
  29. package/src/claude/agents/code-auditor.md +35 -50
  30. package/src/claude/agents/debugger.md +5 -79
  31. package/src/claude/agents/deployer.md +3 -5
  32. package/src/claude/agents/docs-keeper.md +2 -7
  33. package/src/claude/agents/implementer.md +6 -9
  34. package/src/claude/agents/inspector.md +2 -3
  35. package/src/claude/agents/project-manager.md +7 -15
  36. package/src/claude/agents/researcher.md +9 -3
  37. package/src/claude/agents/spec-maker.md +11 -11
  38. package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -1
  39. package/src/claude/hooks/__tests__/spec-gate.test.js +74 -3
  40. package/src/claude/hooks/__tests__/spec-state-touched.test.js +134 -0
  41. package/src/claude/hooks/__tests__/state.test.js +68 -0
  42. package/src/claude/hooks/__tests__/statusline.test.js +140 -11
  43. package/src/claude/hooks/agent.cjs +2 -1
  44. package/src/claude/hooks/lib/context.cjs +0 -89
  45. package/src/claude/hooks/lib/hook-payload.cjs +2 -2
  46. package/src/claude/hooks/rules.cjs +2 -1
  47. package/src/claude/hooks/session.cjs +0 -1
  48. package/src/claude/hooks/spec-gate.cjs +17 -28
  49. package/src/claude/hooks/spec-state.cjs +95 -1
  50. package/src/claude/hooks/state.cjs +21 -2
  51. package/src/claude/migration-manifest.json +30 -15
  52. package/src/claude/rules/ai-dev-rules.md +1 -1
  53. package/src/claude/rules/hook-protocols.md +8 -15
  54. package/src/claude/rules/manage-docs.md +9 -23
  55. package/src/claude/rules/orchestrator.md +3 -4
  56. package/src/claude/rules/review-audit-self-decision.md +3 -3
  57. package/src/claude/rules/skill-domain-routing.md +1 -3
  58. package/src/claude/rules/skill-workflow-routing.md +4 -5
  59. package/src/claude/rules/state-sync.md +3 -12
  60. package/src/claude/rules/workflow.md +10 -18
  61. package/src/claude/runtime.schema.json +5 -3
  62. package/src/claude/scripts/generate-skill-catalog.cjs +7 -6
  63. package/src/claude/scripts/provenance.cjs +23 -5
  64. package/src/claude/scripts/spec-receipt.cjs +24 -7
  65. package/src/claude/scripts/spec-resolver.cjs +1 -2
  66. package/src/claude/scripts/validate-spec-output.cjs +5 -32
  67. package/src/claude/settings/settings.json +1 -32
  68. package/src/claude/skills/{question → ask}/SKILL.md +9 -75
  69. package/src/claude/skills/brainstorm/SKILL.md +43 -131
  70. package/src/claude/skills/code-review/SKILL.md +48 -17
  71. package/src/claude/skills/code-review/references/spec-compliance-review.md +2 -3
  72. package/src/claude/skills/code-review/references/verification-gate.md +22 -27
  73. package/src/claude/skills/debug/SKILL.md +29 -149
  74. package/src/claude/skills/develop/SKILL.md +27 -36
  75. package/src/claude/skills/develop/references/parallel-waves.md +0 -8
  76. package/src/claude/skills/develop/references/quality-gate.md +15 -13
  77. package/src/claude/skills/docs/SKILL.md +2 -2
  78. package/src/claude/skills/docs/references/update-workflow.md +1 -1
  79. package/src/claude/skills/fix/SKILL.md +153 -0
  80. package/src/claude/skills/{hotfix → fix}/references/diagnosis-protocol.md +2 -2
  81. package/src/claude/skills/{hotfix → fix}/references/parallel-patterns.md +2 -2
  82. package/src/claude/skills/{hotfix → fix}/references/prevention-gate.md +3 -3
  83. package/src/claude/skills/{hotfix → fix}/references/review-cycle.md +1 -1
  84. package/src/claude/skills/git/SKILL.md +48 -9
  85. package/src/claude/skills/git/references/commit-protocols.md +35 -16
  86. package/src/claude/skills/git/references/worktree-blueprint.md +42 -6
  87. package/src/claude/skills/orca/SKILL.md +9 -8
  88. package/src/claude/skills/research/SKILL.md +2 -0
  89. package/src/claude/skills/scout/SKILL.md +61 -0
  90. package/src/claude/skills/{inspect → scout}/references/internal-inspection.md +26 -10
  91. package/src/claude/skills/specs/SKILL.md +22 -29
  92. package/src/claude/skills/specs/references/review.md +8 -6
  93. package/src/claude/skills/specs/references/templates.md +34 -41
  94. package/src/claude/skills/sync/SKILL.md +8 -15
  95. package/src/claude/skills/sync/references/rebind-and-audit.md +59 -0
  96. package/src/claude/skills/sync/references/sync-protocols.md +4 -13
  97. package/src/claude/skills/test/SKILL.md +22 -3
  98. package/src/claude/skills/test/references/execution-strategy.md +83 -0
  99. package/src/claude/skills/test/references/failure-triage.md +1 -1
  100. package/src/claude/skills/ui-ux/LICENSE +21 -0
  101. package/src/claude/skills/ui-ux/SKILL.md +497 -0
  102. package/src/claude/skills/ui-ux/references/brand-tokens.md +90 -0
  103. package/src/claude/skills/ui-ux/references/budgets.md +113 -0
  104. package/src/claude/skills/ui-ux/references/checklist.md +271 -0
  105. package/src/claude/skills/ui-ux/references/components/accordion.md +246 -0
  106. package/src/claude/skills/ui-ux/references/components/avatar.md +153 -0
  107. package/src/claude/skills/ui-ux/references/components/banner.md +43 -0
  108. package/src/claude/skills/ui-ux/references/components/breadcrumb.md +201 -0
  109. package/src/claude/skills/ui-ux/references/components/button.md +142 -0
  110. package/src/claude/skills/ui-ux/references/components/card.md +113 -0
  111. package/src/claude/skills/ui-ux/references/components/charts.md +376 -0
  112. package/src/claude/skills/ui-ux/references/components/chat.md +132 -0
  113. package/src/claude/skills/ui-ux/references/components/choice-controls.md +369 -0
  114. package/src/claude/skills/ui-ux/references/components/comment-thread.md +17 -0
  115. package/src/claude/skills/ui-ux/references/components/description-list.md +116 -0
  116. package/src/claude/skills/ui-ux/references/components/empty-state.md +98 -0
  117. package/src/claude/skills/ui-ux/references/components/file-upload.md +107 -0
  118. package/src/claude/skills/ui-ux/references/components/inline-edit.md +128 -0
  119. package/src/claude/skills/ui-ux/references/components/input.md +161 -0
  120. package/src/claude/skills/ui-ux/references/components/list-row.md +56 -0
  121. package/src/claude/skills/ui-ux/references/components/loading.md +198 -0
  122. package/src/claude/skills/ui-ux/references/components/logo.md +147 -0
  123. package/src/claude/skills/ui-ux/references/components/otp-input.md +43 -0
  124. package/src/claude/skills/ui-ux/references/components/quantity-input.md +100 -0
  125. package/src/claude/skills/ui-ux/references/components/range-slider.md +16 -0
  126. package/src/claude/skills/ui-ux/references/components/small-controls.md +340 -0
  127. package/src/claude/skills/ui-ux/references/components/sortable-header.md +86 -0
  128. package/src/claude/skills/ui-ux/references/components/tag-input.md +14 -0
  129. package/src/claude/skills/ui-ux/references/components/timeline.md +38 -0
  130. package/src/claude/skills/ui-ux/references/components/tree.md +30 -0
  131. package/src/claude/skills/ui-ux/references/design-process.md +650 -0
  132. package/src/claude/skills/ui-ux/references/layouts/app-kanban.html +303 -0
  133. package/src/claude/skills/ui-ux/references/layouts/app.md +1369 -0
  134. package/src/claude/skills/ui-ux/references/layouts/form.md +430 -0
  135. package/src/claude/skills/ui-ux/references/layouts/overlay.md +552 -0
  136. package/src/claude/skills/ui-ux/references/layouts/pricing.md +204 -0
  137. package/src/claude/skills/ui-ux/references/locked-rules.md +35 -0
  138. package/src/claude/skills/ui-ux/references/principles.md +408 -0
  139. package/src/claude/skills/ui-ux/references/refactor.md +245 -0
  140. package/src/claude/skills/ui-ux/references/responsive.md +195 -0
  141. package/src/claude/skills/ui-ux/references/review.md +528 -0
  142. package/src/claude/skills/ui-ux/references/rules-color.md +623 -0
  143. package/src/claude/skills/ui-ux/references/rules-form.md +235 -0
  144. package/src/claude/skills/ui-ux/references/rules-state.md +680 -0
  145. package/src/claude/skills/ui-ux/references/rules-type.md +369 -0
  146. package/src/claude/skills/ui-ux/references/styles.md +311 -0
  147. package/src/claude/skills/ui-ux/references/system.md +219 -0
  148. package/src/claude/skills/ui-ux/references/tailwind-v4-traps.md +237 -0
  149. package/src/claude/skills/ui-ux/references/tokens.css +362 -0
  150. package/src/claude/skills/ui-ux/scripts/lint-skill.mjs +216 -0
  151. package/src/claude/skills/ui-ux/scripts/package.json +9 -0
  152. package/src/claude/skills/ui-ux/scripts/probe.mjs +4447 -0
  153. package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
  154. package/src/claude/status.cjs +149 -144
  155. package/src/codex/AGENTS.md +8 -13
  156. package/src/codex/hooks/agent.cjs +2 -1
  157. package/src/codex/hooks/lib/spec-receipt.cjs +2 -2
  158. package/src/codex/hooks/lib/spec-utils.cjs +0 -7
  159. package/src/codex/hooks/rules.cjs +2 -1
  160. package/src/codex/hooks/session.cjs +0 -2
  161. package/src/codex/hooks/spec-gate.cjs +7 -18
  162. package/src/codex/hooks.json +0 -20
  163. package/src/codex/rules/state-sync.md +3 -12
  164. package/src/common/AGENTS.md +2 -2
  165. package/src/omp/extensions/cafekit-bridge.mjs +6 -6
  166. package/src/claude/hooks/__tests__/completion-authority.test.js +0 -990
  167. package/src/claude/hooks/__tests__/semantic-review-authority.test.js +0 -259
  168. package/src/claude/hooks/completion-authority-check.cjs +0 -56
  169. package/src/claude/hooks/completion-authority-state.cjs +0 -527
  170. package/src/claude/hooks/completion-authority.cjs +0 -163
  171. package/src/claude/hooks/semantic-review-authority.cjs +0 -154
  172. package/src/claude/hooks/task-scaffold-guard.cjs +0 -114
  173. package/src/claude/hooks/usage.cjs +0 -197
  174. package/src/claude/skills/delegate/SKILL.md +0 -124
  175. package/src/claude/skills/delegate/references/codex-delegation.md +0 -71
  176. package/src/claude/skills/delegate/references/grok-delegation.md +0 -84
  177. package/src/claude/skills/hotfix/SKILL.md +0 -289
  178. package/src/claude/skills/inspect/SKILL.md +0 -142
  179. package/src/claude/skills/loop/SKILL.md +0 -114
  180. package/src/claude/skills/loop/references/bounded-loop-protocol.md +0 -104
  181. package/src/claude/skills/loop/references/metric-and-guard-contract.md +0 -76
  182. package/src/claude/skills/route/SKILL.md +0 -94
  183. package/src/claude/skills/route/references/agent-timing.md +0 -46
  184. package/src/claude/skills/route/references/chaining-patterns.md +0 -53
  185. package/src/claude/skills/route/references/task-taxonomy.md +0 -48
  186. package/src/codex/hooks/completion-authority-check.cjs +0 -67
  187. package/src/codex/hooks/completion-authority-state.cjs +0 -527
  188. package/src/codex/hooks/completion-authority.cjs +0 -109
  189. package/src/codex/hooks/semantic-review-authority.cjs +0 -130
  190. package/src/codex/hooks/task-scaffold-guard.cjs +0 -63
  191. /package/src/claude/skills/{question → ask}/templates/question.md +0 -0
  192. /package/src/claude/skills/{hotfix → fix}/references/escalation-tactics.md +0 -0
  193. /package/src/claude/skills/{hotfix → fix}/references/workflow-specialized.md +0 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Native spec-driven workflow and runtime bundle for Claude Code and Codex CLI.
4
4
 
5
- [![Version](https://img.shields.io/badge/version-0.16.7-blue.svg)](https://github.com/haposoft/cafekit)
5
+ [![Version](https://img.shields.io/badge/version-0.18.0-blue.svg)](https://github.com/haposoft/cafekit)
6
6
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
7
7
  [![Claude%20Code](https://img.shields.io/badge/Claude%20Code-Native-orange.svg)](https://claude.ai/code)
8
8
  [![Codex%20CLI](https://img.shields.io/badge/Codex%20CLI-Native-111111.svg)](https://developers.openai.com/codex)
@@ -147,6 +147,13 @@ cat .codex/cafekit.json
147
147
  The Claude statusline reads three keys from `.claude/runtime.json`:
148
148
 
149
149
  - `"statusline"`: render mode — `full` (default), `compact`, `minimal`, or `none`.
150
+ The default is one line, `◆ model (effort) ϟ✱ ◔ context% ⧗ 5h quota% reset ◷ weekly% ⎇ branch ●changed ↑↓ #PR✓ ⊟ ± +added/-removed ⏱ session ↻ cache hit%`
151
+ (`ϟ` fast mode, `✱` thinking, `#PR` with ✓ approved / ✗ changes requested, `⊟` inside a git worktree;
152
+ each appears only when present), which drops cache, session time, changes, weekly, quota, then the
153
+ branch as the terminal narrows. Quota comes only from the `rate_limits` Claude Code sends (Pro/Max,
154
+ after a session's first API response); without it the quota segments are hidden. `full` adds
155
+ agent and todo lines only while they exist, `compact` is the line alone, and `minimal`
156
+ keeps model, context and branch.
150
157
  - `statuslineColors`: set `false` to disable ANSI colors (`NO_COLOR` also wins).
151
158
  - `statuslineLayout`: optional custom layout. Global shape
152
159
  `{ "lines": [["model", "context"], ["directory", "git"]] }` — each inner
@@ -156,8 +163,8 @@ The Claude statusline reads three keys from `.claude/runtime.json`:
156
163
  ids are ignored; an empty or invalid layout falls back to the default
157
164
  renderers, and leaving the key out keeps the default output unchanged. The
158
165
  `cost` section renders only when enabled here, billing mode is API, and cost
159
- data exists. Quota shows five-hour and weekly windows only while the usage
160
- cache is fresh.
166
+ data exists. Quota shows five-hour and weekly windows only while Claude Code
167
+ sends `rate_limits`. The `usage` key is deprecated and has no effect.
161
168
 
162
169
  ## Core Skills
163
170
 
@@ -167,8 +174,6 @@ CafeKit ships many skills, but the main release surface is:
167
174
  - `/cf:scout <search-target>`: discover relevant files locally first, delegating only for permitted broad independent scopes
168
175
  - `/cf:brainstorm <idea-or-problem>`: scout the repo, clarify exact requirements, compare approaches, and hand off to specs
169
176
  - `/cf:research <decision>`: choose proportional depth and return traceable evidence for an uncertain technical decision
170
- - `/cf:route <material-request>`: classify ambiguous, multi-step, multi-domain, or elevated-risk work and compose the shortest valid installed chain
171
- - `/cf:loop <bounded-experiment>`: run explicit-only numeric optimization in an isolated worktree and return a base-bound patch handoff
172
177
  - `/cf:orca <orca-request>`: inside an Orca (onorca.dev) pane, route a request to read, wait on, or send to another agent pane, or spawn one into a worktree
173
178
  - `/cf:specs <feature-description>`: create or resume a structured spec workflow
174
179
  - `/cf:develop <feature-name>`: implement from approved spec artifacts
@@ -194,7 +199,7 @@ completes work. Chat is the default output. A durable file needs explicit user
194
199
  authority, and no Brainstorm output is live proof or Specs/Develop approval or
195
200
  execution authority.
196
201
 
197
- ### Adaptive Research and bounded Loop
202
+ ### Adaptive Research
198
203
 
199
204
  Use `/cf:research` when the result is a decision: Quick, Standard, or Deep
200
205
  research binds material claims to a URL or repository anchor, authority,
@@ -202,18 +207,9 @@ date/version, applicability, and `confirmed`, `inferred`, or `unresolved`
202
207
  state. Research returns evidence and tradeoffs; it does not implement the
203
208
  recommendation or guarantee correctness.
204
209
 
205
- Use `/cf:loop` only by explicit request and only after its preflight freezes
206
- Goal, isolated Scope, finite numeric Metric and Direction, reproducible
207
- Baseline, distinct Guard, noise policy and minimum delta, budget, and stop
208
- conditions. Each iteration stays in a detached worktree. The result is a
209
- base-bound isolated patch handoff, never an automatic apply, commit, push, or
210
- guarantee of improvement.
211
-
212
210
  ```text
213
211
  /cf:research Compare current local-first search libraries for this repository
214
- /cf:loop Goal="reduce parser latency" Scope="packages/parser" Metric="median ms, lower" Baseline="pinned base" Guard="npm test" Noise="MAD; minimum delta 2%" Budget="10 iterations" Stop="budget, drift, or failed guard"
215
212
  $cf-research Compare current local-first search libraries for this repository
216
- $cf-loop Goal="reduce parser latency" Scope="packages/parser" Metric="median ms, lower" Baseline="pinned base" Guard="npm test" Noise="MAD; minimum delta 2%" Budget="10 iterations" Stop="budget, drift, or failed guard"
217
213
  ```
218
214
 
219
215
  Optional document skills are `docs`, `docx`, `pdf`, `pptx`, `xlsx`, and
@@ -244,7 +240,7 @@ node .claude/scripts/generate-skill-catalog.cjs --skills
244
240
  Routing uses progressive disclosure: live catalog metadata selects a candidate,
245
241
  the selected `SKILL.md` supplies its contract, and only relevant references are
246
242
  loaded. Invoke an installed skill directly for explicit or obvious low-risk
247
- work; use `cf:route` only when classification or chaining is material. When a
243
+ work; compose a short chain only when classification or chaining is material. When a
248
244
  capability or agent is absent, continue inline when safe or name the gap.
249
245
  Hooks are not a skill router and never grant capability presence or authority. Source
250
246
  and installed projections are verified; live-model adherence remains
@@ -310,17 +306,13 @@ specs/<feature-name>/
310
306
  ```
311
307
 
312
308
  The process-first workflow has three human decision gates. `cf:specs` opens
313
- C1 to fix scope before authoring and C2 to resolve adversarial findings, then
309
+ GATE-SCOPE to fix scope before authoring and GATE-REVIEW to resolve adversarial findings, then
314
310
  stops. A later explicit `cf:develop` invocation executes the tasks and
315
- presents C3 for closeout only after real execution proof. Each task has one
311
+ presents GATE-DONE for closeout only after real execution proof. Each task has one
316
312
  `Status:` field and keeps its canonical `## Receipt` inline, including the
317
313
  exact Verification Plan command, `Exit: 0`, `Verification: PASS`,
318
314
  runtime-derived Base and Head, and current command output.
319
315
 
320
- Existing packets with `spec.json`, nested `tasks/task-R*.md`, or separate
321
- receipts remain supported through the legacy compatibility adapter. New Specs
322
- work does not author those legacy artifacts.
323
-
324
316
  ## Development
325
317
 
326
318
  Run package self-tests:
@@ -136,8 +136,8 @@ test('repeated installs never duplicate a CafeKit hook', () => {
136
136
  const config = readHooks(root);
137
137
  assert.equal(allHandlers(config).length, afterFirst, 'a reinstall added handlers that were already registered');
138
138
 
139
- // Uniqueness is per event, not global: state.cjs and completion-authority.cjs each
140
- // register under several events by design.
139
+ // Uniqueness is per event, not global: state.cjs registers under several events by
140
+ // design.
141
141
  for (const [eventName, groups] of Object.entries(config.hooks)) {
142
142
  const scripts = groups
143
143
  .flatMap((group) => group.hooks || [])
@@ -611,24 +611,6 @@ test('Codex inspect hook scans native shell commands and structured paths', () =
611
611
  });
612
612
  });
613
613
 
614
- test('Codex task scaffold hook blocks apply_patch Add File with stderr guidance', () => {
615
- inHookFixture((root, hooks) => {
616
- const result = runHook(path.join(hooks, 'task-scaffold-guard.cjs'), root, {
617
- cwd: root,
618
- session_id: 'session-a',
619
- hook_event_name: 'PreToolUse',
620
- tool_name: 'apply_patch',
621
- tool_input: {
622
- command: '*** Begin Patch\n*** Add File: specs/auth/tasks/task-R0-01-auth.md\n+x\n*** End Patch\n'
623
- }
624
- });
625
-
626
- assert.equal(result.status, 2);
627
- assert.match(result.stderr, /TASK SCAFFOLD REQUIRED/);
628
- assert.match(result.stderr, /node \.codex\/scripts\/spec-scaffold\.cjs auth/);
629
- });
630
- });
631
-
632
614
  test('Codex completion gate cannot be bypassed from a nested cwd', () => {
633
615
  inHookFixture((root, hooks) => {
634
616
  const nested = path.join(root, 'packages', 'app');
@@ -1036,24 +1018,6 @@ test('Codex state hook persists direct native event fields at project root', ()
1036
1018
  });
1037
1019
  });
1038
1020
 
1039
- test('semantic review authority hook is registered only for SubagentStop on Claude and Codex', () => {
1040
- const configurations = [
1041
- JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'src/claude/settings/settings.json'), 'utf8')).hooks,
1042
- JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'src/codex/hooks.json'), 'utf8')).hooks,
1043
- ];
1044
- for (const hooks of configurations) {
1045
- const registrations = [];
1046
- for (const [event, groups] of Object.entries(hooks)) {
1047
- for (const group of groups) {
1048
- for (const hook of group.hooks || []) {
1049
- if (String(hook.command || '').includes('semantic-review-authority.cjs')) registrations.push(event);
1050
- }
1051
- }
1052
- }
1053
- assert.deepEqual(registrations, ['SubagentStop']);
1054
- }
1055
- });
1056
-
1057
1021
  test('Codex canonical receipt provenance requires both Base and Head', () => {
1058
1022
  const receipt = require(path.join(CODEX_HOOKS, 'lib', 'spec-receipt.cjs'));
1059
1023
  const onlyBase = receipt.validateCanonicalReceipt('Verification: PASS\nCommand: pnpm test\nExit: 0\nBase: abc\n');
@@ -69,7 +69,7 @@ const DOCS_ADAPTIVE_BUNDLE = [
69
69
  'references/update-workflow.md',
70
70
  'references/standard-docs-workflow.md'
71
71
  ];
72
- const HOTFIX_SOURCE_ROOT = path.join(PACKAGE_ROOT, 'src/claude/skills/hotfix');
72
+ const HOTFIX_SOURCE_ROOT = path.join(PACKAGE_ROOT, 'src/claude/skills/fix');
73
73
  const HOTFIX_BUNDLE = [
74
74
  'SKILL.md',
75
75
  'references/diagnosis-protocol.md',
@@ -111,7 +111,7 @@ function boundaryTableHasRequiredRows(table) {
111
111
  }
112
112
 
113
113
  const IMPLEMENTATION_READINESS_CLAUSES = {
114
- noInvention: 'Before implementation handoff, apply the **no-invention gate**: if two implementations conform to the packet text yet can produce different externally observable output, state, error, security, or compatibility behavior, surface the missing choice as an explicit C1 or C2 question and block handoff.',
114
+ noInvention: 'Before implementation handoff, apply the **no-invention gate**: if two implementations conform to the packet text yet can produce different externally observable output, state, error, security, or compatibility behavior, surface the missing choice as an explicit GATE-SCOPE or GATE-REVIEW question and block handoff.',
115
115
  materialDefinition: 'A boundary is material when the task creates, changes, or depends on it and a different choice changes an external observation, security, durable data, compatibility, or proof reachability. Require only the matching material row; omit nonmaterial categories.',
116
116
  exactBoundaryChoices: 'For every required row, name each listed choice exactly; labels such as “JSON”, “local path”, “locked”, or “timestamped” alone remain unresolved.',
117
117
  proofPlanLines: [
@@ -130,11 +130,11 @@ const IMPLEMENTATION_READINESS_CLAUSES = {
130
130
  disposableReviewControls: 'Run mutation or destructive negative controls only on disposable copies below a verified temporary root, never tracked worktree or canonical source bytes.',
131
131
  failureSemantics: '`Crash` means abrupt unhandled termination before the claimed catch point; a catchable failure returns/raises an error or exits nonzero. Never use them interchangeably.',
132
132
  privacyIdentifiers: 'Any privacy/security claim names the exact identifier surface at risk, such as an env var, header, path, token class, or field name; generic “sensitive data” is insufficient.',
133
- freshReplay: 'After applying an accepted C2 finding, a fresh-context closure pass records and freshly replays its original counterexample after the repair under this exact review-log header:',
133
+ freshReplay: 'After applying an accepted GATE-REVIEW finding, a fresh-context closure pass records and freshly replays its original counterexample after the repair under this exact review-log header:',
134
134
  distinctRepairProof: '`Repaired at` cites the repair edit; `Proved at` must cite distinct evidence from the fresh replay, never the repair-edit citation.',
135
135
  closureTransition: 'An accepted finding transitions `accepted → repaired → PASS|FAIL|UNKNOWN`.',
136
136
  unknownBlocks: 'Only `PASS` closes it; `FAIL` remains open for the remaining paper-review round; `UNKNOWN` blocks implementation handoff.',
137
- scopeReturnsToC1: 'A repair that adds user semantics or scope returns to C1.'
137
+ scopeReturnsToC1: 'A repair that adds user semantics or scope returns to GATE-SCOPE.'
138
138
  };
139
139
  const ADAPTIVE_COVERAGE_PROFILE_HEADER = [
140
140
  'ID', 'Outcome', 'Change kinds', 'Material surfaces', 'Ambiguity/action',
@@ -148,7 +148,7 @@ const ADAPTIVE_COVERAGE_AMBIGUITY_ROWS = [
148
148
  ['State', 'Required action'],
149
149
  ['`none`', 'proceed'],
150
150
  ['`examples-needed`', 'add two or three examples only for an already decided rule; promote to `decision-needed` if an example changes observable behavior'],
151
- ['`decision-needed`', 'ask the user at C1/C2 and keep affected tasks blocked'],
151
+ ['`decision-needed`', 'ask the user at GATE-SCOPE/GATE-REVIEW and keep affected tasks blocked'],
152
152
  ['`design-needed`', 'after user-owned decisions settle, route material competing technical designs through Brainstorm']
153
153
  ];
154
154
  const ADAPTIVE_REVIEWER_ROWS = [
@@ -169,12 +169,12 @@ const ADAPTIVE_COVERAGE_CLAUSES = {
169
169
  openKinds: 'Change kinds are multi-valued (`add`, `modify`, `fix`, `refactor`, `remove`, `migrate`, `integrate`), and unfamiliar kinds or surfaces use `other:<verbatim>` rather than disappearing.',
170
170
  scopedUnion: 'Each task references its CP IDs; authoring, review, edge, and proof obligations union only inside affected rows/tasks.',
171
171
  profileRederivation: 'Rederive affected CP rows after any accepted scope, outcome, criteria, ownership, dependency, risk, or proof delta before task status.',
172
- plannedProof: '`Required proof` is a planned level set, not execution\nevidence: known but unrun proof may be `pending`; `UNKNOWN` reachability blocks\n`pending`; missing, failed, or unavailable required evidence blocks `done`/C3.',
172
+ plannedProof: '`Required proof` is a planned level set, not execution\nevidence: known but unrun proof may be `pending`; `UNKNOWN` reachability blocks\n`pending`; missing, failed, or unavailable required evidence blocks `done`/GATE-DONE.',
173
173
  proofSeparation: 'Levels stay separate and never promote one another.',
174
174
  liveLimit: 'Source/static checks prove the written contract, not live-model adherence.',
175
175
  specMakerAuthority: 'they are the canonical risk and coverage authority. Do not duplicate\ntheir taxonomy here.',
176
176
  specMakerAmbiguity: 'Apply the canonical ambiguity action; examples never decide observable behavior.',
177
- specMakerRoute: 'Apply their risk-first route before C1 and stop when the\nrequest qualifies for direct work; hand off when it requires Brainstorm-only exploration.',
177
+ specMakerRoute: 'Apply their risk-first route before GATE-SCOPE and stop when the\nrequest qualifies for direct work; hand off when it requires Brainstorm-only exploration.',
178
178
  reviewRisk: 'Keep Fact Checker as the baseline. Assign every remaining material CP risk to a\nnamed reviewer lens; a critical row includes both relevant security-adversary and\nfailure-mode coverage, and nonmaterial lenses are not added.',
179
179
  reviewCapacity: 'Reviewer count is fixed by the table, not lens count. Give each reviewer a distinct primary lens; when material lenses exceed reviewers, combine related named lenses on one reviewer and keep every material lens assigned.'
180
180
  };
@@ -558,7 +558,7 @@ function authoringProjectionIssues(files) {
558
558
  || !files.templates.includes('task-NN-<slug>.md')) {
559
559
  issues.push('flat-layout-template');
560
560
  }
561
- for (const gate of ['C1 — Scope', 'C2 — Findings', 'C3 — Done']) {
561
+ for (const gate of ['GATE-SCOPE', 'GATE-REVIEW', 'GATE-DONE']) {
562
562
  if (!files.skill.includes(gate)) issues.push(`human-gate-${gate.slice(0, 2).toLowerCase()}`);
563
563
  }
564
564
  if (!files.review.includes('fresh-context red team')
@@ -596,7 +596,7 @@ function authoringProjectionIssues(files) {
596
596
  }
597
597
  if (!files.codex.includes('flat `task-NN-*.md` files')
598
598
  || !files.codex.includes('inline `## Receipt`')
599
- || !files.codex.includes('C1') || !files.codex.includes('C2') || !files.codex.includes('C3')) {
599
+ || !files.codex.includes('GATE-SCOPE') || !files.codex.includes('GATE-REVIEW') || !files.codex.includes('GATE-DONE')) {
600
600
  issues.push('codex-process-v3');
601
601
  }
602
602
  return [...new Set(issues)].sort();
@@ -1203,8 +1203,8 @@ function assertInstalledAuthoringProjection(root, installedRoot) {
1203
1203
  name: 'fresh-original-counterexample-replay',
1204
1204
  issue: 'repair-closure',
1205
1205
  relative: 'references/review.md',
1206
- from: 'After applying an accepted C2 finding, a fresh-context closure pass records and\nfreshly replays its original counterexample after the repair under this exact review-log header:',
1207
- to: 'After applying an accepted C2 finding, record the repair under this review-log header:'
1206
+ from: 'After applying an accepted GATE-REVIEW finding, a fresh-context closure pass records and\nfreshly replays its original counterexample after the repair under this exact review-log header:',
1207
+ to: 'After applying an accepted GATE-REVIEW finding, record the repair under this review-log header:'
1208
1208
  },
1209
1209
  {
1210
1210
  name: 'distinct-repair-and-proof-evidence',
@@ -1313,7 +1313,7 @@ function assertInstalledAuthoringProjection(root, installedRoot) {
1313
1313
  ['stale-profile-after-c2', 'templates', ADAPTIVE_COVERAGE_CLAUSES.profileRederivation,
1314
1314
  'Keep existing coverage rows after accepted plan changes.', ['profile-lifecycle']],
1315
1315
  ['planned-proof-blocks-start', 'templates', ADAPTIVE_COVERAGE_CLAUSES.plannedProof,
1316
- '`Required proof` is execution evidence: known but unrun proof blocks `pending`; `UNKNOWN` may proceed; missing evidence may still reach `done`/C3.', ['proof-lifecycle']],
1316
+ '`Required proof` is execution evidence: known but unrun proof blocks `pending`; `UNKNOWN` may proceed; missing evidence may still reach `done`/GATE-DONE.', ['proof-lifecycle']],
1317
1317
  ['source-promotes-live', 'templates', ADAPTIVE_COVERAGE_CLAUSES.proofSeparation,
1318
1318
  'Source proof may promote installed and live proof.', ['proof-lifecycle']],
1319
1319
  ['unmapped-proof-level', 'templates', IMPLEMENTATION_READINESS_CLAUSES.proofLevelMapping,
@@ -1327,7 +1327,7 @@ function assertInstalledAuthoringProjection(root, installedRoot) {
1327
1327
  ['spec-maker-examples-decide', 'specMaker', ADAPTIVE_COVERAGE_CLAUSES.specMakerAmbiguity,
1328
1328
  'Use examples to settle every ambiguous observable behavior.', ['spec-maker-authority']],
1329
1329
  ['spec-maker-skips-brainstorm', 'specMaker', ADAPTIVE_COVERAGE_CLAUSES.specMakerRoute,
1330
- 'Apply the risk-first route before C1 and stop only for direct work.', ['spec-maker-authority']],
1330
+ 'Apply the risk-first route before GATE-SCOPE and stop only for direct work.', ['spec-maker-authority']],
1331
1331
  ['static-proves-live', 'skill', ADAPTIVE_COVERAGE_CLAUSES.liveLimit,
1332
1332
  'Source/static checks prove live-model adherence.', ['proof-lifecycle']]
1333
1333
  ];
@@ -1561,13 +1561,15 @@ test('Codex structured-input corpus oracle stays differential and production-awa
1561
1561
  'src/claude/agents/spec-maker.md',
1562
1562
  'src/claude/hooks/session.cjs',
1563
1563
  'src/claude/skills/git/SKILL.md',
1564
- 'src/claude/skills/inspect/SKILL.md'
1564
+ 'src/claude/skills/scout/SKILL.md',
1565
+ 'src/claude/skills/sync/references/rebind-and-audit.md'
1565
1566
  ];
1566
1567
  assert.deepEqual(actualPaths, expectedPaths, 'every source occurrence needs an explicit projection oracle');
1567
1568
 
1568
1569
  const instructionExpectedSnippets = new Map([
1569
1570
  ['src/claude/skills/git/SKILL.md', 'Present options via a structured user-input request — header'],
1570
- ['src/claude/skills/inspect/SKILL.md', '**Fallback to a structured user-input request:**']
1571
+ ['src/claude/skills/scout/SKILL.md', '**Fallback to a structured user-input request:**'],
1572
+ ['src/claude/skills/sync/references/rebind-and-audit.md', 'End by asking with a structured user-input request when the host has']
1571
1573
  ]);
1572
1574
  for (const [relativePath, expectedSnippet] of instructionExpectedSnippets) {
1573
1575
  const sourcePath = path.join(PACKAGE_ROOT, relativePath);
@@ -1983,8 +1985,7 @@ test('Codex Windows hook launchers stay project-bound without Git from nested cw
1983
1985
  );
1984
1986
  const launchers = allHookLaunchers(config);
1985
1987
  assert.ok(launchers.length > 0, 'installed Codex config must register hook launchers');
1986
- const semanticReviewEvents = [];
1987
- for (const { event, handler } of launchers) {
1988
+ for (const { handler } of launchers) {
1988
1989
  assert.doesNotMatch(handler.commandWindows, /\$\(/);
1989
1990
  assert.doesNotMatch(handler.commandWindows, /\bgit\b/i);
1990
1991
  assert.doesNotMatch(handler.commandWindows, /process\.cwd\(\)|existsSync/);
@@ -1997,11 +1998,7 @@ test('Codex Windows hook launchers stay project-bound without Git from nested cw
1997
1998
  true,
1998
1999
  `missing installed hook: ${path.basename(target)}`
1999
2000
  );
2000
- if (path.basename(target) === 'semantic-review-authority.cjs') {
2001
- semanticReviewEvents.push(event);
2002
- }
2003
2001
  }
2004
- assert.deepEqual(semanticReviewEvents, ['SubagentStop']);
2005
2002
 
2006
2003
  const nested = path.join(projectRoot, 'nested', 'workspace');
2007
2004
  fs.mkdirSync(nested, { recursive: true });
@@ -2260,24 +2257,24 @@ test('Codex installed Specs and spec-maker reject adaptive coverage mutations',
2260
2257
  assert.ok(skillNames.every((name) => /^[a-z0-9-]+$/.test(name)));
2261
2258
 
2262
2259
  const scoutSkill = fs.readFileSync(
2263
- path.join(root, '.agents', 'skills', 'inspect', 'SKILL.md'),
2260
+ path.join(root, '.agents', 'skills', 'scout', 'SKILL.md'),
2264
2261
  'utf8'
2265
2262
  );
2266
2263
  assert.match(scoutSkill, /^name:\s*cf-scout$/m);
2267
2264
  assert.equal(
2268
- fs.existsSync(path.join(root, '.agents', 'skills', 'scout')),
2265
+ fs.existsSync(path.join(root, '.agents', 'skills', 'inspect')),
2269
2266
  false,
2270
- 'public Scout rename must keep the manifest-owned inspect directory'
2267
+ 'Scout lives in the scout directory; the retired inspect directory must not be installed'
2271
2268
  );
2272
2269
  const askSkill = fs.readFileSync(
2273
- path.join(root, '.agents', 'skills', 'question', 'SKILL.md'),
2270
+ path.join(root, '.agents', 'skills', 'ask', 'SKILL.md'),
2274
2271
  'utf8'
2275
2272
  );
2276
2273
  assert.match(askSkill, /^name:\s*cf-ask$/m);
2277
2274
  assert.equal(
2278
- fs.existsSync(path.join(root, '.agents', 'skills', 'ask')),
2275
+ fs.existsSync(path.join(root, '.agents', 'skills', 'question')),
2279
2276
  false,
2280
- 'public Ask rename must keep the manifest-owned question directory'
2277
+ 'Ask lives in the ask directory; the retired question directory must not be installed'
2281
2278
  );
2282
2279
 
2283
2280
  const catalog = spawnSync(
@@ -2338,7 +2335,7 @@ test('Codex installed Specs and spec-maker reject adaptive coverage mutations',
2338
2335
  (key.startsWith('.codex/') || key.startsWith('.agents/')) && !key.includes('../')
2339
2336
  )));
2340
2337
 
2341
- const questionSkill = path.join(root, '.agents', 'skills', 'question', 'SKILL.md');
2338
+ const questionSkill = path.join(root, '.agents', 'skills', 'ask', 'SKILL.md');
2342
2339
  fs.appendFileSync(questionSkill, '\nUSER-CODEX-SENTINEL\n');
2343
2340
  // Fresh installs are exact. Refresh/upgrade intentionally documents the
2344
2341
  // current Codex limitation: removed skill paths are not pruned.
@@ -2426,7 +2423,7 @@ test('Codex installed Brainstorm skill reference and agent preserve proportional
2426
2423
  const mutations = [
2427
2424
  {
2428
2425
  name: 'adaptive-direct-precedence-removed', source: 'skill',
2429
- from: 'Route Direct first, then\napply controls only to requests that remain in Brainstorm.',
2426
+ from: 'Route Direct first, then apply controls only to requests that remain in Brainstorm.',
2430
2427
  to: 'Apply controls before Direct classification.', expected: ['adaptive-direct-precedence']
2431
2428
  },
2432
2429
  {
@@ -2441,37 +2438,37 @@ test('Codex installed Brainstorm skill reference and agent preserve proportional
2441
2438
  },
2442
2439
  {
2443
2440
  name: 'adaptive-failure-isolation-removed', source: 'skill',
2444
- from: 'failure isolation for partial or cascading failure\nacross boundaries',
2441
+ from: 'failure isolation for partial or cascading failure across boundaries',
2445
2442
  to: 'generic failure notes', expected: ['adaptive-lens-trigger-skip']
2446
2443
  },
2447
2444
  {
2448
2445
  name: 'adaptive-evidence-fallback-removed', source: 'skill',
2449
- from: 'Missing evidence\nforces feasibility `unknown` and confidence `low`.',
2446
+ from: 'Missing evidence forces feasibility `unknown` and confidence `low`.',
2450
2447
  to: 'Missing evidence permits a confident guess.', expected: ['adaptive-evidence-semantics']
2451
2448
  },
2452
2449
  {
2453
2450
  name: 'adaptive-numeric-evidence-removed', source: 'skill',
2454
- from: 'A numeric estimate requires\nrange, unit, basis, evidence, and assumptions; otherwise report `unknown`.',
2451
+ from: 'A numeric estimate requires range, unit, basis, evidence, and assumptions; otherwise report `unknown`.',
2455
2452
  to: 'A numeric estimate may be a best-effort number.', expected: ['adaptive-numeric-estimates']
2456
2453
  },
2457
2454
  {
2458
2455
  name: 'adaptive-pre-tool-redaction-removed', source: 'skill',
2459
- from: 'Before an\nexternal visual tool or adviser handoff, minimize context and redact secrets,\ncredentials, private keys, access tokens, and unnecessary PII.',
2456
+ from: 'Before an external visual tool or adviser handoff, minimize context and redact secrets, credentials, private keys, access tokens, and unnecessary PII.',
2460
2457
  to: 'Forward full context to every external tool and adviser.', expected: ['adaptive-pre-tool-redaction']
2461
2458
  },
2462
2459
  {
2463
2460
  name: 'adaptive-adviser-gate-removed', source: 'skill',
2464
- from: '`--advice` invokes\n`brainstormer` only after the material-choice gate;',
2461
+ from: '`--advice` invokes `brainstormer` only after the material-choice gate;',
2465
2462
  to: '`--advice` invokes `brainstormer` before routing;', expected: ['adaptive-adviser-gate']
2466
2463
  },
2467
2464
  {
2468
2465
  name: 'adaptive-decision-freshness-removed', source: 'skill',
2469
- from: 'The first section records target\nidentity, current source revision and worktree state or `[UNVERIFIED]`, an\nevidence-as-of value, and what change invalidates the brief.',
2466
+ from: 'The first section records target identity, current source revision and worktree state or `[UNVERIFIED]`, an evidence-as-of value, and what change invalidates the brief.',
2470
2467
  to: 'The handoff has no revision or freshness binding.', expected: ['adaptive-decision-freshness']
2471
2468
  },
2472
2469
  {
2473
2470
  name: 'adaptive-overlay-authority-removed', source: 'skill',
2474
- from: 'Neither overlay\nwrites, approves, persists, dispatches, or completes work.',
2471
+ from: 'Neither overlay writes, approves, persists, dispatches, or completes work.',
2475
2472
  to: 'Overlays may persist, approve, dispatch, and complete work.', expected: ['adaptive-non-authority']
2476
2473
  },
2477
2474
  {
@@ -2491,7 +2488,7 @@ test('Codex installed Brainstorm skill reference and agent preserve proportional
2491
2488
  {
2492
2489
  name: 'exploration-stop-removed',
2493
2490
  source: 'skill',
2494
- from: 'Do not request design approval, persist a report, or\n invoke another workflow without a new explicit request.',
2491
+ from: 'Do not request design approval, persist a report, or invoke another workflow without a new explicit request.',
2495
2492
  to: 'Request approval, persist a report, and invoke another workflow.',
2496
2493
  expected: ['exploration-stop']
2497
2494
  },
@@ -2841,7 +2838,7 @@ function hotfixProjectionIssues(files) {
2841
2838
  }
2842
2839
  if (!parallel.includes('Diagnosis still starts only')
2843
2840
  || !parallel.includes('after the required scout outputs are synthesized')
2844
- || !parallel.includes('Research begins only after Step 2 diagnosis')
2841
+ || !parallel.includes('Research begins only after diagnosis')
2845
2842
  || parallel.includes('scout + diagnose + research together')
2846
2843
  || parallel.includes("You don't need to wait for scouting")) {
2847
2844
  issues.add('scout-before-diagnosis');
@@ -2858,9 +2855,9 @@ test('Codex installed Fix preserves the adaptive repair contract', () => {
2858
2855
  const result = install(root);
2859
2856
  assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
2860
2857
 
2861
- const installedRoot = path.join(root, '.agents/skills/hotfix');
2862
- assert.equal(fs.existsSync(path.join(root, '.agents/skills/fix')), false,
2863
- 'public Fix rename must keep the manifest-owned hotfix directory');
2858
+ const installedRoot = path.join(root, '.agents/skills/fix');
2859
+ assert.equal(fs.existsSync(path.join(root, '.agents/skills/hotfix')), false,
2860
+ 'Fix lives in the fix directory; the retired hotfix directory must not be installed');
2864
2861
  for (const relative of HOTFIX_BUNDLE) {
2865
2862
  const sourcePath = path.join(HOTFIX_SOURCE_ROOT, relative);
2866
2863
  assert.equal(
@@ -2952,7 +2949,7 @@ test('Codex installed Fix preserves the adaptive repair contract', () => {
2952
2949
  },
2953
2950
  {
2954
2951
  name: 'research-starts-before-diagnosis', file: 'references/parallel-patterns.md',
2955
- from: 'Research begins only after Step 2 diagnosis', to: 'Research may begin before Step 2 diagnosis',
2952
+ from: 'Research begins only after diagnosis', to: 'Research may begin before diagnosis',
2956
2953
  expected: ['scout-before-diagnosis']
2957
2954
  }
2958
2955
  ];
@@ -3162,16 +3159,14 @@ test('Codex install on top of existing Claude installation preserves content and
3162
3159
  });
3163
3160
  });
3164
3161
 
3165
- test('Codex installed code_auditor contains Strict conditional marker', () => {
3162
+ test('Codex installed code_auditor carries no Strict attestation marker', () => {
3166
3163
  inTempProject((root) => {
3167
3164
  const result = install(root);
3168
3165
  assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
3169
3166
  const toml = fs.readFileSync(path.join(root, '.codex', 'agents', 'code_auditor.toml'), 'utf8');
3170
- assert.match(toml, /Strict Semantic Review Attestation/);
3171
- assert.match(toml, /CAFEKIT_SEMANTIC_REVIEW_ATTESTATION/);
3172
- assert.match(toml, /MAC-protected host-hook observation/);
3173
- assert.doesNotMatch(toml, /host-signed/);
3174
- assert.match(toml, /specs\/<feature>\/spec\.json/);
3167
+ assert.doesNotMatch(toml, /CAFEKIT_SEMANTIC_REVIEW_ATTESTATION/);
3168
+ assert.doesNotMatch(toml, /Strict Semantic Review Attestation/);
3169
+ assert.doesNotMatch(toml, /MAC-protected host-hook observation/);
3175
3170
  });
3176
3171
  });
3177
3172
 
@@ -3195,26 +3190,14 @@ test('Codex scaffold resolver rejects symlink template', () => {
3195
3190
  });
3196
3191
  });
3197
3192
 
3198
- test('Claude and Codex installed Route preserve proportional live-catalog semantics', () => {
3193
+ test('Claude and Codex installed routing rules preserve the live-catalog semantics and install no Route', () => {
3199
3194
  inTempProject((root) => {
3200
3195
  const result = installPlatforms(root, ['claude', 'codex']);
3201
3196
  assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
3202
- const sourceRoot = path.join(PACKAGE_ROOT, 'src/claude/skills/route');
3203
- const expectedFiles = [
3204
- 'SKILL.md', 'references/task-taxonomy.md',
3205
- 'references/chaining-patterns.md', 'references/agent-timing.md'
3206
- ];
3207
3197
  const expectedRules = ['skill-workflow-routing.md', 'skill-domain-routing.md'];
3208
3198
  for (const runtime of ['claude', 'codex']) {
3209
3199
  const installedRoot = path.join(root, runtime === 'codex' ? '.agents/skills/route' : '.claude/skills/route');
3210
- for (const relative of expectedFiles) {
3211
- const source = fs.readFileSync(path.join(sourceRoot, relative), 'utf8');
3212
- const installed = fs.readFileSync(path.join(installedRoot, relative), 'utf8');
3213
- const expected = runtime === 'codex'
3214
- ? normalizeCodexBody(source, path.join(sourceRoot, relative))
3215
- : source;
3216
- assert.equal(installed, expected, `${runtime}:${relative}`);
3217
- }
3200
+ assert.equal(fs.existsSync(installedRoot), false, `${runtime} still installs Route`);
3218
3201
  for (const relative of expectedRules) {
3219
3202
  const sourcePath = path.join(PACKAGE_ROOT, 'src/claude/rules', relative);
3220
3203
  const source = fs.readFileSync(sourcePath, 'utf8');
@@ -3224,12 +3207,8 @@ test('Claude and Codex installed Route preserve proportional live-catalog semant
3224
3207
  const expected = runtime === 'codex' ? normalizeCodexBody(source, sourcePath) : source;
3225
3208
  assert.equal(installed, expected, `${runtime}:rules/${relative}`);
3226
3209
  }
3227
- const route = fs.readFileSync(path.join(installedRoot, 'SKILL.md'), 'utf8');
3228
- assert.match(route, /names a valid installed skill[\s\S]*one installed skill clearly covers[\s\S]*Direct factual conversation/);
3229
- assert.match(route, /highest-link[\s\S]*risk[\s\S]*number of material domains/);
3230
- assert.match(route, /never expand it/);
3231
3210
  const catalog = installedCatalog(root, runtime);
3232
- assert.ok(catalog.skills.some((skill) => skill.public_id === 'cf:route'));
3211
+ assert.equal(catalog.skills.some((skill) => skill.public_id === 'cf:route'), false);
3233
3212
  assert.equal(catalog.skills.some((skill) => skill.public_id === 'cf:docs'), false);
3234
3213
  }
3235
3214
  });
@@ -3304,24 +3283,3 @@ test('Claude and Codex installed rules preserve the ported review and process gu
3304
3283
  });
3305
3284
  });
3306
3285
 
3307
- test('installed Route degrades safely when an agent is absent', () => {
3308
- inTempProject((root) => {
3309
- const result = installPlatforms(root, ['claude', 'codex']);
3310
- assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
3311
- const cases = [
3312
- ['claude', '.claude/agents/researcher.md', '.claude/skills/route'],
3313
- ['codex', '.codex/agents/researcher.toml', '.agents/skills/route'],
3314
- ];
3315
- for (const [runtime, agentRelative, routeRelative] of cases) {
3316
- fs.rmSync(path.join(root, agentRelative), { force: true });
3317
- assert.equal(fs.existsSync(path.join(root, agentRelative)), false);
3318
- const timing = fs.readFileSync(path.join(root, routeRelative, 'references/agent-timing.md'), 'utf8');
3319
- const route = fs.readFileSync(path.join(root, routeRelative, 'SKILL.md'), 'utf8');
3320
- const normalizedRoute = route.replace(/\s+/g, ' ');
3321
- assert.match(timing, /If the preferred agent is absent[\s\S]*never synthesize a role/);
3322
- assert.match(normalizedRoute, /continue inline when safe or return the named gap/);
3323
- assert.match(normalizedRoute, /Never synthesize an unavailable agent/);
3324
- assert.doesNotMatch(`${timing}\n${route}`, /researcher(?:\.md|\.toml)/i, runtime);
3325
- }
3326
- });
3327
- });