ruvnet-brain 4.6.3 → 4.7.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 (75) hide show
  1. package/README.md +1 -1
  2. package/bin/install.mjs +6 -50
  3. package/config/practical-rule-catalog.json +22 -22
  4. package/console/app.js +1 -1
  5. package/console/architecture.html +2 -2
  6. package/package.json +2 -2
  7. package/plugin/.claude-plugin/plugin.json +1 -1
  8. package/plugin/.codex-plugin/plugin.json +1 -1
  9. package/plugin/commands/checkpoint.md +22 -40
  10. package/plugin/commands/rnb-brief.md +18 -15
  11. package/plugin/hooks/codex-hooks.json +1 -58
  12. package/plugin/hooks/hook-contracts.json +19 -220
  13. package/plugin/hooks/hooks.json +1 -70
  14. package/plugin/mcp/managed-cli-interface.mjs +0 -56
  15. package/plugin/scripts/agentdb-recall-reader.mjs +29 -9
  16. package/plugin/scripts/agentdb-recall.mjs +27 -21
  17. package/plugin/scripts/brain-footprint.mjs +1 -1
  18. package/plugin/scripts/codex-hook-wrapper.mjs +13 -3
  19. package/plugin/scripts/completion-claim-evidence.mjs +1 -1
  20. package/plugin/scripts/continuation-gate.mjs +78 -1
  21. package/plugin/scripts/continuity-events.mjs +90 -82
  22. package/plugin/scripts/continuity-hook-policy.mjs +5 -14
  23. package/plugin/scripts/decision-gate.mjs +3 -3
  24. package/plugin/scripts/decision-recall-gate.mjs +141 -0
  25. package/plugin/scripts/decision-record.mjs +324 -0
  26. package/plugin/scripts/deferral-evidence.mjs +134 -0
  27. package/plugin/scripts/hook-failures.mjs +61 -0
  28. package/plugin/scripts/hook-shim.mjs +71 -6
  29. package/plugin/scripts/learn-capture.mjs +88 -37
  30. package/plugin/scripts/learning-store.mjs +70 -60
  31. package/plugin/scripts/node-sqlite.mjs +1 -1
  32. package/plugin/scripts/ruflo-bin.mjs +71 -1
  33. package/plugin/scripts/ruflo-memory-hooks.mjs +132 -0
  34. package/plugin/scripts/runtime-preferences.mjs +1 -1
  35. package/plugin/scripts/session-snapshot-hook.mjs +85 -332
  36. package/plugin/scripts/session-start-core.mjs +7 -9
  37. package/plugin/scripts/signal-watch.mjs +1 -1
  38. package/plugin/scripts/substitution-wall.mjs +222 -0
  39. package/plugin/scripts/turn-outcome-capture.mjs +74 -88
  40. package/scripts/codex-host-execution-proof.mjs +1 -1
  41. package/scripts/console-engine.mjs +0 -32
  42. package/scripts/deferral-replay.mjs +47 -0
  43. package/scripts/health-repair.mjs +1 -81
  44. package/scripts/hook-qualify-core.mjs +2 -2
  45. package/scripts/model-managed-workflow-service.mjs +9 -10
  46. package/scripts/model-routing-controller.mjs +9 -8
  47. package/scripts/no-silent-substitution.mjs +65 -1
  48. package/scripts/onboarding-console.mjs +8 -23
  49. package/scripts/product-integrity-contract.mjs +1 -1
  50. package/scripts/release-qualification-contract.mjs +9 -27
  51. package/scripts/remedy-registry.mjs +0 -18
  52. package/scripts/wired-check.mjs +1 -5
  53. package/plugin/scripts/continuity-brief.mjs +0 -357
  54. package/plugin/scripts/continuity-journal.mjs +0 -553
  55. package/plugin/scripts/learn-flush.mjs +0 -96
  56. package/plugin/scripts/learning-observation.mjs +0 -51
  57. package/plugin/scripts/learning-queue.mjs +0 -135
  58. package/plugin/scripts/learning-worker-supervisor.mjs +0 -79
  59. package/plugin/scripts/project-capture-queue.mjs +0 -357
  60. package/plugin/scripts/project-memory-enrollment.mjs +0 -203
  61. package/plugin/scripts/project-progression-checkpoint.mjs +0 -145
  62. package/plugin/scripts/project-progression-contract.mjs +0 -496
  63. package/plugin/scripts/project-progression-hook.mjs +0 -233
  64. package/plugin/scripts/project-progression-outbox.mjs +0 -225
  65. package/plugin/scripts/project-progression-producer.mjs +0 -309
  66. package/plugin/scripts/project-progression-reader.mjs +0 -304
  67. package/plugin/scripts/project-progression-session-start.mjs +0 -320
  68. package/plugin/scripts/project-progression-sources.mjs +0 -246
  69. package/plugin/scripts/project-progression-store.mjs +0 -723
  70. package/plugin/scripts/project-progression-suspension.mjs +0 -60
  71. package/plugin/scripts/project-transition-hook.mjs +0 -246
  72. package/plugin/scripts/session-snapshot-contract.mjs +0 -105
  73. package/plugin/scripts/turn-transport-journal.mjs +0 -108
  74. package/scripts/qa/progression-validation-benchmark.mjs +0 -66
  75. package/scripts/session-snapshot-contract.mjs +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ruvnet-brain",
