0xray 4.0.40 → 4.0.41

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 (129) hide show
  1. package/.grok-plugin/plugin.json +1 -1
  2. package/.opencode/agents/api-design.yml +31 -0
  3. package/.opencode/agents/architect.yml +15 -0
  4. package/.opencode/agents/architecture-patterns.yml +14 -0
  5. package/.opencode/agents/auto-format.yml +14 -0
  6. package/.opencode/agents/backend-engineer.yml +12 -0
  7. package/.opencode/agents/boot-orchestrator.yml +14 -0
  8. package/.opencode/agents/bug-triage-specialist.yml +15 -0
  9. package/.opencode/agents/code-analyzer.yml +12 -0
  10. package/.opencode/agents/code-reviewer.yml +14 -0
  11. package/.opencode/agents/content-creator.yml +12 -0
  12. package/.opencode/agents/database-engineer.yml +12 -0
  13. package/.opencode/agents/devops-engineer.yml +12 -0
  14. package/.opencode/agents/framework-compliance-audit.yml +14 -0
  15. package/.opencode/agents/frontend-engineer.yml +12 -0
  16. package/.opencode/agents/frontend-ui-ux-engineer.yml +12 -0
  17. package/.opencode/agents/git-workflow.yml +15 -0
  18. package/.opencode/agents/growth-strategist.yml +12 -0
  19. package/.opencode/agents/hermes-agent.yml +12 -0
  20. package/.opencode/agents/inference-improve.yml +12 -0
  21. package/.opencode/agents/lint.yml +14 -0
  22. package/.opencode/agents/log-monitor.yml +12 -0
  23. package/.opencode/agents/mobile-developer.yml +12 -0
  24. package/.opencode/agents/model-health-check.yml +12 -0
  25. package/.opencode/agents/multimodal-looker.yml +12 -0
  26. package/.opencode/agents/performance-analysis.yml +12 -0
  27. package/.opencode/agents/performance-engineer.yml +12 -0
  28. package/.opencode/agents/performance-optimization.yml +12 -0
  29. package/.opencode/agents/processor-pipeline.yml +14 -0
  30. package/.opencode/agents/project-analysis.yml +12 -0
  31. package/.opencode/agents/refactorer.yml +12 -0
  32. package/.opencode/agents/researcher.yml +12 -0
  33. package/.opencode/agents/security-auditor.yml +12 -0
  34. package/.opencode/agents/security-scan.yml +12 -0
  35. package/.opencode/agents/seo-consultant.yml +12 -0
  36. package/.opencode/agents/session-management.yml +12 -0
  37. package/.opencode/agents/state-manager.yml +12 -0
  38. package/.opencode/agents/storyteller.yml +12 -0
  39. package/.opencode/agents/strategist.yml +12 -0
  40. package/.opencode/agents/tech-writer.yml +12 -0
  41. package/.opencode/agents/testing-best-practices.yml +12 -0
  42. package/.opencode/agents/testing-lead.yml +12 -0
  43. package/.opencode/agents/ui-ux-design.yml +12 -0
  44. package/.opencode/codex.codex +8 -0
  45. package/.opencode/commands/auto-format.md +99 -0
  46. package/.opencode/commands/auto-summary-capture.md +90 -0
  47. package/.opencode/commands/dependency-audit.md +184 -0
  48. package/.opencode/commands/enforcer-daily-scan.md +137 -0
  49. package/.opencode/commands/framework-compliance-audit.md +205 -0
  50. package/.opencode/commands/interactive-validator.md +75 -0
  51. package/.opencode/commands/job-summary-logger.md +68 -0
  52. package/.opencode/commands/lint.md +11 -0
  53. package/.opencode/commands/mode-switch.md +95 -0
  54. package/.opencode/commands/model-health-check.md +186 -0
  55. package/.opencode/commands/performance-analysis.md +144 -0
  56. package/.opencode/commands/pre-commit-introspection.md +185 -0
  57. package/.opencode/commands/pre-commit-introspection.sh +133 -0
  58. package/.opencode/commands/security-scan.md +157 -0
  59. package/.opencode/commands/sisyphus-validation.md +128 -0
  60. package/.opencode/commands/summary-logger.md +83 -0
  61. package/.opencode/enforcer-config.json +282 -0
  62. package/.opencode/workflows/post-deployment-audit.yml +123 -0
  63. package/.xray/features.json +1 -1
  64. package/dist/CHANGELOG.md +16 -0
  65. package/dist/integrations/grok/hooks/grok-hook-utils.js +21 -1
  66. package/dist/integrations/grok/hooks/session-start.js +2 -20
  67. package/dist/integrations/hooks/goggles-mcp.mjs +36 -4
  68. package/dist/integrations/hooks/goggles-pipeline.mjs +55 -15
  69. package/dist/integrations/hooks/goggles-planes.json +9 -3
  70. package/dist/integrations/hooks/plates.cjs +22 -0
  71. package/dist/integrations/hooks/session-note-index.cjs +298 -0
  72. package/dist/integrations/hooks/session-note-index.mjs +22 -0
  73. package/dist/integrations/hooks/sleeve.cjs +335 -0
  74. package/dist/integrations/hooks/sleeve.mjs +18 -0
  75. package/dist/integrations/hooks/station-hook-runtime.cjs +205 -9
  76. package/dist/integrations/hooks/wake-cascade.cjs +102 -0
  77. package/dist/integrations/hooks/wake-cascade.mjs +16 -0
  78. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  79. package/dist/memory-routing/plates.d.ts +1 -1
  80. package/dist/memory-routing/plates.js +1 -0
  81. package/docs-site/docs/plates/activity-log.md +1 -1
  82. package/docs-site/docs/plates/boot.md +2 -0
  83. package/docs-site/docs/plates/centrifuge.md +30 -0
  84. package/docs-site/docs/plates/cursor-compact.md +1 -1
  85. package/docs-site/docs/plates/glossary.md +1 -2
  86. package/docs-site/docs/plates/goggles.md +4 -0
  87. package/docs-site/docs/plates/governance.md +2 -0
  88. package/docs-site/docs/plates/grok-compact.md +1 -1
  89. package/docs-site/docs/plates/grokbot.md +1 -1
  90. package/docs-site/docs/plates/host-pack.md +2 -0
  91. package/docs-site/docs/plates/house.md +1 -1
  92. package/docs-site/docs/plates/index.md +3 -1
  93. package/docs-site/docs/plates/inference-files.md +1 -1
  94. package/docs-site/docs/plates/kept-line.md +1 -1
  95. package/docs-site/docs/plates/kits.md +2 -0
  96. package/docs-site/docs/plates/lens-gate.md +1 -1
  97. package/docs-site/docs/plates/lens-page.md +1 -1
  98. package/docs-site/docs/plates/live-mesh.md +1 -1
  99. package/docs-site/docs/plates/memory-recall.md +4 -0
  100. package/docs-site/docs/plates/notes-page.md +2 -1
  101. package/docs-site/docs/plates/orchestration.md +2 -0
  102. package/docs-site/docs/plates/package-face.md +1 -1
  103. package/docs-site/docs/plates/payload-heat.md +1 -1
  104. package/docs-site/docs/plates/pickup-stamp.md +1 -1
  105. package/docs-site/docs/plates/pre-tool.md +1 -1
  106. package/docs-site/docs/plates/processor.md +2 -0
  107. package/docs-site/docs/plates/record-map.md +2 -1
  108. package/docs-site/docs/plates/reflection-page.md +1 -1
  109. package/docs-site/docs/plates/reporting.md +2 -0
  110. package/docs-site/docs/plates/review.md +1 -1
  111. package/docs-site/docs/plates/routing.md +2 -0
  112. package/docs-site/docs/plates/session-capture.md +1 -1
  113. package/docs-site/docs/plates/site-manual.md +1 -1
  114. package/docs-site/docs/plates/stamp-plate.md +1 -1
  115. package/docs-site/docs/plates/station-card.md +4 -1
  116. package/docs-site/docs/plates/station-heat.md +1 -1
  117. package/docs-site/docs/plates/suit-organs.md +1 -1
  118. package/docs-site/docs/plates/suit-settings.md +1 -1
  119. package/docs-site/docs/plates/suit-wear.md +3 -1
  120. package/docs-site/docs/plates/suit.md +2 -0
  121. package/docs-site/docs/plates/trail-state.md +1 -1
  122. package/docs-site/docs/plates/work-fresh.md +1 -1
  123. package/docs-site/docs/plates/write-home.md +1 -1
  124. package/package.json +1 -1
  125. package/scripts/node/bridge-mcp-wiring.cjs +37 -4
  126. package/scripts/node/install-bridges.cjs +172 -19
  127. package/scripts/node/setup.cjs +2 -46
  128. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  129. package/xray/features.json +1 -1
