contextos-mcp 0.4.0

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.
Files changed (223) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +260 -0
  3. package/bin/mcp.mjs +61 -0
  4. package/bin/swarm.mjs +45 -0
  5. package/dist/agents/aider.d.ts +12 -0
  6. package/dist/agents/aider.js +192 -0
  7. package/dist/agents/aider.js.map +1 -0
  8. package/dist/agents/claude-code.d.ts +9 -0
  9. package/dist/agents/claude-code.js +236 -0
  10. package/dist/agents/claude-code.js.map +1 -0
  11. package/dist/agents/codex.d.ts +14 -0
  12. package/dist/agents/codex.js +203 -0
  13. package/dist/agents/codex.js.map +1 -0
  14. package/dist/agents/direct-llm.d.ts +22 -0
  15. package/dist/agents/direct-llm.js +254 -0
  16. package/dist/agents/direct-llm.js.map +1 -0
  17. package/dist/agents/mock.d.ts +10 -0
  18. package/dist/agents/mock.js +170 -0
  19. package/dist/agents/mock.js.map +1 -0
  20. package/dist/agents/opencode.d.ts +23 -0
  21. package/dist/agents/opencode.js +631 -0
  22. package/dist/agents/opencode.js.map +1 -0
  23. package/dist/agents/provider.d.ts +11 -0
  24. package/dist/agents/provider.js +31 -0
  25. package/dist/agents/provider.js.map +1 -0
  26. package/dist/compression/compressor.d.ts +28 -0
  27. package/dist/compression/compressor.js +268 -0
  28. package/dist/compression/compressor.js.map +1 -0
  29. package/dist/config.d.ts +43 -0
  30. package/dist/config.js +172 -0
  31. package/dist/config.js.map +1 -0
  32. package/dist/contextos/loader.d.ts +46 -0
  33. package/dist/contextos/loader.js +120 -0
  34. package/dist/contextos/loader.js.map +1 -0
  35. package/dist/contextos/selector.d.ts +46 -0
  36. package/dist/contextos/selector.js +80 -0
  37. package/dist/contextos/selector.js.map +1 -0
  38. package/dist/core/action-dispatcher.d.ts +15 -0
  39. package/dist/core/action-dispatcher.js +28 -0
  40. package/dist/core/action-dispatcher.js.map +1 -0
  41. package/dist/core/action-schema.d.ts +72 -0
  42. package/dist/core/action-schema.js +86 -0
  43. package/dist/core/action-schema.js.map +1 -0
  44. package/dist/core/repl-interface.d.ts +48 -0
  45. package/dist/core/repl-interface.js +5 -0
  46. package/dist/core/repl-interface.js.map +1 -0
  47. package/dist/core/repl.d.ts +59 -0
  48. package/dist/core/repl.js +353 -0
  49. package/dist/core/repl.js.map +1 -0
  50. package/dist/core/rlm.d.ts +65 -0
  51. package/dist/core/rlm.js +564 -0
  52. package/dist/core/rlm.js.map +1 -0
  53. package/dist/core/runtime.py +470 -0
  54. package/dist/core/types.d.ts +265 -0
  55. package/dist/core/types.js +19 -0
  56. package/dist/core/types.js.map +1 -0
  57. package/dist/env.d.ts +10 -0
  58. package/dist/env.js +75 -0
  59. package/dist/env.js.map +1 -0
  60. package/dist/hooks/runner.d.ts +43 -0
  61. package/dist/hooks/runner.js +173 -0
  62. package/dist/hooks/runner.js.map +1 -0
  63. package/dist/labs/cli.d.ts +15 -0
  64. package/dist/labs/cli.js +295 -0
  65. package/dist/labs/cli.js.map +1 -0
  66. package/dist/labs/episodic-memory.d.ts +132 -0
  67. package/dist/labs/episodic-memory.js +391 -0
  68. package/dist/labs/episodic-memory.js.map +1 -0
  69. package/dist/labs/interactive-swarm.d.ts +20 -0
  70. package/dist/labs/interactive-swarm.js +1173 -0
  71. package/dist/labs/interactive-swarm.js.map +1 -0
  72. package/dist/labs/interactive.d.ts +10 -0
  73. package/dist/labs/interactive.js +2099 -0
  74. package/dist/labs/interactive.js.map +1 -0
  75. package/dist/labs/ts-analyzer.d.ts +74 -0
  76. package/dist/labs/ts-analyzer.js +379 -0
  77. package/dist/labs/ts-analyzer.js.map +1 -0
  78. package/dist/labs/viewer.d.ts +12 -0
  79. package/dist/labs/viewer.js +1284 -0
  80. package/dist/labs/viewer.js.map +1 -0
  81. package/dist/main.d.ts +15 -0
  82. package/dist/main.js +247 -0
  83. package/dist/main.js.map +1 -0
  84. package/dist/mcp/server.d.ts +16 -0
  85. package/dist/mcp/server.js +192775 -0
  86. package/dist/mcp/server.js.map +1 -0
  87. package/dist/mcp/session.d.ts +117 -0
  88. package/dist/mcp/session.js +450 -0
  89. package/dist/mcp/session.js.map +1 -0
  90. package/dist/mcp/state.d.ts +42 -0
  91. package/dist/mcp/state.js +537 -0
  92. package/dist/mcp/state.js.map +1 -0
  93. package/dist/mcp/tools/contextos.d.ts +17 -0
  94. package/dist/mcp/tools/contextos.js +583 -0
  95. package/dist/mcp/tools/contextos.js.map +1 -0
  96. package/dist/mcp/tools.d.ts +15 -0
  97. package/dist/mcp/tools.js +393 -0
  98. package/dist/mcp/tools.js.map +1 -0
  99. package/dist/orchestration/reviewer-gate.d.ts +43 -0
  100. package/dist/orchestration/reviewer-gate.js +280 -0
  101. package/dist/orchestration/reviewer-gate.js.map +1 -0
  102. package/dist/orchestration/reviewer-prompt.d.ts +18 -0
  103. package/dist/orchestration/reviewer-prompt.js +67 -0
  104. package/dist/orchestration/reviewer-prompt.js.map +1 -0
  105. package/dist/orchestration/verification-runner.d.ts +53 -0
  106. package/dist/orchestration/verification-runner.js +352 -0
  107. package/dist/orchestration/verification-runner.js.map +1 -0
  108. package/dist/plugins/adapter.d.ts +11 -0
  109. package/dist/plugins/adapter.js +11 -0
  110. package/dist/plugins/adapter.js.map +1 -0
  111. package/dist/plugins/core/archive.d.ts +9 -0
  112. package/dist/plugins/core/archive.js +128 -0
  113. package/dist/plugins/core/archive.js.map +1 -0
  114. package/dist/plugins/core/digest.d.ts +11 -0
  115. package/dist/plugins/core/digest.js +70 -0
  116. package/dist/plugins/core/digest.js.map +1 -0
  117. package/dist/plugins/core/grants.d.ts +22 -0
  118. package/dist/plugins/core/grants.js +90 -0
  119. package/dist/plugins/core/grants.js.map +1 -0
  120. package/dist/plugins/core/index.d.ts +10 -0
  121. package/dist/plugins/core/index.js +11 -0
  122. package/dist/plugins/core/index.js.map +1 -0
  123. package/dist/plugins/core/pinning.d.ts +15 -0
  124. package/dist/plugins/core/pinning.js +86 -0
  125. package/dist/plugins/core/pinning.js.map +1 -0
  126. package/dist/plugins/core/types.d.ts +105 -0
  127. package/dist/plugins/core/types.js +22 -0
  128. package/dist/plugins/core/types.js.map +1 -0
  129. package/dist/plugins/core/updater.d.ts +16 -0
  130. package/dist/plugins/core/updater.js +64 -0
  131. package/dist/plugins/core/updater.js.map +1 -0
  132. package/dist/plugins/loader.d.ts +65 -0
  133. package/dist/plugins/loader.js +110 -0
  134. package/dist/plugins/loader.js.map +1 -0
  135. package/dist/prompts/orchestrator.d.ts +6 -0
  136. package/dist/prompts/orchestrator.js +114 -0
  137. package/dist/prompts/orchestrator.js.map +1 -0
  138. package/dist/routing/model-resolver.d.ts +27 -0
  139. package/dist/routing/model-resolver.js +265 -0
  140. package/dist/routing/model-resolver.js.map +1 -0
  141. package/dist/routing/model-router.d.ts +130 -0
  142. package/dist/routing/model-router.js +515 -0
  143. package/dist/routing/model-router.js.map +1 -0
  144. package/dist/runtime/attestations.cjs +260 -0
  145. package/dist/runtime/reviewer-pipeline.cjs +319 -0
  146. package/dist/runtime/sandbox.cjs +468 -0
  147. package/dist/runtime/state-machine.cjs +885 -0
  148. package/dist/runtime/thread-store.cjs +175 -0
  149. package/dist/runtime/transactional-git.cjs +315 -0
  150. package/dist/runtime/verification-pipeline.cjs +435 -0
  151. package/dist/sandbox/execution.d.ts +165 -0
  152. package/dist/sandbox/execution.js +497 -0
  153. package/dist/sandbox/execution.js.map +1 -0
  154. package/dist/security/file-policy.d.ts +22 -0
  155. package/dist/security/file-policy.js +53 -0
  156. package/dist/security/file-policy.js.map +1 -0
  157. package/dist/security/repository-boundary.d.ts +21 -0
  158. package/dist/security/repository-boundary.js +119 -0
  159. package/dist/security/repository-boundary.js.map +1 -0
  160. package/dist/security/secret-filter.d.ts +36 -0
  161. package/dist/security/secret-filter.js +149 -0
  162. package/dist/security/secret-filter.js.map +1 -0
  163. package/dist/swarm.d.ts +14 -0
  164. package/dist/swarm.js +624 -0
  165. package/dist/swarm.js.map +1 -0
  166. package/dist/threads/cache.d.ts +64 -0
  167. package/dist/threads/cache.js +241 -0
  168. package/dist/threads/cache.js.map +1 -0
  169. package/dist/threads/manager.d.ts +94 -0
  170. package/dist/threads/manager.js +914 -0
  171. package/dist/threads/manager.js.map +1 -0
  172. package/dist/ui/banner.d.ts +14 -0
  173. package/dist/ui/banner.js +42 -0
  174. package/dist/ui/banner.js.map +1 -0
  175. package/dist/ui/dashboard.d.ts +33 -0
  176. package/dist/ui/dashboard.js +135 -0
  177. package/dist/ui/dashboard.js.map +1 -0
  178. package/dist/ui/index.d.ts +11 -0
  179. package/dist/ui/index.js +12 -0
  180. package/dist/ui/index.js.map +1 -0
  181. package/dist/ui/log.d.ts +39 -0
  182. package/dist/ui/log.js +126 -0
  183. package/dist/ui/log.js.map +1 -0
  184. package/dist/ui/onboarding.d.ts +14 -0
  185. package/dist/ui/onboarding.js +755 -0
  186. package/dist/ui/onboarding.js.map +1 -0
  187. package/dist/ui/run-log.d.ts +50 -0
  188. package/dist/ui/run-log.js +60 -0
  189. package/dist/ui/run-log.js.map +1 -0
  190. package/dist/ui/spinner.d.ts +41 -0
  191. package/dist/ui/spinner.js +172 -0
  192. package/dist/ui/spinner.js.map +1 -0
  193. package/dist/ui/streaming-feed.d.ts +72 -0
  194. package/dist/ui/streaming-feed.js +386 -0
  195. package/dist/ui/streaming-feed.js.map +1 -0
  196. package/dist/ui/summary.d.ts +18 -0
  197. package/dist/ui/summary.js +113 -0
  198. package/dist/ui/summary.js.map +1 -0
  199. package/dist/ui/text-input.d.ts +19 -0
  200. package/dist/ui/text-input.js +266 -0
  201. package/dist/ui/text-input.js.map +1 -0
  202. package/dist/ui/theme.d.ts +63 -0
  203. package/dist/ui/theme.js +97 -0
  204. package/dist/ui/theme.js.map +1 -0
  205. package/dist/utils/command-exists.d.ts +11 -0
  206. package/dist/utils/command-exists.js +41 -0
  207. package/dist/utils/command-exists.js.map +1 -0
  208. package/dist/utils/process-security.d.ts +19 -0
  209. package/dist/utils/process-security.js +90 -0
  210. package/dist/utils/process-security.js.map +1 -0
  211. package/dist/utils/rolling-buffer.d.ts +16 -0
  212. package/dist/utils/rolling-buffer.js +30 -0
  213. package/dist/utils/rolling-buffer.js.map +1 -0
  214. package/dist/utils/safe-spawn.d.ts +13 -0
  215. package/dist/utils/safe-spawn.js +49 -0
  216. package/dist/utils/safe-spawn.js.map +1 -0
  217. package/dist/worktree/manager.d.ts +69 -0
  218. package/dist/worktree/manager.js +593 -0
  219. package/dist/worktree/manager.js.map +1 -0
  220. package/dist/worktree/merge.d.ts +58 -0
  221. package/dist/worktree/merge.js +389 -0
  222. package/dist/worktree/merge.js.map +1 -0
  223. package/package.json +63 -0
