@xenosystem/acp-agent 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +22 -0
- package/dist/acpAgentServer.d.ts +43 -0
- package/dist/acpAgentServer.d.ts.map +1 -0
- package/dist/acpAgentServer.js +450 -0
- package/dist/acpAgentServer.js.map +1 -0
- package/dist/adapters/adapterContractVersion.d.ts +24 -0
- package/dist/adapters/adapterContractVersion.d.ts.map +1 -0
- package/dist/adapters/adapterContractVersion.js +29 -0
- package/dist/adapters/adapterContractVersion.js.map +1 -0
- package/dist/adapters/adapterDiagnostics.d.ts +19 -0
- package/dist/adapters/adapterDiagnostics.d.ts.map +1 -0
- package/dist/adapters/adapterDiagnostics.js +18 -0
- package/dist/adapters/adapterDiagnostics.js.map +1 -0
- package/dist/adapters/adapterErrors.d.ts +19 -0
- package/dist/adapters/adapterErrors.d.ts.map +1 -0
- package/dist/adapters/adapterErrors.js +23 -0
- package/dist/adapters/adapterErrors.js.map +1 -0
- package/dist/adapters/adapterEventMapper.d.ts +22 -0
- package/dist/adapters/adapterEventMapper.d.ts.map +1 -0
- package/dist/adapters/adapterEventMapper.js +70 -0
- package/dist/adapters/adapterEventMapper.js.map +1 -0
- package/dist/adapters/adapterEventParser.d.ts +16 -0
- package/dist/adapters/adapterEventParser.d.ts.map +1 -0
- package/dist/adapters/adapterEventParser.js +95 -0
- package/dist/adapters/adapterEventParser.js.map +1 -0
- package/dist/adapters/adapterEventProtocol.d.ts +85 -0
- package/dist/adapters/adapterEventProtocol.d.ts.map +1 -0
- package/dist/adapters/adapterEventProtocol.js +74 -0
- package/dist/adapters/adapterEventProtocol.js.map +1 -0
- package/dist/adapters/adapterFailureTaxonomy.d.ts +19 -0
- package/dist/adapters/adapterFailureTaxonomy.d.ts.map +1 -0
- package/dist/adapters/adapterFailureTaxonomy.js +62 -0
- package/dist/adapters/adapterFailureTaxonomy.js.map +1 -0
- package/dist/adapters/adapterHarnessTypes.d.ts +103 -0
- package/dist/adapters/adapterHarnessTypes.d.ts.map +1 -0
- package/dist/adapters/adapterHarnessTypes.js +15 -0
- package/dist/adapters/adapterHarnessTypes.js.map +1 -0
- package/dist/adapters/adapterProcessHarness.d.ts +23 -0
- package/dist/adapters/adapterProcessHarness.d.ts.map +1 -0
- package/dist/adapters/adapterProcessHarness.js +235 -0
- package/dist/adapters/adapterProcessHarness.js.map +1 -0
- package/dist/adapters/providerContractTypes.d.ts +64 -0
- package/dist/adapters/providerContractTypes.d.ts.map +1 -0
- package/dist/adapters/providerContractTypes.js +79 -0
- package/dist/adapters/providerContractTypes.js.map +1 -0
- package/dist/adapters/testAdapterProvider.d.ts +19 -0
- package/dist/adapters/testAdapterProvider.d.ts.map +1 -0
- package/dist/adapters/testAdapterProvider.js +95 -0
- package/dist/adapters/testAdapterProvider.js.map +1 -0
- package/dist/cli.d.ts +16 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1059 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/providerApprovalStore.d.ts +39 -0
- package/dist/config/providerApprovalStore.d.ts.map +1 -0
- package/dist/config/providerApprovalStore.js +87 -0
- package/dist/config/providerApprovalStore.js.map +1 -0
- package/dist/config/providerApprovalTypes.d.ts +30 -0
- package/dist/config/providerApprovalTypes.d.ts.map +1 -0
- package/dist/config/providerApprovalTypes.js +11 -0
- package/dist/config/providerApprovalTypes.js.map +1 -0
- package/dist/config/providerPolicyConfig.d.ts +31 -0
- package/dist/config/providerPolicyConfig.d.ts.map +1 -0
- package/dist/config/providerPolicyConfig.js +111 -0
- package/dist/config/providerPolicyConfig.js.map +1 -0
- package/dist/config/providerPolicyDiagnostics.d.ts +49 -0
- package/dist/config/providerPolicyDiagnostics.d.ts.map +1 -0
- package/dist/config/providerPolicyDiagnostics.js +76 -0
- package/dist/config/providerPolicyDiagnostics.js.map +1 -0
- package/dist/config/providerPolicyHash.d.ts +14 -0
- package/dist/config/providerPolicyHash.d.ts.map +1 -0
- package/dist/config/providerPolicyHash.js +65 -0
- package/dist/config/providerPolicyHash.js.map +1 -0
- package/dist/config/providerPolicySchema.d.ts +32 -0
- package/dist/config/providerPolicySchema.d.ts.map +1 -0
- package/dist/config/providerPolicySchema.js +130 -0
- package/dist/config/providerPolicySchema.js.map +1 -0
- package/dist/config/providerRunnability.d.ts +36 -0
- package/dist/config/providerRunnability.d.ts.map +1 -0
- package/dist/config/providerRunnability.js +72 -0
- package/dist/config/providerRunnability.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +45 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/process/providerProcessAudit.d.ts +14 -0
- package/dist/process/providerProcessAudit.d.ts.map +1 -0
- package/dist/process/providerProcessAudit.js +27 -0
- package/dist/process/providerProcessAudit.js.map +1 -0
- package/dist/process/providerProcessDiagnostics.d.ts +30 -0
- package/dist/process/providerProcessDiagnostics.d.ts.map +1 -0
- package/dist/process/providerProcessDiagnostics.js +51 -0
- package/dist/process/providerProcessDiagnostics.js.map +1 -0
- package/dist/process/providerProcessEnvironment.d.ts +29 -0
- package/dist/process/providerProcessEnvironment.d.ts.map +1 -0
- package/dist/process/providerProcessEnvironment.js +37 -0
- package/dist/process/providerProcessEnvironment.js.map +1 -0
- package/dist/process/providerProcessErrors.d.ts +21 -0
- package/dist/process/providerProcessErrors.d.ts.map +1 -0
- package/dist/process/providerProcessErrors.js +25 -0
- package/dist/process/providerProcessErrors.js.map +1 -0
- package/dist/process/providerProcessOutput.d.ts +24 -0
- package/dist/process/providerProcessOutput.d.ts.map +1 -0
- package/dist/process/providerProcessOutput.js +52 -0
- package/dist/process/providerProcessOutput.js.map +1 -0
- package/dist/process/providerProcessSupervisor.d.ts +40 -0
- package/dist/process/providerProcessSupervisor.d.ts.map +1 -0
- package/dist/process/providerProcessSupervisor.js +305 -0
- package/dist/process/providerProcessSupervisor.js.map +1 -0
- package/dist/process/providerProcessTypes.d.ts +114 -0
- package/dist/process/providerProcessTypes.d.ts.map +1 -0
- package/dist/process/providerProcessTypes.js +30 -0
- package/dist/process/providerProcessTypes.js.map +1 -0
- package/dist/process/providerProcessValidation.d.ts +26 -0
- package/dist/process/providerProcessValidation.d.ts.map +1 -0
- package/dist/process/providerProcessValidation.js +112 -0
- package/dist/process/providerProcessValidation.js.map +1 -0
- package/dist/process/providerProcessWorkspace.d.ts +38 -0
- package/dist/process/providerProcessWorkspace.d.ts.map +1 -0
- package/dist/process/providerProcessWorkspace.js +86 -0
- package/dist/process/providerProcessWorkspace.js.map +1 -0
- package/dist/providers/claudeLocalProvider.d.ts +68 -0
- package/dist/providers/claudeLocalProvider.d.ts.map +1 -0
- package/dist/providers/claudeLocalProvider.js +217 -0
- package/dist/providers/claudeLocalProvider.js.map +1 -0
- package/dist/providers/claudeStreamJsonParser.d.ts +39 -0
- package/dist/providers/claudeStreamJsonParser.d.ts.map +1 -0
- package/dist/providers/claudeStreamJsonParser.js +180 -0
- package/dist/providers/claudeStreamJsonParser.js.map +1 -0
- package/dist/providers/codexExecJsonParser.d.ts +38 -0
- package/dist/providers/codexExecJsonParser.d.ts.map +1 -0
- package/dist/providers/codexExecJsonParser.js +245 -0
- package/dist/providers/codexExecJsonParser.js.map +1 -0
- package/dist/providers/codexLocalProvider.d.ts +46 -0
- package/dist/providers/codexLocalProvider.d.ts.map +1 -0
- package/dist/providers/codexLocalProvider.js +430 -0
- package/dist/providers/codexLocalProvider.js.map +1 -0
- package/dist/providers/codexModelCatalog.d.ts +13 -0
- package/dist/providers/codexModelCatalog.d.ts.map +1 -0
- package/dist/providers/codexModelCatalog.js +133 -0
- package/dist/providers/codexModelCatalog.js.map +1 -0
- package/dist/providers/fixtureProvider.d.ts +14 -0
- package/dist/providers/fixtureProvider.d.ts.map +1 -0
- package/dist/providers/fixtureProvider.js +160 -0
- package/dist/providers/fixtureProvider.js.map +1 -0
- package/dist/providers/providerDiscovery.d.ts +24 -0
- package/dist/providers/providerDiscovery.d.ts.map +1 -0
- package/dist/providers/providerDiscovery.js +128 -0
- package/dist/providers/providerDiscovery.js.map +1 -0
- package/dist/providers/providerErrors.d.ts +64 -0
- package/dist/providers/providerErrors.d.ts.map +1 -0
- package/dist/providers/providerErrors.js +101 -0
- package/dist/providers/providerErrors.js.map +1 -0
- package/dist/providers/providerEvents.d.ts +63 -0
- package/dist/providers/providerEvents.d.ts.map +1 -0
- package/dist/providers/providerEvents.js +86 -0
- package/dist/providers/providerEvents.js.map +1 -0
- package/dist/providers/providerRegistry.d.ts +31 -0
- package/dist/providers/providerRegistry.d.ts.map +1 -0
- package/dist/providers/providerRegistry.js +234 -0
- package/dist/providers/providerRegistry.js.map +1 -0
- package/dist/providers/providerSafety.d.ts +17 -0
- package/dist/providers/providerSafety.d.ts.map +1 -0
- package/dist/providers/providerSafety.js +36 -0
- package/dist/providers/providerSafety.js.map +1 -0
- package/dist/providers/providerTypes.d.ts +212 -0
- package/dist/providers/providerTypes.d.ts.map +1 -0
- package/dist/providers/providerTypes.js +15 -0
- package/dist/providers/providerTypes.js.map +1 -0
- package/dist/providers/xenoLocalProvider.d.ts +35 -0
- package/dist/providers/xenoLocalProvider.d.ts.map +1 -0
- package/dist/providers/xenoLocalProvider.js +159 -0
- package/dist/providers/xenoLocalProvider.js.map +1 -0
- package/dist/sandbox/providerSandbox.d.ts +35 -0
- package/dist/sandbox/providerSandbox.d.ts.map +1 -0
- package/dist/sandbox/providerSandbox.js +93 -0
- package/dist/sandbox/providerSandbox.js.map +1 -0
- package/dist/sandbox/providerSandboxAudit.d.ts +12 -0
- package/dist/sandbox/providerSandboxAudit.d.ts.map +1 -0
- package/dist/sandbox/providerSandboxAudit.js +25 -0
- package/dist/sandbox/providerSandboxAudit.js.map +1 -0
- package/dist/sandbox/providerSandboxDiagnostics.d.ts +13 -0
- package/dist/sandbox/providerSandboxDiagnostics.d.ts.map +1 -0
- package/dist/sandbox/providerSandboxDiagnostics.js +28 -0
- package/dist/sandbox/providerSandboxDiagnostics.js.map +1 -0
- package/dist/sandbox/providerSandboxTypes.d.ts +138 -0
- package/dist/sandbox/providerSandboxTypes.d.ts.map +1 -0
- package/dist/sandbox/providerSandboxTypes.js +17 -0
- package/dist/sandbox/providerSandboxTypes.js.map +1 -0
- package/dist/sandbox/sandboxCancellation.d.ts +6 -0
- package/dist/sandbox/sandboxCancellation.d.ts.map +1 -0
- package/dist/sandbox/sandboxCancellation.js +24 -0
- package/dist/sandbox/sandboxCancellation.js.map +1 -0
- package/dist/sandbox/sandboxErrors.d.ts +17 -0
- package/dist/sandbox/sandboxErrors.d.ts.map +1 -0
- package/dist/sandbox/sandboxErrors.js +21 -0
- package/dist/sandbox/sandboxErrors.js.map +1 -0
- package/dist/sandbox/sandboxFilesystem.d.ts +14 -0
- package/dist/sandbox/sandboxFilesystem.d.ts.map +1 -0
- package/dist/sandbox/sandboxFilesystem.js +51 -0
- package/dist/sandbox/sandboxFilesystem.js.map +1 -0
- package/dist/sandbox/sandboxNetwork.d.ts +14 -0
- package/dist/sandbox/sandboxNetwork.d.ts.map +1 -0
- package/dist/sandbox/sandboxNetwork.js +60 -0
- package/dist/sandbox/sandboxNetwork.js.map +1 -0
- package/dist/sandbox/sandboxSecrets.d.ts +17 -0
- package/dist/sandbox/sandboxSecrets.d.ts.map +1 -0
- package/dist/sandbox/sandboxSecrets.js +61 -0
- package/dist/sandbox/sandboxSecrets.js.map +1 -0
- package/dist/sandbox/sandboxTerminal.d.ts +14 -0
- package/dist/sandbox/sandboxTerminal.d.ts.map +1 -0
- package/dist/sandbox/sandboxTerminal.js +32 -0
- package/dist/sandbox/sandboxTerminal.js.map +1 -0
- package/dist/security/authPolicy.d.ts +31 -0
- package/dist/security/authPolicy.d.ts.map +1 -0
- package/dist/security/authPolicy.js +72 -0
- package/dist/security/authPolicy.js.map +1 -0
- package/dist/security/capabilityGate.d.ts +16 -0
- package/dist/security/capabilityGate.d.ts.map +1 -0
- package/dist/security/capabilityGate.js +101 -0
- package/dist/security/capabilityGate.js.map +1 -0
- package/dist/security/egressPolicy.d.ts +31 -0
- package/dist/security/egressPolicy.d.ts.map +1 -0
- package/dist/security/egressPolicy.js +120 -0
- package/dist/security/egressPolicy.js.map +1 -0
- package/dist/security/redaction.d.ts +16 -0
- package/dist/security/redaction.d.ts.map +1 -0
- package/dist/security/redaction.js +65 -0
- package/dist/security/redaction.js.map +1 -0
- package/dist/security/secretBinding.d.ts +34 -0
- package/dist/security/secretBinding.d.ts.map +1 -0
- package/dist/security/secretBinding.js +66 -0
- package/dist/security/secretBinding.js.map +1 -0
- package/dist/security/secretStore.d.ts +37 -0
- package/dist/security/secretStore.d.ts.map +1 -0
- package/dist/security/secretStore.js +55 -0
- package/dist/security/secretStore.js.map +1 -0
- package/dist/security/securityDiagnostics.d.ts +39 -0
- package/dist/security/securityDiagnostics.d.ts.map +1 -0
- package/dist/security/securityDiagnostics.js +36 -0
- package/dist/security/securityDiagnostics.js.map +1 -0
- package/dist/security/securityTypes.d.ts +77 -0
- package/dist/security/securityTypes.d.ts.map +1 -0
- package/dist/security/securityTypes.js +17 -0
- package/dist/security/securityTypes.js.map +1 -0
- package/dist/sessionStore.d.ts +33 -0
- package/dist/sessionStore.d.ts.map +1 -0
- package/dist/sessionStore.js +42 -0
- package/dist/sessionStore.js.map +1 -0
- package/dist/stdioJsonRpc.d.ts +43 -0
- package/dist/stdioJsonRpc.d.ts.map +1 -0
- package/dist/stdioJsonRpc.js +219 -0
- package/dist/stdioJsonRpc.js.map +1 -0
- package/dist/types.d.ts +78 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform MINIMAL provider process supervisor (XACP-010).
|
|
3
|
+
*
|
|
4
|
+
* SCOPED I/O EXCEPTION. This is the one file in the process/ layer that spawns a child process.
|
|
5
|
+
* It exists so provider adapters have a concrete, audited process boundary. It only runs after a
|
|
6
|
+
* higher layer supplies a policy/approval-gated config; the ACP handler itself keeps its
|
|
7
|
+
* zero-I/O-authority posture.
|
|
8
|
+
*
|
|
9
|
+
* What it enforces: no-shell launch (`shell:false`), validated executable/args, a clean env
|
|
10
|
+
* allowlist, an absolute cwd, a hard timeout, bounded+redacted output capture, best-effort
|
|
11
|
+
* process-tree cleanup, and an append-only audit trail.
|
|
12
|
+
*
|
|
13
|
+
* What it does NOT enforce — and must never claim to: network egress, filesystem access against
|
|
14
|
+
* a hostile process, or full child-process syscall containment. See
|
|
15
|
+
* `MINIMAL_SUPERVISOR_ENFORCEMENT`. The supervisor itself opens no sockets and makes no network
|
|
16
|
+
* call; it uses NO `exec`/`execFile` (only `spawn` with an argv array).
|
|
17
|
+
*/
|
|
18
|
+
import { spawn } from "node:child_process";
|
|
19
|
+
import { isAbsolute } from "node:path";
|
|
20
|
+
import { buildProviderEnv, envKeyList } from "./providerProcessEnvironment.js";
|
|
21
|
+
import { createProviderProcessAudit } from "./providerProcessAudit.js";
|
|
22
|
+
import { buildProcessDiagnostics } from "./providerProcessDiagnostics.js";
|
|
23
|
+
import { ProviderProcessError } from "./providerProcessErrors.js";
|
|
24
|
+
import { BoundedCapture } from "./providerProcessOutput.js";
|
|
25
|
+
import { validateProviderProcessConfig, } from "./providerProcessValidation.js";
|
|
26
|
+
let PROCESS_SEQ = 0;
|
|
27
|
+
/** Resolve a no-shell spawn invocation. Mirrors core/process-resolver (kept dep-free here). */
|
|
28
|
+
function resolveSpawn(executable, args, platform, comspec) {
|
|
29
|
+
if (platform !== "win32")
|
|
30
|
+
return { file: executable, args: [...args] };
|
|
31
|
+
// Windows: route .cmd/.bat shims through cmd.exe /c explicitly (still shell:false).
|
|
32
|
+
if (/\.(cmd|bat)$/i.test(executable)) {
|
|
33
|
+
const interp = comspec ?? process.env.ComSpec ?? "cmd.exe";
|
|
34
|
+
return { file: interp, args: ["/c", executable, ...args] };
|
|
35
|
+
}
|
|
36
|
+
return { file: executable, args: [...args] };
|
|
37
|
+
}
|
|
38
|
+
/** Best-effort process-tree kill. NO shell, NO exec — only spawn(argv) for `taskkill`. */
|
|
39
|
+
function killProcessTree(child, platform, spawnImpl) {
|
|
40
|
+
const pid = child.pid;
|
|
41
|
+
if (pid === undefined)
|
|
42
|
+
return { attempted: false, succeeded: false };
|
|
43
|
+
try {
|
|
44
|
+
if (platform === "win32") {
|
|
45
|
+
// taskkill /PID <pid> /T /F — terminates the tree. shell:false, argv only.
|
|
46
|
+
const tk = spawnImpl("taskkill", ["/PID", String(pid), "/T", "/F"], { shell: false });
|
|
47
|
+
tk.on("error", () => {
|
|
48
|
+
/* taskkill missing → fall back to child.kill below; swallow */
|
|
49
|
+
});
|
|
50
|
+
child.kill();
|
|
51
|
+
return { attempted: true, succeeded: true };
|
|
52
|
+
}
|
|
53
|
+
// POSIX: child is started detached → kill the whole process group.
|
|
54
|
+
try {
|
|
55
|
+
process.kill(-pid, "SIGKILL");
|
|
56
|
+
return { attempted: true, succeeded: true };
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
child.kill("SIGKILL");
|
|
60
|
+
return { attempted: true, succeeded: true };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return { attempted: true, succeeded: false };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
class MinimalSupervisorHandle {
|
|
68
|
+
processId;
|
|
69
|
+
pid;
|
|
70
|
+
status = "starting";
|
|
71
|
+
child;
|
|
72
|
+
platform;
|
|
73
|
+
spawnImpl;
|
|
74
|
+
audit;
|
|
75
|
+
stdout;
|
|
76
|
+
stderr;
|
|
77
|
+
monotonicMs;
|
|
78
|
+
startedAt;
|
|
79
|
+
envKeys;
|
|
80
|
+
workspaceMarker;
|
|
81
|
+
killTree;
|
|
82
|
+
timer;
|
|
83
|
+
resultPromise;
|
|
84
|
+
treeKillAttempted = false;
|
|
85
|
+
treeKillSucceeded;
|
|
86
|
+
terminalStatus = "exited";
|
|
87
|
+
constructor(init) {
|
|
88
|
+
this.processId = init.audit.events()[0]?.processId ?? `proc-${++PROCESS_SEQ}`;
|
|
89
|
+
this.child = init.child;
|
|
90
|
+
this.pid = init.child.pid;
|
|
91
|
+
this.platform = init.platform;
|
|
92
|
+
this.spawnImpl = init.spawnImpl;
|
|
93
|
+
this.audit = init.audit;
|
|
94
|
+
this.envKeys = init.envKeys;
|
|
95
|
+
this.workspaceMarker = init.workspaceMarker;
|
|
96
|
+
this.killTree = init.config.killTree;
|
|
97
|
+
this.monotonicMs = init.monotonicMs;
|
|
98
|
+
this.startedAt = init.monotonicMs();
|
|
99
|
+
this.stdout = new BoundedCapture(init.config.stdoutLimitBytes);
|
|
100
|
+
this.stderr = new BoundedCapture(init.config.stderrLimitBytes);
|
|
101
|
+
this.status = "running";
|
|
102
|
+
this.child.stdout?.on("data", (d) => this.stdout.push(d));
|
|
103
|
+
this.child.stderr?.on("data", (d) => this.stderr.push(d));
|
|
104
|
+
this.resultPromise = new Promise((resolve) => {
|
|
105
|
+
const finish = (exitCode, signal) => {
|
|
106
|
+
if (this.timer)
|
|
107
|
+
clearTimeout(this.timer);
|
|
108
|
+
const durationMs = Math.max(0, Math.round(this.monotonicMs() - this.startedAt));
|
|
109
|
+
if (this.stdout.isTruncated) {
|
|
110
|
+
this.audit.record("provider.process.stdout.truncated", "stdout truncated at limit", {
|
|
111
|
+
bytes: this.stdout.bytes,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (this.stderr.isTruncated) {
|
|
115
|
+
this.audit.record("provider.process.stderr.truncated", "stderr truncated at limit", {
|
|
116
|
+
bytes: this.stderr.bytes,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// Resolve terminal status: explicit (cancel/timeout) wins; else exit code.
|
|
120
|
+
let status = this.terminalStatus;
|
|
121
|
+
if (status === "exited") {
|
|
122
|
+
status = exitCode === 0 ? "completed" : "failed";
|
|
123
|
+
}
|
|
124
|
+
this.status =
|
|
125
|
+
status === "completed"
|
|
126
|
+
? "completed"
|
|
127
|
+
: status === "cancelled"
|
|
128
|
+
? "cancelled"
|
|
129
|
+
: status === "timed_out"
|
|
130
|
+
? "timed_out"
|
|
131
|
+
: "failed";
|
|
132
|
+
const auditKind = status === "completed"
|
|
133
|
+
? "provider.process.completed"
|
|
134
|
+
: status === "cancelled"
|
|
135
|
+
? "provider.process.cancelled"
|
|
136
|
+
: status === "timed_out"
|
|
137
|
+
? "provider.process.timed_out"
|
|
138
|
+
: "provider.process.failed";
|
|
139
|
+
this.audit.record(auditKind, `process ${status}`, {
|
|
140
|
+
exitCode,
|
|
141
|
+
signal,
|
|
142
|
+
durationMs,
|
|
143
|
+
});
|
|
144
|
+
// Always emit the honest "not enforced" markers so consumers can't infer containment.
|
|
145
|
+
this.audit.record("provider.process.policy.not_enforced", "network egress is NOT enforced by the minimal supervisor", { capability: "network" });
|
|
146
|
+
this.audit.record("provider.process.policy.not_enforced", "filesystem is NOT enforced against a hostile process", { capability: "filesystem" });
|
|
147
|
+
resolve({
|
|
148
|
+
status,
|
|
149
|
+
exitCode,
|
|
150
|
+
signal: signal ?? null,
|
|
151
|
+
stdout: this.stdout.text(),
|
|
152
|
+
stderr: this.stderr.text(),
|
|
153
|
+
stdoutTruncated: this.stdout.isTruncated,
|
|
154
|
+
stderrTruncated: this.stderr.isTruncated,
|
|
155
|
+
durationMs,
|
|
156
|
+
auditEvents: this.audit.events(),
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
this.child.on("error", (err) => {
|
|
160
|
+
this.terminalStatus = "failed";
|
|
161
|
+
this.audit.record("provider.process.failed", "spawn error", { message: safe(err) });
|
|
162
|
+
finish(null, null);
|
|
163
|
+
});
|
|
164
|
+
this.child.on("close", (code, signal) => finish(code, signal));
|
|
165
|
+
});
|
|
166
|
+
if (init.config.stdin !== undefined) {
|
|
167
|
+
this.child.stdin?.end(init.config.stdin);
|
|
168
|
+
}
|
|
169
|
+
// Hard timeout.
|
|
170
|
+
this.timer = setTimeout(() => {
|
|
171
|
+
this.terminalStatus = "timed_out";
|
|
172
|
+
this.audit.record("provider.process.timed_out", "timeout elapsed; terminating");
|
|
173
|
+
this.terminate();
|
|
174
|
+
}, init.config.timeoutMs);
|
|
175
|
+
this.timer.unref?.();
|
|
176
|
+
}
|
|
177
|
+
terminate() {
|
|
178
|
+
if (this.killTree) {
|
|
179
|
+
this.audit.record("provider.process.kill.attempted", "attempting process-tree kill", {
|
|
180
|
+
platform: this.platform,
|
|
181
|
+
});
|
|
182
|
+
const r = killProcessTree(this.child, this.platform, this.spawnImpl);
|
|
183
|
+
this.treeKillAttempted = r.attempted;
|
|
184
|
+
this.treeKillSucceeded = r.succeeded;
|
|
185
|
+
this.audit.record("provider.process.kill.completed", "process-tree kill attempt finished", {
|
|
186
|
+
attempted: r.attempted,
|
|
187
|
+
succeeded: r.succeeded,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
this.treeKillAttempted = false;
|
|
192
|
+
this.child.kill();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
wait() {
|
|
196
|
+
return this.resultPromise;
|
|
197
|
+
}
|
|
198
|
+
async cancel(reason) {
|
|
199
|
+
if (this.status === "completed" || this.status === "failed" || this.status === "cancelled")
|
|
200
|
+
return;
|
|
201
|
+
this.terminalStatus = "cancelled";
|
|
202
|
+
this.audit.record("provider.process.cancelled", "cancel requested", reason ? { reason: safeStr(reason) } : undefined);
|
|
203
|
+
this.terminate();
|
|
204
|
+
await this.resultPromise;
|
|
205
|
+
}
|
|
206
|
+
async kill(reason) {
|
|
207
|
+
if (this.status === "completed" || this.status === "failed")
|
|
208
|
+
return;
|
|
209
|
+
if (this.terminalStatus === "exited")
|
|
210
|
+
this.terminalStatus = "cancelled";
|
|
211
|
+
this.audit.record("provider.process.kill.attempted", "kill requested", reason ? { reason: safeStr(reason) } : undefined);
|
|
212
|
+
this.terminate();
|
|
213
|
+
await this.resultPromise;
|
|
214
|
+
}
|
|
215
|
+
diagnostics() {
|
|
216
|
+
return buildProcessDiagnostics({
|
|
217
|
+
providerId: this.audit.events()[0]?.providerId ?? "unknown",
|
|
218
|
+
processId: this.processId,
|
|
219
|
+
platform: this.platform,
|
|
220
|
+
status: this.status,
|
|
221
|
+
envKeys: this.envKeys,
|
|
222
|
+
workspace: this.workspaceMarker,
|
|
223
|
+
stdoutBytes: this.stdout.bytes,
|
|
224
|
+
stderrBytes: this.stderr.bytes,
|
|
225
|
+
stdoutTruncated: this.stdout.isTruncated,
|
|
226
|
+
stderrTruncated: this.stderr.isTruncated,
|
|
227
|
+
treeKillAttempted: this.treeKillAttempted,
|
|
228
|
+
treeKillSucceeded: this.treeKillSucceeded,
|
|
229
|
+
auditCount: this.audit.events().length,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/** Redact an Error for audit details (message only, no stack). */
|
|
234
|
+
function safe(err) {
|
|
235
|
+
return err instanceof Error ? safeStr(err.message) : "error";
|
|
236
|
+
}
|
|
237
|
+
function safeStr(s) {
|
|
238
|
+
return String(s).slice(0, 200);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Create the minimal supervisor. `start()` validates the config, builds a clean env, and spawns
|
|
242
|
+
* the child with `shell:false`. It throws a `ProviderProcessError` (safe message) on invalid
|
|
243
|
+
* config or spawn-setup failure; runtime spawn errors surface as a `failed` result via `wait()`.
|
|
244
|
+
*/
|
|
245
|
+
export function createProviderProcessSupervisor(opts = {}) {
|
|
246
|
+
const platform = opts.platform ?? process.platform;
|
|
247
|
+
const spawnImpl = opts.spawnImpl ?? spawn;
|
|
248
|
+
const monotonicMs = opts.monotonicMs ?? (() => Number(performance.now()));
|
|
249
|
+
let nowSeq = 0;
|
|
250
|
+
const now = opts.now ?? (() => `t${++nowSeq}`); // deterministic, no Date.* in source
|
|
251
|
+
return {
|
|
252
|
+
start(rawConfig) {
|
|
253
|
+
const config = validateProviderProcessConfig(rawConfig);
|
|
254
|
+
const processId = `${config.providerId}-proc-${++PROCESS_SEQ}`;
|
|
255
|
+
const audit = createProviderProcessAudit({ providerId: config.providerId, processId, now });
|
|
256
|
+
const env = buildProviderEnv(config, { platformBasics: opts.platformBasics });
|
|
257
|
+
const keys = envKeyList(env);
|
|
258
|
+
audit.record("provider.process.validated", "config validated; launching no-shell", {
|
|
259
|
+
envKeys: keys,
|
|
260
|
+
argc: config.args.length,
|
|
261
|
+
timeoutMs: config.timeoutMs,
|
|
262
|
+
killTree: config.killTree,
|
|
263
|
+
});
|
|
264
|
+
if (!isAbsolute(config.cwd)) {
|
|
265
|
+
throw new ProviderProcessError({
|
|
266
|
+
code: "PROCESS_CWD_INVALID",
|
|
267
|
+
safeMessage: "cwd must be an absolute path",
|
|
268
|
+
providerId: config.providerId,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
const resolved = resolveSpawn(config.executable, config.args, platform);
|
|
272
|
+
let child;
|
|
273
|
+
try {
|
|
274
|
+
child = spawnImpl(resolved.file, resolved.args, {
|
|
275
|
+
cwd: config.cwd,
|
|
276
|
+
env, // CLEAN allowlist — process.env is NOT inherited
|
|
277
|
+
shell: false, // never a shell
|
|
278
|
+
stdio: [config.stdin !== undefined ? "pipe" : "ignore", "pipe", "pipe"],
|
|
279
|
+
detached: platform !== "win32", // POSIX: own process group → tree kill
|
|
280
|
+
windowsHide: true,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
audit.record("provider.process.failed", "spawn setup failed", { message: safe(err) });
|
|
285
|
+
throw new ProviderProcessError({
|
|
286
|
+
code: "PROCESS_SPAWN_FAILED",
|
|
287
|
+
safeMessage: "failed to spawn process",
|
|
288
|
+
providerId: config.providerId,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
audit.record("provider.process.started", "process started", { pid: child.pid ?? null });
|
|
292
|
+
return new MinimalSupervisorHandle({
|
|
293
|
+
config,
|
|
294
|
+
child,
|
|
295
|
+
platform,
|
|
296
|
+
spawnImpl,
|
|
297
|
+
audit,
|
|
298
|
+
envKeys: keys,
|
|
299
|
+
workspaceMarker: config.workspaceRoot ? "<supervisor-temp-workspace>" : "<configured-cwd>",
|
|
300
|
+
monotonicMs,
|
|
301
|
+
});
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=providerProcessSupervisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerProcessSupervisor.js","sourceRoot":"","sources":["../../src/process/providerProcessSupervisor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the cross-platform **minimal provider process supervisor** (XACP-010).
|
|
3
|
+
*
|
|
4
|
+
* HONEST SCOPE — read this before extending. This layer is a *minimal supervisor / process
|
|
5
|
+
* boundary*, NOT a sandbox. It enforces launch hygiene (no-shell, validated executable/args,
|
|
6
|
+
* env allowlist, isolated cwd/temp workspace, timeout/cancel, bounded+redacted output capture,
|
|
7
|
+
* best-effort process-tree cleanup, audit). It does **NOT** enforce, and must never claim to
|
|
8
|
+
* enforce:
|
|
9
|
+
* - network containment (a launched process can open any socket) → `network: not_enforced`
|
|
10
|
+
* - filesystem containment against a hostile process → `filesystem: not_enforced_against_hostile_process`
|
|
11
|
+
* - full child-process syscall containment → tree kill is `best_effort`
|
|
12
|
+
*
|
|
13
|
+
* It can run a provider CLI only after a higher layer has passed policy/approval and supplied a
|
|
14
|
+
* validated config. The supervisor itself does not certify any provider; tests still use harmless
|
|
15
|
+
* fixtures/fakes.
|
|
16
|
+
*/
|
|
17
|
+
/** What the supervisor will launch and how it is bounded. No shell, no raw command line. */
|
|
18
|
+
export interface ProviderProcessConfig {
|
|
19
|
+
/** Logical provider id (for audit/diagnostics only — does not select a real adapter). */
|
|
20
|
+
providerId: string;
|
|
21
|
+
/** A SINGLE executable token (path or bare name). Never a shell command line. */
|
|
22
|
+
executable: string;
|
|
23
|
+
/** Arguments passed literally as argv (no shell interpolation). */
|
|
24
|
+
args: string[];
|
|
25
|
+
/** Optional stdin written to the child and then closed. Never logged or audited. */
|
|
26
|
+
stdin?: string;
|
|
27
|
+
/** Absolute working directory the child runs in. */
|
|
28
|
+
cwd: string;
|
|
29
|
+
/** Explicit env allowlist — the child sees ONLY these keys (plus documented platform basics). */
|
|
30
|
+
envAllowlist: Record<string, string>;
|
|
31
|
+
/** Hard wall-clock limit; the child is killed when it elapses. */
|
|
32
|
+
timeoutMs: number;
|
|
33
|
+
/** Max stdout bytes retained (excess is dropped, `stdoutTruncated` set). */
|
|
34
|
+
stdoutLimitBytes: number;
|
|
35
|
+
/** Max stderr bytes retained (excess is dropped, `stderrTruncated` set). */
|
|
36
|
+
stderrLimitBytes: number;
|
|
37
|
+
/** Optional supervisor-owned temp workspace root (created/cleaned only if used). */
|
|
38
|
+
workspaceRoot?: string;
|
|
39
|
+
/** Attempt best-effort process-tree cleanup on stop (default true). */
|
|
40
|
+
killTree: boolean;
|
|
41
|
+
/** Only `'minimal'` exists in XACP-010 — a marker that strong containment is NOT present. */
|
|
42
|
+
platformMode: "minimal";
|
|
43
|
+
}
|
|
44
|
+
export type ProviderProcessStatus = "starting" | "running" | "completed" | "failed" | "cancelled" | "timed_out" | "killed";
|
|
45
|
+
/** Terminal result of a supervised run. stdout/stderr are bounded; diagnostics are redacted. */
|
|
46
|
+
export interface ProviderProcessResult {
|
|
47
|
+
status: "completed" | "failed" | "cancelled" | "timed_out" | "exited";
|
|
48
|
+
exitCode?: number | null;
|
|
49
|
+
signal?: string | null;
|
|
50
|
+
stdout: string;
|
|
51
|
+
stderr: string;
|
|
52
|
+
stdoutTruncated: boolean;
|
|
53
|
+
stderrTruncated: boolean;
|
|
54
|
+
durationMs: number;
|
|
55
|
+
auditEvents: ProviderProcessAuditEvent[];
|
|
56
|
+
}
|
|
57
|
+
export interface ProviderProcessHandle {
|
|
58
|
+
readonly processId: string;
|
|
59
|
+
readonly pid?: number;
|
|
60
|
+
readonly status: ProviderProcessStatus;
|
|
61
|
+
wait(): Promise<ProviderProcessResult>;
|
|
62
|
+
cancel(reason?: string): Promise<void>;
|
|
63
|
+
kill(reason?: string): Promise<void>;
|
|
64
|
+
diagnostics(): ProviderProcessDiagnostics;
|
|
65
|
+
}
|
|
66
|
+
export type ProviderProcessAuditKind = "provider.process.validated" | "provider.process.started" | "provider.process.stdout.truncated" | "provider.process.stderr.truncated" | "provider.process.completed" | "provider.process.failed" | "provider.process.cancelled" | "provider.process.timed_out" | "provider.process.kill.attempted" | "provider.process.kill.completed" | "provider.process.cleanup.completed" | "provider.process.cleanup.failed" | "provider.process.policy.not_enforced";
|
|
67
|
+
export interface ProviderProcessAuditEvent {
|
|
68
|
+
eventId: string;
|
|
69
|
+
timestamp: string;
|
|
70
|
+
providerId: string;
|
|
71
|
+
processId: string;
|
|
72
|
+
kind: ProviderProcessAuditKind;
|
|
73
|
+
safeMessage: string;
|
|
74
|
+
redactedDetails?: Record<string, unknown>;
|
|
75
|
+
}
|
|
76
|
+
export interface ProviderProcessAudit {
|
|
77
|
+
record(kind: ProviderProcessAuditKind, safeMessage: string, redactedDetails?: Record<string, unknown>): void;
|
|
78
|
+
events(): ProviderProcessAuditEvent[];
|
|
79
|
+
}
|
|
80
|
+
/** Honest per-capability enforcement classification. Surfaced in diagnostics + docs. */
|
|
81
|
+
export interface ProviderProcessEnforcement {
|
|
82
|
+
shell: "enforced";
|
|
83
|
+
env: "enforced";
|
|
84
|
+
cwd: "enforced";
|
|
85
|
+
timeout: "enforced";
|
|
86
|
+
processTreeKill: "best_effort";
|
|
87
|
+
stdoutStderrCapture: "enforced";
|
|
88
|
+
redaction: "best_effort";
|
|
89
|
+
network: "not_enforced";
|
|
90
|
+
filesystem: "not_enforced_against_hostile_process";
|
|
91
|
+
terminal: "not_applicable";
|
|
92
|
+
}
|
|
93
|
+
export interface ProviderProcessDiagnostics {
|
|
94
|
+
providerId: string;
|
|
95
|
+
processId: string;
|
|
96
|
+
platform: NodeJS.Platform;
|
|
97
|
+
supervisorMode: "minimal";
|
|
98
|
+
status: ProviderProcessStatus;
|
|
99
|
+
/** Env KEY names only — never values. */
|
|
100
|
+
envKeys: string[];
|
|
101
|
+
/** Redacted workspace marker — never a raw personal path. */
|
|
102
|
+
workspace: string;
|
|
103
|
+
stdoutBytes: number;
|
|
104
|
+
stderrBytes: number;
|
|
105
|
+
stdoutTruncated: boolean;
|
|
106
|
+
stderrTruncated: boolean;
|
|
107
|
+
treeKillAttempted: boolean;
|
|
108
|
+
treeKillSucceeded?: boolean;
|
|
109
|
+
enforcement: ProviderProcessEnforcement;
|
|
110
|
+
auditCount: number;
|
|
111
|
+
}
|
|
112
|
+
/** The honest, fixed enforcement classification for the XACP-010 minimal supervisor. */
|
|
113
|
+
export declare const MINIMAL_SUPERVISOR_ENFORCEMENT: ProviderProcessEnforcement;
|
|
114
|
+
//# sourceMappingURL=providerProcessTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerProcessTypes.d.ts","sourceRoot":"","sources":["../../src/process/providerProcessTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the cross-platform **minimal provider process supervisor** (XACP-010).
|
|
3
|
+
*
|
|
4
|
+
* HONEST SCOPE — read this before extending. This layer is a *minimal supervisor / process
|
|
5
|
+
* boundary*, NOT a sandbox. It enforces launch hygiene (no-shell, validated executable/args,
|
|
6
|
+
* env allowlist, isolated cwd/temp workspace, timeout/cancel, bounded+redacted output capture,
|
|
7
|
+
* best-effort process-tree cleanup, audit). It does **NOT** enforce, and must never claim to
|
|
8
|
+
* enforce:
|
|
9
|
+
* - network containment (a launched process can open any socket) → `network: not_enforced`
|
|
10
|
+
* - filesystem containment against a hostile process → `filesystem: not_enforced_against_hostile_process`
|
|
11
|
+
* - full child-process syscall containment → tree kill is `best_effort`
|
|
12
|
+
*
|
|
13
|
+
* It can run a provider CLI only after a higher layer has passed policy/approval and supplied a
|
|
14
|
+
* validated config. The supervisor itself does not certify any provider; tests still use harmless
|
|
15
|
+
* fixtures/fakes.
|
|
16
|
+
*/
|
|
17
|
+
/** The honest, fixed enforcement classification for the XACP-010 minimal supervisor. */
|
|
18
|
+
export const MINIMAL_SUPERVISOR_ENFORCEMENT = {
|
|
19
|
+
shell: "enforced",
|
|
20
|
+
env: "enforced",
|
|
21
|
+
cwd: "enforced",
|
|
22
|
+
timeout: "enforced",
|
|
23
|
+
processTreeKill: "best_effort",
|
|
24
|
+
stdoutStderrCapture: "enforced",
|
|
25
|
+
redaction: "best_effort",
|
|
26
|
+
network: "not_enforced",
|
|
27
|
+
filesystem: "not_enforced_against_hostile_process",
|
|
28
|
+
terminal: "not_applicable",
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=providerProcessTypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerProcessTypes.js","sourceRoot":"","sources":["../../src/process/providerProcessTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAkIH,wFAAwF;AACxF,MAAM,CAAC,MAAM,8BAA8B,GAA+B;IACxE,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,UAAU;IACf,OAAO,EAAE,UAAU;IACnB,eAAe,EAAE,aAAa;IAC9B,mBAAmB,EAAE,UAAU;IAC/B,SAAS,EAAE,aAAa;IACxB,OAAO,EAAE,cAAc;IACvB,UAAU,EAAE,sCAAsC;IAClD,QAAQ,EAAE,gBAAgB;CAC3B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config validation for the minimal supervisor (XACP-010).
|
|
3
|
+
*
|
|
4
|
+
* Fail-closed: every unsafe input is REJECTED, never silently "fixed". In particular a raw
|
|
5
|
+
* command line (shell metacharacters, or an executable token that is really `cmd arg arg`) is
|
|
6
|
+
* rejected — the caller must pass a single executable token plus a separate `args` array. This
|
|
7
|
+
* is the same no-shell discipline as core's process-resolver, re-implemented here to keep
|
|
8
|
+
* `@xenosystem/acp-agent` dependency-free.
|
|
9
|
+
*/
|
|
10
|
+
import type { ProviderProcessConfig } from "./providerProcessTypes.js";
|
|
11
|
+
export interface ValidatedProviderProcessConfig extends ProviderProcessConfig {
|
|
12
|
+
readonly __validated: true;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Validate a supervisor config. Returns a branded value on success; throws a
|
|
16
|
+
* `ProviderProcessError` (safe message, no secrets) on any unsafe input.
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateProviderProcessConfig(config: ProviderProcessConfig): ValidatedProviderProcessConfig;
|
|
19
|
+
export declare const VALIDATION_BOUNDS: {
|
|
20
|
+
readonly MIN_TIMEOUT_MS: 100;
|
|
21
|
+
readonly MAX_TIMEOUT_MS: number;
|
|
22
|
+
readonly MIN_LIMIT_BYTES: 1024;
|
|
23
|
+
readonly MAX_LIMIT_BYTES: number;
|
|
24
|
+
readonly MAX_STDIN_CHARS: 1000000;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=providerProcessValidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerProcessValidation.d.ts","sourceRoot":"","sources":["../../src/process/providerProcessValidation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAavE,MAAM,WAAW,8BAA+B,SAAQ,qBAAqB;IAC3E,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;CAC5B;AAWD;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,qBAAqB,GAC5B,8BAA8B,CAyFhC;AAED,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config validation for the minimal supervisor (XACP-010).
|
|
3
|
+
*
|
|
4
|
+
* Fail-closed: every unsafe input is REJECTED, never silently "fixed". In particular a raw
|
|
5
|
+
* command line (shell metacharacters, or an executable token that is really `cmd arg arg`) is
|
|
6
|
+
* rejected — the caller must pass a single executable token plus a separate `args` array. This
|
|
7
|
+
* is the same no-shell discipline as core's process-resolver, re-implemented here to keep
|
|
8
|
+
* `@xenosystem/acp-agent` dependency-free.
|
|
9
|
+
*/
|
|
10
|
+
import { isAbsolute } from "node:path";
|
|
11
|
+
import { ProviderProcessError } from "./providerProcessErrors.js";
|
|
12
|
+
/** Shell metacharacters that must never appear in an executable token. */
|
|
13
|
+
const SHELL_METACHARS = /[&|;<>$`\n\r(){}!*?~"']/;
|
|
14
|
+
/** A safe environment variable name. */
|
|
15
|
+
const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
16
|
+
const MIN_TIMEOUT_MS = 100;
|
|
17
|
+
const MAX_TIMEOUT_MS = 10 * 60_000; // 10 minutes
|
|
18
|
+
const MIN_LIMIT_BYTES = 1_024; // 1 KiB
|
|
19
|
+
const MAX_LIMIT_BYTES = 64 * 1_024 * 1_024; // 64 MiB
|
|
20
|
+
const MAX_STDIN_CHARS = 1_000_000;
|
|
21
|
+
function fail(code, safeMessage, providerId, redactedDetails) {
|
|
22
|
+
throw new ProviderProcessError({ code, safeMessage, providerId, redactedDetails });
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validate a supervisor config. Returns a branded value on success; throws a
|
|
26
|
+
* `ProviderProcessError` (safe message, no secrets) on any unsafe input.
|
|
27
|
+
*/
|
|
28
|
+
export function validateProviderProcessConfig(config) {
|
|
29
|
+
const pid = config?.providerId;
|
|
30
|
+
if (!config || typeof config !== "object") {
|
|
31
|
+
fail("PROCESS_CONFIG_INVALID", "config must be an object");
|
|
32
|
+
}
|
|
33
|
+
if (typeof pid !== "string" || pid.trim().length === 0) {
|
|
34
|
+
fail("PROCESS_CONFIG_INVALID", "providerId must be a non-empty string");
|
|
35
|
+
}
|
|
36
|
+
if (config.platformMode !== "minimal") {
|
|
37
|
+
fail("PROCESS_CONFIG_INVALID", "platformMode must be 'minimal' (no strong containment exists)", pid);
|
|
38
|
+
}
|
|
39
|
+
// Executable: a single token, no shell metacharacters, no embedded spaces unless it is an
|
|
40
|
+
// absolute/relative path (a real path may contain spaces; a bare `cmd arg` may not).
|
|
41
|
+
const exe = config.executable;
|
|
42
|
+
if (typeof exe !== "string" || exe.trim().length === 0) {
|
|
43
|
+
fail("PROCESS_EXECUTABLE_INVALID", "executable must be a non-empty string", pid);
|
|
44
|
+
}
|
|
45
|
+
if (SHELL_METACHARS.test(exe)) {
|
|
46
|
+
fail("PROCESS_EXECUTABLE_INVALID", "executable contains shell metacharacters (pass a single executable token)", pid);
|
|
47
|
+
}
|
|
48
|
+
const looksLikePath = exe.includes("/") || exe.includes("\\") || isAbsolute(exe);
|
|
49
|
+
if (/\s/.test(exe) && !looksLikePath) {
|
|
50
|
+
fail("PROCESS_EXECUTABLE_INVALID", "executable looks like a command line with spaces (split it into executable + args)", pid);
|
|
51
|
+
}
|
|
52
|
+
// Args: a real array of strings (no raw command string, no non-string entries).
|
|
53
|
+
if (!Array.isArray(config.args)) {
|
|
54
|
+
fail("PROCESS_ARGS_INVALID", "args must be an array of strings", pid);
|
|
55
|
+
}
|
|
56
|
+
for (const a of config.args) {
|
|
57
|
+
if (typeof a !== "string") {
|
|
58
|
+
fail("PROCESS_ARGS_INVALID", "every arg must be a string", pid);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (config.stdin !== undefined) {
|
|
62
|
+
if (typeof config.stdin !== "string" || config.stdin.length > MAX_STDIN_CHARS) {
|
|
63
|
+
fail("PROCESS_CONFIG_INVALID", `stdin must be a string with at most ${MAX_STDIN_CHARS} characters`, pid);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// cwd: absolute.
|
|
67
|
+
if (typeof config.cwd !== "string" || !isAbsolute(config.cwd)) {
|
|
68
|
+
fail("PROCESS_CWD_INVALID", "cwd must be an absolute path", pid);
|
|
69
|
+
}
|
|
70
|
+
// env allowlist: explicit record of string→string with safe key names.
|
|
71
|
+
if (!config.envAllowlist || typeof config.envAllowlist !== "object") {
|
|
72
|
+
fail("PROCESS_ENV_INVALID", "envAllowlist must be an object", pid);
|
|
73
|
+
}
|
|
74
|
+
for (const [k, v] of Object.entries(config.envAllowlist)) {
|
|
75
|
+
if (!ENV_KEY_RE.test(k)) {
|
|
76
|
+
fail("PROCESS_ENV_INVALID", `env key is not a safe name: ${k}`, pid);
|
|
77
|
+
}
|
|
78
|
+
if (typeof v !== "string") {
|
|
79
|
+
fail("PROCESS_ENV_INVALID", `env value for ${k} must be a string`, pid);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// timeout + limits: bounded.
|
|
83
|
+
if (!Number.isFinite(config.timeoutMs) || config.timeoutMs < MIN_TIMEOUT_MS || config.timeoutMs > MAX_TIMEOUT_MS) {
|
|
84
|
+
fail("PROCESS_TIMEOUT_INVALID", `timeoutMs must be between ${MIN_TIMEOUT_MS} and ${MAX_TIMEOUT_MS}`, pid);
|
|
85
|
+
}
|
|
86
|
+
for (const [name, val] of [
|
|
87
|
+
["stdoutLimitBytes", config.stdoutLimitBytes],
|
|
88
|
+
["stderrLimitBytes", config.stderrLimitBytes],
|
|
89
|
+
]) {
|
|
90
|
+
if (!Number.isInteger(val) || val < MIN_LIMIT_BYTES || val > MAX_LIMIT_BYTES) {
|
|
91
|
+
fail("PROCESS_LIMIT_INVALID", `${name} must be an integer between ${MIN_LIMIT_BYTES} and ${MAX_LIMIT_BYTES}`, pid);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// workspaceRoot (optional): absolute when provided.
|
|
95
|
+
if (config.workspaceRoot !== undefined) {
|
|
96
|
+
if (typeof config.workspaceRoot !== "string" || !isAbsolute(config.workspaceRoot)) {
|
|
97
|
+
fail("PROCESS_WORKSPACE_INVALID", "workspaceRoot must be an absolute path when provided", pid);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (typeof config.killTree !== "boolean") {
|
|
101
|
+
fail("PROCESS_CONFIG_INVALID", "killTree must be a boolean", pid);
|
|
102
|
+
}
|
|
103
|
+
return { ...config, __validated: true };
|
|
104
|
+
}
|
|
105
|
+
export const VALIDATION_BOUNDS = {
|
|
106
|
+
MIN_TIMEOUT_MS,
|
|
107
|
+
MAX_TIMEOUT_MS,
|
|
108
|
+
MIN_LIMIT_BYTES,
|
|
109
|
+
MAX_LIMIT_BYTES,
|
|
110
|
+
MAX_STDIN_CHARS,
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=providerProcessValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerProcessValidation.js","sourceRoot":"","sources":["../../src/process/providerProcessValidation.ts"],"names":[],"mappings":"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"}
|