4runr-os 2.10.68 → 2.10.70
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/apps/gateway/dist/apps/gateway/src/db/docker-manager.d.ts +4 -0
- package/apps/gateway/dist/apps/gateway/src/db/docker-manager.d.ts.map +1 -1
- package/apps/gateway/dist/apps/gateway/src/db/docker-manager.js +55 -45
- package/apps/gateway/dist/apps/gateway/src/db/docker-manager.js.map +1 -1
- package/apps/gateway/dist/apps/gateway/src/db/init.d.ts.map +1 -1
- package/apps/gateway/dist/apps/gateway/src/db/init.js +4 -11
- package/apps/gateway/dist/apps/gateway/src/db/init.js.map +1 -1
- package/apps/gateway/docker-compose.local.yml +2 -0
- package/apps/gateway/package-lock.json +3 -3
- package/apps/gateway/scripts/verify-sentinel-persist.mjs +81 -81
- package/apps/gateway/src/__tests__/sentinel-config-persist-http.test.ts +93 -93
- package/apps/gateway/src/__tests__/sentinel-config-store.test.ts +133 -133
- package/apps/gateway/src/db/docker-manager.ts +98 -62
- package/apps/gateway/src/db/init.ts +9 -15
- package/apps/gateway/src/security/sentinel-config-store.ts +208 -208
- package/dist/tui-handlers.js +129 -23
- package/dist/tui-handlers.js.map +1 -1
- package/dist/watchdog.js +2 -2
- package/dist/watchdog.js.map +1 -1
- package/mk3-tui/binaries/win32-x64/mk3-tui.exe +0 -0
- package/package.json +2 -2
- package/scripts/os-tools-smoke.cjs +1 -1
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
export declare const FOURRUNR_DB_CONTAINERS: readonly ["4runr-postgres", "4runr-redis"];
|
|
1
2
|
export declare function isDockerAvailable(): Promise<boolean>;
|
|
2
3
|
export declare function isDockerRunning(): Promise<boolean>;
|
|
4
|
+
export declare function isContainerRunning(containerName: string): boolean;
|
|
3
5
|
export declare function areContainersRunning(): Promise<boolean>;
|
|
6
|
+
export declare function startStoppedContainers(): Promise<void>;
|
|
4
7
|
export declare function startDockerCompose(composeFilePath: string): Promise<void>;
|
|
8
|
+
export declare function ensure4RunrStackRunning(composeFilePath: string): Promise<void>;
|
|
5
9
|
export declare function stopDockerCompose(composeFilePath: string): Promise<void>;
|
|
6
10
|
export declare function stop4RunrContainers(): Promise<void>;
|
|
7
11
|
export declare function waitForHealthy(containerName: string, timeoutMs?: number): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker-manager.d.ts","sourceRoot":"","sources":["../../../../../src/db/docker-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"docker-manager.d.ts","sourceRoot":"","sources":["../../../../../src/db/docker-manager.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,sBAAsB,4CAA6C,CAAC;AAqBjF,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO1D;AAKD,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAOxD;AAKD,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAUjE;AAKD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE7D;AAKD,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAW5D;AAMD,wBAAsB,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO/E;AAKD,wBAAsB,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASpF;AAMD,wBAAsB,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM9E;AAKD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBzD;AAOD,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,GAAE,MAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCpG;AAMD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhE;AAOD,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAMlF;AAYD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CA0B7D"}
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
|
+
export const FOURRUNR_DB_CONTAINERS = ['4runr-postgres', '4runr-redis'];
|
|
3
|
+
const COMPOSE_PROJECT = '4runr';
|
|
4
|
+
function dockerShell() {
|
|
5
|
+
return process.platform === 'win32' ? process.env['COMSPEC'] || 'cmd.exe' : undefined;
|
|
6
|
+
}
|
|
7
|
+
function dockerExec(command, timeoutMs = 30000) {
|
|
8
|
+
return execSync(command, {
|
|
9
|
+
encoding: 'utf-8',
|
|
10
|
+
stdio: 'pipe',
|
|
11
|
+
timeout: timeoutMs,
|
|
12
|
+
...(dockerShell() ? { shell: dockerShell() } : {}),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
2
15
|
export async function isDockerAvailable() {
|
|
3
16
|
try {
|
|
4
|
-
const result =
|
|
5
|
-
encoding: 'utf-8',
|
|
6
|
-
stdio: 'pipe',
|
|
7
|
-
timeout: 5000
|
|
8
|
-
});
|
|
17
|
+
const result = dockerExec('docker --version', 5000);
|
|
9
18
|
return result.includes('Docker version');
|
|
10
19
|
}
|
|
11
20
|
catch {
|
|
@@ -14,40 +23,56 @@ export async function isDockerAvailable() {
|
|
|
14
23
|
}
|
|
15
24
|
export async function isDockerRunning() {
|
|
16
25
|
try {
|
|
17
|
-
|
|
18
|
-
encoding: 'utf-8',
|
|
19
|
-
stdio: 'pipe',
|
|
20
|
-
timeout: 5000
|
|
21
|
-
});
|
|
26
|
+
dockerExec('docker info', 5000);
|
|
22
27
|
return true;
|
|
23
28
|
}
|
|
24
29
|
catch {
|
|
25
30
|
return false;
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
|
-
export
|
|
33
|
+
export function isContainerRunning(containerName) {
|
|
29
34
|
try {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
stdio: 'pipe',
|
|
33
|
-
timeout: 5000
|
|
34
|
-
});
|
|
35
|
-
return result.trim().includes('4runr-postgres');
|
|
35
|
+
const state = dockerExec(`docker inspect --format="{{.State.Running}}" ${containerName}`, 5000).trim();
|
|
36
|
+
return state === 'true';
|
|
36
37
|
}
|
|
37
38
|
catch {
|
|
38
39
|
return false;
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
export async function areContainersRunning() {
|
|
43
|
+
return FOURRUNR_DB_CONTAINERS.every((name) => isContainerRunning(name));
|
|
44
|
+
}
|
|
45
|
+
export async function startStoppedContainers() {
|
|
46
|
+
const stopped = FOURRUNR_DB_CONTAINERS.filter((name) => !isContainerRunning(name));
|
|
47
|
+
if (stopped.length === 0) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
dockerExec(`docker start ${stopped.join(' ')}`, 60000);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
}
|
|
55
|
+
}
|
|
41
56
|
export async function startDockerCompose(composeFilePath) {
|
|
42
|
-
|
|
57
|
+
const cmd = `docker compose -p ${COMPOSE_PROJECT} -f "${composeFilePath}" up -d`;
|
|
58
|
+
execSync(cmd, {
|
|
43
59
|
stdio: 'inherit',
|
|
44
|
-
timeout:
|
|
60
|
+
timeout: 120000,
|
|
61
|
+
...(dockerShell() ? { shell: dockerShell() } : {}),
|
|
45
62
|
});
|
|
46
63
|
}
|
|
64
|
+
export async function ensure4RunrStackRunning(composeFilePath) {
|
|
65
|
+
await startStoppedContainers();
|
|
66
|
+
if (!(await areContainersRunning())) {
|
|
67
|
+
await startDockerCompose(composeFilePath);
|
|
68
|
+
}
|
|
69
|
+
await startStoppedContainers();
|
|
70
|
+
}
|
|
47
71
|
export async function stopDockerCompose(composeFilePath) {
|
|
48
|
-
execSync(`docker compose -f "${composeFilePath}" stop`, {
|
|
72
|
+
execSync(`docker compose -p ${COMPOSE_PROJECT} -f "${composeFilePath}" stop`, {
|
|
49
73
|
stdio: 'pipe',
|
|
50
|
-
timeout: 30000
|
|
74
|
+
timeout: 30000,
|
|
75
|
+
...(dockerShell() ? { shell: dockerShell() } : {}),
|
|
51
76
|
});
|
|
52
77
|
}
|
|
53
78
|
export async function stop4RunrContainers() {
|
|
@@ -74,39 +99,28 @@ export async function waitForHealthy(containerName, timeoutMs = 30000) {
|
|
|
74
99
|
const start = Date.now();
|
|
75
100
|
while (Date.now() - start < timeoutMs) {
|
|
76
101
|
try {
|
|
77
|
-
const health =
|
|
78
|
-
encoding: 'utf-8',
|
|
79
|
-
stdio: 'pipe',
|
|
80
|
-
timeout: 5000
|
|
81
|
-
}).trim();
|
|
102
|
+
const health = dockerExec(`docker inspect --format="{{.State.Health.Status}}" ${containerName}`, 5000).trim();
|
|
82
103
|
if (health === 'healthy') {
|
|
83
104
|
return;
|
|
84
105
|
}
|
|
85
106
|
if (health === '' || health === '<no value>') {
|
|
86
|
-
const running =
|
|
87
|
-
encoding: 'utf-8',
|
|
88
|
-
stdio: 'pipe',
|
|
89
|
-
timeout: 5000
|
|
90
|
-
}).trim();
|
|
107
|
+
const running = dockerExec(`docker inspect --format="{{.State.Running}}" ${containerName}`, 5000).trim();
|
|
91
108
|
if (running === 'true') {
|
|
92
109
|
await sleep(2000);
|
|
93
110
|
return;
|
|
94
111
|
}
|
|
95
112
|
}
|
|
96
113
|
}
|
|
97
|
-
catch
|
|
114
|
+
catch {
|
|
98
115
|
}
|
|
99
116
|
await sleep(1000);
|
|
100
117
|
}
|
|
101
|
-
|
|
118
|
+
const logs = getContainerLogs(containerName, 20);
|
|
119
|
+
throw new Error(`Container ${containerName} did not become healthy within ${timeoutMs}ms. Recent logs:\n${logs}`);
|
|
102
120
|
}
|
|
103
121
|
export async function isPortInUse(port) {
|
|
104
122
|
try {
|
|
105
|
-
const result =
|
|
106
|
-
encoding: 'utf-8',
|
|
107
|
-
stdio: 'pipe',
|
|
108
|
-
timeout: 5000
|
|
109
|
-
});
|
|
123
|
+
const result = dockerExec(`docker ps --filter "publish=${port}" --format "{{.Names}}"`, 5000);
|
|
110
124
|
return result.trim().length > 0;
|
|
111
125
|
}
|
|
112
126
|
catch {
|
|
@@ -115,24 +129,20 @@ export async function isPortInUse(port) {
|
|
|
115
129
|
}
|
|
116
130
|
export function getContainerLogs(containerName, lines = 50) {
|
|
117
131
|
try {
|
|
118
|
-
return
|
|
119
|
-
encoding: 'utf-8',
|
|
120
|
-
stdio: 'pipe',
|
|
121
|
-
timeout: 10000
|
|
122
|
-
});
|
|
132
|
+
return dockerExec(`docker logs --tail ${lines} ${containerName}`, 10000);
|
|
123
133
|
}
|
|
124
134
|
catch (err) {
|
|
125
135
|
return `Failed to retrieve logs: ${err instanceof Error ? err.message : String(err)}`;
|
|
126
136
|
}
|
|
127
137
|
}
|
|
128
138
|
function sleep(ms) {
|
|
129
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
139
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
130
140
|
}
|
|
131
141
|
export async function getDockerStatus() {
|
|
132
142
|
const status = {
|
|
133
143
|
available: false,
|
|
134
144
|
running: false,
|
|
135
|
-
containersRunning: false
|
|
145
|
+
containersRunning: false,
|
|
136
146
|
};
|
|
137
147
|
try {
|
|
138
148
|
status.available = await isDockerAvailable();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker-manager.js","sourceRoot":"","sources":["../../../../../src/db/docker-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"docker-manager.js","sourceRoot":"","sources":["../../../../../src/db/docker-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../src/db/init.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../src/db/init.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAkB9C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAQD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgGjF;AA2ID,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB9F"}
|
|
@@ -7,7 +7,7 @@ import { PrismaClient } from '@prisma/client';
|
|
|
7
7
|
import { get4RunrDataDir } from '@4runr/shared';
|
|
8
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
9
|
const __dirname = dirname(__filename);
|
|
10
|
-
import {
|
|
10
|
+
import { ensure4RunrStackRunning, waitForHealthy, getDockerStatus } from './docker-manager.js';
|
|
11
11
|
export async function initializeDatabase(logger) {
|
|
12
12
|
const warnings = [];
|
|
13
13
|
const persistenceMode = process.env['GATEWAY_PERSISTENCE'] || 'auto';
|
|
@@ -32,15 +32,8 @@ export async function initializeDatabase(logger) {
|
|
|
32
32
|
return { mode: 'memory', client: null, warnings };
|
|
33
33
|
}
|
|
34
34
|
try {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
logger.info('Starting 4Runr Docker containers...');
|
|
38
|
-
await startDockerContainers(logger);
|
|
39
|
-
logger.info('✓ Docker containers started');
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
logger.info('✓ Docker containers already running');
|
|
43
|
-
}
|
|
35
|
+
logger.info('Ensuring 4Runr Docker containers (Postgres + Redis) are running...');
|
|
36
|
+
await startDockerContainers(logger);
|
|
44
37
|
logger.info('Waiting for database to be ready...');
|
|
45
38
|
await waitForHealthy('4runr-postgres', 60000);
|
|
46
39
|
await waitForHealthy('4runr-redis', 15000);
|
|
@@ -145,7 +138,7 @@ async function startDockerContainers(logger) {
|
|
|
145
138
|
else {
|
|
146
139
|
logger.warn(`Docker Compose template missing; using existing ${composeFilePath}`);
|
|
147
140
|
}
|
|
148
|
-
await
|
|
141
|
+
await ensure4RunrStackRunning(composeFilePath);
|
|
149
142
|
}
|
|
150
143
|
async function runMigrations(databaseUrl, logger) {
|
|
151
144
|
const candidates = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../../src/db/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../../src/db/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -2929,9 +2929,9 @@
|
|
|
2929
2929
|
"license": "MIT"
|
|
2930
2930
|
},
|
|
2931
2931
|
"node_modules/@types/node": {
|
|
2932
|
-
"version": "20.19.
|
|
2933
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.
|
|
2934
|
-
"integrity": "sha512-
|
|
2932
|
+
"version": "20.19.42",
|
|
2933
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.42.tgz",
|
|
2934
|
+
"integrity": "sha512-5L7SUaFC1RyDraj2yRhyBzHTobyXHmohD100CChNtyPyleoq37Mqab5Gn8XEKI04dfN/oqPdpHk38MgcQWHbZg==",
|
|
2935
2935
|
"license": "MIT",
|
|
2936
2936
|
"dependencies": {
|
|
2937
2937
|
"undici-types": "~6.21.0"
|
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One-shot: prove sentinel-limits.json round-trip changes Sentinel.getConfig()
|
|
3
|
-
* and policy thresholds (simulates Gateway restart without HTTP).
|
|
4
|
-
*
|
|
5
|
-
* Usage: node scripts/verify-sentinel-persist.mjs
|
|
6
|
-
*/
|
|
7
|
-
import * as fs from 'fs';
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
import * as os from 'os';
|
|
10
|
-
|
|
11
|
-
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), '4runr-persist-verify-'));
|
|
12
|
-
process.env['APPDATA'] = tmp;
|
|
13
|
-
|
|
14
|
-
const { Sentinel, policyManager } = await import('@4runr/sentinel');
|
|
15
|
-
const {
|
|
16
|
-
saveSentinelLimitsToDisk,
|
|
17
|
-
loadSentinelLimitsFromDisk,
|
|
18
|
-
applyPersistedSentinelConfig,
|
|
19
|
-
getSentinelLimitsFilePath,
|
|
20
|
-
} = await import('../dist/security/sentinel-config-store.js');
|
|
21
|
-
|
|
22
|
-
const distinctive = {
|
|
23
|
-
enabled: true,
|
|
24
|
-
runMaxDurationMs: 111_000,
|
|
25
|
-
runMaxTokens: 22_000,
|
|
26
|
-
runIdleMs: 12_345,
|
|
27
|
-
loopWindow: 9,
|
|
28
|
-
loopMax: 4,
|
|
29
|
-
runMaxCost: 2.75,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
saveSentinelLimitsToDisk(distinctive);
|
|
33
|
-
const filePath = getSentinelLimitsFilePath();
|
|
34
|
-
if (!fs.existsSync(filePath)) {
|
|
35
|
-
console.error('FAIL: file not written', filePath);
|
|
36
|
-
process.exit(1);
|
|
37
|
-
}
|
|
38
|
-
const onDisk = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
39
|
-
console.log('OK: wrote', filePath);
|
|
40
|
-
console.log(' config.runIdleMs on disk:', onDisk.config?.runIdleMs);
|
|
41
|
-
|
|
42
|
-
const loaded = loadSentinelLimitsFromDisk();
|
|
43
|
-
if (loaded?.runIdleMs !== distinctive.runIdleMs) {
|
|
44
|
-
console.error('FAIL: load from disk', loaded);
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
console.log('OK: loadSentinelLimitsFromDisk matches');
|
|
48
|
-
|
|
49
|
-
Sentinel.resetInstance();
|
|
50
|
-
const sentinel = Sentinel.getInstance();
|
|
51
|
-
const before = sentinel.getConfig().runIdleMs;
|
|
52
|
-
applyPersistedSentinelConfig(sentinel);
|
|
53
|
-
const after = sentinel.getConfig().runIdleMs;
|
|
54
|
-
if (after !== distinctive.runIdleMs) {
|
|
55
|
-
console.error('FAIL: after boot apply', { before, after, expected: distinctive.runIdleMs });
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
console.log('OK: fresh singleton after applyPersistedSentinelConfig', { before, after });
|
|
59
|
-
|
|
60
|
-
const violations = policyManager.evaluatePolicies(
|
|
61
|
-
'verify-run',
|
|
62
|
-
{
|
|
63
|
-
runId: 'verify-run',
|
|
64
|
-
createdAt: Date.now(),
|
|
65
|
-
startedAt: Date.now() - 30_000,
|
|
66
|
-
lastTokenAt: Date.now() - 30_000,
|
|
67
|
-
tokenCount: 0,
|
|
68
|
-
status: 'running',
|
|
69
|
-
events: [],
|
|
70
|
-
},
|
|
71
|
-
sentinel.getConfig()
|
|
72
|
-
);
|
|
73
|
-
const idle = violations.find((v) => v.policy === 'idle');
|
|
74
|
-
if (!idle || idle.threshold !== distinctive.runIdleMs) {
|
|
75
|
-
console.error('FAIL: policy threshold', idle);
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
console.log('OK: idle policy threshold = persisted runIdleMs', idle.threshold);
|
|
79
|
-
|
|
80
|
-
fs.rmSync(tmp, { recursive: true, force: true });
|
|
81
|
-
console.log('\nAll persistence checks passed (fundamental, not UI-only).');
|
|
1
|
+
/**
|
|
2
|
+
* One-shot: prove sentinel-limits.json round-trip changes Sentinel.getConfig()
|
|
3
|
+
* and policy thresholds (simulates Gateway restart without HTTP).
|
|
4
|
+
*
|
|
5
|
+
* Usage: node scripts/verify-sentinel-persist.mjs
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import * as os from 'os';
|
|
10
|
+
|
|
11
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), '4runr-persist-verify-'));
|
|
12
|
+
process.env['APPDATA'] = tmp;
|
|
13
|
+
|
|
14
|
+
const { Sentinel, policyManager } = await import('@4runr/sentinel');
|
|
15
|
+
const {
|
|
16
|
+
saveSentinelLimitsToDisk,
|
|
17
|
+
loadSentinelLimitsFromDisk,
|
|
18
|
+
applyPersistedSentinelConfig,
|
|
19
|
+
getSentinelLimitsFilePath,
|
|
20
|
+
} = await import('../dist/security/sentinel-config-store.js');
|
|
21
|
+
|
|
22
|
+
const distinctive = {
|
|
23
|
+
enabled: true,
|
|
24
|
+
runMaxDurationMs: 111_000,
|
|
25
|
+
runMaxTokens: 22_000,
|
|
26
|
+
runIdleMs: 12_345,
|
|
27
|
+
loopWindow: 9,
|
|
28
|
+
loopMax: 4,
|
|
29
|
+
runMaxCost: 2.75,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
saveSentinelLimitsToDisk(distinctive);
|
|
33
|
+
const filePath = getSentinelLimitsFilePath();
|
|
34
|
+
if (!fs.existsSync(filePath)) {
|
|
35
|
+
console.error('FAIL: file not written', filePath);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
const onDisk = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
39
|
+
console.log('OK: wrote', filePath);
|
|
40
|
+
console.log(' config.runIdleMs on disk:', onDisk.config?.runIdleMs);
|
|
41
|
+
|
|
42
|
+
const loaded = loadSentinelLimitsFromDisk();
|
|
43
|
+
if (loaded?.runIdleMs !== distinctive.runIdleMs) {
|
|
44
|
+
console.error('FAIL: load from disk', loaded);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
console.log('OK: loadSentinelLimitsFromDisk matches');
|
|
48
|
+
|
|
49
|
+
Sentinel.resetInstance();
|
|
50
|
+
const sentinel = Sentinel.getInstance();
|
|
51
|
+
const before = sentinel.getConfig().runIdleMs;
|
|
52
|
+
applyPersistedSentinelConfig(sentinel);
|
|
53
|
+
const after = sentinel.getConfig().runIdleMs;
|
|
54
|
+
if (after !== distinctive.runIdleMs) {
|
|
55
|
+
console.error('FAIL: after boot apply', { before, after, expected: distinctive.runIdleMs });
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
console.log('OK: fresh singleton after applyPersistedSentinelConfig', { before, after });
|
|
59
|
+
|
|
60
|
+
const violations = policyManager.evaluatePolicies(
|
|
61
|
+
'verify-run',
|
|
62
|
+
{
|
|
63
|
+
runId: 'verify-run',
|
|
64
|
+
createdAt: Date.now(),
|
|
65
|
+
startedAt: Date.now() - 30_000,
|
|
66
|
+
lastTokenAt: Date.now() - 30_000,
|
|
67
|
+
tokenCount: 0,
|
|
68
|
+
status: 'running',
|
|
69
|
+
events: [],
|
|
70
|
+
},
|
|
71
|
+
sentinel.getConfig()
|
|
72
|
+
);
|
|
73
|
+
const idle = violations.find((v) => v.policy === 'idle');
|
|
74
|
+
if (!idle || idle.threshold !== distinctive.runIdleMs) {
|
|
75
|
+
console.error('FAIL: policy threshold', idle);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
console.log('OK: idle policy threshold = persisted runIdleMs', idle.threshold);
|
|
79
|
+
|
|
80
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
81
|
+
console.log('\nAll persistence checks passed (fundamental, not UI-only).');
|