3
- "version": "4.6.3",
3
+ "version": "4.7.0",
4
4
  "description": "One-command installer for RuvNet Brain — a portable, source-grounded brain over rUv's RuvNet building blocks, delivered as a Claude Code plugin so Claude uses the stack instead of fighting it.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -73,11 +73,11 @@
73
73
  "cap:report": "node scripts/rerank-cap-eval.mjs --report",
74
74
  "cap:ab": "node scripts/rerank-cap-warm-ab.mjs",
75
75
  "completion-claim:replay": "node scripts/completion-claim-replay.mjs",
76
+ "deferral:replay": "node scripts/deferral-replay.mjs",
76
77
  "hooks:check": "node scripts/hook-retirement-check.mjs",
77
78
  "release:qualify": "node scripts/release-qualification.mjs",
78
79
  "rehearse:corpus": "node scripts/rehearse-corpus-pipeline.mjs",
79
80
  "single-source:check": "node scripts/single-source-check.mjs",
80
- "benchmark:continuity": "node scripts/qa/progression-validation-benchmark.mjs",
81
81
  "host:codex:execution-proof": "node scripts/codex-host-execution-proof.mjs"
82
82
  },
83
83
  "files": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ruvnet-brain",
3
3
  "description": "RuvNet brain transplant for Claude Code — grounds every RuvNet decision in real source across 77 rUv repositories, prefers Ruflo / RuVector-RVF / AgentDB over training-prior defaults (pgvector, Pinecone, hand-rolled cosine), and can pull in any RuvNet repo on demand. Ships a UserPromptSubmit retrieve-and-inject grounding hook and a PreToolUse write gate that refuses ungrounded rUv-product code until search_ruvnet has been consulted (ADR-0012 / ADR-067).",
