0xray 4.0.34 → 4.0.35

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 (155) hide show
  1. package/.grok-plugin/plugin.json +1 -1
  2. package/.xray/codex.json +12 -4
  3. package/.xray/features.json +1 -1
  4. package/AGENTS-consumer.md +6 -6
  5. package/AGENTS.md +5 -5
  6. package/README.md +2 -2
  7. package/dist/AGENTS.md +5 -5
  8. package/dist/CHANGELOG.md +16 -0
  9. package/dist/README.md +2 -2
  10. package/dist/cli/index.js +2 -5
  11. package/dist/governance/governance-service.js +1 -1
  12. package/dist/integrations/base/README.md +1 -9
  13. package/dist/integrations/base/index.d.ts +0 -1
  14. package/dist/integrations/base/index.js +0 -2
  15. package/dist/integrations/governance/index.js +31 -8
  16. package/dist/integrations/grok/hooks/grok-hook-utils.js +1 -1
  17. package/dist/integrations/grok/hooks/session-start.js +12 -0
  18. package/dist/integrations/hooks/goggles-pipeline.mjs +62 -11
  19. package/dist/integrations/hooks/host-truth.mjs +74 -0
  20. package/dist/integrations/hooks/station-hook-runtime.cjs +3 -0
  21. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  22. package/dist/mcps/knowledge-skills/storyteller.server.js +0 -1
  23. package/dist/nucleus/delegation-gate.d.ts +2 -2
  24. package/dist/nucleus/delegation-gate.js +13 -2
  25. package/dist/nucleus/work-freshness.mjs +189 -0
  26. package/dist/processors/implementations/agents-md-validation-processor.js +1 -1
  27. package/docs-site/docs/plates/boot.md +17 -2
  28. package/docs-site/docs/plates/governance.md +3 -2
  29. package/docs-site/docs/plates/index.md +3 -1
  30. package/docs-site/docs/plates/memory-recall.md +26 -35
  31. package/docs-site/docs/plates/orchestration.md +39 -35
  32. package/docs-site/docs/plates/processor.md +34 -36
  33. package/docs-site/docs/plates/reporting.md +3 -8
  34. package/docs-site/docs/plates/routing.md +22 -11
  35. package/package.json +2 -2
  36. package/scripts/foundry/release.mjs +48 -5
  37. package/scripts/mjs/test-consumer-readiness.mjs +1 -0
  38. package/scripts/mjs/test-mcp-functionality.mjs +14 -9
  39. package/scripts/node/basic-security-audit.cjs +0 -1
  40. package/scripts/node/bridge-mcp-wiring.cjs +66 -3
  41. package/scripts/node/postinstall.cjs +1 -1
  42. package/scripts/node/prepare-consumer.cjs +11 -7
  43. package/scripts/node/setup-dev.cjs +18 -26
  44. package/scripts/node/validate-mcp-connectivity.js +2 -1
  45. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  46. package/src/mcps/knowledge-skills/storyteller.server.ts +0 -1
  47. package/xray/agents_template.md +5 -5
  48. package/xray/codex.json +12 -4
  49. package/xray/features.json +1 -1
  50. package/dist/agents/known-names.d.ts +0 -26
  51. package/dist/agents/known-names.js +0 -72
  52. package/dist/analytics/consent-manager.d.ts +0 -92
  53. package/dist/analytics/consent-manager.js +0 -257
  54. package/dist/benchmark/performance-benchmark.d.ts +0 -103
  55. package/dist/benchmark/performance-benchmark.js +0 -373
  56. package/dist/cli/commands/analytics-disable.d.ts +0 -9
  57. package/dist/cli/commands/analytics-disable.js +0 -72
  58. package/dist/cli/commands/analytics-enable-action.d.ts +0 -8
  59. package/dist/cli/commands/analytics-enable-action.js +0 -82
  60. package/dist/cli/commands/analytics-preview.d.ts +0 -9
  61. package/dist/cli/commands/analytics-preview.js +0 -106
  62. package/dist/cli/commands/analytics-status.d.ts +0 -9
  63. package/dist/cli/commands/analytics-status.js +0 -68
  64. package/dist/cli/commands/enforce.d.ts +0 -12
  65. package/dist/cli/commands/enforce.js +0 -78
  66. package/dist/cli/commands/govern.d.ts +0 -29
  67. package/dist/cli/commands/govern.js +0 -149
  68. package/dist/cli/commands/security-audit.d.ts +0 -23
  69. package/dist/cli/commands/security-audit.js +0 -219
  70. package/dist/cli/server.d.ts +0 -1
  71. package/dist/cli/server.js +0 -147
  72. package/dist/config/routing-mappings.d.ts +0 -26
  73. package/dist/config/routing-mappings.js +0 -151
  74. package/dist/core/bridge.mjs +0 -922
  75. package/dist/core/trace-context.d.ts +0 -12
  76. package/dist/core/trace-context.js +0 -33
  77. package/dist/enforcement/index.d.ts +0 -22
  78. package/dist/enforcement/index.js +0 -40
  79. package/dist/enforcement/loaders/index.d.ts +0 -36
  80. package/dist/enforcement/loaders/index.js +0 -39
  81. package/dist/enforcement/test-auto-healing.d.ts +0 -83
  82. package/dist/enforcement/test-auto-healing.js +0 -325
  83. package/dist/inference/index.d.ts +0 -10
  84. package/dist/inference/index.js +0 -5
  85. package/dist/infrastructure/iac-validator.d.ts +0 -150
  86. package/dist/infrastructure/iac-validator.js +0 -465
  87. package/dist/infrastructure/schemas/cloud-schemas.d.ts +0 -482
  88. package/dist/infrastructure/schemas/cloud-schemas.js +0 -488
  89. package/dist/integrations/base/ExampleIntegration.d.ts +0 -46
  90. package/dist/integrations/base/ExampleIntegration.js +0 -180
  91. package/dist/integrations/enforcement-gate.d.ts +0 -44
  92. package/dist/integrations/enforcement-gate.js +0 -348
  93. package/dist/mcps/connection/connection-manager.d.ts +0 -39
  94. package/dist/mcps/connection/connection-manager.js +0 -79
  95. package/dist/mcps/index.d.ts +0 -17
  96. package/dist/mcps/index.js +0 -65
  97. package/dist/mcps/orchestrator/index.d.ts +0 -6
  98. package/dist/mcps/orchestrator/index.js +0 -5
  99. package/dist/metrics/index.d.ts +0 -6
  100. package/dist/metrics/index.js +0 -6
  101. package/dist/orchestrator/self-direction-activation.d.ts +0 -108
  102. package/dist/orchestrator/self-direction-activation.js +0 -244
  103. package/dist/orchestrator/universal-registry-bridge.d.ts +0 -84
  104. package/dist/orchestrator/universal-registry-bridge.js +0 -246
  105. package/dist/performance/performance-budget-enforcer.d.ts +0 -157
  106. package/dist/performance/performance-budget-enforcer.js +0 -433
  107. package/dist/performance/performance-regression-tester.d.ts +0 -107
  108. package/dist/performance/performance-regression-tester.js +0 -341
  109. package/dist/postprocessor/analysis/CodeChangeAnalyzer.d.ts +0 -11
  110. package/dist/postprocessor/analysis/CodeChangeAnalyzer.js +0 -50
  111. package/dist/postprocessor/config/ProcessorConfigLoader.d.ts +0 -44
  112. package/dist/postprocessor/config/ProcessorConfigLoader.js +0 -16
  113. package/dist/postprocessor/integration.d.ts +0 -156
  114. package/dist/postprocessor/integration.js +0 -194
  115. package/dist/postprocessor/metamorphosis/index.d.ts +0 -2
  116. package/dist/postprocessor/metamorphosis/index.js +0 -1
  117. package/dist/postprocessor/redeploy/RetryHandler.d.ts +0 -49
  118. package/dist/postprocessor/redeploy/RetryHandler.js +0 -118
  119. package/dist/processors/implementations/session-capture-processor.d.ts +0 -14
  120. package/dist/processors/implementations/session-capture-processor.js +0 -37
  121. package/dist/public/XrayService.d.ts +0 -17
  122. package/dist/public/XrayService.js +0 -40
  123. package/dist/public/index.d.ts +0 -4
  124. package/dist/public/index.js +0 -2
  125. package/dist/security/comprehensive-security-audit.d.ts +0 -157
  126. package/dist/security/comprehensive-security-audit.js +0 -1004
  127. package/dist/security/index.d.ts +0 -13
  128. package/dist/security/index.js +0 -13
  129. package/dist/security/security-agent-coordinator.d.ts +0 -71
  130. package/dist/security/security-agent-coordinator.js +0 -203
  131. package/dist/security/security-hardening-system.d.ts +0 -238
  132. package/dist/security/security-hardening-system.js +0 -726
  133. package/dist/security/security-orchestration-layer.d.ts +0 -118
  134. package/dist/security/security-orchestration-layer.js +0 -495
  135. package/dist/testing/memory-regression-suite.d.ts +0 -105
  136. package/dist/testing/memory-regression-suite.js +0 -258
  137. package/dist/tools/assess-complexity-tool.d.ts +0 -28
  138. package/dist/tools/assess-complexity-tool.js +0 -44
  139. package/dist/tools/query-routing-tool.d.ts +0 -17
  140. package/dist/tools/query-routing-tool.js +0 -59
  141. package/dist/utils/batch-operations.d.ts +0 -25
  142. package/dist/utils/batch-operations.js +0 -292
  143. package/dist/utils/task-graph.d.ts +0 -29
  144. package/dist/utils/task-graph.js +0 -106
  145. package/dist/utils/test-template-generator.d.ts +0 -25
  146. package/dist/utils/test-template-generator.js +0 -178
  147. package/dist/utils/token-manager.d.ts +0 -48
  148. package/dist/utils/token-manager.js +0 -163
  149. package/dist/validation/agent-config-validator.d.ts +0 -110
  150. package/dist/validation/agent-config-validator.js +0 -280
  151. package/dist/validation/orchestration-flow-validator.d.ts +0 -87
  152. package/dist/validation/orchestration-flow-validator.js +0 -606
  153. package/src/mcps/connection/connection-manager.ts +0 -91
  154. package/src/mcps/index.ts +0 -80
  155. package/src/mcps/orchestrator/index.ts +0 -29
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0xray",
3
- "version": "4.0.34",
3
+ "version": "4.0.35",
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",
package/.xray/codex.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "3.1.0",
3
- "lastUpdated": "2026-08-24",
3
+ "lastUpdated": "2026-10-01",
4
4
  "errorPreventionTarget": 0.998,
