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.
- package/.grok-plugin/plugin.json +1 -1
- package/.xray/codex.json +12 -4
- package/.xray/features.json +1 -1
- package/AGENTS-consumer.md +6 -6
- package/AGENTS.md +5 -5
- package/README.md +2 -2
- package/dist/AGENTS.md +5 -5
- package/dist/CHANGELOG.md +25 -0
- package/dist/README.md +2 -2
- package/dist/cli/index.js +2 -5
- package/dist/governance/governance-service.js +1 -1
- package/dist/integrations/base/README.md +1 -9
- package/dist/integrations/base/index.d.ts +0 -1
- package/dist/integrations/base/index.js +0 -2
- package/dist/integrations/governance/index.js +31 -8
- package/dist/integrations/grok/hooks/grok-hook-utils.js +1 -1
- package/dist/integrations/grok/hooks/session-start.js +12 -0
- package/dist/integrations/hooks/goggles-pipeline.mjs +108 -22
- package/dist/integrations/hooks/goggles-planes.json +23 -0
- package/dist/integrations/hooks/host-truth.mjs +74 -0
- package/dist/integrations/hooks/station-hook-runtime.cjs +3 -0
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/mcps/knowledge-skills/storyteller.server.js +0 -1
- package/dist/nucleus/delegation-gate.d.ts +2 -2
- package/dist/nucleus/delegation-gate.js +13 -2
- package/dist/nucleus/work-freshness.mjs +189 -0
- package/dist/processors/implementations/agents-md-validation-processor.js +1 -1
- package/docs-site/docs/plates/boot.md +17 -2
- package/docs-site/docs/plates/governance.md +3 -2
- package/docs-site/docs/plates/index.md +3 -1
- package/docs-site/docs/plates/memory-recall.md +26 -35
- package/docs-site/docs/plates/orchestration.md +39 -35
- package/docs-site/docs/plates/processor.md +34 -36
- package/docs-site/docs/plates/reporting.md +3 -8
- package/docs-site/docs/plates/routing.md +22 -11
- package/package.json +2 -2
- package/scripts/foundry/release.mjs +48 -5
- package/scripts/mjs/test-consumer-readiness.mjs +1 -0
- package/scripts/mjs/test-mcp-functionality.mjs +14 -9
- package/scripts/node/basic-security-audit.cjs +0 -1
- package/scripts/node/bridge-mcp-wiring.cjs +66 -3
- package/scripts/node/postinstall.cjs +1 -1
- package/scripts/node/prepare-consumer.cjs +11 -7
- package/scripts/node/setup-dev.cjs +18 -26
- package/scripts/node/validate-mcp-connectivity.js +2 -1
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/src/mcps/knowledge-skills/storyteller.server.ts +0 -1
- package/xray/agents_template.md +5 -5
- package/xray/codex.json +12 -4
- package/xray/features.json +1 -1
- package/dist/agents/known-names.d.ts +0 -26
- package/dist/agents/known-names.js +0 -72
- package/dist/analytics/consent-manager.d.ts +0 -92
- package/dist/analytics/consent-manager.js +0 -257
- package/dist/benchmark/performance-benchmark.d.ts +0 -103
- package/dist/benchmark/performance-benchmark.js +0 -373
- package/dist/cli/commands/analytics-disable.d.ts +0 -9
- package/dist/cli/commands/analytics-disable.js +0 -72
- package/dist/cli/commands/analytics-enable-action.d.ts +0 -8
- package/dist/cli/commands/analytics-enable-action.js +0 -82
- package/dist/cli/commands/analytics-preview.d.ts +0 -9
- package/dist/cli/commands/analytics-preview.js +0 -106
- package/dist/cli/commands/analytics-status.d.ts +0 -9
- package/dist/cli/commands/analytics-status.js +0 -68
- package/dist/cli/commands/enforce.d.ts +0 -12
- package/dist/cli/commands/enforce.js +0 -78
- package/dist/cli/commands/govern.d.ts +0 -29
- package/dist/cli/commands/govern.js +0 -149
- package/dist/cli/commands/security-audit.d.ts +0 -23
- package/dist/cli/commands/security-audit.js +0 -219
- package/dist/cli/server.d.ts +0 -1
- package/dist/cli/server.js +0 -147
- package/dist/config/routing-mappings.d.ts +0 -26
- package/dist/config/routing-mappings.js +0 -151
- package/dist/core/bridge.mjs +0 -922
- package/dist/core/trace-context.d.ts +0 -12
- package/dist/core/trace-context.js +0 -33
- package/dist/enforcement/index.d.ts +0 -22
- package/dist/enforcement/index.js +0 -40
- package/dist/enforcement/loaders/index.d.ts +0 -36
- package/dist/enforcement/loaders/index.js +0 -39
- package/dist/enforcement/test-auto-healing.d.ts +0 -83
- package/dist/enforcement/test-auto-healing.js +0 -325
- package/dist/inference/index.d.ts +0 -10
- package/dist/inference/index.js +0 -5
- package/dist/infrastructure/iac-validator.d.ts +0 -150
- package/dist/infrastructure/iac-validator.js +0 -465
- package/dist/infrastructure/schemas/cloud-schemas.d.ts +0 -482
- package/dist/infrastructure/schemas/cloud-schemas.js +0 -488
- package/dist/integrations/base/ExampleIntegration.d.ts +0 -46
- package/dist/integrations/base/ExampleIntegration.js +0 -180
- package/dist/integrations/enforcement-gate.d.ts +0 -44
- package/dist/integrations/enforcement-gate.js +0 -348
- package/dist/mcps/connection/connection-manager.d.ts +0 -39
- package/dist/mcps/connection/connection-manager.js +0 -79
- package/dist/mcps/index.d.ts +0 -17
- package/dist/mcps/index.js +0 -65
- package/dist/mcps/orchestrator/index.d.ts +0 -6
- package/dist/mcps/orchestrator/index.js +0 -5
- package/dist/metrics/index.d.ts +0 -6
- package/dist/metrics/index.js +0 -6
- package/dist/orchestrator/self-direction-activation.d.ts +0 -108
- package/dist/orchestrator/self-direction-activation.js +0 -244
- package/dist/orchestrator/universal-registry-bridge.d.ts +0 -84
- package/dist/orchestrator/universal-registry-bridge.js +0 -246
- package/dist/performance/performance-budget-enforcer.d.ts +0 -157
- package/dist/performance/performance-budget-enforcer.js +0 -433
- package/dist/performance/performance-regression-tester.d.ts +0 -107
- package/dist/performance/performance-regression-tester.js +0 -341
- package/dist/postprocessor/analysis/CodeChangeAnalyzer.d.ts +0 -11
- package/dist/postprocessor/analysis/CodeChangeAnalyzer.js +0 -50
- package/dist/postprocessor/config/ProcessorConfigLoader.d.ts +0 -44
- package/dist/postprocessor/config/ProcessorConfigLoader.js +0 -16
- package/dist/postprocessor/integration.d.ts +0 -156
- package/dist/postprocessor/integration.js +0 -194
- package/dist/postprocessor/metamorphosis/index.d.ts +0 -2
- package/dist/postprocessor/metamorphosis/index.js +0 -1
- package/dist/postprocessor/redeploy/RetryHandler.d.ts +0 -49
- package/dist/postprocessor/redeploy/RetryHandler.js +0 -118
- package/dist/processors/implementations/session-capture-processor.d.ts +0 -14
- package/dist/processors/implementations/session-capture-processor.js +0 -37
- package/dist/public/XrayService.d.ts +0 -17
- package/dist/public/XrayService.js +0 -40
- package/dist/public/index.d.ts +0 -4
- package/dist/public/index.js +0 -2
- package/dist/security/comprehensive-security-audit.d.ts +0 -157
- package/dist/security/comprehensive-security-audit.js +0 -1004
- package/dist/security/index.d.ts +0 -13
- package/dist/security/index.js +0 -13
- package/dist/security/security-agent-coordinator.d.ts +0 -71
- package/dist/security/security-agent-coordinator.js +0 -203
- package/dist/security/security-hardening-system.d.ts +0 -238
- package/dist/security/security-hardening-system.js +0 -726
- package/dist/security/security-orchestration-layer.d.ts +0 -118
- package/dist/security/security-orchestration-layer.js +0 -495
- package/dist/testing/memory-regression-suite.d.ts +0 -105
- package/dist/testing/memory-regression-suite.js +0 -258
- package/dist/tools/assess-complexity-tool.d.ts +0 -28
- package/dist/tools/assess-complexity-tool.js +0 -44
- package/dist/tools/query-routing-tool.d.ts +0 -17
- package/dist/tools/query-routing-tool.js +0 -59
- package/dist/utils/batch-operations.d.ts +0 -25
- package/dist/utils/batch-operations.js +0 -292
- package/dist/utils/task-graph.d.ts +0 -29
- package/dist/utils/task-graph.js +0 -106
- package/dist/utils/test-template-generator.d.ts +0 -25
- package/dist/utils/test-template-generator.js +0 -178
- package/dist/utils/token-manager.d.ts +0 -48
- package/dist/utils/token-manager.js +0 -163
- package/dist/validation/agent-config-validator.d.ts +0 -110
- package/dist/validation/agent-config-validator.js +0 -280
- package/dist/validation/orchestration-flow-validator.d.ts +0 -87
- package/dist/validation/orchestration-flow-validator.js +0 -606
- package/src/mcps/connection/connection-manager.ts +0 -91
- package/src/mcps/index.ts +0 -80
- package/src/mcps/orchestrator/index.ts +0 -29
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
],
|
|
16
16
|
"skills": "SKILLS.md"
|
|
17
17
|
},
|
|
18
|
+
"synthesis": {
|
|
19
|
+
"file": "src/nucleus/synthesis.ts"
|
|
20
|
+
},
|
|
18
21
|
"routing": {
|
|
19
22
|
"files": ["src/nucleus/thin-dispatch.ts"],
|
|
20
23
|
"worn": "dist/nucleus/thin-dispatch.js",
|
|
@@ -24,5 +27,25 @@
|
|
|
24
27
|
},
|
|
25
28
|
"house": {
|
|
26
29
|
"files": ["grok-bot/lib/seat-doctor.cjs"]
|
|
30
|
+
},
|
|
31
|
+
"boot": {
|
|
32
|
+
"files": ["src/core/boot-orchestrator.ts"],
|
|
33
|
+
"skills": "src/skills/boot-orchestrator/SKILL.md"
|
|
34
|
+
},
|
|
35
|
+
"governance": {
|
|
36
|
+
"files": ["src/governance/governance-service.ts"]
|
|
37
|
+
},
|
|
38
|
+
"memory-recall": {
|
|
39
|
+
"files": ["src/integrations/hooks/plates.cjs"]
|
|
40
|
+
},
|
|
41
|
+
"orchestration": {
|
|
42
|
+
"files": ["src/mcps/orchestrator/server.ts"]
|
|
43
|
+
},
|
|
44
|
+
"processor": {
|
|
45
|
+
"files": ["src/processors/processor-manager.ts"],
|
|
46
|
+
"skills": "src/skills/processor-pipeline/SKILL.md"
|
|
47
|
+
},
|
|
48
|
+
"reporting": {
|
|
49
|
+
"files": ["src/reporting/framework-reporting-system.ts"]
|
|
27
50
|
}
|
|
28
51
|
}
|
|
@@ -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);
|
|
@@ -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;
|
|
@@ -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 * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
@@ -11,6 +11,7 @@ import { allPlanTodos, areSynthesisConsultTodosComplete, findRecentStalePlanArch
|
|
|
11
11
|
import { getSynthesisDueReason, isSynthesisCheckpointDue, recordExecutionSlice, } from './synthesis.js';
|
|
12
12
|
import { isSynthesisConsultTodoId, tryRecordSynthesisConsultReceipt, } from './synthesis-consult-receipt.js';
|
|
13
13
|
import { resolveSpawnPlan, hasValidSpawnPlanContext } from './spawn-plan-resolution.js';
|
|
14
|
+
import { probeFreshness } from './work-freshness.mjs';
|
|
14
15
|
import { isUserAsidesEnabled, isUserAsideTodoId, loadActiveAsidePointer, loadActiveUserAside, } from './user-aside.js';
|
|
15
16
|
import { validateAsideWorktreeCwd, } from './aside-worktree.js';
|
|
16
17
|
import { ceremonyForProfile, resolveSuitProfile, spawnPlanModeForProfile, writeSuitSessionBoot, maybeHeatHostStation, } from './suit-temperament.js';
|
|
@@ -416,11 +417,21 @@ function collectWritePaths(toolInput) {
|
|
|
416
417
|
}
|
|
417
418
|
return paths;
|
|
418
419
|
}
|
|
419
|
-
/** Codex 11 / 29 / 69 + destructive shell — always on, all hosts that call this SSOT. */
|
|
420
|
+
/** Codex 11 / 29 / 69 / 70 + destructive shell — always on, all hosts that call this SSOT. */
|
|
420
421
|
export function evaluateConstitutionGate(toolName, toolInput, ctx) {
|
|
421
422
|
const content = collectWriteContent(toolInput);
|
|
422
423
|
const paths = collectWritePaths(toolInput);
|
|
423
424
|
const writing = isWriteTool(toolName, ctx.host ?? 'generic');
|
|
425
|
+
if (writing) {
|
|
426
|
+
const freshness = probeFreshness(ctx.projectRoot);
|
|
427
|
+
if (freshness.stale) {
|
|
428
|
+
return {
|
|
429
|
+
allow: false,
|
|
430
|
+
reason: freshness.reason,
|
|
431
|
+
gate: 'codex-70',
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
}
|
|
424
435
|
if (writing && ctx.features.no_new_surface !== false) {
|
|
425
436
|
for (const p of paths) {
|
|
426
437
|
const normalized = p.replace(/\\/g, '/');
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex 70. An edit waits until this copy is on the latest main
|
|
3
|
+
* and the package is not older than the published one.
|
|
4
|
+
* This repo is that package when package.json name is 0xray.
|
|
5
|
+
* The check is saved at session start. The edit gate reads the saved result.
|
|
6
|
+
* A temp directory inside a repo is not the workspace, so unit tests stay quiet.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { execFileSync } from 'node:child_process';
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
11
|
+
import { join, resolve } from 'node:path';
|
|
12
|
+
|
|
13
|
+
export function compareVersions(left, right) {
|
|
14
|
+
const a = String(left).split('.').map((part) => parseInt(part, 10) || 0);
|
|
15
|
+
const b = String(right).split('.').map((part) => parseInt(part, 10) || 0);
|
|
16
|
+
const length = Math.max(a.length, b.length);
|
|
17
|
+
for (let i = 0; i < length; i += 1) {
|
|
18
|
+
const da = a[i] || 0;
|
|
19
|
+
const db = b[i] || 0;
|
|
20
|
+
if (da !== db) return da < db ? -1 : 1;
|
|
21
|
+
}
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function decideFreshness(input) {
|
|
26
|
+
const behind = Number(input.behind) || 0;
|
|
27
|
+
if (behind > 0) {
|
|
28
|
+
const commits = behind === 1 ? '1 commit' : `${behind} commits`;
|
|
29
|
+
return {
|
|
30
|
+
stale: true,
|
|
31
|
+
reason: `Codex 70: this copy is ${commits} behind main. Update before you edit. Compare set-aside work to main before you throw it away.`,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const repoVersion = input.repoName === '0xray' ? input.repoVersion || null : null;
|
|
35
|
+
const worn = input.wornSuit || repoVersion;
|
|
36
|
+
const published = input.publishedSuit || null;
|
|
37
|
+
const target = published || repoVersion;
|
|
38
|
+
if (target && worn && compareVersions(worn, target) < 0) {
|
|
39
|
+
return {
|
|
40
|
+
stale: true,
|
|
41
|
+
reason: `Codex 70: package ${worn} is older than ${target}. Install the current one before you edit.`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return { stale: false, reason: '' };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function describeFreshness(input) {
|
|
48
|
+
const behind = Number(input.behind) || 0;
|
|
49
|
+
const parts = [behind > 0 ? `${behind} behind main` : 'up to date'];
|
|
50
|
+
if (input.wornSuit) parts.push(`package ${input.wornSuit}`);
|
|
51
|
+
if (input.publishedSuit) parts.push(`published ${input.publishedSuit}`);
|
|
52
|
+
const stashCount = Number(input.stashCount) || 0;
|
|
53
|
+
if (stashCount > 0) parts.push(`${stashCount} set aside, compare before drop`);
|
|
54
|
+
return `Fresh: ${parts.join('. ')}.`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function run(cmd, args, cwd, timeout) {
|
|
58
|
+
return execFileSync(cmd, args, {
|
|
59
|
+
cwd,
|
|
60
|
+
encoding: 'utf8',
|
|
61
|
+
timeout,
|
|
62
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
63
|
+
}).trim();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function gitTop(cwd) {
|
|
67
|
+
try {
|
|
68
|
+
return run('git', ['rev-parse', '--show-toplevel'], cwd, 3000);
|
|
69
|
+
} catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function readJson(file) {
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(readFileSync(file, 'utf8'));
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function wornSuitVersion(projectRoot, opts = {}) {
|
|
83
|
+
if (projectRoot) {
|
|
84
|
+
const local = readJson(join(projectRoot, 'node_modules', '0xray', 'package.json'));
|
|
85
|
+
if (local && local.version) return String(local.version);
|
|
86
|
+
}
|
|
87
|
+
const candidates = [
|
|
88
|
+
'/opt/homebrew/lib/node_modules/0xray/package.json',
|
|
89
|
+
'/usr/local/lib/node_modules/0xray/package.json',
|
|
90
|
+
];
|
|
91
|
+
for (const file of candidates) {
|
|
92
|
+
const pkg = readJson(file);
|
|
93
|
+
if (pkg && pkg.version) return String(pkg.version);
|
|
94
|
+
}
|
|
95
|
+
if (!opts.liveGlobal) return null;
|
|
96
|
+
try {
|
|
97
|
+
const root = run('npm', ['root', '-g'], projectRoot || process.cwd(), 8000);
|
|
98
|
+
const pkg = readJson(join(root, '0xray', 'package.json'));
|
|
99
|
+
return pkg && pkg.version ? String(pkg.version) : null;
|
|
100
|
+
} catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function readWorkSnapshot(projectRoot) {
|
|
106
|
+
const top = gitTop(projectRoot);
|
|
107
|
+
let behind = 0;
|
|
108
|
+
let stashCount = 0;
|
|
109
|
+
if (top && resolve(top) === resolve(projectRoot)) {
|
|
110
|
+
try {
|
|
111
|
+
behind = Number(run('git', ['rev-list', '--count', 'HEAD..origin/main'], projectRoot, 4000)) || 0;
|
|
112
|
+
} catch {
|
|
113
|
+
behind = 0;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const list = run('git', ['stash', 'list'], projectRoot, 4000);
|
|
117
|
+
stashCount = list ? list.split('\n').filter(Boolean).length : 0;
|
|
118
|
+
} catch {
|
|
119
|
+
stashCount = 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const repo = readJson(join(projectRoot, 'package.json'));
|
|
123
|
+
const saved = readJson(join(projectRoot, '.xray', 'state', 'freshness.json'));
|
|
124
|
+
return {
|
|
125
|
+
behind,
|
|
126
|
+
stashCount,
|
|
127
|
+
repoName: repo && repo.name ? String(repo.name) : null,
|
|
128
|
+
repoVersion: repo && repo.version ? String(repo.version) : null,
|
|
129
|
+
wornSuit: wornSuitVersion(projectRoot),
|
|
130
|
+
publishedSuit: saved && saved.publishedSuit ? String(saved.publishedSuit) : null,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function freshnessFile(projectRoot) {
|
|
135
|
+
return join(projectRoot, '.xray', 'state', 'freshness.json');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function readSavedFreshness(projectRoot) {
|
|
139
|
+
const saved = readJson(freshnessFile(projectRoot));
|
|
140
|
+
return saved ? describeFreshness(saved) : null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function probeFreshness(projectRoot) {
|
|
144
|
+
const saved = readJson(freshnessFile(projectRoot));
|
|
145
|
+
if (saved && saved.behind != null) return decideFreshness(saved);
|
|
146
|
+
return decideFreshness(readWorkSnapshot(projectRoot));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function refreshFreshness(projectRoot) {
|
|
150
|
+
const top = gitTop(projectRoot);
|
|
151
|
+
if (top && resolve(top) === resolve(projectRoot)) {
|
|
152
|
+
try {
|
|
153
|
+
run('git', ['fetch', 'origin', '--prune'], projectRoot, 8000);
|
|
154
|
+
} catch {
|
|
155
|
+
/* offline fetch must not block the boot */
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
let publishedSuit = null;
|
|
159
|
+
try {
|
|
160
|
+
publishedSuit = run('npm', ['view', '0xray', 'version'], projectRoot, 8000);
|
|
161
|
+
} catch {
|
|
162
|
+
publishedSuit = null;
|
|
163
|
+
}
|
|
164
|
+
const snapshot = readWorkSnapshot(projectRoot);
|
|
165
|
+
if (publishedSuit) snapshot.publishedSuit = publishedSuit;
|
|
166
|
+
if (snapshot.repoName === '0xray' && snapshot.repoVersion) {
|
|
167
|
+
snapshot.wornSuit = snapshot.repoVersion;
|
|
168
|
+
} else {
|
|
169
|
+
const globalWorn = wornSuitVersion(projectRoot, { liveGlobal: true });
|
|
170
|
+
if (globalWorn) snapshot.wornSuit = globalWorn;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
const dir = join(projectRoot, '.xray', 'state');
|
|
174
|
+
mkdirSync(dir, { recursive: true });
|
|
175
|
+
writeFileSync(freshnessFile(projectRoot), `${JSON.stringify({
|
|
176
|
+
publishedSuit: snapshot.publishedSuit,
|
|
177
|
+
wornSuit: snapshot.wornSuit,
|
|
178
|
+
behind: snapshot.behind,
|
|
179
|
+
stashCount: snapshot.stashCount,
|
|
180
|
+
checkedAt: new Date().toISOString(),
|
|
181
|
+
}, null, 2)}\n`);
|
|
182
|
+
} catch {
|
|
183
|
+
/* the gate still reads git and the worn package */
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
...snapshot,
|
|
187
|
+
freshnessLine: describeFreshness(snapshot),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
@@ -224,7 +224,7 @@ export class AgentsMdValidationProcessor {
|
|
|
224
224
|
"",
|
|
225
225
|
"## Codex",
|
|
226
226
|
"",
|
|
227
|
-
`0xRay enforces Universal Development Codex (
|
|
227
|
+
`0xRay enforces Universal Development Codex (70 terms) for systematic error prevention.`,
|
|
228
228
|
"",
|
|
229
229
|
].join("\n"),
|
|
230
230
|
"## CLI Commands": [
|
|
@@ -20,6 +20,11 @@ sidebar_label: Boot
|
|
|
20
20
|
┌─────────────────────────────┼──────────────────────────────┐
|
|
21
21
|
│ PROCESSING LAYER v │
|
|
22
22
|
│ ┌────────────────────────────────────────────────────┐ │
|
|
23
|
+
│ │ memory monitoring │ │
|
|
24
|
+
│ │ setupMemoryMonitoring │ │
|
|
25
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
26
|
+
│ v │
|
|
27
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
23
28
|
│ │ load .xray config │ │
|
|
24
29
|
│ └──────────────────────────┬─────────────────────────┘ │
|
|
25
30
|
│ v │
|
|
@@ -33,12 +38,22 @@ sidebar_label: Boot
|
|
|
33
38
|
│ v │
|
|
34
39
|
│ ┌────────────────────────────────────────────────────┐ │
|
|
35
40
|
│ │ activateProcessors (PROCESSOR_DEFS) │ │
|
|
36
|
-
│
|
|
41
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
42
|
+
│ v │
|
|
43
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
44
|
+
│ │ processor health │ │
|
|
45
|
+
│ │ validateProcessorHealth │ │
|
|
46
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
47
|
+
│ v │
|
|
48
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
49
|
+
│ │ agents and plugins │ │
|
|
50
|
+
│ │ loadRemainingAgents · initializePluginSystem │ │
|
|
37
51
|
│ └──────────────────────────┬─────────────────────────┘ │
|
|
38
52
|
│ v │
|
|
39
53
|
│ ┌────────────────────────────────────────────────────┐ │
|
|
40
54
|
│ │ enforcement · codex compliance │ │
|
|
41
|
-
│ │
|
|
55
|
+
│ │ finalizeSecurityIntegration │ │
|
|
56
|
+
│ │ governance init when that flag is not false │ │
|
|
42
57
|
│ └──────────────────────────┬─────────────────────────┘ │
|
|
43
58
|
└──────────────────────────────┼────────────────────────────┘
|
|
44
59
|
v
|
|
@@ -5,7 +5,7 @@ sidebar_label: Governance
|
|
|
5
5
|
|
|
6
6
|
# Governance
|
|
7
7
|
|
|
8
|
-
A proposal is deliberated inside the suit, filtered by Dynamo Solar, then merged. The PreToolUse codex gate stands beside the vote.
|
|
8
|
+
A proposal is deliberated inside the suit, filtered by Dynamo Solar, then merged. The vote is approve, reject, or needs_revision. The PreToolUse codex gate stands beside the vote.
|
|
9
9
|
|
|
10
10
|
```
|
|
11
11
|
┌────────────────────────────────────────────────────────────┐
|
|
@@ -44,7 +44,8 @@ A proposal is deliberated inside the suit, filtered by Dynamo Solar, then merged
|
|
|
44
44
|
│ OUTPUT LAYER v │
|
|
45
45
|
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
|
46
46
|
│ │ vote │ │ codex decision │ │
|
|
47
|
-
│ │ approve / reject
|
|
47
|
+
│ │ approve / reject / │ │ allow / deny │ │
|
|
48
|
+
│ │ needs_revision │ │ │ │
|
|
48
49
|
│ └──────────────────────┘ └──────────────────────┘ │
|
|
49
50
|
└────────────────────────────────────────────────────────────┘
|
|
50
51
|
```
|
|
@@ -23,6 +23,8 @@ Plates have a type. A domain model plate shows how named parts fit. A state flow
|
|
|
23
23
|
|
|
24
24
|
[House](./house.md)
|
|
25
25
|
|
|
26
|
-
##
|
|
26
|
+
## Pipeline
|
|
27
27
|
|
|
28
28
|
[Routing](./routing.md) · [Governance](./governance.md) · [Boot](./boot.md) · [Orchestration](./orchestration.md) · [Processor](./processor.md) · [Reporting](./reporting.md) · [Memory recall](./memory-recall.md)
|
|
29
|
+
|
|
30
|
+
These seven are the lens planes. Each drawing is an input layer, a processing layer, and an output layer. Ground has no plate file.
|
|
@@ -5,45 +5,36 @@ sidebar_label: Memory recall
|
|
|
5
5
|
|
|
6
6
|
# Memory recall
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Intent names one plate. Equal top scores recall nothing. A missing worn copy is stamped from the docs plate. An edited copy stays.
|
|
9
9
|
|
|
10
10
|
```
|
|
11
11
|
┌──────────────────────────────────────────────────────────────┐
|
|
12
12
|
│ INPUT LAYER │
|
|
13
13
|
│ │
|
|
14
|
-
│
|
|
15
|
-
│ │
|
|
16
|
-
│
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
│ PROCESSING LAYER │
|
|
21
|
-
│
|
|
22
|
-
│
|
|
23
|
-
│ │
|
|
24
|
-
│ │
|
|
25
|
-
│
|
|
26
|
-
│
|
|
27
|
-
│
|
|
28
|
-
│
|
|
29
|
-
│
|
|
30
|
-
│
|
|
31
|
-
│
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
│
|
|
38
|
-
│
|
|
39
|
-
│ ┌────────────────────────────┐ ┌─────────────────────┐ │
|
|
40
|
-
│ │ lesson on the signal │ │ stamp file │ │
|
|
41
|
-
│ │ an episode of what happened│ │ the schematic │ │
|
|
42
|
-
│ └────────────────────────────┘ │ docs-site/docs/ │ │
|
|
43
|
-
│ │ plates/<id>.md │ │
|
|
44
|
-
│ │ worn copy only when │ │
|
|
45
|
-
│ │ .xray/state/plates/ │ │
|
|
46
|
-
│ │ <id>.md is missing │ │
|
|
47
|
-
│ └─────────────────────┘ │
|
|
14
|
+
│ ┌──────────────────────────────────────────────────────┐ │
|
|
15
|
+
│ │ intent │ │
|
|
16
|
+
│ └──────────────────────────┬───────────────────────────┘ │
|
|
17
|
+
└──────────────────────────────┼──────────────────────────────┘
|
|
18
|
+
v
|
|
19
|
+
┌──────────────────────────────┼──────────────────────────────┐
|
|
20
|
+
│ PROCESSING LAYER v │
|
|
21
|
+
│ ┌──────────────────────────────────────────────────────┐ │
|
|
22
|
+
│ │ score cues │ │
|
|
23
|
+
│ │ one winner loads that plate │ │
|
|
24
|
+
│ │ a tie returns nothing │ │
|
|
25
|
+
│ └──────────────────────────┬───────────────────────────┘ │
|
|
26
|
+
│ v │
|
|
27
|
+
│ ┌──────────────────────────────────────────────────────┐ │
|
|
28
|
+
│ │ stampPlateIfMissing │ │
|
|
29
|
+
│ │ writes .xray/state/plates only when that file │ │
|
|
30
|
+
│ │ is missing │ │
|
|
31
|
+
│ └──────────────────────────┬───────────────────────────┘ │
|
|
32
|
+
└──────────────────────────────┼──────────────────────────────┘
|
|
33
|
+
v
|
|
34
|
+
┌──────────────────────────────┼──────────────────────────────┐
|
|
35
|
+
│ OUTPUT LAYER v │
|
|
36
|
+
│ ┌────────────────────┐ ┌────────────────────────┐ │
|
|
37
|
+
│ │ plate line │ │ stamp file │ │
|
|
38
|
+
│ └────────────────────┘ └────────────────────────┘ │
|
|
48
39
|
└──────────────────────────────────────────────────────────────┘
|
|
49
40
|
```
|
|
@@ -5,51 +5,55 @@ sidebar_label: Orchestration
|
|
|
5
5
|
|
|
6
6
|
# Orchestration
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Each tool is its own call. `spawnAside` opens around `orchestrate-task`, `analyze-complexity`, and `govern-and-apply`. `closeAside` runs when that call returns.
|
|
9
9
|
|
|
10
10
|
```
|
|
11
11
|
┌────────────────────────────────────────────────────────────┐
|
|
12
12
|
│ INPUT LAYER │
|
|
13
13
|
│ │
|
|
14
|
-
│
|
|
15
|
-
│ │
|
|
16
|
-
│
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
│
|
|
22
|
-
│ ┌────────────────────────────────────────────────────┐
|
|
23
|
-
│ │
|
|
24
|
-
│ │
|
|
25
|
-
│ └──────────────────────────┬─────────────────────────┘
|
|
26
|
-
│ v
|
|
27
|
-
│ ┌────────────────────────────────────────────────────┐
|
|
28
|
-
│ │
|
|
29
|
-
│ │
|
|
30
|
-
│
|
|
31
|
-
│
|
|
32
|
-
│
|
|
33
|
-
│
|
|
34
|
-
│ │
|
|
35
|
-
│ │
|
|
36
|
-
│ │
|
|
37
|
-
│ └──────────────────────────┬─────────────────────────┘
|
|
38
|
-
│ v
|
|
39
|
-
│ ┌────────────────────────────────────────────────────┐
|
|
40
|
-
│ │
|
|
41
|
-
│
|
|
42
|
-
│
|
|
43
|
-
│
|
|
44
|
-
│
|
|
45
|
-
│ │ closeAside
|
|
46
|
-
│ └──────────────────────────┬─────────────────────────┘
|
|
14
|
+
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
|
15
|
+
│ │ tool name │ │ arguments │ │
|
|
16
|
+
│ └──────────┬───────────┘ └──────────┬───────────┘ │
|
|
17
|
+
└──────────────┼─────────────────────────────┼──────────────┘
|
|
18
|
+
v v
|
|
19
|
+
┌──────────────┼─────────────────────────────┼──────────────┐
|
|
20
|
+
│ PROCESSING LAYER │ │
|
|
21
|
+
│ v v │
|
|
22
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
23
|
+
│ │ orchestrate-task │ │
|
|
24
|
+
│ │ spawnAside · handleOrchestrateTask · closeAside │ │
|
|
25
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
26
|
+
│ v │
|
|
27
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
28
|
+
│ │ analyze-complexity │ │
|
|
29
|
+
│ │ a due synthesis checkpoint can return first │ │
|
|
30
|
+
│ │ spawnAside · handleAnalyzeComplexity · closeAside │ │
|
|
31
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
32
|
+
│ v │
|
|
33
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
34
|
+
│ │ govern-and-apply │ │
|
|
35
|
+
│ │ a due synthesis checkpoint blocks first │ │
|
|
36
|
+
│ │ spawnAside · governExternalProposals · closeAside │ │
|
|
37
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
38
|
+
│ v │
|
|
39
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
40
|
+
│ │ get-orchestration-status │ │
|
|
41
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
42
|
+
│ v │
|
|
43
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
44
|
+
│ │ cancel-orchestration │ │
|
|
45
|
+
│ │ closeAside on a forced cancel or a matching session│ │
|
|
46
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
47
|
+
│ v │
|
|
48
|
+
│ ┌────────────────────────────────────────────────────┐ │
|
|
49
|
+
│ │ optimize-orchestration │ │
|
|
50
|
+
│ └──────────────────────────┬─────────────────────────┘ │
|
|
47
51
|
└──────────────────────────────┼────────────────────────────┘
|
|
48
52
|
v
|
|
49
53
|
┌──────────────────────────────┼────────────────────────────┐
|
|
50
54
|
│ OUTPUT LAYER v │
|
|
51
55
|
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
|
|
52
|
-
│ │
|
|
56
|
+
│ │ tool result │ │ aside id │ │
|
|
53
57
|
│ └─────────────────────┘ └─────────────────────────┘ │
|
|
54
58
|
└────────────────────────────────────────────────────────────┘
|
|
55
59
|
```
|