4
- "version": "4.6.3",
4
+ "version": "4.7.0",
5
5
  "author": {
6
6
  "name": "Stuart Kerr"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ruvnet-brain",
3
- "version": "4.6.3",
3
+ "version": "4.7.0",
4
4
  "description": "Source-grounded RuvNet knowledge, lifecycle enforcement, and learning for Codex.",
5
5
  "author": {
6
6
  "name": "Stuart Kerr"
@@ -1,61 +1,43 @@
1
1
  ---
2
- description: "Write a full project checkpoint to this project's canonical AgentDB store — the goal, the acceptance contract, the decisions, what is done, what is blocked, and the exact next action — so the next session (in Claude Code or Codex) resumes from a verified record instead of from nothing. Prints a read-back receipt."
3
- updated: 2026-09-11
2
+ description: "Write a project checkpoint to this project's AgentDB store with `ruflo memory store` — the goal, the acceptance contract, the decisions, what is done, what is blocked, and the exact next action — and prove it by exact-key `ruflo memory retrieve`. The next session (Claude Code or Codex) restores the newest checkpoint by exact key."
3
+ updated: 2026-10-12
4
4
  ---
5
5
 
6
6
  # RuvNet-Brain: checkpoint
7
7
 
8
8
  The user is asking you to **persist the state of this project** so the next session can resume it.
9
9
 
10
- Automatic capture already runs at Stop, PreCompact and SessionEnd, and it records everything that can
11
- be READ from the machine: the git tree, their work ledger, their newest `project-state-current` note,
12
- a bounded transcript reference. **It cannot read what only you know** — the acceptance contract you
13
- are working to, the decision you just made and why, the exact next action. That is what this command
14
- is for, and it is why a checkpoint is worth more than another automatic snapshot.
10
+ PreCompact and SessionEnd already store a small automatic `project-state-auto-<ms>` marker (event,
11
+ branch, head). **It cannot record what only you know** — the acceptance contract, the decision you
12
+ just made and why, the exact next action. That is what this command is for.
15
13
 
16
14
  ## Do this
17
15
 
18
- **1. Write down the real state — from THIS session, not from a template.**
16
+ **1. Write down the real state — from THIS session, not from a template.** Plain text or JSON with the
17
+ fields you can honestly fill: current goal, acceptance contract, next action, decisions (and why),
18
+ completed / in progress / blockers, failures, changed files, proof artifacts, and what is UNTESTED.
19
+ Empty is better than invented: a fabricated "next action" is worse than none.
19
20
 
20
- Build a JSON object with the fields you can honestly fill. Every field is optional; set at least one.
21
- Empty is better than invented: a fabricated "next action" is worse than no next action, because the
22
- next session will act on it.
23
-
24
- | field | what goes in it |
25
- |---|---|
26
- | `currentGoal` | one sentence: what this work is actually for |
27
- | `acceptanceContract` | what would make it DONE — the conditions, not the vibe |
28
- | `nextAction` | the single next concrete step, specific enough to start cold |
29
- | `decisions` | decisions made and WHY; include the ones you'd otherwise have to re-derive |
30
- | `completed` / `inProgress` / `blockers` | honest status; a blocker named is a blocker halved |
31
- | `failures` | what was tried and did not work, so it is not tried again |
32
- | `changedFiles` | the files this work touched |
33
- | `proofArtifacts` | commands run, outputs seen, receipts — the evidence, not the claim |
34
- | `untested` | what was built but NOT verified. Do not omit this one. |
35
-
36
- **2. Store it.**
21
+ **2. Store it with rUv's own tool** (append-only: a new key every time, never an update), in the
22
+ project's namespace (the repository directory name):
37
23
 
38
24
  ```bash
39
- node "${CLAUDE_PLUGIN_ROOT}/scripts/project-progression-checkpoint.mjs" --json '<your JSON>'
25
+ KEY="project-state-current-$(node -e 'process.stdout.write(String(Date.now()))')"
26
+ ruflo memory store -k "$KEY" -n "<project-dir-name>" --path "<project>/.swarm/memory.db" --value "<the checkpoint text>"
40
27
  ```
41
28
 
42
- For anything longer than a line or two, write the JSON to a temp file first and use
43
- `--json-file <path>` — a large single-quoted argument is how a shell mangles a checkpoint.
44
-
45
- **3. Report the receipt, not a claim.**
29
+ **3. Prove it, then report the receipt, not a claim.**
46
30
 
47
- The command prints the exact event key, the payload digest, and the digest of the row **read back
48
- from the store by that exact key**. Tell the user it is stored only when `readbackVerified` is
49
- `true`. If the command exits non-zero, say exactly what it printed — an unstored checkpoint that is
50
- reported as stored is the specific failure this whole system exists to prevent.
31
+ ```bash
32
+ ruflo memory retrieve -k "$KEY" -n "<project-dir-name>" --path "<project>/.swarm/memory.db" --value-only
33
+ ```
51
34
 
52
- If it reports `replayedPending`, say so: those were snapshots a previously interrupted session had
53
- made durable but never committed, and this checkpoint settled them.
35
+ Say it is stored only when the retrieved value is exactly what you stored. If either command exits
36
+ non-zero, quote what it printed.
54
37
 
55
38
  ## What NOT to do
56
39
 
57
40
  - **Do not** invent progress, decisions, or proof to make the checkpoint look complete.
58
- - **Do not** write the user's secrets into it. Redaction runs anyway, but do not rely on it.
59
- - **Do not** hand-write rows into `.swarm/memory.db` or call `ruflo memory store` yourself. This
60
- command is the one writer; a second path is how two stores drift apart.
61
- - **Do not** claim the next session "will remember" anything the receipt did not confirm.
41
+ - **Do not** write secrets into it.
42
+ - **Do not** reuse a key: `project-state-current-<epochms>` is append-only, so concurrent sessions never
43
+ overwrite each other. SessionStart restores the newest one by exact key.
@@ -1,41 +1,44 @@
1
1
  ---
2
- description: "Come up to speed on this project from AgentDB: the brief (state, what changed, decisions, standing rules, open items, gate outcomes, agent findings) and, on request, the full recorded history. Also records a decision, lesson or open item explicitly, with a read-back receipt."
3
- updated: 2026-10-01
2
+ description: "Come up to speed on this project from AgentDB with rUv's own tools: the newest project-state-current checkpoint, lessons, recent turn outcomes and decisions, read by exact key with `ruflo memory list|retrieve|search`. Also records a decision, lesson or open item with a read-back receipt."
3
+ updated: 2026-10-12
4
4
  ---
5
5
 
6
6
  # RuvNet-Brain: rnb-brief
7
7
 
8
8
  The user wants to know **what has happened on this project**, from the record — not from your memory.
9
+ Every command below is `ruflo` (the global binary); `<db>` is `<project>/.swarm/memory.db` and `<ns>` is
10
+ the project directory name.
9
11
 
10
12
  ## Do this
11
13
 
12
- **1. Show the brief.** Run it and show the output as-is:
14
+ **1. The newest checkpoint.** List, pick the newest `project-state-current-*` key, read it exactly:
13
15
 
14
16
  ```bash
15
- node "${CLAUDE_PLUGIN_ROOT}/scripts/continuity-brief.mjs"
17
+ ruflo memory list -n <ns> --limit 1000 --format json --path <db>
18
+ ruflo memory retrieve -k <newest project-state-current-key> -n <ns> --value-only --path <db>
16
19
  ```
17
20
 
18
- **2. If they asked for more** (history, "everything", one kind of thing, a time window), pull it:
21
+ **2. Lessons, decisions and recent turns.**
19
22
 
20
23
  ```bash
21
- node "${CLAUDE_PLUGIN_ROOT}/scripts/continuity-brief.mjs" --full [--kind decision|lesson|commit|release|gate|finding|open-item] [--since 7d] [--limit 200]
24
+ ruflo memory list -n lessons --format json --path <db>
25
+ ruflo memory list -n turns --limit 20 --format json --path <db>
26
+ ruflo memory search -q "<what the user asked about>" -n continuity-events --limit 10 --path <db>
22
27
  ```
23
28
 
24
- Every line carries its provenance (the AgentDB key and time, or the commit SHA). Quote it when you
25
- rely on an item. A line marked `detected` was inferred from the transcript, not stated explicitly —
26
- say so. A line marked `PENDING` is durable in the outbox but not yet committed to AgentDB.
29
+ Quote the key of every item you rely on. Search hits are ranked previews: read the exact value with
30
+ `ruflo memory retrieve` before asserting it.
27
31
 
28
32
  **3. If they asked you to record something** (a decision, a standing rule, an open item):
29
33
 
30
34
  ```bash
31
- node "${CLAUDE_PLUGIN_ROOT}/scripts/continuity-brief.mjs" --record --kind decision|lesson|open-item --text "<exactly what was decided>" [--owner "<who>"]
35
+ ruflo memory store -k "<decision|lesson|open-item>-$(node -e 'process.stdout.write(String(Date.now()))')" -n continuity-events --path <db> --value "<exactly what was decided>"
36
+ ruflo memory retrieve -k <that key> -n continuity-events --value-only --path <db>
32
37
  ```
33
38
 
34
- Report it as stored only when it prints `stored-and-read-back`. `durable-pending` means it is safe in the
35
- outbox and will commit at the next capture boundary — say exactly that, not "stored".
39
+ Report it as stored only when the retrieved value matches exactly.
36
40
 
37
41
  ## What NOT to do
38
42
 
39
- - Do not summarize the history from memory or from the conversation instead of running the command.
40
- - Do not hand-write rows into `.swarm/memory.db` or call `ruflo memory store` for these yourself.
41
- - If the last line says `AgentDB: recording stuck`, tell the user that line verbatim before anything else.
43
+ - Do not summarize the history from memory or from the conversation instead of running the commands.
44
+ - Do not use the MCP `agentdb_hierarchical-*` tools for this: they read a different store.
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "RuvNet Brain continuity plane for Codex. Broad legacy automatic gates remain retired. Registrations here are MEASURED, not assumed: a probe hook was registered on all twelve event names the installed codex-cli 0.154.0 binary declares and a real `codex exec` run was observed (2026-09-11). SessionStart, UserPromptSubmit and SessionEnd FIRED and carry handlers. Stop keeps the pre-existing, project-scoped continuation gate; session-snapshot was added at Stop on 2026-09-29 to record each turn's outcome (turn-outcome-capture.mjs) — Codex SessionEnd carries no last_assistant_message, so Stop is the only boundary that can. Its delivery rests on codex-cli 0.158.0's declared stop.command.input schema and the other Codex Stop handlers; it has NOT been live-observed and fails open. PreCompact uses the existing session-snapshot capture handler: Codex0.160.1 declares this native boundary. Registration is not proof of native delivery; manual/automatic delivery remains separately evidenced. All handlers are bounded and fail open. Amended 2026-09-11: UserPromptSubmit also runs ground-ruvnet (grounding injection, ADR-040 §Amendment). Amended 2026-09-12: the 2026-09-11 PreToolUse/PostToolUse \"not observed\" note was measured with a prompt (`codex exec \"reply OK\"`) that never invoked a tool, so neither event had anything to fire on — that was an untested path, not a failing one. Re-probed with prompts that actually call a tool: a real apply_patch write fired PreToolUse/PostToolUse with tool_name \"apply_patch\", and a real MCP call to this repo's own search_ruvnet server fired both with tool_name \"mcp__ruvnet_brain__search_ruvnet\". Both are now registered below: decision-gate's write route (matcher includes apply_patch, Codex's raw write-tool name) and grounding-stamp (unchanged matcher already recognizes the mcp__..__search_ruvnet shape). The bash route (exec_command) remains unregistered — today's measurement covered a write and an MCP call, not exec_command, and extending on that evidence would be the same unproven leap this note replaces. Also added 2026-09-12: grounding-turn-mark (UserPromptSubmit) and grounding-turn-gate (Stop), the \"answered without searching\" pair — a prompt-level grounding directive is advisory, so this records whether it fired and forces continuation at Stop if no search_ruvnet call was recorded since (reusing grounding-stamp's own stamp evidence). Both are registered on Codex identically to Claude: the Stop-block contract (hookSpecificOutput.additionalContext) already has a proven Codex translation via codex-hook-adapter.mjs's Stop branch (see tests/unit/codex-lifecycle-hooks.test.mjs), the same path continuation-gate already uses. Capacity-aware parallel-work guidance is also registered at UserPromptSubmit: it advises the coordinator to launch only real independent workers within sampled resource headroom and the live runtime/tool cap; it never spawns workers or claims execution. Automatic normalized project observations are captured at prompt, pre-tool, post-tool and child completion; Claude also observes PostToolUseFailure. Pending and degraded memory are disclosed; this does not establish synchronous ADR-073 conformance or native Grok recall. SessionStart has an 8-second measured replay/restore envelope. Issue377: consent-eligible learning captures only fixed workflow metadata; lifecycle recovery schedules one finite worker. Original records remain retained with hash-bound acknowledgments. Native delivery must be separately evidenced; registration is not proof.",
2
+ "description": "RuvNet Brain continuity plane for Codex. Broad legacy automatic gates remain retired. Registrations here are MEASURED, not assumed: a probe hook was registered on all twelve event names the installed codex-cli 0.154.0 binary declares and a real `codex exec` run was observed (2026-09-11). SessionStart, UserPromptSubmit and SessionEnd FIRED and carry handlers. Stop keeps the pre-existing, project-scoped continuation gate; session-snapshot was added at Stop on 2026-09-29 to record each turn's outcome (turn-outcome-capture.mjs) — Codex SessionEnd carries no last_assistant_message, so Stop is the only boundary that can. Its delivery rests on codex-cli 0.158.0's declared stop.command.input schema and the other Codex Stop handlers; it has NOT been live-observed and fails open. PreCompact uses the existing session-snapshot capture handler: Codex0.160.1 declares this native boundary. Registration is not proof of native delivery; manual/automatic delivery remains separately evidenced. All handlers are bounded and fail open. Amended 2026-09-11: UserPromptSubmit also runs ground-ruvnet (grounding injection, ADR-040 §Amendment). Amended 2026-09-12: the 2026-09-11 PreToolUse/PostToolUse \"not observed\" note was measured with a prompt (`codex exec \"reply OK\"`) that never invoked a tool, so neither event had anything to fire on — that was an untested path, not a failing one. Re-probed with prompts that actually call a tool: a real apply_patch write fired PreToolUse/PostToolUse with tool_name \"apply_patch\", and a real MCP call to this repo's own search_ruvnet server fired both with tool_name \"mcp__ruvnet_brain__search_ruvnet\". Both are now registered below: decision-gate's write route (matcher includes apply_patch, Codex's raw write-tool name) and grounding-stamp (unchanged matcher already recognizes the mcp__..__search_ruvnet shape). The bash route (exec_command) remains unregistered — today's measurement covered a write and an MCP call, not exec_command, and extending on that evidence would be the same unproven leap this note replaces. Also added 2026-09-12: grounding-turn-mark (UserPromptSubmit) and grounding-turn-gate (Stop), the \"answered without searching\" pair — a prompt-level grounding directive is advisory, so this records whether it fired and forces continuation at Stop if no search_ruvnet call was recorded since (reusing grounding-stamp's own stamp evidence). Both are registered on Codex identically to Claude: the Stop-block contract (hookSpecificOutput.additionalContext) already has a proven Codex translation via codex-hook-adapter.mjs's Stop branch (see tests/unit/codex-lifecycle-hooks.test.mjs), the same path continuation-gate already uses. Capacity-aware parallel-work guidance is also registered at UserPromptSubmit: it advises the coordinator to launch only real independent workers within sampled resource headroom and the live runtime/tool cap; it never spawns workers or claims execution. Automatic normalized project observations are captured at prompt, pre-tool, post-tool and child completion; Claude also observes PostToolUseFailure. Queued memory is silent (the normal state at prompt and tool boundaries); a stuck queue (queued work older than 10 minutes), an unwritable queue and a hook that failed or timed out internally are disclosed; this does not establish synchronous ADR-073 conformance or native Grok recall. SessionStart has an 8-second measured replay/restore envelope. Issue377: consent-eligible learning captures only fixed workflow metadata; lifecycle recovery schedules one finite worker. Original records remain retained with hash-bound acknowledgments. Native delivery must be separately evidenced; registration is not proof. Amended 2026-10-12 (ADR-106): lifecycle memory only calls ruflo; no local queue, journal or outbox; a refused write is a hook-failures row.",
3
3
  "hooks": {
4
4
  "SessionStart": [
5
5
  {
@@ -11,16 +11,6 @@
11
11
  "timeout": 8
12
12
  }
13
13
  ]
14
- },
15
- {
16
- "matcher": "startup|resume|clear|compact|fork",
17
- "hooks": [
18
- {
19
- "type": "command",
20
- "command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 2500 learn-flush",
21
- "timeout": 3
22
- }
23
- ]
24
14
  }
25
15
  ],
26
16
  "Stop": [
@@ -46,16 +36,6 @@
46
36
  }
47
37
  ],
