0xray 4.0.33 → 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 (156) 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 +25 -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 +108 -22
  19. package/dist/integrations/hooks/goggles-planes.json +23 -0
  20. package/dist/integrations/hooks/host-truth.mjs +74 -0
  21. package/dist/integrations/hooks/station-hook-runtime.cjs +3 -0
  22. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  23. package/dist/mcps/knowledge-skills/storyteller.server.js +0 -1
  24. package/dist/nucleus/delegation-gate.d.ts +2 -2
  25. package/dist/nucleus/delegation-gate.js +13 -2
  26. package/dist/nucleus/work-freshness.mjs +189 -0
  27. package/dist/processors/implementations/agents-md-validation-processor.js +1 -1
  28. package/docs-site/docs/plates/boot.md +17 -2
  29. package/docs-site/docs/plates/governance.md +3 -2
  30. package/docs-site/docs/plates/index.md +3 -1
  31. package/docs-site/docs/plates/memory-recall.md +26 -35
  32. package/docs-site/docs/plates/orchestration.md +39 -35
  33. package/docs-site/docs/plates/processor.md +34 -36
  34. package/docs-site/docs/plates/reporting.md +3 -8
  35. package/docs-site/docs/plates/routing.md +22 -11
  36. package/package.json +2 -2
  37. package/scripts/foundry/release.mjs +48 -5
  38. package/scripts/mjs/test-consumer-readiness.mjs +1 -0
  39. package/scripts/mjs/test-mcp-functionality.mjs +14 -9
  40. package/scripts/node/basic-security-audit.cjs +0 -1
  41. package/scripts/node/bridge-mcp-wiring.cjs +66 -3
  42. package/scripts/node/postinstall.cjs +1 -1
  43. package/scripts/node/prepare-consumer.cjs +11 -7
  44. package/scripts/node/setup-dev.cjs +18 -26
  45. package/scripts/node/validate-mcp-connectivity.js +2 -1
  46. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  47. package/src/mcps/knowledge-skills/storyteller.server.ts +0 -1
  48. package/xray/agents_template.md +5 -5
  49. package/xray/codex.json +12 -4
  50. package/xray/features.json +1 -1
  51. package/dist/agents/known-names.d.ts +0 -26
  52. package/dist/agents/known-names.js +0 -72
  53. package/dist/analytics/consent-manager.d.ts +0 -92
  54. package/dist/analytics/consent-manager.js +0 -257
  55. package/dist/benchmark/performance-benchmark.d.ts +0 -103
  56. package/dist/benchmark/performance-benchmark.js +0 -373
  57. package/dist/cli/commands/analytics-disable.d.ts +0 -9
  58. package/dist/cli/commands/analytics-disable.js +0 -72
  59. package/dist/cli/commands/analytics-enable-action.d.ts +0 -8
  60. package/dist/cli/commands/analytics-enable-action.js +0 -82
  61. package/dist/cli/commands/analytics-preview.d.ts +0 -9
  62. package/dist/cli/commands/analytics-preview.js +0 -106
  63. package/dist/cli/commands/analytics-status.d.ts +0 -9
  64. package/dist/cli/commands/analytics-status.js +0 -68
  65. package/dist/cli/commands/enforce.d.ts +0 -12
  66. package/dist/cli/commands/enforce.js +0 -78
  67. package/dist/cli/commands/govern.d.ts +0 -29
  68. package/dist/cli/commands/govern.js +0 -149
  69. package/dist/cli/commands/security-audit.d.ts +0 -23
  70. package/dist/cli/commands/security-audit.js +0 -219
  71. package/dist/cli/server.d.ts +0 -1
  72. package/dist/cli/server.js +0 -147
  73. package/dist/config/routing-mappings.d.ts +0 -26
  74. package/dist/config/routing-mappings.js +0 -151
  75. package/dist/core/bridge.mjs +0 -922
  76. package/dist/core/trace-context.d.ts +0 -12
  77. package/dist/core/trace-context.js +0 -33
  78. package/dist/enforcement/index.d.ts +0 -22
  79. package/dist/enforcement/index.js +0 -40
  80. package/dist/enforcement/loaders/index.d.ts +0 -36
  81. package/dist/enforcement/loaders/index.js +0 -39
  82. package/dist/enforcement/test-auto-healing.d.ts +0 -83
  83. package/dist/enforcement/test-auto-healing.js +0 -325
  84. package/dist/inference/index.d.ts +0 -10
  85. package/dist/inference/index.js +0 -5
  86. package/dist/infrastructure/iac-validator.d.ts +0 -150
  87. package/dist/infrastructure/iac-validator.js +0 -465
  88. package/dist/infrastructure/schemas/cloud-schemas.d.ts +0 -482
  89. package/dist/infrastructure/schemas/cloud-schemas.js +0 -488
  90. package/dist/integrations/base/ExampleIntegration.d.ts +0 -46
  91. package/dist/integrations/base/ExampleIntegration.js +0 -180
  92. package/dist/integrations/enforcement-gate.d.ts +0 -44
  93. package/dist/integrations/enforcement-gate.js +0 -348
  94. package/dist/mcps/connection/connection-manager.d.ts +0 -39
  95. package/dist/mcps/connection/connection-manager.js +0 -79
  96. package/dist/mcps/index.d.ts +0 -17
  97. package/dist/mcps/index.js +0 -65
  98. package/dist/mcps/orchestrator/index.d.ts +0 -6
  99. package/dist/mcps/orchestrator/index.js +0 -5
  100. package/dist/metrics/index.d.ts +0 -6
  101. package/dist/metrics/index.js +0 -6
  102. package/dist/orchestrator/self-direction-activation.d.ts +0 -108
  103. package/dist/orchestrator/self-direction-activation.js +0 -244
  104. package/dist/orchestrator/universal-registry-bridge.d.ts +0 -84
  105. package/dist/orchestrator/universal-registry-bridge.js +0 -246
  106. package/dist/performance/performance-budget-enforcer.d.ts +0 -157
  107. package/dist/performance/performance-budget-enforcer.js +0 -433
  108. package/dist/performance/performance-regression-tester.d.ts +0 -107
  109. package/dist/performance/performance-regression-tester.js +0 -341
  110. package/dist/postprocessor/analysis/CodeChangeAnalyzer.d.ts +0 -11
  111. package/dist/postprocessor/analysis/CodeChangeAnalyzer.js +0 -50
  112. package/dist/postprocessor/config/ProcessorConfigLoader.d.ts +0 -44
  113. package/dist/postprocessor/config/ProcessorConfigLoader.js +0 -16
  114. package/dist/postprocessor/integration.d.ts +0 -156
  115. package/dist/postprocessor/integration.js +0 -194
  116. package/dist/postprocessor/metamorphosis/index.d.ts +0 -2
  117. package/dist/postprocessor/metamorphosis/index.js +0 -1
  118. package/dist/postprocessor/redeploy/RetryHandler.d.ts +0 -49
  119. package/dist/postprocessor/redeploy/RetryHandler.js +0 -118
  120. package/dist/processors/implementations/session-capture-processor.d.ts +0 -14
  121. package/dist/processors/implementations/session-capture-processor.js +0 -37
  122. package/dist/public/XrayService.d.ts +0 -17
  123. package/dist/public/XrayService.js +0 -40
  124. package/dist/public/index.d.ts +0 -4
  125. package/dist/public/index.js +0 -2
  126. package/dist/security/comprehensive-security-audit.d.ts +0 -157
  127. package/dist/security/comprehensive-security-audit.js +0 -1004
  128. package/dist/security/index.d.ts +0 -13
  129. package/dist/security/index.js +0 -13
  130. package/dist/security/security-agent-coordinator.d.ts +0 -71
  131. package/dist/security/security-agent-coordinator.js +0 -203
  132. package/dist/security/security-hardening-system.d.ts +0 -238
  133. package/dist/security/security-hardening-system.js +0 -726
  134. package/dist/security/security-orchestration-layer.d.ts +0 -118
  135. package/dist/security/security-orchestration-layer.js +0 -495
  136. package/dist/testing/memory-regression-suite.d.ts +0 -105
  137. package/dist/testing/memory-regression-suite.js +0 -258
  138. package/dist/tools/assess-complexity-tool.d.ts +0 -28
  139. package/dist/tools/assess-complexity-tool.js +0 -44
  140. package/dist/tools/query-routing-tool.d.ts +0 -17
  141. package/dist/tools/query-routing-tool.js +0 -59
  142. package/dist/utils/batch-operations.d.ts +0 -25
  143. package/dist/utils/batch-operations.js +0 -292
  144. package/dist/utils/task-graph.d.ts +0 -29
  145. package/dist/utils/task-graph.js +0 -106
  146. package/dist/utils/test-template-generator.d.ts +0 -25
  147. package/dist/utils/test-template-generator.js +0 -178
  148. package/dist/utils/token-manager.d.ts +0 -48
  149. package/dist/utils/token-manager.js +0 -163
  150. package/dist/validation/agent-config-validator.d.ts +0 -110
  151. package/dist/validation/agent-config-validator.js +0 -280
  152. package/dist/validation/orchestration-flow-validator.d.ts +0 -87
  153. package/dist/validation/orchestration-flow-validator.js +0 -606
  154. package/src/mcps/connection/connection-manager.ts +0 -91
  155. package/src/mcps/index.ts +0 -80
  156. package/src/mcps/orchestrator/index.ts +0 -29
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0xray",
3
- "version": "4.0.33",
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.33",
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,31 @@ 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
+
61
+ ## [4.0.34] - 2026-10-01
62
+
63
+ ### 🔄 Changes
64
+
65
+ ### 🐛 Bug Fixes
66
+ - fix: hold the lens on the worn build when the source is not packed (6f561ef6f)
67
+
68
+ ---
69
+
45
70
  ## [4.0.33] - 2026-10-01