@@ -0,0 +1,102 @@
1
+ /**
2
+ * One wake hands the lens, the ticket, the laws, and the current notes.
3
+ * Goggles names plane record-map.
4
+ * The station module writes STATION.md and NOTES.md.
5
+ * Repertoire keeps the law list.
6
+ * The current session-note index sits beside that list.
7
+ * The card carries the count. A memory look carries the current lines.
8
+ */
9
+ const { existsSync, readFileSync } = require("fs");
10
+ const { join } = require("path");
11
+ const { shortSessionIndex } = require("./session-note-index.cjs");
12
+
13
+ const CASCADE_PLANE = "record-map";
14
+ const MEMORY_PLANES = ["record-map", "station-card", "notes-page", "memory-recall"];
15
+
16
+ function isCascadePlane(id) {
17
+ return MEMORY_PLANES.includes(String(id || ""));
18
+ }
19
+
20
+ function clipNames(names) {
21
+ if (!Array.isArray(names)) return [];
22
+ const out = [];
23
+ for (const raw of names) {
24
+ const name = String(raw || "").trim();
25
+ if (!name || out.includes(name)) continue;
26
+ out.push(name);
27
+ if (out.length >= 8) break;
28
+ }
29
+ return out;
30
+ }
31
+
32
+ function lawNamesFromWorking(root) {
33
+ const file = join(root, ".xray", "state", "repertoire-working.json");
34
+ if (!existsSync(file)) return [];
35
+ try {
36
+ const data = JSON.parse(readFileSync(file, "utf8"));
37
+ return clipNames(data && data.matchedSignals);
38
+ } catch {
39
+ return [];
40
+ }
41
+ }
42
+
43
+ function currentNotes(root) {
44
+ try {
45
+ return shortSessionIndex(root).map((note) => {
46
+ const row = { id: note.id, text: note.text };
47
+ if (note.slot) row.slot = note.slot;
48
+ return row;
49
+ });
50
+ } catch {
51
+ return [];
52
+ }
53
+ }
54
+
55
+ /** Laws come from this wake when passed. Otherwise the working file. Notes are current lines only. */
56
+ function readWakeCascade(root, opts = {}) {
57
+ const laws = Array.isArray(opts.laws) ? clipNames(opts.laws) : lawNamesFromWorking(root);
58
+ return {
59
+ plane: CASCADE_PLANE,
60
+ station: ".xray/state/STATION.md",
61
+ notesPage: ".xray/state/NOTES.md",
62
+ index: ".xray/state/repertoire/session-notes.json",
63
+ laws,
64
+ notes: currentNotes(root),
65
+ };
66
+ }
67
+
68
+ function formatCascadePointer(cascade) {
69
+ const count = cascade && Array.isArray(cascade.notes) ? cascade.notes.length : 0;
70
+ const plane = cascade && cascade.plane ? cascade.plane : CASCADE_PLANE;
71
+ return `Cascade: ${plane} · notes ${count} current`;
72
+ }
73
+
74
+ function formatCascadeReading(cascade) {
75
+ const plane = cascade && cascade.plane ? cascade.plane : CASCADE_PLANE;
76
+ const laws = cascade && Array.isArray(cascade.laws) && cascade.laws.length
77
+ ? cascade.laws.join(", ")
78
+ : "(none yet)";
79
+ const notes = cascade && Array.isArray(cascade.notes) ? cascade.notes : [];
80
+ const lines = [
81
+ `Cascade: ${plane}`,
82
+ `Station: ${cascade && cascade.station ? cascade.station : ".xray/state/STATION.md"}`,
83
+ `Notes page: ${cascade && cascade.notesPage ? cascade.notesPage : ".xray/state/NOTES.md"}`,
84
+ `Index: ${cascade && cascade.index ? cascade.index : ".xray/state/repertoire/session-notes.json"}`,
85
+ `Laws: ${laws}`,
86
+ `Notes: ${notes.length} current`,
87
+ ];
88
+ for (const note of notes) {
89
+ const slot = note.slot ? `${note.slot} ` : "";
90
+ lines.push(`- ${note.id} ${slot}${note.text}`);
91
+ }
92
+ return lines.join("\n");
93
+ }
94
+
95
+ module.exports = {
96
+ CASCADE_PLANE,
97
+ MEMORY_PLANES,
98
+ isCascadePlane,
99
+ readWakeCascade,
100
+ formatCascadePointer,
101
+ formatCascadeReading,
102
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * ESM face for wake-cascade.cjs.
3
+ */
4
+ import { createRequire } from "node:module";
5
+ import { fileURLToPath } from "node:url";
6
+ import { dirname, join } from "node:path";
7
+
8
+ const require = createRequire(import.meta.url);
9
+ const impl = require(join(dirname(fileURLToPath(import.meta.url)), "wake-cascade.cjs"));
10
+
11
+ export const CASCADE_PLANE = impl.CASCADE_PLANE;
12
+ export const MEMORY_PLANES = impl.MEMORY_PLANES;
13
+ export const isCascadePlane = impl.isCascadePlane;
14
+ export const readWakeCascade = impl.readWakeCascade;
15
+ export const formatCascadePointer = impl.formatCascadePointer;
16
+ export const formatCascadeReading = impl.formatCascadeReading;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xray-pre-tool",
3
- "version": "4.0.40",
3
+ "version": "4.0.41",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "0xRay constitution + temperament PreToolUse for OpenClaw",
@@ -1,4 +1,4 @@
1
- export declare const PLATE_IDS: readonly ["routing", "governance", "boot", "orchestration", "processor", "reporting", "memory-recall", "stamp-plate", "house", "review", "goggles", "suit", "kits", "host-pack", "glossary", "record-map", "write-home", "activity-log", "session-capture", "suit-wear", "suit-organs", "station-card", "notes-page", "reflection-page", "site-manual", "package-face", "suit-settings", "trail-state", "inference-files", "grok-compact", "payload-heat", "station-heat", "pickup-stamp", "cursor-compact", "work-fresh", "kept-line", "lens-gate", "pre-tool", "lens-page"];
1
+ export declare const PLATE_IDS: readonly ["routing", "governance", "boot", "orchestration", "processor", "reporting", "memory-recall", "stamp-plate", "house", "review", "goggles", "suit", "kits", "host-pack", "glossary", "record-map", "write-home", "activity-log", "session-capture", "suit-wear", "suit-organs", "station-card", "notes-page", "reflection-page", "site-manual", "package-face", "suit-settings", "trail-state", "inference-files", "grok-compact", "payload-heat", "station-heat", "pickup-stamp", "cursor-compact", "work-fresh", "kept-line", "lens-gate", "pre-tool", "lens-page", "centrifuge"];
2
2
  export type PlateId = (typeof PLATE_IDS)[number];
3
3
  export interface PlateStamp {
4
4
  id: PlateId;
@@ -45,6 +45,7 @@ export const PLATE_IDS = [
45
45
  'lens-gate',
46
46
  'pre-tool',
47
47
  'lens-page',
48
+ 'centrifuge',
48
49
  ];
49
50
  function isPlateId(value) {
50
51
  return PLATE_IDS.includes(value);
@@ -35,4 +35,4 @@ Today those writers append `logs/framework/activity.log`. The features default s
35
35
 
36
36
  When: on the tool hook, on framework logger flush, and on boot when file logging is on. Why: the report and the pulse read one tail, not a pile of copies.
37
37
 
38
- stamped · 0xray 4.0.40
38
+ stamped · 0xray 4.0.41
@@ -65,3 +65,5 @@ sidebar_label: Boot
65
65
  │ └────────────────────────────────────────────────────┘ │
66
66
  └────────────────────────────────────────────────────────────┘
67
67
  ```
68
+
69
+ stamped · 0xray 4.0.41
@@ -0,0 +1,30 @@
1
+ ---
2
+ title: Centrifuge
3
+ sidebar_label: Centrifuge
4
+ plate_type: domain model
5
+ ---
6
+
7
+ # Centrifuge
8
+
9
+ One wake is one turn. Station is the axle. The gap stays open.
10
+
11
+ ```
12
+ CENTRIFUGE
13
+ ┌──── VISOR ────┐
14
+ │ GOGGLES │
15
+ └───────┬───────┘
16
+ │ looks down
17
+ ┌──────────────────┴──────────────────┐
18
+ │ DOMAIN │
19
+ │ │
20
+ JUDGEMENT│ LOOP STATE │PAYMENTS
21
+ · off │ STATION │ · off
22
+ · fixed │ FOUNDRY │ · fixed
23
+ │ MEMORY │
24
+ └────────────── ONE TURN ─────────────┘
25
+ the gap stays open
26
+ ```
27
+
28
+ Loop, domain, state, foundry, and memory ride that turn. Judgement and payments stay off the rotor. Goggles looks on and does not spin. The next turn waits for the next session or compact.
29
+
30
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ Cursor preCompact writes the station card and cannot block the compact.
32
32
 
33
33
  The file is `src/integrations/cursor/hooks/pre-compact.js`. The message tells the seat to read STATION.md. The plates that belong here are payload-heat and station-heat.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -23,5 +23,4 @@ What the words mean.
23
23
  │ grok-bot · the package you install │
24
24
  └────────────────────────────────────────────────────────────┘
25
25
  ```
26
-
27
-
26
+ stamped · 0xray 4.0.41
@@ -16,3 +16,7 @@ It views one plane.
16
16
  │ · not every plane at once │
17
17
  └────────────────────────────────────────────────────────────┘
18
18
  ```
19
+
20
+ A checkout named `0xray` records `scripts/mjs/run-goggles-mcp.mjs`. Any other project records `node_modules/0xray/scripts/mjs/run-goggles-mcp.mjs`.
21
+
22
+ stamped · 0xray 4.0.41
@@ -49,3 +49,5 @@ A proposal is deliberated inside the suit, filtered by Dynamo Solar, then merged
49
49
  │ └──────────────────────┘ └──────────────────────┘ │
50
50
  └────────────────────────────────────────────────────────────┘
51
51
  ```
52
+
53
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ Grok PreCompact runs session-start.js with the pre_compact event.
32
32
 
33
33
  The hook is `session-start.js --hook-event=pre_compact`. It calls `buildSessionBootPayload`, writes the station card, and prints nothing. It does not match the conversation. Grok ignores hook stdout. The plates that belong here are payload-heat, cursor-compact, and work-fresh.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -38,4 +38,4 @@ Give your bots a house: shared rules, one board for the work, and memory that st
38
38
  code links: suit → memory, house → doctor, memory → station. Other lines show reading order only.
39
39
  ```
40
40
 
41
- stamped · 0xray 4.0.40 · @0xray/grok-bot 0.1.8
41
+ stamped · 0xray 4.0.41 · @0xray/grok-bot 0.1.8
@@ -30,3 +30,5 @@ Run it in the tool you already open. Same suit. No new app.
30
30
  ```
31
31
 
32
32
  These six already run.
33
+
34
+ stamped · 0xray 4.0.41
@@ -50,4 +50,4 @@ A state flow plate: the stages a house goes through before doctor says House: PA
50
50
  └──────────────────────────────┘
51
51
  ```
52
52
 
53
- stamped · 0xray 4.0.40 · @0xray/grok-bot 0.1.8
53
+ stamped · 0xray 4.0.41 · @0xray/grok-bot 0.1.8
@@ -17,7 +17,7 @@ Plates have a type. A domain model plate shows how named parts fit. A state flow
17
17
 
18
18
  ## Domain model
19
19
 
20
- [Goggles](./goggles.md) · [Suit](./suit.md) · [Kits](./kits.md) · [Host Pack](./host-pack.md) · [Glossary](./glossary.md) · [Grok Bot](./grokbot.md)
20
+ [Goggles](./goggles.md) · [Suit](./suit.md) · [Kits](./kits.md) · [Host Pack](./host-pack.md) · [Glossary](./glossary.md) · [Grok Bot](./grokbot.md) · [Centrifuge](./centrifuge.md)
21
21
 
22
22
  ## State flow
23
23
 
@@ -50,3 +50,5 @@ These eight are the pages the file ref names. Each one is a search lens. Each le
50
50
  [Work fresh](./work-fresh.md) · [Kept line](./kept-line.md) · [Lens gate](./lens-gate.md) · [Pre tool](./pre-tool.md) · [Lens page](./lens-page.md)
51
51
 
52
52
  These five are the compact path that was opened. Each one is a search lens. Each lens lists one skill and the plates that belong with it.
53
+
54
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ Inference cycle state already lives under .xray/inference.
32
32
 
33
33
  Cycle state, history, graded ids, and governance state are already there. Session files still fall back to `docs/inference` until the writers move.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ A station rewrite keeps one Fresh line and drops the copies.
32
32
 
33
33
  mergeStationMarkdown in src/integrations/hooks/station-hook-runtime.cjs treats a Fresh line as stock. Copies are not preserved. When the new card has no Fresh line, the latest one is kept. The plates that belong here are station-card and work-fresh.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -26,3 +26,5 @@ Add a power. Memory, judgment, or payments.
26
26
  ```
27
27
 
28
28
  Three. That's the set.
29
+
30
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ A search names one plane or it stops.
32
32
 
33
33
  lensBeforeResearch in src/integrations/hooks/goggles-pipeline.mjs returns null when the call is not research, and when the spoken text names exactly one card plane. Zero names, or more than one, deny with Name one plane. A shell that reads a project source file is research. The first open of a source file that no lens lists is allowed and remembered. The next search stops until that file is on a lens and the plate is on disk. The hook does not author the plate. The plate that belongs here is pre-tool.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ The lens page is the card for one plane.
32
32
 
33
33
  `formatCardPane` in `src/integrations/hooks/goggles-pipeline.mjs` draws the card. Read the card instead of searching the tree. The plates that belong here are record-map and lens-gate.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -38,4 +38,4 @@ Ping-pong eng events become one ordered JSON feed, then a mesh render. Markdown
38
38
 
39
39
  Paths live under `house/live-mesh/`. Schema is `schema.json`. The plate that belongs here is house.
40
40
 
41
- stamped · 0xray 4.0.40
41
+ stamped · 0xray 4.0.41
@@ -38,3 +38,7 @@ Intent names one plate. Equal top scores recall nothing. A missing worn copy is
38
38
  │ └────────────────────┘ └────────────────────────┘ │
39
39
  └──────────────────────────────────────────────────────────────┘
40
40
  ```
41
+
42
+ A look returns the named plane, the matched law names, and the current lines from the session-note index. It does not write a law.
43
+
44
+ stamped · 0xray 4.0.41
@@ -32,4 +32,5 @@ Notes are the body the station card cannot hold.
32
32
 
33
33
  The page is `.xray/state/NOTES.md`. The pickup line equals the station intent. The default depth is the working notes: the point, the coverage, the library, the open pull requests, the rituals, and the next cut. A pickup line alone does not survive a compact. PreCompact calls `stampNotesPickup`, which updates only that line and leaves the body alone. The hook does not check the body. The seat writes it before the compact. Do not commit this file. Do not feed it to Repertoire.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ The station module writes this page. Heat keeps the current lines in `.xray/state/repertoire/session-notes.json` beside the laws. The wake cascade reads that index and does not write a law. A replaced note stays in that index as history. The short index returns the current line.
36
+ stamped · 0xray 4.0.41
@@ -57,3 +57,5 @@ Each tool is its own call. `spawnAside` opens around `orchestrate-task`, `analyz
57
57
  │ └─────────────────────┘ └─────────────────────────┘ │
58
58
  └────────────────────────────────────────────────────────────┘
59
59
  ```
60
+
61
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ A release writes the package face, and the agent reads it.
32
32
 
33
33
  The face is `README.md`, `package.json`, `AGENTS.md`, `llms.txt`, `CHANGELOG.md`, and `SKILLS.md`. Do not hand-bump the version.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ buildSessionBootPayload calls applyStationHeat and writes the station card.
32
32
 
33
33
  The function is in `src/integrations/grok/hooks/grok-hook-utils.js`. The plates that belong here are station-heat and pickup-stamp.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ stampNotesPickup writes one pickup line and leaves the rest of NOTES.md alone.
32
32
 
33
33
  The comment on the function is one pickup line. There is no check that the working notes are present. The plate that belongs here is notes-page.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ The tool hook is where the lens gate runs.
32
32
 
33
33
  pre-tool-use.js joins the command, the written content, and the paths, then calls lensBeforeResearch. A deny ends the hook. The plate that belongs here is lens-gate.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -42,3 +42,5 @@ sidebar_label: Processor
42
42
  │ └──────────────────────────┘ └───────────────────────┘ │
43
43
  └──────────────────────────────────────────────────────────────┘
44
44
  ```
45
+
46
+ stamped · 0xray 4.0.41
@@ -38,4 +38,5 @@ Trail: state and logs under `.xray`. Codex is already loaded. This plate is the
38
38
 
39
39
  The published manual is `docs-site/docs/`. The rule sheet is `grok-bot/OP-PROC.md`. Neither is one of the five pages.
40
40
 
41
- stamped · 0xray 4.0.40
41
+ Goggles plane `record-map` is the lens over this map. Station and the notes page belong to the station module. Repertoire laws stay in the law file. The session-note index sits beside that file.
42
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ A reflection is one episode written under docs/reflections.
32
32
 
33
33
  The loader is `loadReflectionInferences` in `src/inference/inference-accumulator.ts`. A reflection is not a repertoire law.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -35,3 +35,5 @@ Logs become a report. A valid cache returns the formatted report and does not wr
35
35
  │ └──────────────────────────┘ └─────────────────────┘ │
36
36
  └────────────────────────────────────────────────────────────┘
37
37
  ```
38
+
39
+ stamped · 0xray 4.0.41
@@ -54,4 +54,4 @@ A state flow plate: one critic pass, one fix, one re-review, then stop.
54
54
 
55
55
  A FAIL names the file and a test that fails on the old code. One author fixes that hole. A second session waits while the verdict is open. Re-review that new head. A hole the new test did not lock returns to ONE FIX. A PASS ends the plate. A note stays a note and does not open another lap.
56
56
 
57
- stamped · 0xray 4.0.40
57
+ stamped · 0xray 4.0.41
@@ -58,3 +58,5 @@ Task text becomes an agent. `scoreAndRoute` scores the work, then `routeToAgent`
58
58
  │ └────────────┘ │
59
59
  └──────────────────────────────────────────────────────────────┘
60
60
  ```
61
+
62
+ stamped · 0xray 4.0.41
@@ -35,4 +35,4 @@ Today that file is `docs/inference/latest-session.json`. The home is `.xray/infe
35
35
 
36
36
  Station reads the file for heat. The inference accumulator reads `session-*.json` beside it. Do not mint a `session-<date>-<sha>` file for the station note.
37
37
 
38
- stamped · 0xray 4.0.40
38
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ The published manual is docs-site/docs.
32
32
 
33
33
  Guides, architecture, and introduction live here. Factory notes under `docs/` are a different set. Reflections stay in `docs/reflections/`.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ A stamped plate is one drawing for one plane.
32
32
 
33
33
  The file is `docs-site/docs/plates/<id>.md`. Each opened segue gets its own plate. The hook does not author this file. The plate that belongs here is review.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -32,4 +32,7 @@ The station card is the one-line ticket at .xray/state/STATION.md.
32
32
 
33
33
  Read it after a compact. Leave Intent alone. The plan is the next cut. The long body belongs in notes.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ The station module writes this card. Heat adds `Cascade: record-map · notes N current`. The count is the current index. The body stays on the notes page.
36
+
37
+ The card keeps the named plane. `Sleeve: on` means the previous ticket came back, the worn plate matched the package, the previous ticket matched the working record, and inspect passed. Judgement is continue, retry N, stop, or start. The same miss keeps its retry. A different ticket stops. Payments is on only when the ticket is a payment.
38
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ On a compact event applyStationHeat stamps the notes pickup line.
32
32
 
33
33
  `isCompactHook` is true when the hook name contains compact. The body of NOTES.md is left alone. The plates that belong here are pickup-stamp and notes-page.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -35,4 +35,4 @@ Reporting reads the activity log and may write a report. Station reads `latest-s
35
35
 
36
36
  Repertoire already keeps `inference-state.json` and the day log under `.xray/state/repertoire/`. Goggles does not write these files. It reads a plate when one plane is named.
37
37
 
38
- stamped · 0xray 4.0.40
38
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ Suit settings are features, config, and codex.
32
32
 
33
33
  There is no settings.json. The files are `.xray/features.json`, `.xray/config.json`, and `.xray/codex.json`. The package copies live under `xray/`.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -34,4 +34,6 @@ Wear copies hooks, features.json, and the consumer gitignore into the project, a
34
34
 
35
35
  A worn project is a consumer. Its writes go to its own `.xray/logs` and `.xray/inference`, not into `docs/` and not into `.opencode/logs`.
36
36
 
37
- stamped · 0xray 4.0.40
37
+ A fresh wear fastens mill and inspect. Grok's Goggles launcher stays on that install: the checkout script when the package name is `0xray`, and `node_modules/0xray` for every other project.
38
+
39
+ stamped · 0xray 4.0.41
@@ -38,3 +38,5 @@ Give your agent a suit. The rules stay on, you add powers, and it runs in the to
38
38
  ```
39
39
 
40
40
  Same rules in the repo. You are not locked into one app.
41
+
42
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ The suit writes its trail under .xray.
32
32
 
33
33
  Session boot, the lens match line, and the station card are state. The agent reads them. Do not commit `.xray/state`.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -32,4 +32,4 @@ Refresh writes one Fresh line from git and the published package.
32
32
 
33
33
  refreshFreshness in src/nucleus/work-freshness.mjs fetches origin, reads npm view 0xray version, and returns that one line. A compact hook does not call it. The plate that belongs here is station-card.
34
34
 
35
- stamped · 0xray 4.0.40
35
+ stamped · 0xray 4.0.41
@@ -35,4 +35,4 @@ The path table is `src/integrations/hooks/write-home.cjs`. Writers use it. Reade
35
35
 
36
36
  Still on the old path until each caller is rewired: the activity logger, the framework logger, the pipeline hook, the Grok hook, the Hermes bridge, station capture, `saveSessionInference`, reporting, pulse, monitor, and `features.json` `log_path`.
37
37
 
38
- stamped · 0xray 4.0.40
38
+ stamped · 0xray 4.0.41
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0xray",
3
- "version": "4.0.40",
3
+ "version": "4.0.41",
4
4
  "description": "Multi-agent orchestration and Codex governance for OpenCode, Hermes, Grok Build, and OpenClaw",
5
5
  "readme": "README.md",
6
6
  "license": "MIT",
@@ -139,11 +139,32 @@ function enableMemoryRoutingIfResolves(features, targetDir) {
139
139
  };
140
140
  }
141
141
 
142
+ function isDogfoodXrayPackage(targetDir) {
143
+ try {
144
+ const pkgPath = path.join(targetDir, "package.json");
145
+ if (!fs.existsSync(pkgPath)) return false;
146
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
147
+ return pkg && pkg.name === "0xray";
148
+ } catch {
149
+ return false;
150
+ }
151
+ }
152
+
142
153
  function resolveGogglesMcp(targetDir) {
143
- const candidates = [
144
- path.join(targetDir, "node_modules", "0xray", "scripts", "mjs", "run-goggles-mcp.mjs"),
145
- path.join(targetDir, "scripts", "mjs", "run-goggles-mcp.mjs"),
146
- ];
154
+ const installed = path.join(
155
+ targetDir,
156
+ "node_modules",
157
+ "0xray",
158
+ "scripts",
159
+ "mjs",
160
+ "run-goggles-mcp.mjs",
161
+ );
162
+ const checkout = path.join(targetDir, "scripts", "mjs", "run-goggles-mcp.mjs");
163
+ // The factory package is not installed into its own node_modules. npm upgrade
164
+ // removes that folder, and a recorded node_modules path then fails the handshake.
165
+ const candidates = isDogfoodXrayPackage(targetDir)
166
+ ? [checkout, installed]
167
+ : [installed, checkout];
147
168
  return candidates.find((file) => fs.existsSync(file)) || null;
148
169
  }
149
170
 
@@ -315,7 +336,18 @@ function pinnedMcpLaunch(targetDir, mcpCmd) {
315
336
  */
316
337
  const LIVE_ENV_NAMES = ["PATH", "HOME"];
317
338
 
339
+ let launcherPackageRoot = "";
340
+
341
+ /** Wear sets this so a /tmp checkout is not the path written into a real project. */
342
+ function pinLauncherPackageRoot(packageRoot) {
343
+ launcherPackageRoot = packageRoot ? path.resolve(packageRoot) : "";
344
+ }
345
+
318
346
  function mcpLauncherPath() {
347
+ if (launcherPackageRoot) {
348
+ const candidate = path.join(launcherPackageRoot, "scripts", "node", "mcp-launch.cjs");
349
+ if (fs.existsSync(candidate)) return candidate;
350
+ }
319
351
  return path.join(__dirname, "mcp-launch.cjs");
320
352
  }
321
353
 
@@ -988,6 +1020,7 @@ module.exports = {
988
1020
  enableMemoryRoutingIfResolves,
989
1021
  isEphemeralInstallRoot,
990
1022
  isIsolatedHome,
1023
+ pinLauncherPackageRoot,
991
1024
  copyHermesHookRuntimes,
992
1025
  resolveOpenClawPreToolHookSource,
993
1026
  resolveOpenClawPluginDir,