0xray 3.5.0 → 3.5.1

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.
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Shared 4/4 delegation gate fixture — seeds consumer tmp workspace.
3
+ */
4
+ import { mkdirSync, writeFileSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+
7
+ export const FIXTURE_SESSION_ID = 'verify-gate';
8
+
9
+ export function seedDelegationGateFixture(tmp) {
10
+ mkdirSync(join(tmp, '.xray', 'state'), { recursive: true });
11
+ writeFileSync(
12
+ join(tmp, '.xray', 'features.json'),
13
+ JSON.stringify({
14
+ multi_agent_orchestration: {
15
+ enabled: true,
16
+ lead_dev_mode: true,
17
+ auto_chain_delegations: true,
18
+ },
19
+ }),
20
+ );
21
+ writeFileSync(
22
+ join(tmp, '.xray', 'state', 'lead-dev-plan.json'),
23
+ JSON.stringify({
24
+ active: true,
25
+ persistedAt: new Date().toISOString(),
26
+ phases: [],
27
+ }),
28
+ );
29
+ writeFileSync(
30
+ join(tmp, '.xray', 'state', 'pending-delegations.json'),
31
+ JSON.stringify({
32
+ sessionId: FIXTURE_SESSION_ID,
33
+ createdAt: new Date().toISOString(),
34
+ ttlMs: 14400000,
35
+ delegations: [
36
+ {
37
+ id: 'del-verify',
38
+ taskId: 'impl-1',
39
+ agent: 'backend-engineer',
40
+ taskDescription: 'implement',
41
+ taskType: 'implement',
42
+ sessionId: FIXTURE_SESSION_ID,
43
+ planTodoId: '2.1',
44
+ planTodoTask: 'swap deps',
45
+ matchMethod: 'agent-only',
46
+ matchConfidence: 0.5,
47
+ status: 'pending',
48
+ createdAt: new Date().toISOString(),
49
+ satisfiedAt: null,
50
+ spawnHint: {
51
+ tool: 'Task',
52
+ subagent_type: 'backend-engineer',
53
+ description: 'Lead-dev delegation 2.1',
54
+ planTodoId: '2.1',
55
+ delegationId: 'del-verify',
56
+ },
57
+ },
58
+ ],
59
+ }),
60
+ );
61
+ }
62
+
63
+ export function seedSpawnTodoPlan(tmp) {
64
+ writeFileSync(
65
+ join(tmp, '.xray', 'state', 'lead-dev-plan.json'),
66
+ JSON.stringify({
67
+ active: true,
68
+ persistedAt: new Date().toISOString(),
69
+ phases: [
70
+ {
71
+ id: 'phase-2',
72
+ todos: [
73
+ {
74
+ id: '2.1',
75
+ task: 'swap deps',
76
+ subagent: 'backend-engineer',
77
+ status: 'pending',
78
+ },
79
+ ],
80
+ },
81
+ ],
82
+ }),
83
+ );
84
+ }
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Shared 4/4 delegation gate fixture against nucleus SSOT (any host adapter).
4
+ * Usage: node scripts/mjs/verify-delegation-gate-core.mjs [--host=grok|hermes|opencode]
5
+ */
6
+ import { mkdtempSync, rmSync } from 'node:fs';
7
+ import { tmpdir } from 'node:os';
8
+ import { dirname, join } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ import {
11
+ FIXTURE_SESSION_ID,
12
+ seedDelegationGateFixture,
13
+ seedSpawnTodoPlan,
14
+ } from './delegation-gate-fixture.mjs';
15
+
16
+ const __dirname = dirname(fileURLToPath(import.meta.url));
17
+ const packageRoot = join(__dirname, '../..');
18
+
19
+ const hostArg = process.argv.find((a) => a.startsWith('--host='));
20
+ const host = hostArg?.split('=')[1] || 'generic';
21
+
22
+ const { evaluatePreToolGate, loadDelegationGateFeatures } = await import(
23
+ join(packageRoot, 'dist/integrations/hooks/delegation-gate-runtime.mjs')
24
+ );
25
+
26
+ const WRITE_TOOL =
27
+ host === 'hermes' ? 'write_file' : host === 'opencode' ? 'write' : 'search_replace';
28
+ const READ_TOOL = host === 'hermes' ? 'read_file' : 'read_file';
29
+ const SPAWN_TOOL =
30
+ host === 'hermes' ? 'delegate_task' : host === 'opencode' ? 'task' : 'Task';
31
+
32
+ let failed = 0;
33
+ function pass(n) {
34
+ console.log(`✅ ${n}`);
35
+ }
36
+ function fail(n, d = '') {
37
+ failed++;
38
+ console.error(`❌ ${n}${d ? ` — ${d}` : ''}`);
39
+ }
40
+
41
+ const tmp = mkdtempSync(join(tmpdir(), 'xray-gate-core-'));
42
+ seedDelegationGateFixture(tmp);
43
+
44
+ const ctx = () => ({
45
+ projectRoot: tmp,
46
+ sessionId: FIXTURE_SESSION_ID,
47
+ features: loadDelegationGateFeatures(tmp),
48
+ host,
49
+ });
50
+
51
+ try {
52
+ const deny = evaluatePreToolGate(
53
+ WRITE_TOOL,
54
+ host === 'opencode'
55
+ ? { filePath: 'src/a.ts', content: 'x' }
56
+ : { path: 'src/a.ts', new_string: 'x', content: 'x' },
57
+ ctx(),
58
+ );
59
+ if (!deny.allow && deny.gate === 'auto-chain-pending') {
60
+ pass('denies write while pending');
61
+ } else {
62
+ fail('write deny', JSON.stringify(deny));
63
+ }
64
+
65
+ const allowRead = evaluatePreToolGate(READ_TOOL, { path: 'src/a.ts' }, ctx());
66
+ if (allowRead.allow) pass('allows read while pending');
67
+ else fail('read allow', JSON.stringify(allowRead));
68
+
69
+ const allowSpawn = evaluatePreToolGate(
70
+ SPAWN_TOOL,
71
+ { prompt: 'plan todo 2.1 swap deps', subagent_type: 'backend-engineer' },
72
+ ctx(),
73
+ );
74
+ if (allowSpawn.allow) pass('allows spawn while pending');
75
+ else fail('spawn allow', JSON.stringify(allowSpawn));
76
+
77
+ seedSpawnTodoPlan(tmp);
78
+ const denyWrongTodo = evaluatePreToolGate(
79
+ SPAWN_TOOL,
80
+ { prompt: 'explore only', subagent_type: 'explore' },
81
+ ctx(),
82
+ );
83
+ if (!denyWrongTodo.allow && denyWrongTodo.gate === 'spawn-todo-persistence') {
84
+ pass('denies spawn skipping required plan todo');
85
+ } else {
86
+ fail('spawn todo persistence', JSON.stringify(denyWrongTodo));
87
+ }
88
+ } finally {
89
+ rmSync(tmp, { recursive: true, force: true });
90
+ }
91
+
92
+ const label = host === 'generic' ? 'core' : host;
93
+ console.log(
94
+ '\n' +
95
+ (failed === 0
96
+ ? `🎉 Delegation gate verify passed (4/4) [${label}].`
97
+ : `⚠️ ${failed} gate check(s) failed [${label}].`),
98
+ );
99
+ process.exit(failed === 0 ? 0 : 1);
@@ -4,10 +4,15 @@
4
4
  * Run: node scripts/mjs/verify-grok-delegation-gate.mjs
5
5
  */
6
6
  import { execSync } from 'node:child_process';
7
- import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
7
+ import { mkdtempSync, rmSync } from 'node:fs';
8
8
  import { tmpdir } from 'node:os';
9
9
  import { join, dirname } from 'node:path';
10
10
  import { fileURLToPath } from 'node:url';
11
+ import {
12
+ FIXTURE_SESSION_ID,
13
+ seedDelegationGateFixture,
14
+ seedSpawnTodoPlan,
15
+ } from './delegation-gate-fixture.mjs';
11
16
 
12
17
  const __dirname = dirname(fileURLToPath(import.meta.url));
13
18
  const packageRoot = join(__dirname, '../..');
@@ -32,57 +37,11 @@ function runHook(fixture, env = {}) {
32
37
  }
33
38
 
34
39
  const tmp = mkdtempSync(join(tmpdir(), 'xray-gate-verify-'));
35
- mkdirSync(join(tmp, '.xray', 'state'), { recursive: true });
36
- writeFileSync(
37
- join(tmp, '.xray', 'features.json'),
38
- JSON.stringify({
39
- multi_agent_orchestration: {
40
- enabled: true,
41
- lead_dev_mode: true,
42
- auto_chain_delegations: true,
43
- },
44
- }),
45
- );
46
- writeFileSync(
47
- join(tmp, '.xray', 'state', 'lead-dev-plan.json'),
48
- JSON.stringify({ active: true }),
49
- );
50
- writeFileSync(
51
- join(tmp, '.xray', 'state', 'pending-delegations.json'),
52
- JSON.stringify({
53
- sessionId: 'verify-gate',
54
- createdAt: new Date().toISOString(),
55
- ttlMs: 14400000,
56
- delegations: [
57
- {
58
- id: 'del-verify',
59
- taskId: 'impl-1',
60
- agent: 'backend-engineer',
61
- taskDescription: 'implement',
62
- taskType: 'implement',
63
- sessionId: 'verify-gate',
64
- planTodoId: '2.1',
65
- planTodoTask: 'swap deps',
66
- matchMethod: 'agent-only',
67
- matchConfidence: 0.5,
68
- status: 'pending',
69
- createdAt: new Date().toISOString(),
70
- satisfiedAt: null,
71
- spawnHint: {
72
- tool: 'Task',
73
- subagent_type: 'backend-engineer',
74
- description: 'Lead-dev delegation 2.1',
75
- planTodoId: '2.1',
76
- delegationId: 'del-verify',
77
- },
78
- },
79
- ],
80
- }),
81
- );
40
+ seedDelegationGateFixture(tmp);
82
41
 
83
42
  const baseEnv = {
84
43
  GROK_WORKSPACE_ROOT: tmp,
85
- GROK_SESSION_ID: 'verify-gate',
44
+ GROK_SESSION_ID: FIXTURE_SESSION_ID,
86
45
  };
87
46
 
88
47
  try {
@@ -125,26 +84,7 @@ try {
125
84
  if (allowTask.decision === 'allow') pass('PreToolUse allows Task while pending');
126
85
  else fail('Task allow', JSON.stringify(allowTask));
127
86
 
128
- writeFileSync(
129
- join(tmp, '.xray', 'state', 'lead-dev-plan.json'),
130
- JSON.stringify({
131
- active: true,
132
- persistedAt: new Date().toISOString(),
133
- phases: [
134
- {
135
- id: 'phase-2',
136
- todos: [
137
- {
138
- id: '2.1',
139
- task: 'swap deps',
140
- subagent: 'backend-engineer',
141
- status: 'pending',
142
- },
143
- ],
144
- },
145
- ],
146
- }),
147
- );
87
+ seedSpawnTodoPlan(tmp);
148
88
 
149
89
  const denyWrongTodo = runHook(
150
90
  {
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Hermes bridge delegation gate fixture (4/4) — uses bridge delegation-gate command.
4
+ */
5
+ import { execSync } from 'node:child_process';
6
+ import { mkdtempSync, rmSync } from 'node:fs';
7
+ import { tmpdir } from 'node:os';
8
+ import { dirname, join } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ import {
11
+ FIXTURE_SESSION_ID,
12
+ seedDelegationGateFixture,
13
+ seedSpawnTodoPlan,
14
+ } from './delegation-gate-fixture.mjs';
15
+
16
+ const __dirname = dirname(fileURLToPath(import.meta.url));
17
+ const packageRoot = join(__dirname, '../..');
18
+ const bridge = join(packageRoot, 'dist/integrations/hermes-agent/bridge.mjs');
19
+
20
+ let failed = 0;
21
+ function pass(n) {
22
+ console.log(`✅ ${n}`);
23
+ }
24
+ function fail(n, d = '') {
25
+ failed++;
26
+ console.error(`❌ ${n}${d ? ` — ${d}` : ''}`);
27
+ }
28
+
29
+ function runBridge(payload, cwd) {
30
+ const json = JSON.stringify(payload).replace(/'/g, "'\\''");
31
+ const out = execSync(`node "${bridge}" delegation-gate --cwd "${cwd}" '${json}'`, {
32
+ cwd,
33
+ encoding: 'utf8',
34
+ env: { ...process.env, XRAY_ROOT: cwd },
35
+ });
36
+ return JSON.parse(out.trim());
37
+ }
38
+
39
+ const tmp = mkdtempSync(join(tmpdir(), 'xray-hermes-gate-'));
40
+ seedDelegationGateFixture(tmp);
41
+
42
+ const base = {
43
+ command: 'delegation-gate',
44
+ phase: 'pre',
45
+ sessionId: FIXTURE_SESSION_ID,
46
+ host: 'hermes',
47
+ };
48
+
49
+ try {
50
+ const deny = runBridge({ ...base, tool: 'write_file', args: { path: 'src/a.ts', content: 'x' } }, tmp);
51
+ if (deny.allow === false && deny.gate === 'auto-chain-pending') pass('bridge denies write while pending');
52
+ else fail('write deny', JSON.stringify(deny));
53
+
54
+ const allowRead = runBridge({ ...base, tool: 'read_file', args: { path: 'src/a.ts' } }, tmp);
55
+ if (allowRead.allow === true) pass('bridge allows read while pending');
56
+ else fail('read allow', JSON.stringify(allowRead));
57
+
58
+ const allowSpawn = runBridge(
59
+ {
60
+ ...base,
61
+ tool: 'delegate_task',
62
+ args: { prompt: 'plan todo 2.1 swap deps', subagent_type: 'backend-engineer' },
63
+ },
64
+ tmp,
65
+ );
66
+ if (allowSpawn.allow === true) pass('bridge allows delegate_task while pending');
67
+ else fail('spawn allow', JSON.stringify(allowSpawn));
68
+
69
+ seedSpawnTodoPlan(tmp);
70
+ const denyTodo = runBridge(
71
+ { ...base, tool: 'delegate_task', args: { prompt: 'explore only', subagent_type: 'explore' } },
72
+ tmp,
73
+ );
74
+ if (denyTodo.allow === false && denyTodo.gate === 'spawn-todo-persistence') {
75
+ pass('bridge denies spawn skipping required plan todo');
76
+ } else {
77
+ fail('spawn todo persistence', JSON.stringify(denyTodo));
78
+ }
79
+ } finally {
80
+ rmSync(tmp, { recursive: true, force: true });
81
+ }
82
+
83
+ console.log(
84
+ '\n' +
85
+ (failed === 0
86
+ ? '🎉 Hermes delegation gate verify passed (4/4).'
87
+ : `⚠️ ${failed} Hermes gate check(s) failed.`),
88
+ );
89
+ process.exit(failed === 0 ? 0 : 1);
@@ -152,7 +152,7 @@ const OFFICIAL_VERSIONS = {
152
152
  framework: {
153
153
  version: PACKAGE_VERSION,
154
154
  displayName: "xray: Self-Healing AI Governance OS",
155
- lastUpdated: "2026-06-17",
155
+ lastUpdated: "2026-06-19",
156
156
  // Counts (auto-calculated, but can be overridden)
157
157
  ...CALCULATED_COUNTS,
158
158
  },