5
5
  "terms": {
6
6
  "1": {
@@ -62,7 +62,7 @@
62
62
  "8": {
63
63
  "number": 8,
64
64
  "title": "Prevent Infinite Loops",
65
- "description": "Guarantee termination in all iterative processes. All loops must have clear termination conditions. Recursive functions must have base cases. Event loops must have exit strategies. Async operations must have timeout mechanisms.",
65
+ "description": "Guarantee termination in all iterative processes. All loops must have clear termination conditions. Recursive functions must have base cases. Event loops must have exit strategies. Async operations must have timeout mechanisms. A job names when it is done and when it stops.",
66
66
  "category": "core",
67
67
  "zeroTolerance": true,
68
68
  "enforcementLevel": "blocking"
@@ -230,7 +230,7 @@
230
230
  "29": {
231
231
  "number": 29,
232
232
  "title": "Security by Design",
233
- "description": "Validate all inputs. Sanitize data before rendering. Use HTTPS for all requests. Implement rate limiting. Never expose sensitive data.",
233
+ "description": "Validate all inputs. Sanitize data before rendering. Use HTTPS for all requests. Implement rate limiting. Never expose sensitive data. Do not trust Host or X-Forwarded-Host to choose an environment. A refusal in the UI needs the same check on the server.",
234
234
  "category": "security",
235
235
  "zeroTolerance": true,
236
236
  "enforcementLevel": "blocking"
@@ -534,7 +534,7 @@
534
534
  "67": {
535
535
  "number": 67,
536
536
  "title": "Use Best Subagents, Reuse Session Context",
537
- "description": "Delegate work to the best-suited subagent for each task. Stay responsive to user inquiries, additional todos, and course corrections. Reuse the same subagent via session ID to preserve context and avoid restarting from zero. Do not spawn fresh agents when an existing one has the relevant context.",
537
+ "description": "Delegate work to the best-suited subagent for each task. Stay responsive to user inquiries, additional todos, and course corrections. Reuse the same subagent via session ID to preserve context and avoid restarting from zero. Do not spawn fresh agents when an existing one has the relevant context. Reuse one cloud for a workstream. Do not launch a new agent for a check the seat can run.",
538
538
  "category": "process",
539
539
  "zeroTolerance": false,
540
540
  "enforcementLevel": "high"
@@ -554,6 +554,14 @@
554
554
  "category": "process",
555
555
  "zeroTolerance": true,
556
556
  "enforcementLevel": "blocking"
557
+ },
558
+ "70": {
559
+ "number": 70,
560
+ "title": "Current Copy Before Edits",
561
+ "description": "Before an edit, be on the latest main and run the current package. If this repo is 0xray, this repo is that package. An older package waits. Compare set-aside work to main before you throw it away.",
562
+ "category": "process",
563
+ "zeroTolerance": true,
564
+ "enforcementLevel": "blocking"
557
565
  }
558
566
  },
559
567
  "interweaves": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./features.schema.json",
3
- "version": "4.0.34",
3
+ "version": "4.0.35",
4
4
  "description": "0xRay Framework - Unified Feature Configuration",
5
5
  "suit_temperament": {
6
6
  "profile": "auto",
@@ -72,14 +72,14 @@ Governance deliberation uses **code-review**, **security-audit** (via enforcer/s
72
72
 
73
73
  xray operates under the three-subsystem model: **Inference** + **External Governance** (Dynamo Solar SSOT) + **Autonomous Engine** (thinDispatch 7-flow in MCP orchestrator). All actions are validated against the Universal Development Codex before execution.
74
74
 
75
- **Codex**: `.xray/codex.json` — **69 terms** across all agent interactions.
75
+ **Codex**: `.xray/codex.json` — **70 terms** across all agent interactions.
76
76
 
77
77
  ## thinDispatch Routing
78
78
 
79
- - Simple (≤15): Single agent
80
- - Moderate (≤25): Single agent with tools
81
- - Complex (≤50): Multi-agent coordination
82
- - Enterprise (>50): Orchestrator-led team
79
+ - Simple (≤15): single-agent
80
+ - Moderate (≤25): multi-agent
81
+ - Complex (≤50): orchestrator-led
82
+ - Enterprise (>50): orchestrator-led
83
83
 
84
84
  ## AsideContext (v3.2+)
85
85
 
@@ -117,7 +117,7 @@ Tools: `repertoire__get_task_confidence`, `repertoire__get_high_confidence_signa
117
117
 
118
118
  ## Codex OS (always on — not optional)
119
119
 
120
- The Universal Development Codex (`.xray/codex.json`, **69 terms**) is enforced by **PreToolUse** (blocks) and this section (brain). MCP enforcer is audit — not the gate.
120
+ The Universal Development Codex (`.xray/codex.json`, **70 terms**) is enforced by **PreToolUse** (blocks) and this section (brain). MCP enforcer is audit — not the gate.
121
121
 
122
122
  | Term | Rule | Enforcement |
123
123
  |------|------|-------------|
package/AGENTS.md CHANGED
@@ -125,7 +125,7 @@ Governance deliberation: **code-review**, **security-audit**, **researcher** wit
125
125
  | **3.2.0** | AsideContext wired, SelfProposalEngine, pre-tool-use hook |
126
126
  | **3.1.1** | 0xRay rename, marketplace, AGENTS/SKILLS consumer seeding |
127
127
 
128
- **Removed:** `hermes bridge`, `.opencode/xray/` fallback, `advanced-features/` on consumer boot.
128
+ **Removed:** `hermes bridge`, `.opencode/xray/` fallback, `advanced-features/`.
129
129
 
130
130
  ## Default operating mode: autonomy-command
131
131
 
@@ -209,10 +209,10 @@ Full skill mapping: [SKILLS.md](SKILLS.md).
209
209
 
210
210
  ## thinDispatch routing
211
211
 
212
- - Simple (≤15): Single agent
213
- - Moderate (≤25): Single agent with tools
214
- - Complex (≤50): Multi-agent coordination
215
- - Enterprise (>50): Orchestrator-led team
212
+ - Simple (≤15): single-agent
213
+ - Moderate (≤25): multi-agent
214
+ - Complex (≤50): orchestrator-led
215
+ - Enterprise (>50): orchestrator-led
216
216
 
217
217
  ## Documentation
218
218
 
package/README.md CHANGED
@@ -78,7 +78,7 @@ Docs: [guides/autonomy-command](docs-site/docs/guides/autonomy-command.md) · Sk
78
78
  - **`hermes bridge`** CLI removed — use `npx 0xray hermes install`.
79
79
  - **`.opencode/xray/` fallback** removed from auto-reflection-generator (3.1.1).
80
80
  - **~180 stale `@version` JSDoc tags** and **"xray 2.0" command doc strings** cleaned (3.2.0).
81
- - **`advanced-features/`** decoupled from core boot — not on the consumer install path.
81
+ - **`advanced-features/`** removed. The live Grok hook is `pre-tool-use.js`.
82
82
  - **PostProcessor** soft-deprecated since 3.0 (`enablePostProcessor: false` default).
83
83
 
84
84
  ## Three-Subsystem Architecture
@@ -196,7 +196,7 @@ Docs: [memory routing](docs-site/docs/guides/memory-routing.md) · [Repertoire](
196
196
 
197
197
  ## Governance & Codex
198
198
 
199
- - **69 terms** in `.xray/codex.json` — core, architecture, testing, performance, security, operations, governance (Codex 69: no new MCP/skill/handler surface)
199
+ - **70 terms** in `.xray/codex.json` — core, architecture, testing, performance, security, operations, governance (Codex 69: no new MCP/skill/handler surface; Codex 70: current copy before edits)
200
200
  - CodexPolicyService — Governance-owned SSOT for codex loading
201
201
  - Pre-governance gate blocks non-compliant proposals
202
202
  - Active codex snapshot via `get_active_codex` MCP tool
package/dist/AGENTS.md CHANGED
@@ -125,7 +125,7 @@ Governance deliberation: **code-review**, **security-audit**, **researcher** wit
125
125
  | **3.2.0** | AsideContext wired, SelfProposalEngine, pre-tool-use hook |
126
126
  | **3.1.1** | 0xRay rename, marketplace, AGENTS/SKILLS consumer seeding |
127
127
 
128
- **Removed:** `hermes bridge`, `.opencode/xray/` fallback, `advanced-features/` on consumer boot.
128
+ **Removed:** `hermes bridge`, `.opencode/xray/` fallback, `advanced-features/`.
129
129
 
130
130
  ## Default operating mode: autonomy-command
131
131
 
@@ -209,10 +209,10 @@ Full skill mapping: [SKILLS.md](SKILLS.md).
209
209
 
210
210
  ## thinDispatch routing
211
211
 
212
- - Simple (≤15): Single agent
213
- - Moderate (≤25): Single agent with tools
214
- - Complex (≤50): Multi-agent coordination
215
- - Enterprise (>50): Orchestrator-led team
212
+ - Simple (≤15): single-agent
213
+ - Moderate (≤25): multi-agent
214
+ - Complex (≤50): orchestrator-led
215
+ - Enterprise (>50): orchestrator-led
216
216
 
217
217
  ## Documentation
218
218
 
package/dist/CHANGELOG.md CHANGED
@@ -42,6 +42,22 @@ The format is based on [Conventional Commits](https://www.conventionalcommits.or
42
42
  - Archive root `integrations/` costume SKILL dump → `docs/archive/integrations-costume/`. Live wear is `src/integrations`.
43
43
  - Archive root `commands/` stale copy → `docs/archive/commands-copy/`. Live wear is `src/opencode/commands`.
44
44
 
45
+ ## [4.0.35] - 2026-10-02
46
+
47
+ ### 🔄 Changes
48
+
49
+ ### 🐛 Bug Fixes
50
+ - fix: wear rewrites a checkout dist/cli launch to node_modules/0xray (aa44ae462)
51
+
52
+ ### 📚 Documentation
53
+ - docs: point the trim restore at 601cdafc0 (be2a4e91d)
54
+ - docs: say what each chat can actually do (0c70532a6)
55
+
56
+ ### 🔧 Maintenance
57
+ - chore: drop unused modules and wait for the registry before tagging (3a29409a8)
58
+
59
+ ---
60
+
45
61
  ## [4.0.34] - 2026-10-01
46
62
 
47
63
  ### 🔄 Changes
package/dist/README.md CHANGED
@@ -78,7 +78,7 @@ Docs: [guides/autonomy-command](docs-site/docs/guides/autonomy-command.md) · Sk
78
78
  - **`hermes bridge`** CLI removed — use `npx 0xray hermes install`.
79
79
  - **`.opencode/xray/` fallback** removed from auto-reflection-generator (3.1.1).
80
80
  - **~180 stale `@version` JSDoc tags** and **"xray 2.0" command doc strings** cleaned (3.2.0).
81
- - **`advanced-features/`** decoupled from core boot — not on the consumer install path.
81
+ - **`advanced-features/`** removed. The live Grok hook is `pre-tool-use.js`.
82
82
  - **PostProcessor** soft-deprecated since 3.0 (`enablePostProcessor: false` default).
83
83
 
84
84
  ## Three-Subsystem Architecture
@@ -196,7 +196,7 @@ Docs: [memory routing](docs-site/docs/guides/memory-routing.md) · [Repertoire](
196
196
 
197
197
  ## Governance & Codex
198
198
 
199
- - **69 terms** in `.xray/codex.json` — core, architecture, testing, performance, security, operations, governance (Codex 69: no new MCP/skill/handler surface)
199
+ - **70 terms** in `.xray/codex.json` — core, architecture, testing, performance, security, operations, governance (Codex 69: no new MCP/skill/handler surface; Codex 70: current copy before edits)
200
200
  - CodexPolicyService — Governance-owned SSOT for codex loading
201
201
  - Pre-governance gate blocks non-compliant proposals
202
202
  - Active codex snapshot via `get_active_codex` MCP tool
package/dist/cli/index.js CHANGED
@@ -411,13 +411,10 @@ program
411
411
  process.exit(1);
412
412
  }
413
413
  });
414
- // Analytics command - pattern analysis, insights, and consent management
414
+ // Analytics command - pattern analysis from recent task completions
415
415
  program
416
416
  .command("analytics")
417
- .description("xray Central Analytics - Pattern analysis, insights, and consent management\n" +
418
- " In v1.7.2+: Includes consent management with granular control\n" +
419
- " Use 'npx xray analytics enable' to opt-in to data sharing\n" +
420
- " Core classes: ConsentManager, AnonymizationEngine available programmatically")
417
+ .description("Pattern analysis from recent task completions")
421
418
  .option("-l, --limit <number>", "Limit analysis to last N task completions")
422
419
  .option("-o, --output <file>", "Save report to file")
423
420
  .action(async (opts) => {
@@ -310,7 +310,7 @@ export class GovernanceService {
310
310
  decision: result.vote === 'YES' ? 'approve' : result.vote === 'NO' ? 'reject' : 'needs_revision',
311
311
  confidence: result.governanceResponse?.confidence ?? 0.85,
312
312
  reasoning: result.reason || 'Dynamo Solar SSOT filter decision',
313
- weight: 1.1,
313
+ weight: typeof result.weight === 'number' ? result.weight : 1.1,
314
314
  moralTension: result.moralTension,
315
315
  moralScore: result.moralScore,
316
316
  moralFusion: result.moralFusion,
@@ -18,7 +18,6 @@ src/integrations/
18
18
  │ ├── types.ts # TypeScript interfaces and types
19
19
  │ ├── Integration.ts # BaseIntegration abstract class
20
20
  │ ├── registry.ts # IntegrationRegistry class
21
- │ ├── ExampleIntegration.ts # Example implementation
22
21
  │ └── index.ts # Module exports
23
22
  ├── core/ # Core framework integrations
24
23
  │ └── xray-integration.ts # Cross-framework integration
@@ -417,14 +416,7 @@ await this.log('debug', 'Debug information', { data });
417
416
 
418
417
  ## Example Integration
419
418
 
420
- See [`ExampleIntegration.ts`](./ExampleIntegration.ts) for a complete example demonstrating:
421
-
422
- - Custom integration class extending `BaseIntegration`
423
- - Using `createSimpleIntegration` factory
424
- - Event handling
425
- - Error handling
426
- - Health checks
427
- - Configuration management
419
+ A host integration extends `BaseIntegration` in `Integration.ts`. `createSimpleIntegration` is the short factory. Register the instance from `registry.ts`.
428
420
 
429
421
  ## Testing
430
422
 
@@ -8,4 +8,3 @@
8
8
  export * from "./types.js";
9
9
  export * from "./Integration.js";
10
10
  export * from "./registry.js";
11
- export * from "./ExampleIntegration.js";
@@ -11,5 +11,3 @@ export * from "./types.js";
11
11
  export * from "./Integration.js";
12
12
  // Re-export registry
13
13
  export * from "./registry.js";
14
- // Re-export example (for documentation/testing)
15
- export * from "./ExampleIntegration.js";
@@ -11,6 +11,20 @@ import { DEFAULT_GOVERNANCE_CONFIG, resolveDynamoBaseUrl } from './types.js';
11
11
  import { GovernanceClient } from './governance-client.js';
12
12
  import { frameworkLogger } from '../../core/framework-logger.js';
13
13
  import { featuresConfigLoader } from '../../core/features-config.js';
14
+ const SOLAR_VERDICTS = ['PASS', 'NEEDS_REVISION', 'REJECT'];
15
+ function isSolarVerdict(value) {
16
+ return value === 'PASS' || value === 'NEEDS_REVISION' || value === 'REJECT';
17
+ }
18
+ /**
19
+ * Dynamo's `recommendation` is the decision.
20
+ * A missing or unrecognized verdict fails closed. Solar mood is not a verdict.
21
+ */
22
+ function readSolarVerdict(response) {
23
+ if (isSolarVerdict(response.recommendation)) {
24
+ return response.recommendation;
25
+ }
26
+ return 'NEEDS_REVISION';
27
+ }
14
28
  /**
15
29
  * Main Governance Integration class
16
30
  *
@@ -150,10 +164,19 @@ export class InferenceGovernanceIntegration extends BaseIntegration {
150
164
  baseVoteWeight: this.configData.decisionLogic.voteWeightMultiplier,
151
165
  });
152
166
  const adjustment = solarResponse.confidenceAdjustment;
153
- const recommendation = adjustment <= -0.10 ? 'NEEDS_REVISION' : 'PASS';
167
+ const recommendation = readSolarVerdict(solarResponse);
168
+ const resonanceScore = solarResponse.resonanceScore
169
+ ?? solarResponse.structuralResonance
170
+ ?? solarResponse.solarContext.solarIsotopicResonance
171
+ ?? solarResponse.solarContext.solarResonance
172
+ ?? 0;
173
+ const confidence = typeof solarResponse.confidence === 'number'
174
+ ? Math.max(0, Math.min(1, solarResponse.confidence))
175
+ : Math.max(0, Math.min(1, proposal.confidence));
154
176
  const reasons = [
155
177
  solarResponse.solarContext.recommendation,
156
- `Solar activity: ${solarResponse.solarContext.solarActivityLevel} (adjustment: ${(adjustment * 100).toFixed(0)}%, resonance: ${(solarResponse.solarContext.solarIsotopicResonance ?? solarResponse.solarContext.solarResonance ?? 0).toFixed(4)})`,
178
+ `Solar activity: ${solarResponse.solarContext.solarActivityLevel} (adjustment: ${(adjustment * 100).toFixed(0)}%, resonance: ${resonanceScore.toFixed(4)})`,
179
+ `Dynamo recommendation: ${recommendation}`,
157
180
  ];
158
181
  if (solarResponse.finalRecommendation && solarResponse.finalRecommendation !== solarResponse.originalRecommendation) {
159
182
  reasons.push(solarResponse.finalRecommendation);
@@ -169,12 +192,12 @@ export class InferenceGovernanceIntegration extends BaseIntegration {
169
192
  success: true,
170
193
  proposalId: proposal.id,
171
194
  governanceIsotopeId: `solar-${solarResponse.solarContext.solarActivityLevel}`,
172
- resonanceScore: solarResponse.solarContext.solarIsotopicResonance ?? solarResponse.solarContext.solarResonance ?? 0,
195
+ resonanceScore,
173
196
  isotopicRatio: 0,
174
197
  vortexVolume: 0,
175
198
  historicalCoherence: 0,
176
199
  recommendation,
177
- confidence: Math.max(0, Math.min(1, proposal.confidence + adjustment)),
200
+ confidence,
178
201
  voteWeight: solarResponse.adjustedVoteWeight,
179
202
  reasons,
180
203
  };
@@ -277,9 +300,9 @@ export class InferenceGovernanceIntegration extends BaseIntegration {
277
300
  */
278
301
  createFallbackVote(proposal) {
279
302
  return {
280
- vote: proposal.confidence >= 0.7 ? 'YES' : 'ABSTAIN',
303
+ vote: 'ABSTAIN',
281
304
  weight: 1.0,
282
- reason: 'Fallback: governance endpoint unavailable',
305
+ reason: 'Fallback: governance endpoint unavailable — fail closed',
283
306
  governanceResponse: {
284
307
  success: false,
285
308
  proposalId: proposal.id,
@@ -291,9 +314,9 @@ export class InferenceGovernanceIntegration extends BaseIntegration {
291
314
  recommendation: 'NEEDS_REVISION',
292
315
  confidence: proposal.confidence,
293
316
  voteWeight: 1.0,
294
- reasons: ['Governance endpoint unavailable, using local confidence'],
317
+ reasons: ['Governance endpoint unavailable — fail closed, not a local pass'],
295
318
  },
296
- passed: proposal.confidence >= 0.7,
319
+ passed: false,
297
320
  };
298
321
  }
299
322
  /**
@@ -303,7 +303,7 @@ export function buildSessionBootPayload(root, source = '0xray/grok-session-start
303
303
  ceremony: gateFeatures.ceremony ?? 'full',
304
304
  spawn_plan_mode: gateFeatures.spawn_plan_mode ?? 'deny',
305
305
  codexBlockingTermCount: blockingTerms.length,
306
- codexTerms: [59, 67, 68, 69],
306
+ codexTerms: [59, 67, 68, 69, 70],
307
307
  rules: features.lead_dev_mode ? LEAD_DEV_RULES : [],
308
308
  mcpIntake: frontier
309
309
  ? 'xray-orchestrator analyze-complexity optional on frontier (spawn warns, does not deny)'
@@ -23,6 +23,7 @@ import {
23
23
  runInferenceImprovementLight,
24
24
  } from '../../hooks/pipeline-hook-runtime.mjs';
25
25
  import { maintainLens } from '../../hooks/goggles-pipeline.mjs';
26
+ import { readSavedFreshness, refreshFreshness } from '../../../nucleus/work-freshness.mjs';
26
27
 
27
28
  function resolveHookEvent(event) {
28
29
  if (process.env.GROK_HOOK_EVENT) return process.env.GROK_HOOK_EVENT;
@@ -150,12 +151,23 @@ async function main() {
150
151
  const matchedSignals =
151
152
  HOOK_EVENT === 'user_prompt_submit' ? [] : await matchStationSignals(eventRoot, intent);
152
153
  const compact = COMPACT_EVENTS.has(HOOK_EVENT);
154
+ let freshnessLine = null;
155
+ if (!compact) {
156
+ try {
157
+ freshnessLine = HOOK_EVENT === 'session_start'
158
+ ? refreshFreshness(eventRoot).freshnessLine
159
+ : readSavedFreshness(eventRoot);
160
+ } catch {
161
+ freshnessLine = null;
162
+ }
163
+ }
153
164
  const payload = buildSessionBootPayload(eventRoot, source, {
154
165
  hookEvent: HOOK_EVENT,
155
166
  sessionId: event.sessionId || process.env.GROK_SESSION_ID || null,
156
167
  ...(intent ? { intent } : {}),
157
168
  ...(!compact && intent ? { cardText: intent } : {}),
158
169
  ...(matchedSignals.length ? { matchedSignals } : {}),
170
+ ...(freshnessLine ? { freshnessLine } : {}),
159
171
  });
160
172
 
161
173
  const bootPath = writeSessionBoot(eventRoot, payload) || ensureSessionBoot(eventRoot, source);
@@ -3,6 +3,7 @@
3
3
  * A named plane returns its view. Field pipes fill what they can see.
4
4
  * The view keeps every field for the next look.
5
5
  * A held plane stays quiet. A leave is denied.
6
+ * On this host a search is grep. The lens file stays open.
6
7
  */
7
8
  import { existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, unlinkSync, writeFileSync } from 'node:fs';
8
9
  import { createRequire } from 'node:module';
@@ -684,12 +685,58 @@ export function suitHint(text) {
684
685
  }
685
686
 
686
687
  const DEEP_SEARCH = /search_codebase|find_implementation|get_documentation/i;
688
+ const HOLDS_ON_NAME = new Set(['dichotomy', 'syncopate', 'synthesis']);
689
+
690
+ function mapFiles() {
691
+ try {
692
+ const data = JSON.parse(readFileSync(planesFile(), 'utf8'));
693
+ const files = [];
694
+ for (const name of [...CARD_PLANES, ...WORN_PLANES]) {
695
+ const entry = data[name];
696
+ if (!entry || typeof entry !== 'object') continue;
697
+ const candidates = [entry.file, entry.worn, entry.skills];
698
+ if (Array.isArray(entry.files)) candidates.push(...entry.files);
699
+ for (const file of candidates) {
700
+ if (typeof file === 'string' && file.includes('.') && file.includes('/')) files.push(file);
701
+ }
702
+ }
703
+ return files;
704
+ } catch {
705
+ return [];
706
+ }
707
+ }
708
+
709
+ function opensLensFile(text) {
710
+ const spoken = String(text || '');
711
+ return mapFiles().some((file) => spoken.includes(file));
712
+ }
687
713
 
688
714
  function researchCall(toolName, text) {
689
715
  const tool = String(toolName || '');
690
716
  const spoken = String(text || '');
691
717
  if (/researcher|explorer|deep[- ]?research/i.test(tool) || DEEP_SEARCH.test(tool)) return true;
692
- return /bash|shell/i.test(tool) && (/researcher|explorer|deep[- ]?research/i.test(spoken) || DEEP_SEARCH.test(spoken));
718
+ if (/bash|shell/i.test(tool) && (/researcher|explorer|deep[- ]?research/i.test(spoken) || DEEP_SEARCH.test(spoken))) return true;
719
+ if (/^grep$/i.test(tool)) return true;
720
+ return /^read_file$/i.test(tool) && !opensLensFile(spoken);
721
+ }
722
+
723
+ function passPath(root) {
724
+ return join(root, '.xray', 'state', 'goggles-lens-pass.json');
725
+ }
726
+
727
+ function loadReadPass(root) {
728
+ try {
729
+ const data = JSON.parse(readFileSync(passPath(root), 'utf8'));
730
+ return Boolean(data && data.read === true);
731
+ } catch {
732
+ return false;
733
+ }
734
+ }
735
+
736
+ function saveReadPass(root) {
737
+ const file = passPath(root);
738
+ mkdirSync(dirname(file), { recursive: true });
739
+ writeFileSync(file, `${JSON.stringify({ read: true })}\n`);
693
740
  }
694
741
 
695
742
  /** One plane: the files the suit continues with. A look with no plane stops. Two planes stay quiet. */
@@ -724,11 +771,17 @@ function stampPlane(root, id) {
724
771
  }
725
772
  }
726
773
 
727
- /** A search stays stopped. The next move is the file on the lens, not the same search again. */
774
+ /** A search stays stopped. The lens file stays open. One later read may go on. */
728
775
  export function lensBeforeResearch(root, toolName, text) {
729
776
  const spoken = String(text || '');
730
777
  if (!researchCall(toolName, spoken)) return null;
731
778
  const names = CARD_PLANES.filter((name) => intentWords(spoken).includes(name));
779
+ if (/^read_file$/i.test(String(toolName || ''))) {
780
+ if (loadReadPass(root)) return null;
781
+ if (names.length === 1) stampPlane(root, names[0]);
782
+ saveReadPass(root);
783
+ return { gate: 'lens', decision: 'deny', reason: lensPage(root, names) };
784
+ }
732
785
  if (names.length === 1) stampPlane(root, names[0]);
733
786
  return { gate: 'lens', decision: 'deny', reason: lensPage(root, names) };
734
787
  }
@@ -876,17 +929,13 @@ function isGogglesWork(text) {
876
929
 
877
930
 
878
931
  export function cardStop(root, toolName, text, paths = []) {
879
- const spoken = String(text || '');
880
- if (spoken.length <= 200 && isGogglesWork(spoken) && !(paths || []).some((item) => /goggles/i.test(String(item)))) {
881
- clearReading(root);
882
- clearCardLine(root);
883
- return null;
884
- }
885
932
  const held = loadReading(root);
886
933
  if (!held) return null;
887
934
  const drift = actualityLine();
888
935
  if (drift) return organDeny(drift);
889
- return organStop(held, { tool: toolName, text, paths });
936
+ const stopped = organStop(held, { tool: toolName, text, paths });
937
+ if (stopped) return stopped;
938
+ return { gate: 'goggles', decision: 'allow' };
890
939
  }
891
940
 
892
941
  function stationFile(root) {
@@ -928,14 +977,16 @@ export function handCard(root, intent) {
928
977
  clearCardLine(root);
929
978
  return null;
930
979
  }
931
- if (!lookVerb(words)) return null;
980
+ const asked = lookVerb(words);
981
+ const planes = acceptedPlanes().filter((name) => words.includes(name));
982
+ if (!asked && planes.length === 0) return null;
983
+ if (!asked && planes.length === 1 && !HOLDS_ON_NAME.has(planes[0])) return null;
932
984
  clearCardLine(root);
933
985
  const looked = readGoggles(words);
934
986
  if (looked.text.startsWith('Actuality. Drift')) {
935
987
  saveReading(root, { drift: looked.text });
936
988
  return null;
937
989
  }
938
- const planes = acceptedPlanes().filter((name) => words.includes(name));
939
990
  if (planes.length !== 1) {
940
991
  clearReading(root);
941
992
  return null;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * What each chat can actually do.
3
+ * Friend line first. Hook names are labels, not the sentence.
4
+ *
5
+ * stopsTool — the host can refuse a tool before it runs.
6
+ * noticesDeath — a crush/compact hook runs.
7
+ * note — what comes back into the chat: none, one-line, or the whole card.
8
+ */
9
+
10
+ export const HOST_TRUTH = [
11
+ {
12
+ id: 'cursor',
13
+ name: 'Cursor',
14
+ stopsTool: true,
15
+ noticesDeath: true,
16
+ note: 'one-line',
17
+ hooks: 'preToolUse, preCompact',
18
+ line: 'Cursor can stop a tool. When the chat dies, it can leave one line in the next message. The rest of the card is a file. Read it.',
19
+ },
20
+ {
21
+ id: 'grok',
22
+ name: 'Grok',
23
+ stopsTool: true,
24
+ noticesDeath: true,
25
+ note: 'none',
26
+ hooks: 'PreToolUse, PreCompact',
27
+ line: 'Grok can stop a tool. When the chat dies, the hook still writes the file, and the host throws the note away. Read the file.',
28
+ },
29
+ {
30
+ id: 'grok-bot',
31
+ name: 'Grok Bot',
32
+ stopsTool: false,
33
+ noticesDeath: false,
34
+ note: 'none',
35
+ hooks: 'none',
36
+ line: 'Grok Bot cannot stop a tool and cannot leave a note. The house is how a team shares rules there.',
37
+ },
38
+ {
39
+ id: 'openclaw',
40
+ name: 'OpenClaw',
41
+ stopsTool: true,
42
+ noticesDeath: false,
43
+ note: 'none',
44
+ hooks: 'PreToolUse',
45
+ line: 'OpenClaw can stop a tool. It has no hook for when the chat dies, and it does not leave a note.',
46
+ },
47
+ {
48
+ id: 'hermes',
49
+ name: 'Hermes',
50
+ stopsTool: true,
51
+ noticesDeath: false,
52
+ note: 'none',
53
+ hooks: 'pre_tool_call',
54
+ line: 'Hermes can stop a tool. It does not register a hook for when the chat dies, and it does not leave a note.',
55
+ },
56
+ {
57
+ id: 'opencode',
58
+ name: 'OpenCode',
59
+ stopsTool: true,
60
+ noticesDeath: false,
61
+ note: 'whole-card',
62
+ hooks: 'tool.execute.before',
63
+ line: 'OpenCode can stop a tool. It does not register a hook for when the chat dies. When the card file exists, the whole card is already in the prompt.',
64
+ },
65
+ ];
66
+
67
+ export function hostTruthById(id) {
68
+ return HOST_TRUTH.find((row) => row.id === id) ?? null;
69
+ }
70
+
71
+ /** The card a person reads. One paragraph per chat. */
72
+ export function hostTruthCard() {
73
+ return HOST_TRUTH.map((row) => row.line).join('\n\n');
74
+ }
@@ -1252,6 +1252,9 @@ function formatStationMarkdown(fields) {
1252
1252
  } else {
1253
1253
  lines.push("Git: n/a");
1254
1254
  }
1255
+ if (fields.freshnessLine) {
1256
+ lines.push(fields.freshnessLine);
1257
+ }
1255
1258
  lines.push(fields.repertoireResume || "Repertoire: module unresolved");
1256
1259
  if (fields.workingLine) {
1257
1260
  lines.push(fields.workingLine);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xray-pre-tool",
3
- "version": "4.0.34",
3
+ "version": "4.0.35",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "0xRay constitution + temperament PreToolUse for OpenClaw",
@@ -13,7 +13,6 @@ const STORY_TYPES = ['reflection', 'saga', 'journey', 'narrative'];
13
13
  function resolveSkillMd() {
14
14
  const here = dirname(fileURLToPath(import.meta.url));
15
15
  const candidates = [
16
- join(here, '../../../skills/storyteller/SKILL.md'),
17
16
  join(here, '../../skills/storyteller/SKILL.md'),
18
17
  join(process.cwd(), 'node_modules/0xray/dist/skills/storyteller/SKILL.md'),
19
18
  join(process.cwd(), 'node_modules/xray/dist/skills/storyteller/SKILL.md'),
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Multi-host delegation gate SSOT — pending-delegations + spawn todo enforcement.
3
3
  * Grok / Hermes / OpenCode adapters call evaluatePreToolGate via delegation-gate-runtime.
4
- * Constitution (11/29/69 + destructive shell) lives here. Grok may still extra-block Codex 2/7.
4
+ * Constitution (11/29/69/70 + destructive shell) lives here. Grok may still extra-block Codex 2/7.
5
5
  */
6
6
  import { type PendingDelegation } from './pending-delegations.js';
7
7
  export { getActivePendingDelegations } from './pending-delegations.js';
@@ -91,7 +91,7 @@ export declare function evaluateSpawnPlanGate(toolName: string, toolInput: ToolG
91
91
  export declare function evaluateSynthesisGate(toolName: string, toolInput: ToolGateInput, ctx: PreToolGateContext): PreToolGateResult;
92
92
  /** Block writes / unrelated work while pending delegations exist. */
93
93
  export declare function evaluatePendingDelegationGate(toolName: string, toolInput: ToolGateInput, ctx: PreToolGateContext): PreToolGateResult;
94
- /** Codex 11 / 29 / 69 + destructive shell — always on, all hosts that call this SSOT. */
94
+ /** Codex 11 / 29 / 69 / 70 + destructive shell — always on, all hosts that call this SSOT. */
95
95
  export declare function evaluateConstitutionGate(toolName: string, toolInput: ToolGateInput, ctx: PreToolGateContext): PreToolGateResult;
96
96
  export declare function evaluatePreToolGate(toolName: string, toolInput: ToolGateInput, ctx: PreToolGateContext): PreToolGateResult;
97
97
  export declare function evaluatePostToolSpawn(toolName: string, toolInput: ToolGateInput, projectRoot: string, options?: PostToolSpawnOptions): PostToolSpawnResult;