0xray 4.0.23 → 4.0.25

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 (66) hide show
  1. package/.grok-plugin/plugin.json +1 -1
  2. package/.xray/features.json +11 -1
  3. package/.xray/features.schema.json +17 -0
  4. package/AGENTS-consumer.md +1 -1
  5. package/AGENTS.md +1 -1
  6. package/README.md +2 -2
  7. package/SKILLS.md +1 -1
  8. package/dist/AGENTS.md +1 -1
  9. package/dist/CHANGELOG.md +43 -0
  10. package/dist/README.md +2 -2
  11. package/dist/SKILLS.md +1 -1
  12. package/dist/cli/commands/validate.js +3 -0
  13. package/dist/cli/index.js +131 -100
  14. package/dist/core/features-config.d.ts +4 -0
  15. package/dist/core/features-config.js +10 -0
  16. package/dist/inference/inference-accumulator.d.ts +2 -0
  17. package/dist/inference/inference-accumulator.js +74 -2
  18. package/dist/inference/inference-cycle.js +1 -0
  19. package/dist/inference/inference-proposal-generator.js +65 -7
  20. package/dist/inference/inference-run-gate.d.ts +8 -0
  21. package/dist/inference/inference-run-gate.js +10 -0
  22. package/dist/inference/session-capture.d.ts +27 -0
  23. package/dist/inference/session-capture.js +277 -1
  24. package/dist/integrations/cursor/hooks/pre-compact.js +89 -1
  25. package/dist/integrations/hooks/plates.cjs +165 -0
  26. package/dist/integrations/hooks/station-hook-runtime.cjs +29 -11
  27. package/dist/integrations/hooks/station-memory-ingest.mjs +109 -42
  28. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  29. package/dist/mcps/researcher-confidence.d.ts +5 -1
  30. package/dist/mcps/researcher-confidence.js +37 -0
  31. package/dist/mcps/researcher.server.js +2 -2
  32. package/dist/memory-routing/plates.d.ts +16 -0
  33. package/dist/memory-routing/plates.js +71 -0
  34. package/dist/memory-routing/types.d.ts +2 -0
  35. package/dist/memory-routing/types.js +2 -1
  36. package/dist/processors/implementations/inference-improvement-processor.d.ts +5 -0
  37. package/dist/processors/implementations/inference-improvement-processor.js +101 -2
  38. package/dist/processors/implementations/storytelling-trigger-processor.js +1 -11
  39. package/dist/processors/processor-manager.d.ts +1 -1
  40. package/dist/processors/processor-manager.js +52 -20
  41. package/docs-site/docs/plates/boot.md +52 -0
  42. package/docs-site/docs/plates/governance.md +50 -0
  43. package/docs-site/docs/plates/index.md +16 -0
  44. package/docs-site/docs/plates/memory-recall.md +49 -0
  45. package/docs-site/docs/plates/orchestration.md +55 -0
  46. package/docs-site/docs/plates/processor.md +46 -0
  47. package/docs-site/docs/plates/reporting.md +42 -0
  48. package/docs-site/docs/plates/routing.md +49 -0
  49. package/llms.txt +1 -1
  50. package/package.json +2 -1
  51. package/scripts/foundry/assert-packed-dist-cli.mjs +3 -0
  52. package/scripts/foundry/plant/skills/mill/SKILL.md +1 -1
  53. package/scripts/node/consumer-install-smoke.mjs +7 -4
  54. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  55. package/src/mcps/researcher-confidence.ts +56 -3
  56. package/src/mcps/researcher.server.ts +4 -5
  57. package/vendor/@0xray/repertoire/README.md +3 -1
  58. package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts +23 -3
  59. package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts.map +1 -1
  60. package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js +119 -16
  61. package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js.map +1 -1
  62. package/vendor/@0xray/repertoire/dist/types.d.ts +1 -1
  63. package/vendor/@0xray/repertoire/dist/types.d.ts.map +1 -1
  64. package/vendor/@0xray/repertoire/package.json +1 -1
  65. package/xray/features.json +11 -1
  66. package/xray/features.schema.json +17 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0xray",
3
- "version": "4.0.23",
3
+ "version": "4.0.25",
4
4
  "description": "0xRay suit for Grok, Hermes, OpenClaw, OpenCode: mill+inspect, Codex, 7 MCP servers. Costume 45/42 is opt-in foundry, not the default wear.",
5
5
  "author": {
6
6
  "name": "0xRay AI",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./features.schema.json",
3
- "version": "4.0.23",
3
+ "version": "4.0.25",
4
4
  "description": "0xRay Framework - Unified Feature Configuration",
5
5
  "suit_temperament": {
6
6
  "profile": "auto",
@@ -173,6 +173,16 @@
173
173
  "every_n_turns": 0,
174
174
  "every_n_todos_completed": 0
175
175
  },
176
+ "inference": {
177
+ "description": "Self-improvement cycle that grades a new named session into repertoire",
178
+ "enabled": true,
179
+ "workflow_dir": ".xray/inference",
180
+ "reports_dir": ".xray/reports",
181
+ "pattern_matching": {
182
+ "enabled": true,
183
+ "confidence_threshold": 0.7
184
+ }
185
+ },
176
186
  "inference_governance": {
177
187
  "enabled": false,
178
188
  "request_timeout_ms": 10000,
@@ -97,6 +97,23 @@
97
97
  "lookback_commits": { "type": "integer", "minimum": 1 }
98
98
  }
99
99
  },