46
71
 
47
72
  ### 🔄 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,8 +3,9 @@
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
- import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
8
+ import { existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, unlinkSync, writeFileSync } from 'node:fs';
8
9
  import { createRequire } from 'node:module';
9
10
  import { dirname, join, resolve } from 'node:path';
10
11
  import { fileURLToPath } from 'node:url';
@@ -649,7 +650,21 @@ function skillFor(id, root) {
649
650
  return existsSync(join(root, rel)) ? rel : '';
650
651
  }
651
652
 
653
+ function mappedFile(name) {
654
+ try {
655
+ const data = JSON.parse(readFileSync(planesFile(), 'utf8'));
656
+ const entry = data[name];
657
+ if (!entry || typeof entry !== 'object') return '';
658
+ if (typeof entry.file === 'string' && entry.file) return entry.file;
659
+ } catch {
660
+ return '';
661
+ }
662
+ return '';
663
+ }
664
+
652
665
  function moduleFile(name) {
666
+ const mapped = mappedFile(name);
667
+ if (mapped) return mapped;
653
668
  const platesDir = findPlatesDir(HERE);
654
669
  const root = sourceRoot(platesDir);
655
670
  const hit = sourceTexts(root).find((file) => file.rel.endsWith(`/${name}.ts`) || file.rel.endsWith(`/${name}.mjs`));
@@ -670,12 +685,58 @@ export function suitHint(text) {
670
685
  }
671
686
 
672
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
+ }
673
713
 
