0xray 4.0.18 → 4.0.20
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/features.json +1 -1
- package/dist/CHANGELOG.md +25 -0
- package/dist/integrations/cursor/hooks/after-file-edit.js +6 -3
- package/dist/integrations/cursor/hooks/cursor-hook-utils.js +40 -20
- package/dist/integrations/cursor/hooks/pre-compact.js +30 -22
- package/dist/integrations/cursor/hooks/pre-tool-use.js +5 -4
- package/dist/integrations/grok/hooks/grok-hook-utils.js +3 -1
- package/dist/integrations/hermes-agent/bridge.mjs +14 -0
- package/dist/integrations/hooks/station-hook-runtime.cjs +243 -13
- package/dist/integrations/hooks/station-hook-runtime.mjs +6 -0
- package/dist/integrations/hooks/station-memory-ingest.mjs +153 -4
- package/dist/integrations/hooks/station-memory-match.mjs +8 -8
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/nucleus/delegation-gate.js +10 -11
- package/dist/nucleus/suit-temperament.js +5 -1
- package/package.json +1 -1
- package/scripts/node/consumer-install-smoke.mjs +3 -3
- package/scripts/node/wear-vendored-repertoire.cjs +39 -1
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/vendor/@0xray/repertoire/AGENTS.md +8 -2
- package/vendor/@0xray/repertoire/README.md +35 -8
- package/vendor/@0xray/repertoire/data/stack-overlay.json +750 -0
- package/vendor/@0xray/repertoire/data/subject-overlay.json +297 -0
- package/vendor/@0xray/repertoire/dist/RepertoireService.d.ts +36 -1
- package/vendor/@0xray/repertoire/dist/RepertoireService.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/RepertoireService.js +108 -18
- package/vendor/@0xray/repertoire/dist/RepertoireService.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/index.d.ts +3 -1
- package/vendor/@0xray/repertoire/dist/index.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/index.js +3 -1
- package/vendor/@0xray/repertoire/dist/index.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.d.ts +4 -0
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.js +15 -1
- package/vendor/@0xray/repertoire/dist/ingestion/groover-log-ingester.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.d.ts +22 -8
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js +56 -5
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/mcp/server.js +8 -13
- package/vendor/@0xray/repertoire/dist/mcp/server.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.js +24 -7
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/confidence-gate.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.js +2 -1
- package/vendor/@0xray/repertoire/dist/orchestrator-bridge/signal-injector.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/paths.d.ts +65 -2
- package/vendor/@0xray/repertoire/dist/paths.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/paths.js +377 -6
- package/vendor/@0xray/repertoire/dist/paths.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js +6 -8
- package/vendor/@0xray/repertoire/dist/provider/memory-routing-provider.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts +20 -2
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js +121 -8
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.d.ts +2 -1
- package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.js +21 -3
- package/vendor/@0xray/repertoire/dist/registry/InferenceStateManager.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/registry/confidence-decay.d.ts +40 -0
- package/vendor/@0xray/repertoire/dist/registry/confidence-decay.d.ts.map +1 -0
- package/vendor/@0xray/repertoire/dist/registry/confidence-decay.js +89 -0
- package/vendor/@0xray/repertoire/dist/registry/confidence-decay.js.map +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.js +1 -0
- package/vendor/@0xray/repertoire/dist/synthesis/meta-inference-engine.js.map +1 -1
- package/vendor/@0xray/repertoire/dist/types.d.ts +5 -0
- package/vendor/@0xray/repertoire/dist/types.d.ts.map +1 -1
- package/vendor/@0xray/repertoire/package.json +4 -2
- package/vendor/@0xray/repertoire/scripts/verify-synthesis-dogfood.mjs +2 -2
- package/xray/features.json +1 -1
|
@@ -1,12 +1,161 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Station organ write — compact ingest + wake grow.
|
|
4
|
+
* Grow uses the worn RepertoireService. Groover field stays off.
|
|
4
5
|
*/
|
|
5
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
7
|
import { join } from 'node:path';
|
|
8
|
+
import { pathToFileURL } from 'node:url';
|
|
7
9
|
|
|
8
10
|
const root = process.argv[2];
|
|
9
|
-
const
|
|
11
|
+
const mode = process.argv[3] || 'station';
|
|
12
|
+
|
|
13
|
+
function readRouting(projectRoot) {
|
|
14
|
+
let routing = { enabled: false, provider: 'null' };
|
|
15
|
+
const featuresPath = join(projectRoot, '.xray', 'features.json');
|
|
16
|
+
if (existsSync(featuresPath)) {
|
|
17
|
+
try {
|
|
18
|
+
routing = JSON.parse(readFileSync(featuresPath, 'utf8')).memory_routing || routing;
|
|
19
|
+
} catch {
|
|
20
|
+
/* leftover */
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return routing;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isExplicitOptOut(routing) {
|
|
27
|
+
return routing && routing.enabled === false && routing.provider === 'repertoire';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function organServiceCandidates(projectRoot, routing) {
|
|
31
|
+
const configured = routing.module_path
|
|
32
|
+
? routing.module_path.startsWith('/') || /^[A-Za-z]:[\\/]/.test(routing.module_path)
|
|
33
|
+
? routing.module_path
|
|
34
|
+
: join(projectRoot, routing.module_path)
|
|
35
|
+
: null;
|
|
36
|
+
const fromProvider = configured
|
|
37
|
+
? configured.replace(/provider\/memory-routing-provider\.js$/, 'RepertoireService.js')
|
|
38
|
+
: null;
|
|
39
|
+
const raw = [
|
|
40
|
+
fromProvider,
|
|
41
|
+
join(projectRoot, 'node_modules', '@0xray', 'repertoire', 'dist', 'RepertoireService.js'),
|
|
42
|
+
join(projectRoot, 'vendor', '@0xray', 'repertoire', 'dist', 'RepertoireService.js'),
|
|
43
|
+
join(projectRoot, '..', 'repertoire', 'dist', 'RepertoireService.js'),
|
|
44
|
+
].filter(Boolean);
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
const out = [];
|
|
47
|
+
for (const dest of raw) {
|
|
48
|
+
if (seen.has(dest) || !existsSync(dest)) continue;
|
|
49
|
+
seen.add(dest);
|
|
50
|
+
out.push(dest);
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function ensureDestShape(destSignals) {
|
|
56
|
+
if (!existsSync(destSignals)) return;
|
|
57
|
+
try {
|
|
58
|
+
const data = JSON.parse(readFileSync(destSignals, 'utf8'));
|
|
59
|
+
if (!Array.isArray(data.signals)) return;
|
|
60
|
+
let dirty = false;
|
|
61
|
+
for (const signal of data.signals) {
|
|
62
|
+
if (!signal) continue;
|
|
63
|
+
if (!Array.isArray(signal.tags)) {
|
|
64
|
+
signal.tags = [];
|
|
65
|
+
dirty = true;
|
|
66
|
+
}
|
|
67
|
+
if (typeof signal.definition !== 'string') {
|
|
68
|
+
signal.definition = String(signal.name || '');
|
|
69
|
+
dirty = true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (dirty) writeFileSync(destSignals, `${JSON.stringify(data, null, 2)}\n`);
|
|
73
|
+
} catch {
|
|
74
|
+
/* leftover */
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function readCleanupDiary(projectRoot) {
|
|
79
|
+
const files = [
|
|
80
|
+
join(projectRoot, '.xray', 'state', 'NOTES.md'),
|
|
81
|
+
join(projectRoot, '.xray', 'state', 'CLEANSE-LIST.md'),
|
|
82
|
+
join(projectRoot, 'docs', 'archive', 'README.md'),
|
|
83
|
+
];
|
|
84
|
+
const parts = [];
|
|
85
|
+
const sources = [];
|
|
86
|
+
for (const dest of files) {
|
|
87
|
+
if (!existsSync(dest)) continue;
|
|
88
|
+
try {
|
|
89
|
+
parts.push(readFileSync(dest, 'utf8'));
|
|
90
|
+
sources.push(dest);
|
|
91
|
+
} catch {
|
|
92
|
+
/* leftover */
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { text: parts.join('\n'), sources };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function growDest(projectRoot) {
|
|
99
|
+
const routing = readRouting(projectRoot);
|
|
100
|
+
if (isExplicitOptOut(routing)) {
|
|
101
|
+
process.stdout.write(`${JSON.stringify({ skipped: 'opt-out' })}\n`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
for (const dest of organServiceCandidates(projectRoot, routing)) {
|
|
105
|
+
try {
|
|
106
|
+
const mod = await import(pathToFileURL(dest).href);
|
|
107
|
+
const RepertoireService = mod.RepertoireService;
|
|
108
|
+
if (typeof RepertoireService !== 'function') continue;
|
|
109
|
+
const pathsMod = await import(pathToFileURL(dest.replace(/RepertoireService\.js$/, 'paths.js')).href);
|
|
110
|
+
const destSignals = join(projectRoot, '.xray', 'state', 'repertoire', 'curated_signals.json');
|
|
111
|
+
ensureDestShape(destSignals);
|
|
112
|
+
const service = new RepertoireService({
|
|
113
|
+
projectRoot,
|
|
114
|
+
signalsPath: destSignals,
|
|
115
|
+
syncXray: false,
|
|
116
|
+
syncField: false,
|
|
117
|
+
});
|
|
118
|
+
ensureDestShape(destSignals);
|
|
119
|
+
const before = service.signalsManager.load().signals.length;
|
|
120
|
+
const sessions = service.syncXrayMemory();
|
|
121
|
+
const siblings = service.syncWorkspaceRepos();
|
|
122
|
+
const kernel =
|
|
123
|
+
typeof pathsMod.collectKernelDiaryText === 'function'
|
|
124
|
+
? pathsMod.collectKernelDiaryText(projectRoot)
|
|
125
|
+
: { text: '', sources: [] };
|
|
126
|
+
const cleanup = readCleanupDiary(projectRoot);
|
|
127
|
+
const diary = service.heatKernelDiary({
|
|
128
|
+
text: [kernel.text, cleanup.text].filter(Boolean).join('\n'),
|
|
129
|
+
sources: [...(kernel.sources || []), ...cleanup.sources],
|
|
130
|
+
});
|
|
131
|
+
const after = service.signalsManager.load().signals.length;
|
|
132
|
+
process.stdout.write(
|
|
133
|
+
`${JSON.stringify({
|
|
134
|
+
before,
|
|
135
|
+
after,
|
|
136
|
+
imported: sessions.imported,
|
|
137
|
+
observed: siblings.observed,
|
|
138
|
+
heated: diary.heated,
|
|
139
|
+
})}\n`,
|
|
140
|
+
);
|
|
141
|
+
return;
|
|
142
|
+
} catch {
|
|
143
|
+
/* try next organ */
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
process.stdout.write(`${JSON.stringify({ skipped: 'no-organ' })}\n`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (!root) {
|
|
150
|
+
process.exit(0);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (mode === '--grow') {
|
|
154
|
+
await growDest(root);
|
|
155
|
+
process.exit(0);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const sessionId = mode;
|
|
10
159
|
const hookEvent = process.argv[4] || 'post_compact';
|
|
11
160
|
let signals = [];
|
|
12
161
|
try {
|
|
@@ -14,7 +163,7 @@ try {
|
|
|
14
163
|
} catch {
|
|
15
164
|
signals = [];
|
|
16
165
|
}
|
|
17
|
-
if (!
|
|
166
|
+
if (!Array.isArray(signals) || signals.length === 0) {
|
|
18
167
|
process.exit(0);
|
|
19
168
|
}
|
|
20
169
|
|
|
@@ -32,19 +32,19 @@ function providerCandidates() {
|
|
|
32
32
|
: join(root, routing.module_path)
|
|
33
33
|
: null;
|
|
34
34
|
const raw = [
|
|
35
|
-
join(root, '..', 'repertoire', 'dist', 'provider', 'memory-routing-provider.js'),
|
|
36
|
-
join(root, 'node_modules', '@0xray', 'repertoire', 'dist', 'provider', 'memory-routing-provider.js'),
|
|
37
35
|
configured,
|
|
36
|
+
join(root, 'node_modules', '@0xray', 'repertoire', 'dist', 'provider', 'memory-routing-provider.js'),
|
|
38
37
|
join(root, 'vendor', '@0xray', 'repertoire', 'dist', 'provider', 'memory-routing-provider.js'),
|
|
38
|
+
join(root, '..', 'repertoire', 'dist', 'provider', 'memory-routing-provider.js'),
|
|
39
39
|
].filter(Boolean);
|
|
40
|
-
const
|
|
41
|
-
const
|
|
40
|
+
const seen = new Set();
|
|
41
|
+
const out = [];
|
|
42
42
|
for (const dest of raw) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
if (seen.has(dest)) continue;
|
|
44
|
+
seen.add(dest);
|
|
45
|
+
out.push(dest);
|
|
46
46
|
}
|
|
47
|
-
return
|
|
47
|
+
return out;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
async function loadProvider() {
|
|
@@ -462,17 +462,16 @@ export function evaluateConstitutionGate(toolName, toolInput, ctx) {
|
|
|
462
462
|
return { allow: true };
|
|
463
463
|
}
|
|
464
464
|
export function evaluatePreToolGate(toolName, toolInput, ctx) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
465
|
+
const host = ctx.host || 'generic';
|
|
466
|
+
try {
|
|
467
|
+
maybeHeatHostStation(ctx.projectRoot, host, {
|
|
468
|
+
source: `0xray/${host}-pre-tool`,
|
|
469
|
+
sessionId: ctx.sessionId || host,
|
|
470
|
+
hookEvent: ctx.hookEvent || 'pre_tool_use',
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
/* station heat is best-effort — constitution still runs */
|
|
476
475
|
}
|
|
477
476
|
const constitution = evaluateConstitutionGate(toolName, toolInput, ctx);
|
|
478
477
|
if (!constitution.allow)
|
|
@@ -111,7 +111,11 @@ export function maybeHeatHostStation(projectRoot, host, extra = {}) {
|
|
|
111
111
|
const existingSessionId = concreteSessionId(existing.sessionId);
|
|
112
112
|
const sameHost = existing.host === host;
|
|
113
113
|
const sameSession = existingSessionId !== null && sessionId !== null && existingSessionId === sessionId;
|
|
114
|
-
if (sameHost &&
|
|
114
|
+
if (sameHost &&
|
|
115
|
+
sameSession &&
|
|
116
|
+
fs.existsSync(cardPath) &&
|
|
117
|
+
!stationHeat.stationBootNeedsRefresh(existing, projectRoot, host)) {
|
|
118
|
+
stationHeat.heatLiveMemory(projectRoot);
|
|
115
119
|
return bootPath;
|
|
116
120
|
}
|
|
117
121
|
return writeSuitSessionBoot(projectRoot, host, extra);
|
package/package.json
CHANGED
|
@@ -92,7 +92,7 @@ function assertOrganRequire(tmpRoot) {
|
|
|
92
92
|
if (organPkg.name !== "@0xray/repertoire") {
|
|
93
93
|
throw new Error(`required organ name ${organPkg.name}`);
|
|
94
94
|
}
|
|
95
|
-
if (organPkg.version !== "0.2.
|
|
95
|
+
if (organPkg.version !== "0.2.5") {
|
|
96
96
|
throw new Error(`required organ version ${organPkg.version}`);
|
|
97
97
|
}
|
|
98
98
|
if (fs.existsSync(path.join(tmpRoot, "vendor"))) {
|
|
@@ -165,8 +165,8 @@ function assertFreshInstallDefaults(tmpRoot, version) {
|
|
|
165
165
|
throw new Error("vendored @0xray/repertoire missing from fresh tarball install");
|
|
166
166
|
}
|
|
167
167
|
const organ = JSON.parse(fs.readFileSync(organPkg, "utf-8"));
|
|
168
|
-
if (organ.version !== "0.2.
|
|
169
|
-
throw new Error(`expected organ 0.2.
|
|
168
|
+
if (organ.version !== "0.2.5") {
|
|
169
|
+
throw new Error(`expected organ 0.2.5, got ${organ.version}`);
|
|
170
170
|
}
|
|
171
171
|
console.log(" ✅ .xray/features.json fresh-install defaults (opt-in off)");
|
|
172
172
|
return { consumerFeaturesPath, features };
|
|
@@ -37,6 +37,41 @@ function destIsUsableRepertoire(dest) {
|
|
|
37
37
|
return repertoirePackageName(dest) === "@0xray/repertoire";
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
function packageVersion(dir) {
|
|
41
|
+
try {
|
|
42
|
+
const version = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8")).version;
|
|
43
|
+
return typeof version === "string" ? version : "0.0.0";
|
|
44
|
+
} catch {
|
|
45
|
+
return "0.0.0";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function versionLessThan(left, right) {
|
|
50
|
+
const a = String(left || "0").split(".").map((n) => Number.parseInt(n, 10) || 0);
|
|
51
|
+
const b = String(right || "0").split(".").map((n) => Number.parseInt(n, 10) || 0);
|
|
52
|
+
const n = Math.max(a.length, b.length);
|
|
53
|
+
for (let i = 0; i < n; i += 1) {
|
|
54
|
+
const av = a[i] || 0;
|
|
55
|
+
const bv = b[i] || 0;
|
|
56
|
+
if (av < bv) return true;
|
|
57
|
+
if (av > bv) return false;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function removeDestTree(dest) {
|
|
63
|
+
try {
|
|
64
|
+
const st = fs.lstatSync(dest);
|
|
65
|
+
if (st.isSymbolicLink()) {
|
|
66
|
+
fs.unlinkSync(dest);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
73
|
+
}
|
|
74
|
+
|
|
40
75
|
function removeBrokenDest(dest) {
|
|
41
76
|
try {
|
|
42
77
|
const st = fs.lstatSync(dest);
|
|
@@ -51,7 +86,10 @@ function removeBrokenDest(dest) {
|
|
|
51
86
|
function wearOne(vendor, dest, log) {
|
|
52
87
|
removeBrokenDest(dest);
|
|
53
88
|
if (destAlreadyWorn(dest, vendor)) return true;
|
|
54
|
-
if (fs.existsSync(dest) && destIsUsableRepertoire(dest))
|
|
89
|
+
if (fs.existsSync(dest) && destIsUsableRepertoire(dest)) {
|
|
90
|
+
if (!versionLessThan(packageVersion(dest), packageVersion(vendor))) return true;
|
|
91
|
+
removeDestTree(dest);
|
|
92
|
+
}
|
|
55
93
|
|
|
56
94
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
57
95
|
const rel = path.relative(path.dirname(dest), vendor);
|
|
@@ -74,9 +74,11 @@ Configure in `.xray/features.json`:
|
|
|
74
74
|
"memory_routing": {
|
|
75
75
|
"enabled": true,
|
|
76
76
|
"provider": "repertoire",
|
|
77
|
-
"module_path": "
|
|
77
|
+
"module_path": "./dist/provider/memory-routing-provider.js",
|
|
78
78
|
"config": {
|
|
79
|
-
"signalsPath": "
|
|
79
|
+
"signalsPath": ".xray/state/repertoire/curated_signals.json",
|
|
80
|
+
"statePath": ".xray/state/repertoire/inference-state.json",
|
|
81
|
+
"feedbackDir": ".xray/state/repertoire/feedback"
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
```
|
|
@@ -94,6 +96,10 @@ Without Repertoire: `{ "enabled": false, "provider": "null" }`.
|
|
|
94
96
|
|
|
95
97
|
Tools: `repertoire__get_task_confidence`, `repertoire__get_high_confidence_signals`, `repertoire__search_primitives`, `repertoire__ingest_feedback`.
|
|
96
98
|
|
|
99
|
+
Factory seed (`data/curated_signals.json`) is read-only (8 names). `data/stack-overlay.json` merges into the project copy on hydrate so stack language survives a new clone. `data/subject-overlay.json` merges after that so dest knows what each organ/hangar is. `reloadOpProc` is factory + stack only. Live writes hydrate `.xray/state/repertoire/` even when cwd is this organ repo. Do not pin 0.1.8. Station is the survive-the-cut card — not this organ.
|
|
100
|
+
|
|
101
|
+
Lead cadence lives in worn 0xRay (`grok-bot/ops/LEAD-CADENCE.md` + `orchestrator` skill). Project-local names `lead-cadence-syncopation`, `live-loop-not-pacer`, `peer-wears-without-commands` must route on this copy. A peer continues from Station + these names — no command stream.
|
|
102
|
+
|
|
97
103
|
## Codex OS (always on — not optional)
|
|
98
104
|
|
|
99
105
|
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.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Factory memory organ for [0xRay](https://github.com/0xRayAI/xray): seed primitives, in-process memory routing, extra MCP (not an 8th `xray-*` server).
|
|
4
4
|
|
|
5
|
-
**v0.2.
|
|
5
|
+
**v0.2.5** · 0xRay **4.0** wear. Runtime does **not** depend on `0xray` (optional peer for suit-verify scripts).
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -43,13 +43,17 @@ Default operating model: **`autonomy-command`** — lead dev, phased todos, suba
|
|
|
43
43
|
}
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Bundled `data/curated_signals.json` is
|
|
46
|
+
Bundled `data/curated_signals.json` is **read-only** (8 factory trap names). `data/stack-overlay.json` is the committed stack-language overlay (OP-PROC). `data/subject-overlay.json` is what each workspace organ/hangar *is*. The provider hydrates a project copy under `.xray/state/repertoire/curated_signals.json` (seed + stack + subject) — including when cwd is this organ repo. Feedback never writes the tarball seed. Do not pin 0.1.8.
|
|
47
|
+
|
|
48
|
+
Override with env:
|
|
47
49
|
|
|
48
50
|
| Env | Default |
|
|
49
51
|
|-----|---------|
|
|
50
|
-
| `CURATED_SIGNALS_PATH` |
|
|
51
|
-
| `REPERTOIRE_DATA_DIR` |
|
|
52
|
-
| `
|
|
52
|
+
| `CURATED_SIGNALS_PATH` | factory seed (hydrated to `.xray/state/repertoire/curated_signals.json`) |
|
|
53
|
+
| `REPERTOIRE_DATA_DIR` | `.xray/state/repertoire` |
|
|
54
|
+
| `REPERTOIRE_STATE_PATH` | `.xray/state/repertoire/inference-state.json` |
|
|
55
|
+
| `REPERTOIRE_LOG_DIR` | `.xray/state/repertoire/logs` |
|
|
56
|
+
| `REPERTOIRE_FEEDBACK_DIR` | `.xray/state/repertoire/feedback` |
|
|
53
57
|
|
|
54
58
|
### Tools
|
|
55
59
|
|
|
@@ -60,6 +64,8 @@ Bundled `data/curated_signals.json` is used by default. Override with env:
|
|
|
60
64
|
| `repertoire__get_high_confidence_signals` | Validated signals above threshold |
|
|
61
65
|
| `repertoire__ingest_feedback` | Record orchestrator outcomes |
|
|
62
66
|
|
|
67
|
+
Routing confidence is **time-weighted**: excess above the 0.55 gate fades after a 14-day grace (60-day half-life). Factory seed sitting on the gate keeps routing. `npm run signals:hygiene` reports decay on the hydrated project copy under `.xray/state/repertoire/`; it dry-runs in this repo unless `--i-mean-it` (writes the project copy, never the tarball).
|
|
68
|
+
|
|
63
69
|
## 0xRay memory routing (in-process)
|
|
64
70
|
|
|
65
71
|
In `.xray/features.json` or `xray/features.json`:
|
|
@@ -76,8 +82,10 @@ In `.xray/features.json` or `xray/features.json`:
|
|
|
76
82
|
|
|
77
83
|
```json
|
|
78
84
|
"config": {
|
|
79
|
-
"signalsPath": ".xray/curated_signals.json",
|
|
80
|
-
"
|
|
85
|
+
"signalsPath": ".xray/state/repertoire/curated_signals.json",
|
|
86
|
+
"statePath": ".xray/state/repertoire/inference-state.json",
|
|
87
|
+
"feedbackDir": ".xray/state/repertoire/feedback",
|
|
88
|
+
"logDir": ".xray/state/repertoire/logs"
|
|
81
89
|
}
|
|
82
90
|
```
|
|
83
91
|
|
|
@@ -98,7 +106,26 @@ provider.getTaskConfidence?.({
|
|
|
98
106
|
|
|
99
107
|
## Field actuation add-ons (optional)
|
|
100
108
|
|
|
101
|
-
Repertoire has **no Moltbook dependency**. It ingests **enriched JSONL** from
|
|
109
|
+
Repertoire has **no Moltbook dependency**. It ingests **enriched JSONL** from an **explicit** producer (`matched_primitives` + `match_confidence`) and can grow the project dest — unknown primitives that pass the 0.55 gate are proposed as `field-observed`. **Groover is not Repertoire.** Groover was a broken experiment of how this organ was supposed to work. Do not treat Groover field (145-name `repertoire-brain`, sibling inference JSONL) as the dest becoming real. The factory seed stays 8 names. Do not pin `0.1.8`.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
REPERTOIRE_FIELD_LOGS=/path/to/this-project/enriched npm run ingest
|
|
113
|
+
npm run health:repertoire
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`ingest` without `--path` and `--source groover` reads `REPERTOIRE_FIELD_LOGS` only. It does **not** walk `../groover/`. Health reads `.xray/state/repertoire/`, not the package tarball.
|
|
117
|
+
|
|
118
|
+
## Compact reload (the 37 overlay names are OP-PROC)
|
|
119
|
+
|
|
120
|
+
Station is the ticket. The overlay names (`station-survives-the-cut`, `repertoire-is-long-running-kb`, `compact-rekey-from-disk`, …) are the operating procedure.
|
|
121
|
+
|
|
122
|
+
After compact the suit reloads OP-PROC by hydrating `.xray/state/repertoire/curated_signals.json` and reading that dest — not by restating commands and not by dumping names onto `STATION.md`. `reloadOpProc()` is that snapshot. 0xRay heat writes the same names onto `.xray/state/repertoire-working.json`.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npm run ingest -- --source xray
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Walks `docs/inference` / `.xray/inference` `session-*.json` on this project and suited siblings. Grows dest from session-capture. Heats overlay names that already live on dest. `REPERTOIRE_XRAY_LOGS` is an explicit extra colon list.
|
|
102
129
|
|
|
103
130
|
Each project activates its own public field surface if it wants one:
|
|
104
131
|
|