@guyghost/swarm-dao-core 0.9.0 → 0.10.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.
@@ -4,13 +4,20 @@ import type { ExecutionWorkspacePort, ExecutionWorkspaceResult } from "../ports/
4
4
  import type { Proposal } from "../types/index.js";
5
5
  /**
6
6
  * Build the workspace port from a project config: undefined (no isolation)
7
- * unless config.execution.isolation === "worktree". Fails closed — an absent
8
- * or malformed config never enables isolation.
7
+ * unless config.execution.isolation is "worktree" or "sandbox" (ADR-003).
8
+ * Fails closed — an absent or malformed config never enables isolation; a
9
+ * malformed sandbox section surfaces as an invalid plan at prepare time.
9
10
  */
10
11
  export declare function createExecutionWorkspace(execution: {
11
12
  isolation?: string;
12
13
  worktreeRoot?: string;
13
14
  baseBranch?: string;
15
+ sandbox?: {
16
+ runtime?: string;
17
+ image?: string;
18
+ cpus?: number;
19
+ memoryMb?: number;
20
+ };
14
21
  } | undefined, runner: CommandRunnerPort, repositoryRoot: string): ExecutionWorkspacePort | undefined;
15
22
  export interface GitWorkspaceOptions extends ExecutionIsolationOptions {
16
23
  /** Runs shell commands (typically the host adapter's exec). */
@@ -1 +1 @@
1
- {"version":3,"file":"git-workspace.d.ts","sourceRoot":"","sources":["../../src/adapters/git-workspace.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,yBAAyB,EAA0B,MAAM,oCAAoC,CAAC;AAE5G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIlD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACzF,MAAM,EAAE,iBAAiB,EACzB,cAAc,EAAE,MAAM,GACrB,sBAAsB,GAAG,SAAS,CASpC;AAED,MAAM,WAAW,mBAAoB,SAAQ,yBAAyB;IACpE,+DAA+D;IAC/D,MAAM,EAAE,iBAAiB,CAAC;IAC1B,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;CACxB;AAID,qBAAa,YAAa,YAAW,sBAAsB;;gBAGtC,OAAO,EAAE,mBAAmB;IAIlC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAqDlG"}
1
+ {"version":3,"file":"git-workspace.d.ts","sourceRoot":"","sources":["../../src/adapters/git-workspace.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,yBAAyB,EAA0B,MAAM,oCAAoC,CAAC;AAE5G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIlD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EACL;IACE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClF,GACD,SAAS,EACb,MAAM,EAAE,iBAAiB,EACzB,cAAc,EAAE,MAAM,GACrB,sBAAsB,GAAG,SAAS,CAcpC;AAED,MAAM,WAAW,mBAAoB,SAAQ,yBAAyB;IACpE,+DAA+D;IAC/D,MAAM,EAAE,iBAAiB,CAAC;IAC1B,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;CACxB;AAID,qBAAa,YAAa,YAAW,sBAAsB;;gBAGtC,OAAO,EAAE,mBAAmB;IAIlC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAmElG"}
@@ -10,18 +10,24 @@ import { slugify } from "../integrations/utils.js";
10
10
  const GIT_TIMEOUT_MS = 60_000;
11
11
  /**
12
12
  * Build the workspace port from a project config: undefined (no isolation)
13
- * unless config.execution.isolation === "worktree". Fails closed — an absent
14
- * or malformed config never enables isolation.
13
+ * unless config.execution.isolation is "worktree" or "sandbox" (ADR-003).
14
+ * Fails closed — an absent or malformed config never enables isolation; a
15
+ * malformed sandbox section surfaces as an invalid plan at prepare time.
15
16
  */
16
17
  export function createExecutionWorkspace(execution, runner, repositoryRoot) {
17
- if (execution?.isolation !== "worktree")
18
+ if (execution?.isolation !== "worktree" && execution?.isolation !== "sandbox")
18
19
  return undefined;
20
+ // Raw pass-through: the planner validates runtime/image and fails closed on
21
+ // invalid config (coercing "podman" to docker would fake the boundary —
22
+ // Copilot review on #85).
23
+ const sandbox = execution.isolation === "sandbox" ? execution.sandbox : undefined;
19
24
  return new GitWorkspace({
20
25
  runner,
21
26
  repositoryRoot,
22
- isolation: "worktree",
27
+ isolation: execution.isolation,
23
28
  worktreeRoot: execution.worktreeRoot,
24
29
  baseBranch: execution.baseBranch ?? null,
30
+ ...(sandbox ? { sandbox } : {}),
25
31
  });
26
32
  }
27
33
  const BRANCH_EXISTS = /already exists/i;
@@ -42,6 +48,18 @@ export class GitWorkspace {
42
48
  // execution snapshot can carry it, but change nothing on disk.
43
49
  return { ok: true, branch: `dao/${proposal.id}-${slugify(proposal.title) || "proposal"}`, path: null };
44
50
  }
51
+ if (plan.mode === "sandbox") {
52
+ // Probe the runtime before touching git: an evolution that cannot be
53
+ // bounded must not silently degrade to host execution (ADR-003).
54
+ const probe = await this.#exec(`${plan.runtime} --version`);
55
+ if (!probe.ok) {
56
+ return {
57
+ ok: false,
58
+ error: `sandbox runtime '${plan.runtime}' is not available on this host (${probe.error}). ` +
59
+ `Install Docker or Apple container, or set execution.isolation to "worktree".`,
60
+ };
61
+ }
62
+ }
45
63
  // Idempotent retry: the worktree may already exist and be checked out on
46
64
  // the target branch (previous attempt, re-run of dao_execute).
47
65
  const current = await this.#exec(`git -C ${plan.path} rev-parse --abbrev-ref HEAD`);
@@ -1 +1 @@
1
- {"version":3,"file":"git-workspace.js","sourceRoot":"","sources":["../../src/adapters/git-workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git-workspace.js","sourceRoot":"","sources":["../../src/adapters/git-workspace.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,25 @@
1
1
  import type { Proposal } from "../types/index.js";
2
- export type ExecutionIsolationMode = "none" | "worktree";
2
+ export type ExecutionIsolationMode = "none" | "worktree" | "sandbox";
3
+ /**
4
+ * Container configuration for sandboxed execution (ADR-003). The shape is
5
+ * deliberately loose: runtime and image are operator input, validated by the
6
+ * planner — anything but docker/container fails closed as an invalid plan.
7
+ */
8
+ export interface SandboxExecutionOptions {
9
+ runtime?: string;
10
+ image?: string;
11
+ cpus?: number;
12
+ memoryMb?: number;
13
+ }
3
14
  export interface ExecutionIsolationOptions {
4
- /** "none" (default, no isolation) or "worktree" (dedicated worktree). */
15
+ /** "none" (default), "worktree" (host worktree), or "sandbox" (worktree + bounded container). */
5
16
  isolation?: ExecutionIsolationMode;
6
17
  /** Directory (relative to the repository root) holding worktrees. */
7
18
  worktreeRoot?: string;
8
19
  /** Base branch for the execution branch; null lets git use HEAD. */
9
20
  baseBranch?: string | null;
21
+ /** Required when isolation is "sandbox": container runtime, image, and bounds. */
22
+ sandbox?: SandboxExecutionOptions;
10
23
  }
11
24
  export type ExecutionIsolationPlan = {
12
25
  mode: "none";
@@ -22,6 +35,16 @@ export type ExecutionIsolationPlan = {
22
35
  path: string;
23
36
  /** Configured base branch, or null for git's default (HEAD). */
24
37
  baseBranch: string | null;
38
+ } | {
39
+ /** Worktree + bounded container: files isolated by git, effects by the runtime. */
40
+ mode: "sandbox";
41
+ runtime: "docker" | "container";
42
+ image: string;
43
+ cpus: number;
44
+ memoryMb: number;
45
+ branch: string;
46
+ path: string;
47
+ baseBranch: string | null;
25
48
  };
26
49
  export declare const DEFAULT_WORKTREE_ROOT = ".dao/worktrees";
27
50
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"execution-isolation.d.ts","sourceRoot":"","sources":["../../src/delivery/execution-isolation.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,yBAAyB;IACxC,yEAAyE;IACzE,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEN,eAAO,MAAM,qBAAqB,mBAAmB,CAAC;AA0CtD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC,EACxC,OAAO,GAAE,yBAA8B,GACtC,sBAAsB,CAyBxB"}
1
+ {"version":3,"file":"execution-isolation.d.ts","sourceRoot":"","sources":["../../src/delivery/execution-isolation.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGlD,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,iGAAiG;IACjG,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kFAAkF;IAClF,OAAO,CAAC,EAAE,uBAAuB,CAAC;CACnC;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GACD;IACE,mFAAmF;IACnF,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,QAAQ,GAAG,WAAW,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEN,eAAO,MAAM,qBAAqB,mBAAmB,CAAC;AA0CtD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC,EACxC,OAAO,GAAE,yBAA8B,GACtC,sBAAsB,CA0DxB"}
@@ -17,6 +17,7 @@
17
17
  // metacharacters — fails closed as an `invalid` plan, which surfaces as a
18
18
  // preparation error and leaves the proposal `controlled`.
19
19
  import { slugify } from "../integrations/utils.js";
20
+ import { validateSandboxImage } from "./sandbox-command.js";
20
21
  export const DEFAULT_WORKTREE_ROOT = ".dao/worktrees";
21
22
  /**
22
23
  * Relative path segment charset: alphanumerics plus `._-`, optionally
@@ -68,8 +69,9 @@ function validateBaseBranch(branch) {
68
69
  * closed to "invalid" (never to silent shell interpolation).
69
70
  */
70
71
  export function planExecutionIsolation(proposal, options = {}) {
71
- if (options.isolation !== "worktree")
72
+ if (options.isolation !== "worktree" && options.isolation !== "sandbox")
72
73
  return { mode: "none" };
74
+ const sandboxed = options.isolation === "sandbox";
73
75
  const root = options.worktreeRoot && options.worktreeRoot.length > 0 ? options.worktreeRoot : DEFAULT_WORKTREE_ROOT;
74
76
  const rootError = validateWorktreeRoot(root);
75
77
  if (rootError)
@@ -83,15 +85,55 @@ export function planExecutionIsolation(proposal, options = {}) {
83
85
  return { mode: "invalid", error: branchError };
84
86
  }
85
87
  const baseBranch = typeof rawBase === "string" ? rawBase : null;
88
+ let runtime = "docker";
89
+ let image = "";
90
+ let cpus;
91
+ let memoryMb;
92
+ if (sandboxed) {
93
+ // A sandbox plan without a runtime and a plain image reference fails
94
+ // closed: bounded execution with an unbounded image string would be
95
+ // theater (ADR-003).
96
+ const sandbox = options.sandbox;
97
+ if (!sandbox || (sandbox.runtime !== "docker" && sandbox.runtime !== "container")) {
98
+ return { mode: "invalid", error: 'sandbox isolation requires sandbox.runtime of "docker" or "container"' };
99
+ }
100
+ runtime = sandbox.runtime;
101
+ const imageCandidate = sandbox.image ?? "";
102
+ const imageError = validateSandboxImage(imageCandidate);
103
+ if (imageError)
104
+ return { mode: "invalid", error: imageError };
105
+ image = imageCandidate;
106
+ cpus = sandbox.cpus;
107
+ memoryMb = sandbox.memoryMb;
108
+ }
86
109
  // slugify() output is strictly [a-z0-9-], so the derived branch and path
87
110
  // inherit the validated charset of the root.
88
111
  const slug = slugify(proposal.title) || "proposal";
89
112
  const trimmedRoot = root.replace(/\/+$/, "");
113
+ const branch = `dao/${proposal.id}-${slug}`;
114
+ const worktreePath = `${trimmedRoot}/${proposal.id}-${slug}`;
115
+ if (!sandboxed) {
116
+ return { mode: "worktree", branch, path: worktreePath, baseBranch };
117
+ }
118
+ const boundedCpus = boundedCpusValue(cpus);
119
+ const boundedMemoryMb = boundedMemoryValue(memoryMb);
90
120
  return {
91
- mode: "worktree",
92
- branch: `dao/${proposal.id}-${slug}`,
93
- path: `${trimmedRoot}/${proposal.id}-${slug}`,
121
+ mode: "sandbox",
122
+ runtime,
123
+ image,
124
+ cpus: boundedCpus,
125
+ memoryMb: boundedMemoryMb,
126
+ branch,
127
+ path: worktreePath,
94
128
  baseBranch,
95
129
  };
96
130
  }
131
+ const boundedCpusValue = (value) => {
132
+ const parsed = typeof value === "number" && Number.isFinite(value) ? Math.trunc(value) : 2;
133
+ return Math.min(Math.max(parsed, 1), 64);
134
+ };
135
+ const boundedMemoryValue = (value) => {
136
+ const parsed = typeof value === "number" && Number.isFinite(value) ? Math.trunc(value) : 2048;
137
+ return Math.min(Math.max(parsed, 256), 1_048_576);
138
+ };
97
139
  //# sourceMappingURL=execution-isolation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-isolation.js","sourceRoot":"","sources":["../../src/delivery/execution-isolation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"execution-isolation.js","sourceRoot":"","sources":["../../src/delivery/execution-isolation.ts"],"names":[],"mappings":"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"}
@@ -4,5 +4,6 @@ export * from "./dry-run.js";
4
4
  export * from "./execution.js";
5
5
  export * from "./execution-isolation.js";
6
6
  export * from "./plans.js";
7
+ export * from "./sandbox-command.js";
7
8
  export * from "./ship-audit.js";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/delivery/index.ts"],"names":[],"mappings":"AAEA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/delivery/index.ts"],"names":[],"mappings":"AAEA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC"}
@@ -5,5 +5,6 @@ export * from "./dry-run.js";
5
5
  export * from "./execution.js";
6
6
  export * from "./execution-isolation.js";
7
7
  export * from "./plans.js";
8
+ export * from "./sandbox-command.js";
8
9
  export * from "./ship-audit.js";
9
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delivery/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delivery/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /** Shared mount point for the project workspace inside sandbox containers. */
2
+ export declare const SANDBOX_WORKDIR_MOUNT = "/workspace";
3
+ export type SandboxRuntime = "docker" | "container";
4
+ export interface SandboxCommandOptions {
5
+ runtime: SandboxRuntime;
6
+ /** OCI image reference (validated; never interpolated unquoted). */
7
+ image: string;
8
+ /** Absolute host path mounted read-write at /workspace. */
9
+ workDir: string;
10
+ cpus?: number;
11
+ memoryMb?: number;
12
+ }
13
+ /** Fail closed on anything that is not a plain OCI image reference. */
14
+ export declare function validateSandboxImage(image: string): string | null;
15
+ /**
16
+ * Build the bounded container command line for one command. Both runtimes
17
+ * accept the same option shapes: --rm --network none --cpus N --memory <n>M
18
+ * -v <host>:<target> -w <target> <image> sh -c <command>.
19
+ */
20
+ export declare function buildSandboxCommand(options: SandboxCommandOptions, command: string): string;
21
+ //# sourceMappingURL=sandbox-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-command.d.ts","sourceRoot":"","sources":["../../src/delivery/sandbox-command.ts"],"names":[],"mappings":"AAaA,8EAA8E;AAC9E,eAAO,MAAM,qBAAqB,eAAe,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEpD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,cAAc,CAAC;IACxB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQjE;AAYD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA6B3F"}
@@ -0,0 +1,69 @@
1
+ // ============================================================
2
+ // Swarm DAO Core — Bounded Container Command (pure planning)
3
+ // ============================================================
4
+ // Builds the shell command line that runs one command inside a throwaway
5
+ // container (Docker or Apple container): repository/worktree bind-mounted at
6
+ // /workspace, network disabled, CPU/memory capped. Every value that reaches
7
+ // the command line (image, host path, command) is validated or quoted here;
8
+ // anything ambiguous fails closed.
9
+ //
10
+ // Pure: string in, string out. Executing the command is an effect that lives
11
+ // with the caller (improvement-loop sandbox runner, delivery adapters, hosts).
12
+ // Boundary, not authority: a sandbox never judges outcomes.
13
+ /** Shared mount point for the project workspace inside sandbox containers. */
14
+ export const SANDBOX_WORKDIR_MOUNT = "/workspace";
15
+ /** OCI image reference: optional registry host/port, repo path, tag and/or digest. */
16
+ const SAFE_IMAGE = /^[a-z0-9]+(?:[._-][a-z0-9]+)*(?::[0-9]{1,5})?(\/[a-z0-9]+(?:[._/-][a-z0-9]+)*)?(:[a-zA-Z0-9._-]{1,128})?(@sha256:[a-f0-9]{64})?$/;
17
+ /** Fail closed on anything that is not a plain OCI image reference. */
18
+ export function validateSandboxImage(image) {
19
+ if (typeof image !== "string" || image.length === 0 || image.length > 256) {
20
+ return "sandbox image must be a non-empty image reference";
21
+ }
22
+ if (!SAFE_IMAGE.test(image)) {
23
+ return `sandbox image '${image}' is not a plain OCI reference (registry/repo[:tag][@digest])`;
24
+ }
25
+ return null;
26
+ }
27
+ const DEFAULT_CPUS = 2;
28
+ const DEFAULT_MEMORY_MB = 2048;
29
+ const boundedInt = (value, fallback, min, max) => {
30
+ const parsed = typeof value === "number" && Number.isFinite(value) ? Math.trunc(value) : fallback;
31
+ return Math.min(Math.max(parsed, min), max);
32
+ };
33
+ const shellQuote = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
34
+ /**
35
+ * Build the bounded container command line for one command. Both runtimes
36
+ * accept the same option shapes: --rm --network none --cpus N --memory <n>M
37
+ * -v <host>:<target> -w <target> <image> sh -c <command>.
38
+ */
39
+ export function buildSandboxCommand(options, command) {
40
+ const imageError = validateSandboxImage(options.image);
41
+ if (imageError)
42
+ throw new Error(imageError);
43
+ if (typeof options.workDir !== "string" || !options.workDir.startsWith("/")) {
44
+ throw new Error("sandbox workDir must be an absolute host path");
45
+ }
46
+ const cpus = boundedInt(options.cpus, DEFAULT_CPUS, 1, 64);
47
+ const memoryMb = boundedInt(options.memoryMb, DEFAULT_MEMORY_MB, 256, 1_048_576);
48
+ const args = [
49
+ options.runtime,
50
+ "run",
51
+ "--rm",
52
+ "--network",
53
+ "none",
54
+ "--cpus",
55
+ String(cpus),
56
+ "--memory",
57
+ `${memoryMb}M`,
58
+ "-v",
59
+ shellQuote(`${options.workDir}:${SANDBOX_WORKDIR_MOUNT}`),
60
+ "-w",
61
+ SANDBOX_WORKDIR_MOUNT,
62
+ options.image,
63
+ "sh",
64
+ "-c",
65
+ shellQuote(command),
66
+ ];
67
+ return args.join(" ");
68
+ }
69
+ //# sourceMappingURL=sandbox-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-command.js","sourceRoot":"","sources":["../../src/delivery/sandbox-command.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,6DAA6D;AAC7D,+DAA+D;AAC/D,yEAAyE;AACzE,6EAA6E;AAC7E,4EAA4E;AAC5E,4EAA4E;AAC5E,mCAAmC;AACnC,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,4DAA4D;AAE5D,8EAA8E;AAC9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAclD,sFAAsF;AACtF,MAAM,UAAU,GACd,kIAAkI,CAAC;AAErI,uEAAuE;AACvE,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC1E,OAAO,mDAAmD,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,kBAAkB,KAAK,+DAA+D,CAAC;IAChG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAE/B,MAAM,UAAU,GAAG,CAAC,KAAyB,EAAE,QAAgB,EAAE,GAAW,EAAE,GAAW,EAAU,EAAE;IACnG,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClG,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AAElF;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA8B,EAAE,OAAe;IACjF,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvD,IAAI,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;IACjF,MAAM,IAAI,GAAG;QACX,OAAO,CAAC,OAAO;QACf,KAAK;QACL,MAAM;QACN,WAAW;QACX,MAAM;QACN,QAAQ;QACR,MAAM,CAAC,IAAI,CAAC;QACZ,UAAU;QACV,GAAG,QAAQ,GAAG;QACd,IAAI;QACJ,UAAU,CAAC,GAAG,OAAO,CAAC,OAAO,IAAI,qBAAqB,EAAE,CAAC;QACzD,IAAI;QACJ,qBAAqB;QACrB,OAAO,CAAC,KAAK;QACb,IAAI;QACJ,IAAI;QACJ,UAAU,CAAC,OAAO,CAAC;KACpB,CAAC;IACF,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guyghost/swarm-dao-core",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Swarm DAO core — pure business logic for AI agent governance",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",