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.
- package/AGENTS-consumer.md +1 -1
- package/AGENTS.md +1 -1
- package/README.md +1 -1
- package/SKILLS.md +1 -1
- package/dist/AGENTS.md +1 -1
- package/dist/CHANGELOG.md +16 -0
- package/dist/README.md +1 -1
- package/dist/SKILLS.md +1 -1
- package/dist/integrations/grok/hooks/grok-hook-utils.js +30 -383
- package/dist/integrations/hermes-agent/__init__.py +50 -3
- package/dist/integrations/hermes-agent/bridge.mjs +78 -9
- package/dist/integrations/hooks/delegation-gate-runtime.mjs +75 -0
- package/dist/nucleus/delegation-gate.d.ts +86 -0
- package/dist/nucleus/delegation-gate.js +275 -0
- package/dist/nucleus/lead-dev-plan-persistence.js +3 -3
- package/dist/plugin/xray-codex-injection.js +33 -0
- package/package.json +7 -2
- package/scripts/mjs/delegation-gate-fixture.mjs +84 -0
- package/scripts/mjs/verify-delegation-gate-core.mjs +99 -0
- package/scripts/mjs/verify-grok-delegation-gate.mjs +9 -69
- package/scripts/mjs/verify-hermes-delegation-gate.mjs +89 -0
- package/scripts/node/universal-version-manager.js +1 -1
|
@@ -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,
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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-
|
|
155
|
+
lastUpdated: "2026-06-19",
|
|
156
156
|
// Counts (auto-calculated, but can be overridden)
|
|
157
157
|
...CALCULATED_COUNTS,
|
|
158
158
|
},
|