@@ -0,0 +1,352 @@
1
+ /**
2
+ * Worktree test command execution engine with strict security guards and lifecycle hardening.
3
+ *
4
+ * Implements Section 16 & Milestones W5.1 and W5.2:
5
+ * - Structured VerificationSpec with validation and legacy reader
6
+ * - Command trust validation (bans npx in host mode, whitelist, forbidden eval args)
7
+ * - Cross-platform process tree termination (Windows taskkill /T /F, POSIX process groups)
8
+ * - Sensitive output redaction (API keys, tokens, passwords)
9
+ * - Post-execution candidate immutability verification (HEAD and dirty working tree checks)
10
+ */
11
+ import { execFileSync, spawn } from "node:child_process";
12
+ import * as path from "node:path";
13
+ import { ExecutionSandbox } from "../sandbox/execution.js";
14
+ import { resolveExecutablePath } from "../utils/command-exists.js";
15
+ import { getSanitizedEnv, killProcessTree, redactSensitiveOutput, STRICT_ENV_ALLOWLIST, } from "../utils/process-security.js";
16
+ export { getSanitizedEnv, killProcessTree, redactSensitiveOutput, STRICT_ENV_ALLOWLIST };
17
+ export const ALLOWED_VERIFY_TOOLS = new Set(["npm", "pnpm", "yarn", "node", "pytest", "cargo", "go", "vitest", "jest"]);
18
+ export const FORBIDDEN_VERIFY_ARGS = new Set(["-e", "-c", "--eval", "--print", "-p", "--input-type"]);
19
+ /**
20
+ * Parses a string command or object into a canonical VerificationSpec (Section 16.1).
21
+ */
22
+ export function parseVerificationSpec(input) {
23
+ if (!input) {
24
+ throw new Error("Verification specification cannot be empty");
25
+ }
26
+ if (typeof input === "object" && input !== null) {
27
+ const obj = input;
28
+ if (!obj.executable || typeof obj.executable !== "string" || !obj.executable.trim()) {
29
+ throw new Error("Invalid verification specification: executable must be a non-empty string");
30
+ }
31
+ if (/[&|;`$><%]/.test(obj.executable)) {
32
+ const err = new Error("Security error: Shell metacharacters and command chaining are prohibited in verification commands");
33
+ err.code = "CTX_COMMAND_CHAINING_PROHIBITED";
34
+ throw err;
35
+ }
36
+ if (!Array.isArray(obj.args)) {
37
+ throw new Error("Invalid verification specification: args must be an array of strings");
38
+ }
39
+ for (const arg of obj.args) {
40
+ if (typeof arg !== "string") {
41
+ throw new Error("Invalid verification specification: every arg must be a string");
42
+ }
43
+ }
44
+ const timeoutMs = typeof obj.timeoutMs === "number" && obj.timeoutMs > 0 ? obj.timeoutMs : 60000;
45
+ const required = obj.required !== false;
46
+ const network = obj.network === "allow" ? "allow" : "deny";
47
+ const allowedOutputPaths = Array.isArray(obj.allowedOutputPaths) ? obj.allowedOutputPaths : [];
48
+ return {
49
+ schemaVersion: typeof obj.schemaVersion === "number" ? obj.schemaVersion : 1,
50
+ executable: obj.executable
51
+ .trim()
52
+ .toLowerCase()
53
+ .replace(/\.(cmd|bat|exe)$/i, ""),
54
+ args: [...obj.args],
55
+ timeoutMs,
56
+ required,
57
+ network,
58
+ allowedOutputPaths,
59
+ cwd: typeof obj.cwd === "string" ? obj.cwd : undefined,
60
+ env: typeof obj.env === "object" && obj.env !== null ? { ...obj.env } : undefined,
61
+ trusted: obj.trusted === true,
62
+ isLegacyString: false,
63
+ };
64
+ }
65
+ if (typeof input === "string") {
66
+ const trimmed = input.trim();
67
+ if (!trimmed) {
68
+ throw new Error("Verification command cannot be empty string");
69
+ }
70
+ // Ban shell metacharacters and chaining
71
+ if (/[&|;`$><%]/.test(trimmed)) {
72
+ const err = new Error("Security error: Shell metacharacters and command chaining are not permitted in verify_command");
73
+ err.code = "CTX_COMMAND_CHAINING_PROHIBITED";
74
+ throw err;
75
+ }
76
+ const parts = trimmed.split(/\s+/);
77
+ const rawExe = parts[0].toLowerCase().replace(/\.(cmd|bat|exe)$/i, "");
78
+ const args = parts.slice(1);
79
+ return {
80
+ schemaVersion: 1,
81
+ executable: rawExe,
82
+ args,
83
+ timeoutMs: 60000,
84
+ required: true,
85
+ network: "deny",
86
+ isLegacyString: true,
87
+ };
88
+ }
89
+ throw new Error("Invalid verification specification format: expected VerificationSpec object or command string");
90
+ }
91
+ /**
92
+ * Enforces command trust policy (Section 16.2).
93
+ */
94
+ export function validateCommandTrust(spec, options = {}) {
95
+ const runnerMode = options.runnerMode || "host-unsafe";
96
+ // Rule 1: npx is forbidden in host mode (Section 16.2: "npx запрещён в host mode")
97
+ if (spec.executable === "npx" && runnerMode === "host-unsafe") {
98
+ const err = new Error('Security error: "npx" execution is strictly forbidden in host mode. Use OCI sandbox or local package runner.');
99
+ err.code = "CTX_COMMAND_UNTRUSTED";
100
+ throw err;
101
+ }
102
+ // Rule 2: Unlisted tools require OCI runner or explicit local trust
103
+ if (!ALLOWED_VERIFY_TOOLS.has(spec.executable)) {
104
+ if (runnerMode === "host-unsafe" && !options.trusted && !spec.trusted) {
105
+ const err = new Error(`Security error: Command "${spec.executable}" is not in the trusted tools whitelist (${Array.from(ALLOWED_VERIFY_TOOLS).join(", ")}). Arbitrary commands require OCI sandbox or explicit user trust.`);
106
+ err.code = "CTX_COMMAND_UNTRUSTED";
107
+ throw err;
108
+ }
109
+ }
110
+ // Rule 3: Inline evaluation arguments prohibited
111
+ for (const arg of spec.args) {
112
+ if (FORBIDDEN_VERIFY_ARGS.has(arg.toLowerCase())) {
113
+ const err = new Error(`Security error: Argument "${arg}" is not permitted in verify_command`);
114
+ err.code = "CTX_FORBIDDEN_ARGUMENT";
115
+ throw err;
116
+ }
117
+ }
118
+ }
119
+ /**
120
+ * Checks that the working tree and candidate commit remained immutable (Section 16.3).
121
+ */
122
+ export function verifyCandidateImmutability(worktreePath, expectedHeadSha) {
123
+ try {
124
+ const currentHead = execFileSync("git", ["rev-parse", "HEAD"], {
125
+ cwd: worktreePath,
126
+ encoding: "utf8",
127
+ stdio: ["ignore", "pipe", "ignore"],
128
+ windowsHide: true,
129
+ }).trim();
130
+ if (expectedHeadSha && currentHead !== expectedHeadSha) {
131
+ return { clean: false, mutatedHead: true };
132
+ }
133
+ const statusOutput = execFileSync("git", ["status", "--porcelain"], {
134
+ cwd: worktreePath,
135
+ encoding: "utf8",
136
+ stdio: ["ignore", "pipe", "ignore"],
137
+ windowsHide: true,
138
+ }).trim();
139
+ if (statusOutput.length > 0) {
140
+ const internal = new Set([".contextos-owner", ".contextos-session"]);
141
+ const dirtyFiles = statusOutput
142
+ .split("\n")
143
+ .map((l) => l.trim().slice(3).trim())
144
+ .filter((f) => f && !internal.has(f));
145
+ if (dirtyFiles.length > 0) {
146
+ return { clean: false, mutatedHead: false, dirtyFiles };
147
+ }
148
+ }
149
+ return { clean: true };
150
+ }
151
+ catch (e) {
152
+ // Non-git directory or git failure: fail closed
153
+ return { clean: false, mutatedHead: false, dirtyFiles: [`git-failure: ${e.message || "unknown"}`] };
154
+ }
155
+ }
156
+ /**
157
+ * Executes worktree verification with strict security guards and lifecycle management.
158
+ */
159
+ export async function runWorktreeVerification(worktreePath, commandOrSpec, options = {}) {
160
+ let spec;
161
+ try {
162
+ spec = parseVerificationSpec(commandOrSpec);
163
+ }
164
+ catch (err) {
165
+ return {
166
+ verdict: "ERROR",
167
+ verified: false,
168
+ output: err instanceof Error ? err.message : String(err),
169
+ exitCode: null,
170
+ runnerMode: "host-unsafe",
171
+ };
172
+ }
173
+ try {
174
+ validateCommandTrust(spec, options);
175
+ }
176
+ catch (err) {
177
+ return {
178
+ verdict: "ERROR",
179
+ verified: false,
180
+ output: err instanceof Error ? err.message : String(err),
181
+ exitCode: null,
182
+ runnerMode: "host-unsafe",
183
+ };
184
+ }
185
+ const exePath = await resolveExecutablePath(spec.executable);
186
+ const targetExecutable = exePath || spec.executable;
187
+ const executionCwd = spec.cwd ? path.resolve(worktreePath, spec.cwd) : worktreePath;
188
+ if (!executionCwd.startsWith(path.resolve(worktreePath))) {
189
+ return {
190
+ verdict: "ERROR",
191
+ verified: false,
192
+ output: `Security Violation: execution cwd "${executionCwd}" escapes worktree root.`,
193
+ exitCode: null,
194
+ runnerMode: "host-unsafe",
195
+ };
196
+ }
197
+ // OCI Execution Sandbox Path (Milestones W5.3 and W5.4)
198
+ if (options.sandbox || options.sandboxMode || options.runnerMode === "oci") {
199
+ const sandbox = options.sandbox ||
200
+ new ExecutionSandbox({
201
+ mode: options.sandboxMode || (options.runnerMode === "oci" ? "oci-required" : "oci-preferred"),
202
+ });
203
+ try {
204
+ const res = await sandbox.execute(executionCwd, [targetExecutable, ...spec.args], {
205
+ signal: options.signal,
206
+ timeoutMs: spec.timeoutMs,
207
+ });
208
+ if (res.exitCode === 0) {
209
+ const immutability = verifyCandidateImmutability(worktreePath, options.expectedHeadSha);
210
+ if (!immutability.clean) {
211
+ if (immutability.mutatedHead) {
212
+ return {
213
+ verdict: "STALE",
214
+ verified: false,
215
+ output: "Security violation: Verification test command mutated candidate branch commit HEAD",
216
+ exitCode: res.exitCode,
217
+ runnerMode: res.runnerMode,
218
+ };
219
+ }
220
+ if (immutability.dirtyFiles && immutability.dirtyFiles.length > 0) {
221
+ return {
222
+ verdict: "STALE",
223
+ verified: false,
224
+ output: `Security violation: Verification test left uncommitted dirty files in worktree (${immutability.dirtyFiles.join(", ")})`,
225
+ exitCode: res.exitCode,
226
+ runnerMode: res.runnerMode,
227
+ };
228
+ }
229
+ }
230
+ }
231
+ return {
232
+ verdict: res.success ? "PASS" : "FAIL",
233
+ verified: res.success,
234
+ output: res.redactedOutput.trim().slice(0, 1500),
235
+ exitCode: res.exitCode,
236
+ runnerMode: res.runnerMode,
237
+ };
238
+ }
239
+ catch (err) {
240
+ const isOciUnavailable = err?.code === "CTX_SANDBOX_OCI_UNAVAILABLE";
241
+ const isDigestMismatch = err?.code === "CTX_SANDBOX_DIGEST_MISMATCH";
242
+ const isSecurityViolation = err?.code?.startsWith?.("SEC-") || err?.code === "CTX_SECURITY_VIOLATION";
243
+ const verdict = isOciUnavailable
244
+ ? "UNAVAILABLE"
245
+ : isDigestMismatch || isSecurityViolation
246
+ ? "ERROR"
247
+ : "ERROR";
248
+ return {
249
+ verdict,
250
+ verified: false,
251
+ output: err?.message || String(err),
252
+ exitCode: null,
253
+ runnerMode: "host-unsafe",
254
+ };
255
+ }
256
+ }
257
+ return new Promise((resolveResult) => {
258
+ let settled = false;
259
+ const finish = (verdict, rawOutput, exitCode) => {
260
+ if (settled)
261
+ return;
262
+ settled = true;
263
+ const cleanOutput = redactSensitiveOutput(rawOutput).trim().slice(0, 1500);
264
+ resolveResult({
265
+ verdict,
266
+ verified: verdict === "PASS",
267
+ output: cleanOutput,
268
+ exitCode,
269
+ runnerMode: "host-unsafe",
270
+ });
271
+ };
272
+ let child = null;
273
+ const timeoutMs = spec.timeoutMs || 60000;
274
+ const timeout = setTimeout(() => {
275
+ if (child?.pid) {
276
+ killProcessTree(child.pid);
277
+ }
278
+ finish("TIMEOUT", `Verification timed out after ${timeoutMs}ms`, null);
279
+ }, timeoutMs);
280
+ const onAbort = () => {
281
+ if (child?.pid) {
282
+ killProcessTree(child.pid);
283
+ }
284
+ clearTimeout(timeout);
285
+ finish("CANCELLED", "Verification cancelled by abort signal", null);
286
+ };
287
+ if (options.signal?.aborted) {
288
+ clearTimeout(timeout);
289
+ finish("CANCELLED", "Verification already aborted", null);
290
+ return;
291
+ }
292
+ if (options.signal) {
293
+ options.signal.addEventListener("abort", onAbort, { once: true });
294
+ }
295
+ try {
296
+ child = spawn(targetExecutable, [...spec.args], {
297
+ cwd: executionCwd,
298
+ env: getSanitizedEnv(spec.env || {}),
299
+ shell: false,
300
+ stdio: ["ignore", "pipe", "pipe"],
301
+ windowsHide: true,
302
+ });
303
+ let stdout = "";
304
+ let stderr = "";
305
+ child.stdout?.on("data", (d) => {
306
+ if (stdout.length < 50000)
307
+ stdout += d.toString();
308
+ });
309
+ child.stderr?.on("data", (d) => {
310
+ if (stderr.length < 50000)
311
+ stderr += d.toString();
312
+ });
313
+ child.on("close", (code) => {
314
+ clearTimeout(timeout);
315
+ if (options.signal) {
316
+ options.signal.removeEventListener("abort", onAbort);
317
+ }
318
+ if (code === 0) {
319
+ // Post-execution candidate immutability verification (Section 16.3)
320
+ const immutability = verifyCandidateImmutability(worktreePath, options.expectedHeadSha);
321
+ if (!immutability.clean) {
322
+ if (immutability.mutatedHead) {
323
+ finish("STALE", "Security violation: Verification test command mutated candidate branch commit HEAD", code);
324
+ return;
325
+ }
326
+ if (immutability.dirtyFiles && immutability.dirtyFiles.length > 0) {
327
+ finish("STALE", `Security violation: Verification test left uncommitted dirty files in worktree (${immutability.dirtyFiles.join(", ")})`, code);
328
+ return;
329
+ }
330
+ }
331
+ }
332
+ const output = `${stdout}\n${stderr}`;
333
+ finish(code === 0 ? "PASS" : "FAIL", output, code);
334
+ });
335
+ child.on("error", (err) => {
336
+ clearTimeout(timeout);
337
+ if (options.signal) {
338
+ options.signal.removeEventListener("abort", onAbort);
339
+ }
340
+ finish("ERROR", `Verification execution failed: ${err.message}`, null);
341
+ });
342
+ }
343
+ catch (err) {
344
+ clearTimeout(timeout);
345
+ if (options.signal) {
346
+ options.signal.removeEventListener("abort", onAbort);
347
+ }
348
+ finish("ERROR", err instanceof Error ? err.message : String(err), null);
349
+ }
350
+ });
351
+ }
352
+ //# sourceMappingURL=verification-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification-runner.js","sourceRoot":"","sources":["../../src/orchestration/verification-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,gBAAgB,EAAoB,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EACN,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,oBAAoB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;AAEzF,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAExH,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;AAEtG;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,KAA4B,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC9F,CAAC;QACD,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,IAAI,KAAK,CACpB,mGAAmG,CACnG,CAAC;YACD,GAAW,CAAC,IAAI,GAAG,iCAAiC,CAAC;YACtD,MAAM,GAAG,CAAC;QACX,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QACzF,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACnF,CAAC;QACF,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;QACjG,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,KAAK,CAAC;QACxC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3D,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;QAE/F,OAAO;YACN,aAAa,EAAE,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAC5E,UAAU,EAAE,GAAG,CAAC,UAAU;iBACxB,IAAI,EAAE;iBACN,WAAW,EAAE;iBACb,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;YAClC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;YACnB,SAAS;YACT,QAAQ;YACR,OAAO;YACP,kBAAkB;YAClB,GAAG,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;YACtD,GAAG,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;YACjF,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,IAAI;YAC7B,cAAc,EAAE,KAAK;SACrB,CAAC;IACH,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAChE,CAAC;QAED,wCAAwC;QACxC,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,IAAI,KAAK,CACpB,+FAA+F,CAC/F,CAAC;YACD,GAAW,CAAC,IAAI,GAAG,iCAAiC,CAAC;YACtD,MAAM,GAAG,CAAC;QACX,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QACvE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAE5B,OAAO;YACN,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,MAAM;YAClB,IAAI;YACJ,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,MAAM;YACf,cAAc,EAAE,IAAI;SACpB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;AAClH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CACnC,IAAsB,EACtB,UAAqE,EAAE;IAEvE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,aAAa,CAAC;IAEvD,mFAAmF;IACnF,IAAI,IAAI,CAAC,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,aAAa,EAAE,CAAC;QAC/D,MAAM,GAAG,GAAG,IAAI,KAAK,CACpB,8GAA8G,CAC9G,CAAC;QACD,GAAW,CAAC,IAAI,GAAG,uBAAuB,CAAC;QAC5C,MAAM,GAAG,CAAC;IACX,CAAC;IAED,oEAAoE;IACpE,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAChD,IAAI,UAAU,KAAK,aAAa,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACvE,MAAM,GAAG,GAAG,IAAI,KAAK,CACpB,4BAA4B,IAAI,CAAC,UAAU,4CAA4C,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mEAAmE,CACrM,CAAC;YACD,GAAW,CAAC,IAAI,GAAG,uBAAuB,CAAC;YAC5C,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;IAED,iDAAiD;IACjD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAClD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,6BAA6B,GAAG,sCAAsC,CAAC,CAAC;YAC7F,GAAW,CAAC,IAAI,GAAG,wBAAwB,CAAC;YAC7C,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B,CAC1C,YAAoB,EACpB,eAAwB;IAExB,IAAI,CAAC;QACJ,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE;YAC9D,GAAG,EAAE,YAAY;YACjB,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;YACnC,WAAW,EAAE,IAAI;SACjB,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,IAAI,eAAe,IAAI,WAAW,KAAK,eAAe,EAAE,CAAC;YACxD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;QAED,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE;YACnE,GAAG,EAAE,YAAY;YACjB,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;YACnC,WAAW,EAAE,IAAI;SACjB,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC,CAAC;YACrE,MAAM,UAAU,GAAG,YAAY;iBAC7B,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;YACzD,CAAC;QACF,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QACjB,gDAAgD;QAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,gBAAgB,CAAC,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC,EAAE,CAAC;IACrG,CAAC;AACF,CAAC;AAWD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,YAAoB,EACpB,aAAwC,EACxC,UAA+B,EAAE;IAQjC,IAAI,IAAsB,CAAC;IAC3B,IAAI,CAAC;QACJ,IAAI,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACvB,OAAO;YACN,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YACxD,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,aAAa;SACzB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACJ,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACvB,OAAO;YACN,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YACxD,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,aAAa;SACzB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,gBAAgB,GAAG,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC;IACpD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;IAEpF,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO;YACN,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,sCAAsC,YAAY,0BAA0B;YACpF,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,aAAa;SACzB,CAAC;IACH,CAAC;IAED,wDAAwD;IACxD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;QAC5E,MAAM,OAAO,GACZ,OAAO,CAAC,OAAO;YACf,IAAI,gBAAgB,CAAC;gBACpB,IAAI,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,CAAC;aAC9F,CAAC,CAAC;QAEJ,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE;gBACjF,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,IAAI,CAAC,SAAS;aACzB,CAAC,CAAC;YAEH,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,YAAY,GAAG,2BAA2B,CAAC,YAAY,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;gBACxF,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;oBACzB,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;wBAC9B,OAAO;4BACN,OAAO,EAAE,OAAO;4BAChB,QAAQ,EAAE,KAAK;4BACf,MAAM,EAAE,oFAAoF;4BAC5F,QAAQ,EAAE,GAAG,CAAC,QAAQ;4BACtB,UAAU,EAAE,GAAG,CAAC,UAAU;yBAC1B,CAAC;oBACH,CAAC;oBACD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACnE,OAAO;4BACN,OAAO,EAAE,OAAO;4BAChB,QAAQ,EAAE,KAAK;4BACf,MAAM,EAAE,mFAAmF,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;4BAChI,QAAQ,EAAE,GAAG,CAAC,QAAQ;4BACtB,UAAU,EAAE,GAAG,CAAC,UAAU;yBAC1B,CAAC;oBACH,CAAC;gBACF,CAAC;YACF,CAAC;YAED,OAAO;gBACN,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;gBACtC,QAAQ,EAAE,GAAG,CAAC,OAAO;gBACrB,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;gBAChD,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,UAAU,EAAE,GAAG,CAAC,UAAU;aAC1B,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YACnB,MAAM,gBAAgB,GAAG,GAAG,EAAE,IAAI,KAAK,6BAA6B,CAAC;YACrE,MAAM,gBAAgB,GAAG,GAAG,EAAE,IAAI,KAAK,6BAA6B,CAAC;YACrE,MAAM,mBAAmB,GAAG,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,IAAI,KAAK,wBAAwB,CAAC;YAEtG,MAAM,OAAO,GAAuB,gBAAgB;gBACnD,CAAC,CAAC,aAAa;gBACf,CAAC,CAAC,gBAAgB,IAAI,mBAAmB;oBACxC,CAAC,CAAC,OAAO;oBACT,CAAC,CAAC,OAAO,CAAC;YAEZ,OAAO;gBACN,OAAO;gBACP,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC;gBACnC,QAAQ,EAAE,IAAI;gBACd,UAAU,EAAE,aAAa;aACzB,CAAC;QACH,CAAC;IACF,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;QACpC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,OAA2B,EAAE,SAAiB,EAAE,QAAuB,EAAE,EAAE;YAC1F,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,WAAW,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAC3E,aAAa,CAAC;gBACb,OAAO;gBACP,QAAQ,EAAE,OAAO,KAAK,MAAM;gBAC5B,MAAM,EAAE,WAAW;gBACnB,QAAQ;gBACR,UAAU,EAAE,aAAa;aACzB,CAAC,CAAC;QACJ,CAAC,CAAC;QAEF,IAAI,KAAK,GAAoC,IAAI,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;QAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC/B,IAAI,KAAK,EAAE,GAAG,EAAE,CAAC;gBAChB,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;YACD,MAAM,CAAC,SAAS,EAAE,gCAAgC,SAAS,IAAI,EAAE,IAAI,CAAC,CAAC;QACxE,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,MAAM,OAAO,GAAG,GAAG,EAAE;YACpB,IAAI,KAAK,EAAE,GAAG,EAAE,CAAC;gBAChB,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;YACD,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,CAAC,WAAkB,EAAE,wCAAwC,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC,CAAC;QAEF,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC7B,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,CAAC,WAAkB,EAAE,8BAA8B,EAAE,IAAI,CAAC,CAAC;YACjE,OAAO;QACR,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC;YACJ,KAAK,GAAG,KAAK,CAAC,gBAAgB,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE;gBAC/C,GAAG,EAAE,YAAY;gBACjB,GAAG,EAAE,eAAe,CAAE,IAAI,CAAC,GAA8B,IAAI,EAAE,CAAC;gBAChE,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;gBACjC,WAAW,EAAE,IAAI;aACjB,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAEhB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;gBAC9B,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK;oBAAE,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACnD,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;gBAC9B,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK;oBAAE,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACnD,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC1B,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;oBACpB,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACtD,CAAC;gBAED,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBAChB,oEAAoE;oBACpE,MAAM,YAAY,GAAG,2BAA2B,CAAC,YAAY,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;oBACxF,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;wBACzB,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;4BAC9B,MAAM,CACL,OAAO,EACP,oFAAoF,EACpF,IAAI,CACJ,CAAC;4BACF,OAAO;wBACR,CAAC;wBACD,IAAI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACnE,MAAM,CACL,OAAO,EACP,mFAAmF,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EACxH,IAAI,CACJ,CAAC;4BACF,OAAO;wBACR,CAAC;oBACF,CAAC;gBACF,CAAC;gBAED,MAAM,MAAM,GAAG,GAAG,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtC,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACzB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;oBACpB,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACtD,CAAC;gBACD,MAAM,CAAC,OAAO,EAAE,kCAAkC,GAAG,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACvB,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpB,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACtD,CAAC;YACD,MAAM,CAAC,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QACzE,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * ContextOS Plugin Supply Chain CLI Adapter
3
+ * ADR-002: Bundled CJS entrypoint for CLI consumption
4
+ */
5
+ export { validateArchiveEntry } from "./core/archive.js";
6
+ export { calculateTreeDigest, sha256 } from "./core/digest.js";
7
+ export { ScriptGrantManager } from "./core/grants.js";
8
+ export { validatePluginPinning, verifyNpmTarballIntegrity, } from "./core/pinning.js";
9
+ export type * from "./core/types.js";
10
+ export { THREAT_CODES } from "./core/types.js";
11
+ export { AtomicPluginUpdater } from "./core/updater.js";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * ContextOS Plugin Supply Chain CLI Adapter
3
+ * ADR-002: Bundled CJS entrypoint for CLI consumption
4
+ */
5
+ export { validateArchiveEntry } from "./core/archive.js";
6
+ export { calculateTreeDigest, sha256 } from "./core/digest.js";
7
+ export { ScriptGrantManager } from "./core/grants.js";
8
+ export { validatePluginPinning, verifyNpmTarballIntegrity, } from "./core/pinning.js";
9
+ export { THREAT_CODES } from "./core/types.js";
10
+ export { AtomicPluginUpdater } from "./core/updater.js";
11
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/plugins/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACN,qBAAqB,EACrB,yBAAyB,GACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * ContextOS Safe Archive Extraction Scanner
3
+ * Section 20.4 & Threat Model Hardening
4
+ */
5
+ import { type ArchiveEntryLimits, type ArchiveValidationResult } from "./types.js";
6
+ /**
7
+ * Validates an individual archive entry path and metadata against security vulnerabilities.
8
+ */
9
+ export declare function validateArchiveEntry(entryPath: string, limits?: ArchiveEntryLimits): ArchiveValidationResult;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * ContextOS Safe Archive Extraction Scanner
3
+ * Section 20.4 & Threat Model Hardening
4
+ */
5
+ import * as path from "node:path";
6
+ import { THREAT_CODES } from "./types.js";
7
+ const WINDOWS_RESERVED_NAMES = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/i;
8
+ /**
9
+ * Validates an individual archive entry path and metadata against security vulnerabilities.
10
+ */
11
+ export function validateArchiveEntry(entryPath, limits = {}) {
12
+ if (typeof entryPath !== "string" || !entryPath.trim()) {
13
+ return {
14
+ valid: false,
15
+ code: THREAT_CODES.INVALID_PATH,
16
+ error: "Empty or non-string archive path",
17
+ };
18
+ }
19
+ const normalized = entryPath.replace(/\\/g, "/").replace(/^\.\//, "");
20
+ // 1. Absolute path check
21
+ if (path.isAbsolute(entryPath) ||
22
+ /^[a-zA-Z]:[\\/]/.test(entryPath) ||
23
+ /^[a-zA-Z]:/.test(normalized) ||
24
+ normalized.startsWith("/")) {
25
+ return {
26
+ valid: false,
27
+ code: THREAT_CODES.ABSOLUTE_PATH,
28
+ error: `Security violation: absolute archive path rejected: "${entryPath}"`,
29
+ };
30
+ }
31
+ // 2. Directory traversal check
32
+ const parts = normalized.split("/");
33
+ if (parts.includes("..") || normalized.startsWith("../") || normalized.includes("/../")) {
34
+ return {
35
+ valid: false,
36
+ code: THREAT_CODES.PATH_TRAVERSAL,
37
+ error: `Security violation: archive path attempts traversal outside destination: "${entryPath}"`,
38
+ };
39
+ }
40
+ // 3. Windows reserved device names
41
+ for (const part of parts) {
42
+ if (WINDOWS_RESERVED_NAMES.test(part)) {
43
+ return {
44
+ valid: false,
45
+ code: THREAT_CODES.RESERVED_NAME,
46
+ error: `Security violation: Windows reserved device name rejected: "${part}" in "${entryPath}"`,
47
+ };
48
+ }
49
+ }
50
+ // 4. Special files (devices, sockets, fifos)
51
+ if (limits.entryType === "socket" ||
52
+ limits.entryType === "fifo" ||
53
+ limits.entryType === "characterDevice" ||
54
+ limits.entryType === "blockDevice") {
55
+ return {
56
+ valid: false,
57
+ code: THREAT_CODES.SPECIAL_FILE,
58
+ error: `Security violation: special device or socket rejected: "${entryPath}" (${limits.entryType})`,
59
+ };
60
+ }
61
+ // 5. Symlink / hardlink escape checks
62
+ if (limits.linkTarget || limits.entryType === "symlink" || limits.entryType === "hardlink") {
63
+ if (limits.linkTarget) {
64
+ const targetNorm = limits.linkTarget.replace(/\\/g, "/");
65
+ if (path.isAbsolute(limits.linkTarget) || /^[a-zA-Z]:/.test(targetNorm) || targetNorm.startsWith("/")) {
66
+ return {
67
+ valid: false,
68
+ code: THREAT_CODES.SYMLINK_ESCAPE,
69
+ error: `Security violation: absolute symlink/hardlink target rejected: "${limits.linkTarget}"`,
70
+ };
71
+ }
72
+ const entryDir = path.posix.dirname(normalized);
73
+ const resolvedTarget = path.posix.normalize(path.posix.join(entryDir, targetNorm));
74
+ if (resolvedTarget.startsWith("../") || resolvedTarget === ".." || resolvedTarget.includes("/../")) {
75
+ return {
76
+ valid: false,
77
+ code: THREAT_CODES.SYMLINK_ESCAPE,
78
+ error: `Security violation: symlink target escapes archive boundary: "${limits.linkTarget}"`,
79
+ };
80
+ }
81
+ }
82
+ }
83
+ // 6. Case & Unicode collision checks
84
+ if (limits.seenPaths) {
85
+ const folded = normalized.toLowerCase().normalize("NFC");
86
+ if (limits.seenPaths.has(folded)) {
87
+ return {
88
+ valid: false,
89
+ code: THREAT_CODES.CASE_COLLISION,
90
+ error: `Security violation: case or Unicode collision detected for path: "${entryPath}"`,
91
+ };
92
+ }
93
+ limits.seenPaths.add(folded);
94
+ }
95
+ // 7. Compression ratio bomb check
96
+ if (typeof limits.uncompressedSize === "number" && typeof limits.compressedSize === "number") {
97
+ if (limits.compressedSize > 0) {
98
+ const ratio = limits.uncompressedSize / limits.compressedSize;
99
+ const maxRatio = limits.maxRatio ?? 100;
100
+ if (ratio > maxRatio && limits.uncompressedSize > 1024 * 1024) {
101
+ return {
102
+ valid: false,
103
+ code: THREAT_CODES.RATIO_EXCEEDED,
104
+ error: `Security violation: suspicious compression ratio (${ratio.toFixed(1)}x) exceeds limit (${maxRatio}x)`,
105
+ };
106
+ }
107
+ }
108
+ }
109
+ // 8. Zip bomb / count & size limits
110
+ if (typeof limits.currentCount === "number" && limits.maxFiles && limits.currentCount >= limits.maxFiles) {
111
+ return {
112
+ valid: false,
113
+ code: THREAT_CODES.MAX_FILES_EXCEEDED,
114
+ error: `Security violation: archive exceeds maximum permitted file count (${limits.maxFiles})`,
115
+ };
116
+ }
117
+ if (typeof limits.currentTotalBytes === "number" &&
118
+ limits.maxTotalBytes &&
119
+ limits.currentTotalBytes >= limits.maxTotalBytes) {
120
+ return {
121
+ valid: false,
122
+ code: THREAT_CODES.MAX_SIZE_EXCEEDED,
123
+ error: `Security violation: archive exceeds maximum uncompressed size (${limits.maxTotalBytes} bytes)`,
124
+ };
125
+ }
126
+ return { valid: true };
127
+ }
128
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/plugins/core/archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * ContextOS Plugin Full-Tree Digest Calculation
3
+ * Section 20.3 & Threat Model Hardening
4
+ */
5
+ import type { TreeDigestOptions, TreeDigestResult } from "./types.js";
6
+ export declare function sha256(data: Buffer | string): string;
7
+ /**
8
+ * Calculates a deterministic full-tree digest for a directory.
9
+ * Includes file modes, types (files, symlinks), sizes, and content digests.
10
+ */
11
+ export declare function calculateTreeDigest(dirPath: string, _options?: TreeDigestOptions): TreeDigestResult;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * ContextOS Plugin Full-Tree Digest Calculation
3
+ * Section 20.3 & Threat Model Hardening
4
+ */
5
+ import * as crypto from "node:crypto";
6
+ import * as fs from "node:fs";
7
+ import * as path from "node:path";
8
+ export function sha256(data) {
9
+ return crypto.createHash("sha256").update(data).digest("hex");
10
+ }
11
+ /**
12
+ * Calculates a deterministic full-tree digest for a directory.
13
+ * Includes file modes, types (files, symlinks), sizes, and content digests.
14
+ */
15
+ export function calculateTreeDigest(dirPath, _options = {}) {
16
+ const resolvedDir = path.resolve(dirPath);
17
+ if (!fs.existsSync(resolvedDir)) {
18
+ throw new Error(`Directory does not exist: ${resolvedDir}`);
19
+ }
20
+ const fileEntries = [];
21
+ function walk(current) {
22
+ const items = fs.readdirSync(current, { withFileTypes: true });
23
+ // Deterministic alphabetical sorting
24
+ items.sort((a, b) => a.name.localeCompare(b.name));
25
+ for (const item of items) {
26
+ const fullPath = path.join(current, item.name);
27
+ if (item.isDirectory()) {
28
+ walk(fullPath);
29
+ }
30
+ else if (item.isSymbolicLink()) {
31
+ const rel = path.relative(resolvedDir, fullPath).replace(/\\/g, "/");
32
+ const stat = fs.lstatSync(fullPath);
33
+ const linkTarget = fs.readlinkSync(fullPath);
34
+ const hash = sha256(linkTarget);
35
+ fileEntries.push({
36
+ relativePath: rel,
37
+ size: stat.size,
38
+ mode: stat.mode & 0o777,
39
+ sha256: hash,
40
+ type: "symlink",
41
+ });
42
+ }
43
+ else if (item.isFile()) {
44
+ const rel = path.relative(resolvedDir, fullPath).replace(/\\/g, "/");
45
+ const stat = fs.statSync(fullPath);
46
+ const content = fs.readFileSync(fullPath);
47
+ const hash = sha256(content);
48
+ fileEntries.push({
49
+ relativePath: rel,
50
+ size: stat.size,
51
+ mode: stat.mode & 0o777,
52
+ sha256: hash,
53
+ type: "file",
54
+ });
55
+ }
56
+ }
57
+ }
58
+ walk(resolvedDir);
59
+ // Deterministically sort by relativePath
60
+ fileEntries.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
61
+ const manifestString = fileEntries
62
+ .map((f) => `${f.relativePath}|${f.size}|${f.mode}|${f.type}|${f.sha256}`)
63
+ .join("\n");
64
+ const treeDigest = sha256(manifestString);
65
+ return {
66
+ treeDigest,
67
+ files: fileEntries,
68
+ };
69
+ }
70
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../../../src/plugins/core/digest.ts"],"names":[],"mappings":"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"}