test: harden reporting-governance package boundaries
This commit is contained in:
@@ -1,17 +1,11 @@
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
const packageRoot = path.resolve(import.meta.dirname, '..', '..');
|
||||
const repoRoot = path.resolve(packageRoot, '..', '..');
|
||||
|
||||
export function resolveRepoPath(...segments) {
|
||||
return path.join(repoRoot, ...segments);
|
||||
}
|
||||
import { createRuntimeBinding, packageRoot, repoRoot, resolveRepoPath } from './runtime-binding.mjs';
|
||||
|
||||
export function runNodeScript(scriptPath, args = [], options = {}) {
|
||||
const runtimeBinding = options.runtimeBinding ?? createRuntimeBinding(options);
|
||||
return spawnSync(process.execPath, [scriptPath, ...args], {
|
||||
cwd: repoRoot,
|
||||
cwd: runtimeBinding.cwd,
|
||||
encoding: 'utf8',
|
||||
...options,
|
||||
});
|
||||
@@ -32,4 +26,4 @@ export function parseJsonStdout(label, result) {
|
||||
}
|
||||
}
|
||||
|
||||
export { packageRoot, repoRoot };
|
||||
export { packageRoot, repoRoot, resolveRepoPath };
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
import path from 'node:path';
|
||||
import { ensureSuccess, parseJsonStdout, resolveRepoPath, runNodeScript } from './_script-runner.mjs';
|
||||
|
||||
const DEFAULT_SCRIPT = resolveRepoPath('scripts', 'operator_notify_bridge_supervisor.mjs');
|
||||
const DEFAULT_DISPATCHER_SCRIPT = resolveRepoPath('scripts', 'operator_notify_dispatcher.mjs');
|
||||
import { ensureSuccess, parseJsonStdout, runNodeScript } from './_script-runner.mjs';
|
||||
import { createRuntimeBinding, resolveScriptPath } from './runtime-binding.mjs';
|
||||
|
||||
export function runBridgeSupervisorAdapter({
|
||||
scriptPath = DEFAULT_SCRIPT,
|
||||
scriptPath = null,
|
||||
runtimeBinding = null,
|
||||
spoolDir,
|
||||
queueDir,
|
||||
receiptDir,
|
||||
dispatcherScript = DEFAULT_DISPATCHER_SCRIPT,
|
||||
dispatcherScript = null,
|
||||
senderCommand = null,
|
||||
now = null,
|
||||
compact = true,
|
||||
dryRun = false,
|
||||
} = {}) {
|
||||
const binding = runtimeBinding ?? createRuntimeBinding();
|
||||
const resolvedScriptPath = path.resolve(scriptPath ?? resolveScriptPath('bridgeSupervisor', { runtimeBinding: binding }));
|
||||
const resolvedDispatcherScript = path.resolve(dispatcherScript ?? resolveScriptPath('dispatcher', { runtimeBinding: binding }));
|
||||
|
||||
const args = [];
|
||||
if (spoolDir) args.push('--spool-dir', path.resolve(spoolDir));
|
||||
if (queueDir) args.push('--queue-dir', path.resolve(queueDir));
|
||||
if (receiptDir) args.push('--receipt-dir', path.resolve(receiptDir));
|
||||
if (dispatcherScript) args.push('--dispatcher-script', path.resolve(dispatcherScript));
|
||||
if (resolvedDispatcherScript) args.push('--dispatcher-script', resolvedDispatcherScript);
|
||||
if (senderCommand) args.push('--sender-command', senderCommand);
|
||||
if (now) args.push('--now', now);
|
||||
if (dryRun) args.push('--dry-run');
|
||||
if (compact) args.push('--compact');
|
||||
|
||||
const result = runNodeScript(path.resolve(scriptPath), args);
|
||||
const result = runNodeScript(resolvedScriptPath, args, { runtimeBinding: binding });
|
||||
ensureSuccess('bridge supervisor adapter', result);
|
||||
return parseJsonStdout('bridge supervisor adapter', result);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import path from 'node:path';
|
||||
import { ensureSuccess, parseJsonStdout, resolveRepoPath, runNodeScript } from './_script-runner.mjs';
|
||||
|
||||
const DEFAULT_SCRIPT = resolveRepoPath('scripts', 'operator_notify_dispatcher.mjs');
|
||||
import { ensureSuccess, parseJsonStdout, runNodeScript } from './_script-runner.mjs';
|
||||
import { createRuntimeBinding, resolveScriptPath } from './runtime-binding.mjs';
|
||||
|
||||
export function runDispatcherAdapter({
|
||||
scriptPath = DEFAULT_SCRIPT,
|
||||
scriptPath = null,
|
||||
runtimeBinding = null,
|
||||
queueDir,
|
||||
spoolDir,
|
||||
now = null,
|
||||
@@ -14,6 +14,9 @@ export function runDispatcherAdapter({
|
||||
block = null,
|
||||
note = null,
|
||||
} = {}) {
|
||||
const binding = runtimeBinding ?? createRuntimeBinding();
|
||||
const resolvedScriptPath = path.resolve(scriptPath ?? resolveScriptPath('dispatcher', { runtimeBinding: binding }));
|
||||
|
||||
const args = [];
|
||||
if (queueDir) args.push('--queue-dir', path.resolve(queueDir));
|
||||
if (spoolDir) args.push('--spool-dir', path.resolve(spoolDir));
|
||||
@@ -24,7 +27,7 @@ export function runDispatcherAdapter({
|
||||
if (note) args.push('--note', note);
|
||||
if (compact) args.push('--compact');
|
||||
|
||||
const result = runNodeScript(path.resolve(scriptPath), args);
|
||||
const result = runNodeScript(resolvedScriptPath, args, { runtimeBinding: binding });
|
||||
ensureSuccess('dispatcher adapter', result);
|
||||
return parseJsonStdout('dispatcher adapter', result);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export { createRuntimeBinding, resolveScriptPath, SCRIPT_ENV_KEYS, SCRIPT_NAMES } from './runtime-binding.mjs';
|
||||
export { runWatchdogAdapter } from './watchdog.mjs';
|
||||
export { runDispatcherAdapter } from './dispatcher.mjs';
|
||||
export { runBridgeSupervisorAdapter } from './bridge-supervisor.mjs';
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import path from 'node:path';
|
||||
import { ensureSuccess, parseJsonStdout, resolveRepoPath, runNodeScript } from './_script-runner.mjs';
|
||||
|
||||
const DEFAULT_SCRIPT = resolveRepoPath('scripts', 'watchdog_auto_notify_orchestrator.mjs');
|
||||
const DEFAULT_WATCHDOG_SCRIPT = resolveRepoPath('scripts', 'long_task_watchdog.mjs');
|
||||
const DEFAULT_DISPATCHER_SCRIPT = resolveRepoPath('scripts', 'operator_notify_dispatcher.mjs');
|
||||
const DEFAULT_SUPERVISOR_SCRIPT = resolveRepoPath('scripts', 'operator_notify_bridge_supervisor.mjs');
|
||||
import { ensureSuccess, parseJsonStdout, runNodeScript } from './_script-runner.mjs';
|
||||
import { createRuntimeBinding, resolveScriptPath } from './runtime-binding.mjs';
|
||||
|
||||
export function runOrchestratorAdapter({
|
||||
scriptPath = DEFAULT_SCRIPT,
|
||||
scriptPath = null,
|
||||
runtimeBinding = null,
|
||||
state,
|
||||
evidenceDir,
|
||||
eventDir,
|
||||
queueDir,
|
||||
spoolDir,
|
||||
receiptDir,
|
||||
watchdogScript = DEFAULT_WATCHDOG_SCRIPT,
|
||||
dispatcherScript = DEFAULT_DISPATCHER_SCRIPT,
|
||||
supervisorScript = DEFAULT_SUPERVISOR_SCRIPT,
|
||||
watchdogScript = null,
|
||||
dispatcherScript = null,
|
||||
supervisorScript = null,
|
||||
senderCommand = null,
|
||||
senderMode = null,
|
||||
openclawBin = 'openclaw',
|
||||
@@ -26,6 +23,12 @@ export function runOrchestratorAdapter({
|
||||
claim = false,
|
||||
dryRun = false,
|
||||
} = {}) {
|
||||
const binding = runtimeBinding ?? createRuntimeBinding();
|
||||
const resolvedScriptPath = path.resolve(scriptPath ?? resolveScriptPath('orchestrator', { runtimeBinding: binding }));
|
||||
const resolvedWatchdogScript = path.resolve(watchdogScript ?? resolveScriptPath('watchdog', { runtimeBinding: binding }));
|
||||
const resolvedDispatcherScript = path.resolve(dispatcherScript ?? resolveScriptPath('dispatcher', { runtimeBinding: binding }));
|
||||
const resolvedSupervisorScript = path.resolve(supervisorScript ?? resolveScriptPath('bridgeSupervisor', { runtimeBinding: binding }));
|
||||
|
||||
const args = [];
|
||||
if (state) args.push('--state', path.resolve(state));
|
||||
if (evidenceDir) args.push('--evidence-dir', path.resolve(evidenceDir));
|
||||
@@ -33,9 +36,9 @@ export function runOrchestratorAdapter({
|
||||
if (queueDir) args.push('--queue-dir', path.resolve(queueDir));
|
||||
if (spoolDir) args.push('--spool-dir', path.resolve(spoolDir));
|
||||
if (receiptDir) args.push('--receipt-dir', path.resolve(receiptDir));
|
||||
if (watchdogScript) args.push('--watchdog-script', path.resolve(watchdogScript));
|
||||
if (dispatcherScript) args.push('--dispatcher-script', path.resolve(dispatcherScript));
|
||||
if (supervisorScript) args.push('--supervisor-script', path.resolve(supervisorScript));
|
||||
if (resolvedWatchdogScript) args.push('--watchdog-script', resolvedWatchdogScript);
|
||||
if (resolvedDispatcherScript) args.push('--dispatcher-script', resolvedDispatcherScript);
|
||||
if (resolvedSupervisorScript) args.push('--supervisor-script', resolvedSupervisorScript);
|
||||
if (senderCommand) args.push('--sender-command', senderCommand);
|
||||
if (senderMode) args.push('--sender-mode', senderMode);
|
||||
if (openclawBin) args.push('--openclaw-bin', openclawBin);
|
||||
@@ -45,7 +48,7 @@ export function runOrchestratorAdapter({
|
||||
if (dryRun) args.push('--dry-run');
|
||||
if (compact) args.push('--compact');
|
||||
|
||||
const result = runNodeScript(path.resolve(scriptPath), args);
|
||||
const result = runNodeScript(resolvedScriptPath, args, { runtimeBinding: binding });
|
||||
ensureSuccess('orchestrator adapter', result);
|
||||
return parseJsonStdout('orchestrator adapter', result);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
|
||||
const ENV_PREFIX = 'OPENCLAW_REPORTING_GOVERNANCE_';
|
||||
|
||||
const packageRoot = path.resolve(import.meta.dirname, '..', '..');
|
||||
const repoRoot = path.resolve(packageRoot, '..', '..');
|
||||
|
||||
const SCRIPT_NAMES = {
|
||||
watchdog: 'long_task_watchdog.mjs',
|
||||
dispatcher: 'operator_notify_dispatcher.mjs',
|
||||
bridgeSupervisor: 'operator_notify_bridge_supervisor.mjs',
|
||||
senderBinding: 'operator_notify_sender_binding.mjs',
|
||||
orchestrator: 'watchdog_auto_notify_orchestrator.mjs',
|
||||
};
|
||||
|
||||
const SCRIPT_ENV_KEYS = {
|
||||
watchdog: `${ENV_PREFIX}WATCHDOG_SCRIPT`,
|
||||
dispatcher: `${ENV_PREFIX}DISPATCHER_SCRIPT`,
|
||||
bridgeSupervisor: `${ENV_PREFIX}BRIDGE_SUPERVISOR_SCRIPT`,
|
||||
senderBinding: `${ENV_PREFIX}SENDER_BINDING_SCRIPT`,
|
||||
orchestrator: `${ENV_PREFIX}ORCHESTRATOR_SCRIPT`,
|
||||
};
|
||||
|
||||
function normalizeString(value) {
|
||||
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
||||
}
|
||||
|
||||
export function resolveRepoPath(...segments) {
|
||||
return path.join(repoRoot, ...segments);
|
||||
}
|
||||
|
||||
export function createRuntimeBinding(overrides = {}) {
|
||||
const scripts = {};
|
||||
|
||||
for (const [key, fileName] of Object.entries(SCRIPT_NAMES)) {
|
||||
const envValue = normalizeString(process.env[SCRIPT_ENV_KEYS[key]]);
|
||||
const overrideValue = normalizeString(overrides?.scripts?.[key]);
|
||||
scripts[key] = path.resolve(overrideValue ?? envValue ?? resolveRepoPath('scripts', fileName));
|
||||
}
|
||||
|
||||
return {
|
||||
packageRoot,
|
||||
repoRoot,
|
||||
cwd: path.resolve(normalizeString(overrides.cwd) ?? repoRoot),
|
||||
scripts,
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveScriptPath(name, options = {}) {
|
||||
const runtimeBinding = options.runtimeBinding ?? createRuntimeBinding(options);
|
||||
const scriptPath = runtimeBinding?.scripts?.[name];
|
||||
if (!scriptPath) {
|
||||
throw new Error(`unknown runtime binding script: ${name}`);
|
||||
}
|
||||
return path.resolve(scriptPath);
|
||||
}
|
||||
|
||||
export { packageRoot, repoRoot, SCRIPT_ENV_KEYS, SCRIPT_NAMES };
|
||||
@@ -1,10 +1,11 @@
|
||||
import path from 'node:path';
|
||||
import { ensureSuccess, parseJsonStdout, resolveRepoPath, runNodeScript } from './_script-runner.mjs';
|
||||
|
||||
const DEFAULT_SCRIPT = resolveRepoPath('scripts', 'operator_notify_sender_binding.mjs');
|
||||
import process from 'node:process';
|
||||
import { ensureSuccess, parseJsonStdout, runNodeScript } from './_script-runner.mjs';
|
||||
import { createRuntimeBinding, resolveScriptPath } from './runtime-binding.mjs';
|
||||
|
||||
export function runSenderBindingAdapter({
|
||||
scriptPath = DEFAULT_SCRIPT,
|
||||
scriptPath = null,
|
||||
runtimeBinding = null,
|
||||
mode = 'shim',
|
||||
attemptDir,
|
||||
openclawBin = 'openclaw',
|
||||
@@ -12,16 +13,20 @@ export function runSenderBindingAdapter({
|
||||
compact = true,
|
||||
env = {},
|
||||
} = {}) {
|
||||
const binding = runtimeBinding ?? createRuntimeBinding();
|
||||
const resolvedScriptPath = path.resolve(scriptPath ?? resolveScriptPath('senderBinding', { runtimeBinding: binding }));
|
||||
|
||||
const args = ['--mode', mode, '--openclaw-bin', openclawBin];
|
||||
if (attemptDir) args.push('--attempt-dir', path.resolve(attemptDir));
|
||||
if (now) args.push('--now', now);
|
||||
if (compact) args.push('--compact');
|
||||
|
||||
const result = runNodeScript(path.resolve(scriptPath), args, {
|
||||
const result = runNodeScript(resolvedScriptPath, args, {
|
||||
env: {
|
||||
...process.env,
|
||||
...env,
|
||||
},
|
||||
runtimeBinding: binding,
|
||||
});
|
||||
ensureSuccess('sender binding adapter', result);
|
||||
return parseJsonStdout('sender binding adapter', result);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import path from 'node:path';
|
||||
import { ensureSuccess, parseJsonStdout, resolveRepoPath, runNodeScript } from './_script-runner.mjs';
|
||||
|
||||
const DEFAULT_SCRIPT = resolveRepoPath('scripts', 'long_task_watchdog.mjs');
|
||||
import { ensureSuccess, parseJsonStdout, runNodeScript } from './_script-runner.mjs';
|
||||
import { createRuntimeBinding, resolveScriptPath } from './runtime-binding.mjs';
|
||||
|
||||
export function runWatchdogAdapter({
|
||||
scriptPath = DEFAULT_SCRIPT,
|
||||
scriptPath = null,
|
||||
runtimeBinding = null,
|
||||
state,
|
||||
evidenceDir,
|
||||
eventDir,
|
||||
@@ -13,6 +13,9 @@ export function runWatchdogAdapter({
|
||||
compact = true,
|
||||
writeState = false,
|
||||
} = {}) {
|
||||
const binding = runtimeBinding ?? createRuntimeBinding();
|
||||
const resolvedScriptPath = path.resolve(scriptPath ?? resolveScriptPath('watchdog', { runtimeBinding: binding }));
|
||||
|
||||
const args = [];
|
||||
if (state) args.push('--state', path.resolve(state));
|
||||
if (evidenceDir) args.push('--evidence-dir', path.resolve(evidenceDir));
|
||||
@@ -22,7 +25,7 @@ export function runWatchdogAdapter({
|
||||
if (writeState) args.push('--write-state');
|
||||
if (compact) args.push('--compact');
|
||||
|
||||
const result = runNodeScript(path.resolve(scriptPath), args);
|
||||
const result = runNodeScript(resolvedScriptPath, args, { runtimeBinding: binding });
|
||||
ensureSuccess('watchdog adapter', result);
|
||||
return parseJsonStdout('watchdog adapter', result);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ export const packageBoundaries = {
|
||||
|
||||
export { evaluatePolicyPack, evaluatePolicies, planDecisionExecution } from './core/index.mjs';
|
||||
export {
|
||||
createRuntimeBinding,
|
||||
resolveScriptPath,
|
||||
SCRIPT_ENV_KEYS,
|
||||
SCRIPT_NAMES,
|
||||
runWatchdogAdapter,
|
||||
runDispatcherAdapter,
|
||||
runBridgeSupervisorAdapter,
|
||||
|
||||
Reference in New Issue
Block a user