48
38
  "PreToolUse": [
49
- {
50
- "matcher": "*",
51
- "hooks": [
52
- {
53
- "type": "command",
54
- "command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 9000 session-snapshot PreToolUse",
55
- "timeout": 10
56
- }
57
- ]
58
- },
59
39
  {
60
40
  "matcher": "^(Write|Edit|MultiEdit|NotebookEdit|apply_patch)$",
61
41
  "hooks": [
@@ -87,27 +67,12 @@
87
67
  "timeout": 5
88
68
  }
89
69
  ]
90
- },
91
- {
92
- "matcher": "^(?:Bash|Write|Edit|MultiEdit|exec_command|apply_patch|functions(?:\\.|__)(?:exec_command|apply_patch))$",
93
- "hooks": [
94
- {
95
- "type": "command",
96
- "command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 2500 learn-capture",
97
- "timeout": 3
98
- }
99
- ]
100
70
  }
101
71
  ],
102
72
  "UserPromptSubmit": [
103
73
  {
104
74
  "matcher": "*",
105
75
  "hooks": [
106
- {
107
- "type": "command",
108
- "command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 9000 session-snapshot UserPromptSubmit",
109
- "timeout": 10
110
- },
111
76
  {
112
77
  "type": "command",
113
78
  "command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 9000 unprompted-speech UserPromptSubmit",
@@ -141,28 +106,6 @@
141
106
  "timeout": 3
142
107
  }
143
108
  ]
144
- },
145
- {
146
- "matcher": "*",
147
- "hooks": [
148
- {
149
- "type": "command",
150
- "command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 2500 learn-flush",
151
- "timeout": 3
152
- }
153
- ]
154
- }
155
- ],
156
- "SubagentStop": [
157
- {
158
- "matcher": "*",
159
- "hooks": [
160
- {
161
- "type": "command",
162
- "command": "node -e \"const f=require('node:fs'),o=require('node:os'),p=require('node:path'),c=require('node:child_process'),d=process.env.CODEX_HOME||p.join(o.homedir(),'.codex'),b=process.env.RUVNET_BRAIN_HOME||p.join(p.dirname(d),'.cache','ruvnet-brain'),w=p.join(b,'codex-hook.mjs');let s;try{s=f.statSync(w)}catch{}if(!s?.isFile())process.exit(0);const r=c.spawnSync(process.execPath,[w,...process.argv.slice(2)],{stdio:['inherit','pipe','pipe'],encoding:'utf8',env:process.env,timeout:Number(process.argv[1]),killSignal:'SIGKILL'});if(r.status===0||r.status===2){if(r.stdout)process.stdout.write(r.stdout);if(r.stderr)process.stderr.write(r.stderr)}process.exit(r.status===2?2:0)\" 9000 session-snapshot SubagentStop",
163
- "timeout": 10
164
- }
165
- ]
166
109
  }
167
110
  ],
168
111
  "PreCompact": [