100
+ "inference": {
101
+ "type": "object",
102
+ "description": "Self-improvement cycle. A missing key is on. Explicit enabled false turns inference:run off unless --force.",
103
+ "properties": {
104
+ "description": { "type": "string" },
105
+ "enabled": { "type": "boolean" },
106
+ "workflow_dir": { "type": "string" },
107
+ "reports_dir": { "type": "string" },
108
+ "pattern_matching": {
109
+ "type": "object",
110
+ "properties": {
111
+ "enabled": { "type": "boolean" },
112
+ "confidence_threshold": { "type": "number" }
113
+ }
114
+ }
115
+ }
116
+ },
100
117
  "suit_temperament": {
101
118
  "type": "object",
102
119
  "description": "0xRay 4.0 — constitution always on; ceremony scales by host. Missing key = guided (existing consumers unchanged).",
@@ -6,7 +6,7 @@ Quick reference for the 0xRay AI orchestration framework worn on **{{CONSUMER_NA
6
6
 
7
7
  **4.0** — a suit that survives the context window
8
8
 
9
- Same **three-subsystem OS** as v2 (Inference · External Governance · Autonomous Engine). Constitution always on. Temperament scales ceremony. Four chat bridges plus Cursor project hooks. **Repertoire is preferred** — vendored 0.2.5 ships **on**. Dest is named laws, not keywords. Station is the compact ticket, not a substitute. Explicit opt-out only: `"enabled": false, "provider": "repertoire"`. Trim fat, do not gut the design.
9
+ Same **three-subsystem OS** as v2 (Inference · External Governance · Autonomous Engine). Constitution always on. Temperament scales ceremony. Four chat bridges plus Cursor project hooks. **Repertoire is preferred** — vendored 0.2.8 ships **on**. Dest is named laws, not keywords. Station is the compact ticket, not a substitute. Explicit opt-out only: `"enabled": false, "provider": "repertoire"`. Trim fat, do not gut the design.
10
10
 
11
11
  **Governance always on** (Codex PreToolUse, no new surface, no `eval`). **Engine ceremony** (analyze-complexity before spawn, confer) is **guided** by default so free-model OpenCode/Hermes stay in check. Frontier hosts (Grok 4.6 class) with `suit_temperament.profile: auto` **warn** on spawn-without-plan instead of deny — the engine is still there. Existing `.xray/features.json` without `suit_temperament` stays **guided**. Docs: v3 from v2 · Suit temperament.
12
12
 
package/AGENTS.md CHANGED
@@ -4,7 +4,7 @@ Quick reference for the xray AI orchestration framework (**4.0**).
4
4
 
5
5
  **4.0** — a suit that survives the context window.
6
6
 
7
- **Exo, not catalog.** Three-subsystem OS (Inference · External Governance · Autonomous Engine) · constitution always on · temperament by host · 4 floors · **Repertoire preferred** (vendored 0.2.5, dest = laws).
7
+ **Exo, not catalog.** Three-subsystem OS (Inference · External Governance · Autonomous Engine) · constitution always on · temperament by host · 4 floors · **Repertoire preferred** (vendored 0.2.8, dest = laws).
8
8
 
9
9
  **Temperament:** ceremony (analyze-complexity before spawn, confer) is **guided** by default so free-model OpenCode/Hermes stay in check. Frontier hosts (Grok 4.6 class) with `suit_temperament.profile: auto` **warn** on spawn-without-plan; Codex 11/29/69 still **deny**. Missing `suit_temperament` stays guided. See `docs-site/docs/architecture/v3-from-v2.md`.
10
10
 
package/README.md CHANGED
@@ -14,13 +14,13 @@ Not a catalog of agents. The product is the **skeleton you wear**.
14
14
  - **Always on** — Codex 11 / 29 / 69, destructive shell, no new MCP/skill/handler surface
15
15
  - **Temperament** — `frontier` | `guided` | `strict` | `auto` — how loud the engine is, not whether governance exists
16
16
  - **Wear** — Grok, OpenCode, Hermes, OpenClaw, plus Cursor project hooks. One SSOT gate
17
- - **Muscle** — **Repertoire is preferred.** Vendored 0.2.5 ships **on**. Dest is named laws, not hangar `repo-*` or git slugs. Station is the compact-survival ticket — not a substitute for Repertoire.
17
+ - **Muscle** — **Repertoire is preferred.** Vendored 0.2.8 ships **on**. Dest is named laws, not hangar `repo-*` or git slugs. Station is the compact-survival ticket — not a substitute for Repertoire.
18
18
 
19
19
  ```bash
20
20
  npm install 0xray
21
21
  ```
22
22
 
23
- Consumer `npm install 0xray` auto-wires four chat bridges, Cursor project hooks, and seven MCP servers. **Repertoire is preferred** — vendored **0.2.5** ships on: factory + stack laws, in-process routing, extra host MCP `repertoire`. Not an eighth `xray-*` server. Dest is a judgment index. Explicit opt-out only: `"enabled": false, "provider": "repertoire"`. Do not pin 0.1.8.
23
+ Consumer `npm install 0xray` auto-wires four chat bridges, Cursor project hooks, and seven MCP servers. **Repertoire is preferred** — vendored **0.2.8** ships on: factory + stack laws, in-process routing, extra host MCP `repertoire`. Not an eighth `xray-*` server. Dest is a judgment index. Explicit opt-out only: `"enabled": false, "provider": "repertoire"`. Do not pin 0.1.8.
24
24
 
25
25
  ## Quick Start
26
26
 
package/SKILLS.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **45 skills** in this exo catalog. Default consumer plant is **`mill` + `inspect`**, not this dump. `npm install 0xray` does **not** sync 45 skills unless `foundry.json` `"costume": true`. Factory shop plant (`shop-extract`, `shop-witness`, `shop-pin`) coexists with mill plant when a hangar wears those shops. Extra shops: `foundry.json` `shopPlant`. Fasten is **foundry-plant/0**: builtin plant is mill+inspect only. `foundry.json` `"plant": "@0xray/blip"` (aliases `"plant": "blip"` / `"plant": "sound"`) fastens whatever that mill package declares — organs (looker, vibe, mixer) live in the mill, not this catalog. Nested mill `@0xray/foundry@0.1.12`. CLI shims `foundry blip|sound` still exist on foundry 0.1.11+. Agent map: [llms.txt](llms.txt).
6
6
 
7
- xray ships 45 knowledge skills (`src/skills/<name>/SKILL.md`) as the **costume / self-plant catalog**. Lead-dev operating model lives in **`orchestrator`** skill + `multi_agent_orchestration.lead_dev_mode` in features.json. **Repertoire is preferred** for long-term judgment (vendored 0.2.5, dest = named laws). Station is the compact ticket, not a skill and not a keyword store. Skills load on demand via the **xray-skills** MCP server (`npx -y 0xray mcp skills`) or when you plant them. This file is the exo catalog — mill does **not** write it to the consumer root.
7
+ xray ships 45 knowledge skills (`src/skills/<name>/SKILL.md`) as the **costume / self-plant catalog**. Lead-dev operating model lives in **`orchestrator`** skill + `multi_agent_orchestration.lead_dev_mode` in features.json. **Repertoire is preferred** for long-term judgment (vendored 0.2.8, dest = named laws). Station is the compact ticket, not a skill and not a keyword store. Skills load on demand via the **xray-skills** MCP server (`npx -y 0xray mcp skills`) or when you plant them. This file is the exo catalog — mill does **not** write it to the consumer root.
8
8
 
9
9
  ---
10
10
 
package/dist/AGENTS.md CHANGED
@@ -4,7 +4,7 @@ Quick reference for the xray AI orchestration framework (**4.0**).
4
4
 
5
5
  **4.0** — a suit that survives the context window.
6
6
 
7
- **Exo, not catalog.** Three-subsystem OS (Inference · External Governance · Autonomous Engine) · constitution always on · temperament by host · 4 floors · **Repertoire preferred** (vendored 0.2.5, dest = laws).
7
+ **Exo, not catalog.** Three-subsystem OS (Inference · External Governance · Autonomous Engine) · constitution always on · temperament by host · 4 floors · **Repertoire preferred** (vendored 0.2.8, dest = laws).
8
8
 
9
9
  **Temperament:** ceremony (analyze-complexity before spawn, confer) is **guided** by default so free-model OpenCode/Hermes stay in check. Frontier hosts (Grok 4.6 class) with `suit_temperament.profile: auto` **warn** on spawn-without-plan; Codex 11/29/69 still **deny**. Missing `suit_temperament` stays guided. See `docs-site/docs/architecture/v3-from-v2.md`.
10
10
 
package/dist/CHANGELOG.md CHANGED
@@ -7,9 +7,13 @@ The format is based on [Conventional Commits](https://www.conventionalcommits.or
7
7
  ## [Unreleased]
8
8
 
9
9
  ### Features
10
+ - **Plates.** Pipeline schematics live in `docs-site/docs/plates/` (routing, governance, boot, orchestration, processor, reporting, memory-recall). Station keeps one pointer line. Pre-compact and the `MEMORY_ROUTING` inject carry that one schematic. A lesson is an episode. A plate is the machine. Not a new skill.
11
+ - **Vendored Repertoire 0.2.8.** `vendor/@0xray/repertoire` is that package. Lesson lines and retained ids stay at 20. Speech that names nothing mints a learned signal, and only those mints evict past 24. Not a new skill.
10
12
  - **Feat rebase.** When the mandated work turns into mantra, or the job has split across planes that no longer share one present, stop and answer the original message again from this seat. On `LEAD-CADENCE.md`, the orchestrator skill, and the ship-ready mill gate. Project dest grows the name `feat-rebase` from the stack overlay. Not a new skill.
11
13
 
12
14
  ### Fixed
15
+ - **Lesson caps and speech mint.** `LESSON_LINE_CAP` is 20. `RETAINED_LESSON_ID_CAP` is 20 in insertion order. Speech that names no stored signal mints one `proposed` signal tagged `learned`. `LEARNED_SIGNAL_CAP` is 24 and evicts only those mints. Factory signals stay. Not a new skill.
16
+ - **External grade writes the line.** `governExternalProposals` grades the signals a proposal already named, the same way the local cycle does. Needs-revision and a governance error still do not write. The vendored organ puts a missing lesson ledger back when dest still has its lines, so an aged task id does not step the average again. Not a new skill.
13
17
  - **A governed proposal teaches.** A route lookup does not write a lesson. When a vote finishes, the cycle grades the signals that proposal's sessions already named. A session that names a stored signal is graded even when that name appears once. Landed approaches and no wrong turn clear the solid band. A wrong turn stays below the cutoff. Earlier rejects of other codify proposals do not pull that grade down. Approve steps those signals up by a tenth. Reject steps them down by a tenth. Needs-revision, an abstain, a governance error, and a proposal whose sessions named nothing do not write. Proposal ids stay on the signal and the sessions not yet graded, so a later cycle does not teach those sessions again. A new session is a new id. Those ids remain after the history window of 50 fills, including with empty cycles. A proposal that carries an empty name list does not fall through to matching its text. A grade that passes appends one line — the task, the decision, and the approaches, solutions, or wrong turn from the sessions that named the law — on that signal and beside the average. The same task does not append again. The route for a law above 0.55 includes the law text and those lines, and Station's lessons section is refreshed from dest. Not a new skill.
14
18
  - **Dynamo client on a required external call.** `govern_proposals` with external governance required starts `InferenceGovernanceIntegration` even when `inference_governance.enabled` is false. Boot still skips that client while the flag is off, and the inference cycle still uses the local matrix unless the flag is on or `XRAY_FORCE_MCP_GOVERNANCE=true`. An unreadable MCP payload is stored as the error text, not an abstain at 0.5. The MCP wait matches the governance budget (90s). Not a new skill.
15
19
  - **Subsystem pass.** A session file with no `metrics.commits` is not a session, and a captured pattern with no `evidence` array is empty evidence, so the inference cycle no longer dies before it writes state. `scoreAndRoute` loads the memory organ on the first call with a synchronous require, before any dynamic import of that module. A cached null provider does not block that load, and a late null load does not replace an organ already in hand. Not a new skill.
@@ -37,6 +41,45 @@ The format is based on [Conventional Commits](https://www.conventionalcommits.or
37
41
  - Archive root `integrations/` costume SKILL dump → `docs/archive/integrations-costume/`. Live wear is `src/integrations`.
38
42
  - Archive root `commands/` stale copy → `docs/archive/commands-copy/`. Live wear is `src/opencode/commands`.
39
43
 
44
+ ## [4.0.25] - 2026-09-24
45
+
46
+ `0xray@4.0.25` ships the plate schematics in the package. `docs-site/docs/plates/` is on the npm `files` list. A worn suit resolves `memory-recall` and `processor` from `dist/integrations/hooks/plates.cjs`.
47
+
48
+ ### 🔄 Changes
49
+
50
+ ### 🐛 Bug Fixes
51
+ - fix: ship plate schematics in the npm package (b1bdd7415)
52
+
53
+ ### 📚 Documentation
54
+ - docs: announce 4.0.24 — hot-swap, memory organ, plates (b04b80a15)
55
+
56
+ ---
57
+
58
+ ## [4.0.24] - 2026-09-24
59
+
60
+ `0xray@4.0.24` is on npm. `npm install 0xray`.
61
+
62
+ Exo, not a catalog. A factory stamps a skeleton (Inference, External Governance, Autonomous Engine) and fastens a mill. Code mill, music mill (`@0xray/blip` sound), agents across TUIs and LLMs wear it and operate.
63
+
64
+ - **Hot-swappable compaction.** Compaction and host change are the same cut. The station card (`.xray/state/STATION.md`) is the handoff. The next turn continues the card.
65
+ - **Memory organ.** Finished speech and reflections become lessons on signals. Kernel and activity logs are heat (`last_seen`) only. Unnamed speech mints a signal. Caps: 20 hot lesson lines, 20 retained ids (insertion order), 24 learned proposed signals. Factory laws stay.
66
+ - **Plates.** One INPUT/PROCESSING/OUTPUT schematic per pipeline in `docs-site/docs/plates/`. Station keeps one pointer line. Recall injects that one schematic. A lesson is an episode. A plate is the machine.
67
+ - **Repertoire 0.2.8** is the organ package, vendored in 4.0.24.
68
+
69
+ ### 🔄 Changes
70
+
71
+ ### 🐛 Bug Fixes
72
+ - fix: put matched lesson speech on the MEMORY_ROUTING block (2a2f0411d)
73
+ - fix: process reflection markdown as inference speech (64d7a6eee)
74
+ - fix: run discovered processors and keep commit subjects off the session log (d9fb2ee15)
75
+ - fix: grade a captured operation before the wake ends (c5760000b)
76
+ - fix: heat no longer writes a gradeable lesson from commit subjects (ceeb3a536)
77
+ - fix: grade a new session when another proposal already named the signal (bf4d5e59a)
78
+ - fix: let inference:run enter the cycle and exit (12c3e5142)
79
+ - fix: grade named signals on an external vote (5fc21d174)
80
+
81
+ ---
82
+
40
83
  ## [4.0.23] - 2026-09-23
41
84
 
42
85
  ### 🔄 Changes
package/dist/README.md CHANGED
@@ -14,13 +14,13 @@ Not a catalog of agents. The product is the **skeleton you wear**.
14
14
  - **Always on** — Codex 11 / 29 / 69, destructive shell, no new MCP/skill/handler surface
15
15
  - **Temperament** — `frontier` | `guided` | `strict` | `auto` — how loud the engine is, not whether governance exists
16
16
  - **Wear** — Grok, OpenCode, Hermes, OpenClaw, plus Cursor project hooks. One SSOT gate
17
- - **Muscle** — **Repertoire is preferred.** Vendored 0.2.5 ships **on**. Dest is named laws, not hangar `repo-*` or git slugs. Station is the compact-survival ticket — not a substitute for Repertoire.
17
+ - **Muscle** — **Repertoire is preferred.** Vendored 0.2.8 ships **on**. Dest is named laws, not hangar `repo-*` or git slugs. Station is the compact-survival ticket — not a substitute for Repertoire.
18
18
 
19
19
  ```bash
20
20
  npm install 0xray
21
21
  ```
22
22
 
23
- Consumer `npm install 0xray` auto-wires four chat bridges, Cursor project hooks, and seven MCP servers. **Repertoire is preferred** — vendored **0.2.5** ships on: factory + stack laws, in-process routing, extra host MCP `repertoire`. Not an eighth `xray-*` server. Dest is a judgment index. Explicit opt-out only: `"enabled": false, "provider": "repertoire"`. Do not pin 0.1.8.
23
+ Consumer `npm install 0xray` auto-wires four chat bridges, Cursor project hooks, and seven MCP servers. **Repertoire is preferred** — vendored **0.2.8** ships on: factory + stack laws, in-process routing, extra host MCP `repertoire`. Not an eighth `xray-*` server. Dest is a judgment index. Explicit opt-out only: `"enabled": false, "provider": "repertoire"`. Do not pin 0.1.8.
24
24
 
25
25
  ## Quick Start
26
26
 
package/dist/SKILLS.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **45 skills** in this exo catalog. Default consumer plant is **`mill` + `inspect`**, not this dump. `npm install 0xray` does **not** sync 45 skills unless `foundry.json` `"costume": true`. Factory shop plant (`shop-extract`, `shop-witness`, `shop-pin`) coexists with mill plant when a hangar wears those shops. Extra shops: `foundry.json` `shopPlant`. Fasten is **foundry-plant/0**: builtin plant is mill+inspect only. `foundry.json` `"plant": "@0xray/blip"` (aliases `"plant": "blip"` / `"plant": "sound"`) fastens whatever that mill package declares — organs (looker, vibe, mixer) live in the mill, not this catalog. Nested mill `@0xray/foundry@0.1.12`. CLI shims `foundry blip|sound` still exist on foundry 0.1.11+. Agent map: [llms.txt](llms.txt).
6
6
 
7
- xray ships 45 knowledge skills (`src/skills/<name>/SKILL.md`) as the **costume / self-plant catalog**. Lead-dev operating model lives in **`orchestrator`** skill + `multi_agent_orchestration.lead_dev_mode` in features.json. **Repertoire is preferred** for long-term judgment (vendored 0.2.5, dest = named laws). Station is the compact ticket, not a skill and not a keyword store. Skills load on demand via the **xray-skills** MCP server (`npx -y 0xray mcp skills`) or when you plant them. This file is the exo catalog — mill does **not** write it to the consumer root.
7
+ xray ships 45 knowledge skills (`src/skills/<name>/SKILL.md`) as the **costume / self-plant catalog**. Lead-dev operating model lives in **`orchestrator`** skill + `multi_agent_orchestration.lead_dev_mode` in features.json. **Repertoire is preferred** for long-term judgment (vendored 0.2.8, dest = named laws). Station is the compact ticket, not a skill and not a keyword store. Skills load on demand via the **xray-skills** MCP server (`npx -y 0xray mcp skills`) or when you plant them. This file is the exo catalog — mill does **not** write it to the consumer root.
8
8
 
9
9
  ---
10
10
 
@@ -22,6 +22,9 @@ export const VALIDATE_PACK_PATHS = [
22
22
  "dist/integrations/cursor/hooks/pre-tool-use.sh",
23
23
  "dist/integrations/cursor/hooks/pre-compact.sh",
24
24
  "dist/integrations/cursor/hooks/after-file-edit.sh",
25
+ "dist/integrations/hooks/plates.cjs",
26
+ "docs-site/docs/plates/memory-recall.md",
27
+ "docs-site/docs/plates/processor.md",
25
28
  ];
26
29
  export const CONSUMER_WEAR_PATHS = [
27
30
  "AGENTS.md",
package/dist/cli/index.js CHANGED
@@ -11,6 +11,7 @@ import { fileURLToPath } from "node:url";
11
11
  import { readFileSync, existsSync } from "fs";
12
12
  import { getConfigDir } from "../core/config-paths.js";
13
13
  import { frameworkLogger } from "../core/framework-logger.js";
14
+ import { inferenceRunMayEnter } from "../inference/inference-run-gate.js";
14
15
  // Get package root relative to this script location
15
16
  const packageRoot = resolve(fileURLToPath(new URL("../..", import.meta.url)));
16
17
  // Read version dynamically from package.json
@@ -249,6 +250,16 @@ program
249
250
  process.exit(1);
250
251
  }
251
252
  });
253
+ function cliReportType(value) {
254
+ if (value === "orchestration" ||
255
+ value === "agent-usage" ||
256
+ value === "context-awareness" ||
257
+ value === "performance" ||
258
+ value === "full-analysis") {
259
+ return value;
260
+ }
261
+ return "full-analysis";
262
+ }
252
263
  program
253
264
  .command("report")
254
265
  .description("Generate framework activity and health reports")
@@ -268,7 +279,7 @@ program
268
279
  session: "full-analysis",
269
280
  ci: "full-analysis",
270
281
  };
271
- let reportType = options.type;
282
+ let reportType = cliReportType(typeof options.type === "string" ? options.type : undefined);
272
283
  let outputFormat = "json";
273
284
  // Convenience flags override --type
274
285
  for (const [flag, mappedType] of Object.entries(typeMap)) {
@@ -629,6 +640,11 @@ program
629
640
  console.log(' --run-once Run a single tuning cycle');
630
641
  console.log(' --status Show tuner status');
631
642
  });
643
+ function exitWhenFlushed(code) {
644
+ process.stdout.write("", () => {
645
+ process.exit(code);
646
+ });
647
+ }
632
648
  // Inference cycle run command
633
649
  program
634
650
  .command('inference:run')
@@ -639,118 +655,133 @@ program
639
655
  .option('--no-researcher-review', 'Skip downstream researcher review of PRs')
640
656
  .option('--json', 'Output raw JSON result')
641
657
  .action(async (options) => {
642
- const { InferenceCycle } = await import('../inference/inference-cycle.js');
643
- const { shouldTriggerCycle } = await import('../inference/inference-accumulator.js');
644
- const { accumulateCorpus } = await import('../inference/inference-accumulator.js');
645
- const { featuresConfigLoader } = await import('../core/features-config.js');
646
- const { initializeGovernanceIntegration, shutdownGovernanceIntegration } = await import('../integrations/governance/index.js');
647
- // Guard: inference:run is internal to xray development only
648
- const isxrayRepo = (() => {
649
- try {
650
- const pkg = JSON.parse(readFileSync(join(process.cwd(), 'package.json'), 'utf-8'));
651
- return pkg.name === '0xray' && process.env.NODE_ENV !== 'consumer';
652
- }
653
- catch {
654
- return false;
655
- }
656
- })();
657
- if (!isxrayRepo) {
658
- if (options.json) {
659
- console.log(JSON.stringify({ triggered: false, reason: 'inference:run is for xray development only (internal tool)' }));
660
- }
661
- else {
662
- console.log('The inference:run command is for xray framework development only.');
663
- console.log('It is not intended for consumer projects.');
664
- }
665
- return;
666
- }
667
- const features = featuresConfigLoader.loadConfig();
668
- const inferenceConfig = features?.inference;
669
- if (!inferenceConfig?.enabled) {
670
- if (options.json) {
671
- console.log(JSON.stringify({ triggered: false, reason: 'Inference feature disabled in features.json' }));
672
- }
673
- else {
674
- console.log('Inference feature is disabled in features.json.');
675
- console.log('Enable it by setting inference.enabled = true in .opencode/plugins/features.json (min compat .xray/ fallback for prior 0xRay consumer runtime per Scope Rule)');
658
+ let code = 0;
659
+ try {
660
+ const { InferenceCycle } = await import('../inference/inference-cycle.js');
661
+ const { shouldTriggerCycle } = await import('../inference/inference-accumulator.js');
662
+ const { accumulateCorpus } = await import('../inference/inference-accumulator.js');
663
+ const { featuresConfigLoader } = await import('../core/features-config.js');
664
+ const { initializeGovernanceIntegration, shutdownGovernanceIntegration } = await import('../integrations/governance/index.js');
665
+ // Guard: inference:run is internal to xray development only
666
+ const isxrayRepo = (() => {
667
+ try {
668
+ const pkg = JSON.parse(readFileSync(join(process.cwd(), 'package.json'), 'utf-8'));
669
+ return pkg.name === '0xray' && process.env.NODE_ENV !== 'consumer';
670
+ }
671
+ catch {
672
+ return false;
673
+ }
674
+ })();
675
+ if (!isxrayRepo) {
676
+ if (options.json) {
677
+ console.log(JSON.stringify({ triggered: false, reason: 'inference:run is for xray development only (internal tool)' }));
678
+ }
679
+ else {
680
+ console.log('The inference:run command is for xray framework development only.');
681
+ console.log('It is not intended for consumer projects.');
682
+ }
683
+ return;
676
684
  }
677
- return;
678
- }
679
- const projectRoot = process.cwd();
680
- const inferenceDir = `${projectRoot}/docs/inference`;
681
- const stateDir = `${projectRoot}/.xray/inference`;
682
- const stateFile = `${stateDir}/inference-cycle-state.json`;
683
- if (!options.json) {
684
- console.log('xray Inference Cycle');
685
- console.log('====================');
686
- }
687
- if (!options.force) {
688
- const threshold = shouldTriggerCycle(inferenceDir, stateFile);
689
- if (!threshold.trigger) {
685
+ const features = featuresConfigLoader.loadConfig();
686
+ if (!inferenceRunMayEnter(features.inference, options.force === true)) {
690
687
  if (options.json) {
691
- console.log(JSON.stringify({ triggered: false, reason: threshold.reason }));
688
+ console.log(JSON.stringify({ triggered: false, reason: 'Inference feature disabled in features.json' }));
692
689
  }
693
690
  else {
694
- console.log(`Not triggered: ${threshold.reason}`);
695
- console.log('Use --force to override.');
691
+ console.log('Inference feature is disabled in features.json.');
692
+ console.log('Set inference.enabled to true in xray/features.json, or pass --force.');
696
693
  }
697
694
  return;
698
695
  }
696
+ const projectRoot = process.cwd();
697
+ const inferenceDir = `${projectRoot}/docs/inference`;
698
+ const stateDir = `${projectRoot}/.xray/inference`;
699
+ const stateFile = `${stateDir}/inference-cycle-state.json`;
699
700
  if (!options.json) {
700
- console.log(`Triggered: ${threshold.reason}`);
701
+ console.log('xray Inference Cycle');
702
+ console.log('====================');
703
+ }
704
+ if (!options.force) {
705
+ const threshold = shouldTriggerCycle(inferenceDir, stateFile);
706
+ if (!threshold.trigger) {
707
+ if (options.json) {
708
+ console.log(JSON.stringify({ triggered: false, reason: threshold.reason }));
709
+ }
710
+ else {
711
+ console.log(`Not triggered: ${threshold.reason}`);
712
+ console.log('Use --force to override.');
713
+ }
714
+ return;
715
+ }
716
+ if (!options.json) {
717
+ console.log(`Triggered: ${threshold.reason}`);
718
+ }
701
719
  }
702
- }
703
- else if (!options.json) {
704
- console.log('Force mode — skipping threshold check');
705
- }
706
- if (!options.json) {
707
- const corpus = accumulateCorpus(inferenceDir);
708
- console.log(`\nCorpus: ${corpus.sessions.length} sessions, ${corpus.totalCommits} commits`);
709
- console.log(` Recurring problems: ${corpus.recurringProblems.length}`);
710
- console.log(` Recurring patterns: ${corpus.recurringPatterns.length}`);
711
- }
712
- // Initialize external governance integration for two-oscillator governance
713
- const govConfig = features?.inference_governance;
714
- if (govConfig?.enabled) {
715
- await shutdownGovernanceIntegration();
716
- await initializeGovernanceIntegration();
717
- }
718
- const cycle = InferenceCycle.getInstance(projectRoot, { skipDeployVerify: options.noVerify ?? true, skipApply: options.noApply ?? false, skipResearcherReview: options.noResearcherReview ?? false, force: options.force ?? false });
719
- const result = await cycle.maybeRunCycle();
720
- if (options.json) {
721
- console.log(JSON.stringify(result, null, 2));
722
- return;
723
- }
724
- console.log(`\nCycle: ${result.cycleId}`);
725
- console.log(`Phase: ${result.phase}`);
726
- console.log(`Duration: ${(result.duration / 1000).toFixed(1)}s`);
727
- if (result.proposals.length > 0) {
728
- console.log(`\nProposals (${result.proposals.length}):`);
729
- for (const p of result.proposals) {
730
- const icon = p.status === 'approved' || p.status === 'applied' ? 'APPROVED' : p.status === 'rejected' ? 'REJECTED' : p.status === 'failed' ? 'FAILED' : 'PENDING';
731
- console.log(` [${icon}] ${p.type}: ${p.title} (${(p.confidence * 100).toFixed(0)}%)`);
732
- }
733
- }
734
- else {
735
- console.log('\nNo proposals generated.');
736
- }
737
- if (result.votes.length > 0) {
738
- console.log(`\nGovernance votes (${result.votes.length}):`);
739
- for (const v of result.votes) {
740
- console.log(` ${v.proposalId}: ${v.decision} (${(v.confidence * 100).toFixed(0)}%)`);
741
- for (const d of v.details) {
742
- console.log(` ${d}`);
720
+ else if (!options.json) {
721
+ console.log('Force mode — skipping threshold check');
722
+ }
723
+ if (!options.json) {
724
+ const corpus = accumulateCorpus(inferenceDir);
725
+ console.log(`\nCorpus: ${corpus.sessions.length} sessions, ${corpus.totalCommits} commits`);
726
+ console.log(` Recurring problems: ${corpus.recurringProblems.length}`);
727
+ console.log(` Recurring patterns: ${corpus.recurringPatterns.length}`);
728
+ }
729
+ // Initialize external governance integration for two-oscillator governance
730
+ const govConfig = features.inference_governance;
731
+ if (govConfig?.enabled) {
732
+ await shutdownGovernanceIntegration();
733
+ await initializeGovernanceIntegration();
734
+ }
735
+ const cycle = InferenceCycle.getInstance(projectRoot, { skipDeployVerify: options.noVerify ?? true, skipApply: options.noApply ?? false, skipResearcherReview: options.noResearcherReview ?? false, force: options.force ?? false });
736
+ const result = await cycle.maybeRunCycle();
737
+ if (options.json) {
738
+ console.log(JSON.stringify(result, null, 2));
739
+ return;
740
+ }
741
+ console.log(`\nCycle: ${result.cycleId}`);
742
+ console.log(`Phase: ${result.phase}`);
743
+ console.log(`Duration: ${(result.duration / 1000).toFixed(1)}s`);
744
+ if (result.proposals.length > 0) {
745
+ console.log(`\nProposals (${result.proposals.length}):`);
746
+ for (const p of result.proposals) {
747
+ const icon = p.status === 'approved' || p.status === 'applied' ? 'APPROVED' : p.status === 'rejected' ? 'REJECTED' : p.status === 'failed' ? 'FAILED' : 'PENDING';
748
+ console.log(` [${icon}] ${p.type}: ${p.title} (${(p.confidence * 100).toFixed(0)}%)`);
743
749
  }
744
750
  }
745
- }
746
- if (result.deployVerification) {
747
- console.log(`\nDeploy verification: ${result.deployVerification.success ? 'PASSED' : 'FAILED'}`);
748
- const failedChecks = result.deployVerification.checks.filter((c) => !c.passed);
749
- if (failedChecks.length > 0) {
750
- for (const c of failedChecks) {
751
- console.log(` Failed: ${c.name} — ${c.output?.substring(0, 200)}`);
751
+ else {
752
+ console.log('\nNo proposals generated.');
753
+ }
754
+ if (result.votes.length > 0) {
755
+ console.log(`\nGovernance votes (${result.votes.length}):`);
756
+ for (const v of result.votes) {
757
+ console.log(` ${v.proposalId}: ${v.decision} (${(v.confidence * 100).toFixed(0)}%)`);
758
+ for (const d of v.details) {
759
+ console.log(` ${d}`);
760
+ }
752
761
  }
753
762
  }
763
+ if (result.deployVerification) {
764
+ console.log(`\nDeploy verification: ${result.deployVerification.success ? 'PASSED' : 'FAILED'}`);
765
+ const failedChecks = result.deployVerification.checks.filter((check) => !check.passed);
766
+ if (failedChecks.length > 0) {
767
+ for (const c of failedChecks) {
768
+ console.log(` Failed: ${c.name} — ${c.output?.substring(0, 200)}`);
769
+ }
770
+ }
771
+ }
772
+ }
773
+ catch (error) {
774
+ code = 1;
775
+ const message = error instanceof Error ? error.message : String(error);
776
+ if (options.json) {
777
+ console.log(JSON.stringify({ triggered: false, reason: message }));
778
+ }
779
+ else {
780
+ console.log(message);
781
+ }
782
+ }
783
+ finally {
784
+ exitWhenFlushed(code);
754
785
  }
755
786
  });
756
787
  // Publish agent command
@@ -401,6 +401,10 @@ export interface FeaturesConfig {
401
401
  storytelling?: StorytellingConfig;
402
402
  auto_reflection?: AutoReflectionConfig;
403
403
  inference?: InferenceConfig;
404
+ /** External Dynamo pass. Off uses the local decision matrix. */
405
+ inference_governance?: {
406
+ enabled?: boolean;
407
+ };
404
408
  memory_routing?: MemoryRoutingConfig;
405
409
  /** P2.2 — lightweight Grok write-tool postprocessor marker */
406
410
  grok_postprocessor_light?: boolean;
@@ -409,6 +409,16 @@ export class FeaturesConfigLoader {
409
409
  cache_ttl_seconds: 300,
410
410
  max_cache_size_mb: 50,
411
411
  },
412
+ inference: {
413
+ description: "Self-improvement cycle that grades a new named session into repertoire",
414
+ enabled: true,
415
+ workflow_dir: ".xray/inference",
416
+ reports_dir: ".xray/reports",
417
+ pattern_matching: {
418
+ enabled: true,
419
+ confidence_threshold: 0.7,
420
+ },
421
+ },
412
422
  synthesis: {
413
423
  enabled: false,
414
424
  every_n_gates: 12,
@@ -26,4 +26,6 @@ export declare function shouldTriggerCycle(inferenceDir: string, lastCycleFile:
26
26
  reason: string;
27
27
  };
28
28
  export declare function accumulateCorpus(inferenceDir: string): InferenceCorpus;
29
+ /** Reflection files are graded in memory. They are not copied into session-*.json. */
30
+ export declare function loadReflectionInferences(inferenceDir: string): SessionInference[];
29
31
  export declare function loadSessionInferences(dir: string): SessionInference[];