674
714
  function researchCall(toolName, text) {
675
715
  const tool = String(toolName || '');
676
716
  const spoken = String(text || '');
677
717
  if (/researcher|explorer|deep[- ]?research/i.test(tool) || DEEP_SEARCH.test(tool)) return true;
678
- 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`);
679
740
  }
680
741
 
681
742
  /** One plane: the files the suit continues with. A look with no plane stops. Two planes stay quiet. */
@@ -710,11 +771,17 @@ function stampPlane(root, id) {
710
771
  }
711
772
  }
712
773
 
713
- /** 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. */
714
775
  export function lensBeforeResearch(root, toolName, text) {
715
776
  const spoken = String(text || '');
716
777
  if (!researchCall(toolName, spoken)) return null;
717
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
+ }
718
785
  if (names.length === 1) stampPlane(root, names[0]);
719
786
  return { gate: 'lens', decision: 'deny', reason: lensPage(root, names) };
720
787
  }
@@ -812,26 +879,39 @@ function fileHas(root, rel, mark) {
812
879
  }
813
880
 
814
881
 
815
- function examinePlane(plane, root) {
882
+ function factoryName(rel) {
883
+ return rel.startsWith('src/') || rel.startsWith('grok-bot/');
884
+ }
885
+
886
+ function wornHolds(plane, root) {
887
+ if (!plane.worn || !existsSync(join(root, plane.worn))) return false;
888
+ if (!plane.wornMark) return true;
889
+ return fileHas(root, plane.worn, plane.wornMark);
890
+ }
891
+
892
+ export function examinePlane(plane, root) {
816
893
  const files = Array.isArray(plane.files) ? plane.files : [];
817
894
  const checkable = files.length > 0 || plane.skills || plane.worn;
818
895
  if (!checkable) return drawing();
896
+ const held = wornHolds(plane, root);
897
+ if (plane.worn && !held) {
898
+ return drift(`the worn build is not ${files[0] || plane.worn}`);
899
+ }
819
900
  for (const rel of files) {
820
- if (!existsSync(join(root, rel))) return drift(`${rel} is not there`);
901
+ if (existsSync(join(root, rel))) continue;
902
+ if (held && factoryName(rel)) continue;
903
+ return drift(`${rel} is not there`);
821
904
  }
822
- if (plane.mark && !fileHas(root, files[0], plane.mark)) {
905
+ if (plane.mark && files[0] && existsSync(join(root, files[0])) && !fileHas(root, files[0], plane.mark)) {
823
906
  return drift(`${plane.mark} is not in ${files[0]}`);
824
907
  }
825
- if (plane.worn && !fileHas(root, plane.worn, plane.wornMark || plane.mark)) {
826
- return drift(`the worn build is not ${files[0] || plane.worn}`);
827
- }
828
- if (plane.skills && !existsSync(join(root, plane.skills))) {
908
+ if (plane.skills && !existsSync(join(root, plane.skills)) && !(held && factoryName(plane.skills))) {
829
909
  return drift(`${plane.skills} is not there`);
830
910
  }
831
- if (plane.entryIsMark && plane.entry && files[0] && !fileHas(root, files[0], plane.entry)) {
911
+ if (plane.entryIsMark && plane.entry && files[0] && existsSync(join(root, files[0])) && !fileHas(root, files[0], plane.entry)) {
832
912
  return drift(`${plane.entry} is not in ${files[0]}`);
833
913
  }
834
- if (plane.exitIsMark && plane.exit && files[0] && !fileHas(root, files[0], plane.exit)) {
914
+ if (plane.exitIsMark && plane.exit && files[0] && existsSync(join(root, files[0])) && !fileHas(root, files[0], plane.exit)) {
835
915
  return drift(`${plane.exit} is not in ${files[0]}`);
836
916
  }
837
917
  return holds();
@@ -849,17 +929,13 @@ function isGogglesWork(text) {
849
929
 
850
930
 
851
931
  export function cardStop(root, toolName, text, paths = []) {
852
- const spoken = String(text || '');
853
- if (spoken.length <= 200 && isGogglesWork(spoken) && !(paths || []).some((item) => /goggles/i.test(String(item)))) {
854
- clearReading(root);
855
- clearCardLine(root);
856
- return null;
857
- }
858
932
  const held = loadReading(root);
859
933
  if (!held) return null;
860
934
  const drift = actualityLine();
861
935
  if (drift) return organDeny(drift);
862
- 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' };
863
939
  }
864
940
 
865
941
  function stationFile(root) {
@@ -901,14 +977,16 @@ export function handCard(root, intent) {
901
977
  clearCardLine(root);
902
978
  return null;
903
979
  }
904
- 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;
905
984
  clearCardLine(root);
906
985
  const looked = readGoggles(words);
907
986
  if (looked.text.startsWith('Actuality. Drift')) {
908
987
  saveReading(root, { drift: looked.text });
909
988
  return null;
910
989
  }
911
- const planes = acceptedPlanes().filter((name) => words.includes(name));
912
990
  if (planes.length !== 1) {
913
991
  clearReading(root);
914
992
  return null;
@@ -943,7 +1021,15 @@ export function maintainLens(root) {
943
1021
  }
944
1022
 
945
1023
 
946
- const isMain = Boolean(process.argv[1]) && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
1024
+ function sameInvoked(argvPath, modulePath) {
1025
+ try {
1026
+ return realpathSync(argvPath) === realpathSync(modulePath);
1027
+ } catch {
1028
+ return resolve(argvPath) === resolve(modulePath);
1029
+ }
1030
+ }
1031
+
1032
+ const isMain = Boolean(process.argv[1]) && sameInvoked(process.argv[1], fileURLToPath(import.meta.url));
947
1033
  if (isMain) {
948
1034
  const answered = gogglesAnswer(process.argv.slice(2));
949
1035
  const pane = process.stdout.isTTY && Array.isArray(answered.cards) && answered.cards.length > 0;