@geminixiang/mikan 1.0.0-beta.69 → 1.0.0-beta.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -9,6 +9,12 @@ any release.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.0.0-beta.70]
13
+
14
+ ### Fixed
15
+
16
+ - Sandbox: a container migrated to the office-key mount layout (or recreated after its mount configuration drifted) no longer re-migrates on every subsequent restart. The one-time bridging snapshot image is now removed once the new container is confirmed up, instead of being kept forever on the mistaken assumption that the container would eventually run from the base image again. In production this had pinned dozens of containers to increasingly stale snapshots and left their images unreclaimed, consuming disk space on every restart.
17
+
12
18
  ## [1.0.0-beta.69]
13
19
 
14
20
  ### Changed
@@ -77,13 +77,12 @@ export declare class DockerContainerManager {
77
77
  * Recreate a drifted container with the desired mounts while keeping its
78
78
  * writable layer: commit — the new binds ride the snapshot label, so a
79
79
  * crash at any point resumes through the layout-migration path — then
80
- * remove, create from the snapshot, and start. Committing replaces any
81
- * older snapshot tag for this container; the untagged predecessor is
82
- * removed once the new container is up.
80
+ * remove, create from the snapshot, and start. The snapshot is untagged
81
+ * once the new container is confirmed up: its only job was bridging
82
+ * commit → create, and the container now owns that content in its own
83
+ * writable layer, so nothing still needs the tag.
83
84
  */
84
85
  private recreateContainerPreservingContents;
85
- /** Resolved image id for a reference, or undefined when it does not exist. */
86
- private readImageId;
87
86
  /** Binds recorded on a snapshot image, or undefined when no snapshot exists. */
88
87
  private readMigrateImageBinds;
89
88
  private readImageLabel;
@@ -94,6 +93,17 @@ export declare class DockerContainerManager {
94
93
  */
95
94
  private removeMigrateSnapshot;
96
95
  private listMigrateSnapshotContainerNames;
96
+ /**
97
+ * Catch-up pass for snapshots the success path in
98
+ * `migrateContainerLayoutInner` did not get to remove itself — e.g. a
99
+ * crash between `createContainerFromSnapshot` and its own cleanup. A
100
+ * snapshot is only still needed while its container remains "missing"
101
+ * (the resume path in `migrateContainerLayoutInner` reads pre-removal
102
+ * binds off it); once the container exists again in any state, the
103
+ * snapshot has done its job regardless of whether that container's
104
+ * `Config.Image` still points at it — removing a tag never deletes
105
+ * layers a live container still uses.
106
+ */
97
107
  private removeDanglingMigrateImages;
98
108
  reconcile(): Promise<void>;
99
109
  private setState;
@@ -1 +1 @@
1
- {"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../../src/sandbox/provisioner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../../src/sandbox/provisioner.ts"],"names":[],"mappings":"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"}
@@ -285,6 +285,13 @@ export class DockerContainerManager {
285
285
  await this.execFileImpl("docker", ["rm", "-f", containerName]);
286
286
  }
287
287
  await this.createContainerFromSnapshot(containerName, originalBinds.map(translator));
288
+ // The snapshot's only job was bridging commit → create; the new container
289
+ // already owns that content in its own writable layer; untagging it now
290
+ // (rather than waiting for a "natural recreation from the base image"
291
+ // that never happens — every recreation path here targets this same
292
+ // snapshot family) is what makes migration actually one-time instead of
293
+ // repeating on every future sweep that still finds the tag.
294
+ await this.removeMigrateSnapshot(containerName);
288
295
  log.logInfo(`Container ${containerName} migrated to the office layout`);
289
296
  }
290
297
  /**
@@ -371,14 +378,14 @@ export class DockerContainerManager {
371
378
  * Recreate a drifted container with the desired mounts while keeping its
372
379
  * writable layer: commit — the new binds ride the snapshot label, so a
373
380
  * crash at any point resumes through the layout-migration path — then
374
- * remove, create from the snapshot, and start. Committing replaces any
375
- * older snapshot tag for this container; the untagged predecessor is
376
- * removed once the new container is up.
381
+ * remove, create from the snapshot, and start. The snapshot is untagged
382
+ * once the new container is confirmed up: its only job was bridging
383
+ * commit → create, and the container now owns that content in its own
384
+ * writable layer, so nothing still needs the tag.
377
385
  */
378
386
  async recreateContainerPreservingContents(containerKey, containerName, mounts) {
379
387
  const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;
380
388
  const bindSpecs = mounts.map((mount) => this.toBindSpec(mount));
381
- const previousImageId = await this.readImageId(snapshotImage);
382
389
  await this.execFileImpl("docker", [
383
390
  "commit",
384
391
  "-c",
@@ -390,26 +397,7 @@ export class DockerContainerManager {
390
397
  await this.createContainerFromSnapshot(containerName, bindSpecs, containerKey);
391
398
  await this.execFileImpl("docker", ["start", containerName]);
392
399
  await this.removeStaleMountpoints(containerName, bindSpecs);
393
- const currentImageId = await this.readImageId(snapshotImage);
394
- if (previousImageId && previousImageId !== currentImageId) {
395
- try {
396
- await this.execFileImpl("docker", ["rmi", previousImageId]);
397
- }
398
- catch (err) {
399
- log.logWarning(`Could not remove superseded snapshot image ${previousImageId}`, String(err));
400
- }
401
- }
402
- }
403
- /** Resolved image id for a reference, or undefined when it does not exist. */
404
- async readImageId(image) {
405
- try {
406
- const { stdout } = await this.execFileImpl("docker", ["inspect", "-f", "{{.Id}}", image]);
407
- const id = stdout.trim();
408
- return id.length > 0 ? id : undefined;
409
- }
410
- catch {
411
- return undefined;
412
- }
400
+ await this.removeMigrateSnapshot(containerName);
413
401
  }
414
402
  /** Binds recorded on a snapshot image, or undefined when no snapshot exists. */
415
403
  async readMigrateImageBinds(snapshotImage) {
@@ -466,6 +454,17 @@ export class DockerContainerManager {
466
454
  return [];
467
455
  }
468
456
  }
457
+ /**
458
+ * Catch-up pass for snapshots the success path in
459
+ * `migrateContainerLayoutInner` did not get to remove itself — e.g. a
460
+ * crash between `createContainerFromSnapshot` and its own cleanup. A
461
+ * snapshot is only still needed while its container remains "missing"
462
+ * (the resume path in `migrateContainerLayoutInner` reads pre-removal
463
+ * binds off it); once the container exists again in any state, the
464
+ * snapshot has done its job regardless of whether that container's
465
+ * `Config.Image` still points at it — removing a tag never deletes
466
+ * layers a live container still uses.
467
+ */
469
468
  async removeDanglingMigrateImages() {
470
469
  let stdout;
471
470
  try {
@@ -482,18 +481,8 @@ export class DockerContainerManager {
482
481
  for (const image of this.parseNameLines(stdout)) {
483
482
  const containerName = image.slice(DockerContainerManager.MIGRATE_IMAGE_PREFIX.length + 1);
484
483
  const status = await this.inspectStatus(containerName);
485
- if (status !== "missing") {
486
- // Still referenced (until the container's next natural recreation
487
- // from the base image); keep the snapshot.
488
- const { stdout: imageRef } = await this.execFileImpl("docker", [
489
- "inspect",
490
- "-f",
491
- "{{.Config.Image}}",
492
- containerName,
493
- ]);
494
- if (imageRef.trim() === image)
495
- continue;
496
- }
484
+ if (status === "missing")
485
+ continue; // still needed for a future resume
497
486
  try {
498
487
  await this.execFileImpl("docker", ["rmi", image]);
499
488
  log.logInfo(`Removed layout-migration snapshot image ${image}`);
@@ -1 +1 @@
1
- {"version":3,"file":"provisioner.js","sourceRoot":"","sources":["../../src/sandbox/provisioner.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { legacyConversationResourceKey, sanitizeIdentitySegment } from \"./identity.js\";\nimport { createHash } from \"node:crypto\";\nimport { readFileSync, statSync } from \"node:fs\";\nimport { promisify } from \"node:util\";\nimport * as log from \"../log.js\";\nimport { reportUserFacingError } from \"../observability/index.js\";\n\nconst execFileAsync = promisify(execFile);\ntype ExecFileAsync = typeof execFileAsync;\n\ntype ContainerStatus = \"running\" | \"stopped\" | \"missing\";\n\nfunction isDockerNotFoundError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const stderr = (err as { stderr?: unknown }).stderr;\n const message = (err as { message?: unknown }).message;\n const haystack = `${typeof stderr === \"string\" ? stderr : \"\"}\\n${\n typeof message === \"string\" ? message : \"\"\n }`.toLowerCase();\n return (\n haystack.includes(\"no such network\") ||\n haystack.includes(\"no such container\") ||\n haystack.includes(\"no such object\") ||\n haystack.includes(\"network not found\") ||\n /network [^\\n]+ not found/.test(haystack) ||\n /error: no such [^\\n]+/.test(haystack)\n );\n}\n\ninterface ContainerState {\n status: ContainerStatus;\n lastUsed: number;\n containerName: string;\n}\n\nexport type {\n ContainerBindTranslator,\n ContainerMount,\n DockerContainerManagerOptions,\n ProvisionOptions,\n ResourceLimits,\n SandboxLimitStatus,\n} from \"../types.js\";\nimport type {\n ContainerBindTranslator,\n ContainerMount,\n DockerContainerManagerOptions,\n ProvisionOptions,\n ResourceLimits,\n SandboxLimitStatus,\n} from \"../types.js\";\n\n/** Parse `src:dst[:ro]` back into a ContainerMount for signature computation. */\nfunction bindSpecToMount(bindSpec: string): ContainerMount {\n const readOnly = bindSpec.endsWith(\":ro\");\n const spec = readOnly ? bindSpec.slice(0, -3) : bindSpec;\n const separator = spec.indexOf(\":\");\n return {\n source: spec.slice(0, separator),\n target: spec.slice(separator + 1),\n ...(readOnly ? { readOnly: true as const } : {}),\n };\n}\n\nexport class DockerContainerManager {\n private state = new Map<string, ContainerState>();\n private inflight = new Map<string, Promise<string>>();\n /** Active layout migration; unset means no translation ever applies. */\n private bindTranslator?: ContainerBindTranslator;\n private layoutMigrations = new Map<string, Promise<void>>();\n private static readonly MANAGED_LABEL = \"mikan.managed=true\";\n private static readonly IMAGE_MODE_LABEL = \"mikan.sandbox=image\";\n private static readonly VAULT_ID_LABEL_KEY = \"mikan.vault-id\";\n private static readonly CONVERSATION_ID_LABEL_KEY = \"mikan.conversation-id\";\n private static readonly MOUNT_SIGNATURE_LABEL_KEY = \"mikan.mount-signature\";\n private static readonly MIGRATE_IMAGE_PREFIX = \"mikan-migrate\";\n private static readonly MIGRATE_BINDS_LABEL_KEY = \"mikan.migrate-binds\";\n\n private readonly limits?: ResourceLimits;\n private readonly boostLimits?: ResourceLimits;\n private readonly boostedKeys = new Set<string>();\n private readonly overrideLimits = new Map<string, ResourceLimits>();\n private readonly execFileImpl: ExecFileAsync;\n\n constructor(\n private readonly image: string,\n options: DockerContainerManagerOptions = {},\n ) {\n this.limits = options.limits;\n this.boostLimits = options.boostLimits;\n this.execFileImpl = options.execFileImpl ?? execFileAsync;\n }\n\n static sanitizeSegment(value: string): string {\n return sanitizeIdentitySegment(value);\n }\n\n static containerName(containerKey: string): string {\n return `mikan-sandbox-${containerKey}`;\n }\n\n static networkName(containerKey: string): string {\n return `mikan-sandbox-net-${containerKey}`;\n }\n\n async provision(containerKey: string, options: ProvisionOptions = {}): Promise<string> {\n const existing = this.inflight.get(containerKey);\n if (existing) return existing;\n\n const pending = this.provisionInner(containerKey, options).finally(() => {\n this.inflight.delete(containerKey);\n });\n this.inflight.set(containerKey, pending);\n return pending;\n }\n\n private async provisionInner(containerKey: string, options: ProvisionOptions): Promise<string> {\n const containerName =\n options.containerName ?? DockerContainerManager.containerName(containerKey);\n const mounts = options.mounts ?? [];\n // A container still on the pre-office layout must move its writable layer\n // to the new mounts before the drift check below would recreate it from\n // the base image and discard everything installed inside.\n await this.migrateContainerLayout(containerName);\n const status = await this.inspectStatus(containerName);\n\n try {\n if (\n status !== \"missing\" &&\n (await this.hasRuntimeDrift(containerKey, containerName, mounts))\n ) {\n log.logInfo(`Container ${containerName} configuration changed; recreating container`);\n await this.recreateContainerPreservingContents(containerKey, containerName, mounts);\n log.logInfo(`Container ${containerName} recreated`);\n } else if (status === \"running\") {\n log.logInfo(`Container ${containerName} already running`);\n } else if (status === \"stopped\") {\n await this.execFileImpl(\"docker\", [\"start\", containerName]);\n log.logInfo(`Container ${containerName} started`);\n } else {\n await this.runContainer(containerKey, containerName, mounts, options);\n log.logInfo(`Container ${containerName} created`);\n }\n } catch (err) {\n this.state.delete(containerKey);\n throw err;\n }\n\n this.setState(containerKey, \"running\", containerName);\n await this.applyResourceLimits(containerKey, containerName);\n return containerName;\n }\n\n async boost(containerKey: string): Promise<SandboxLimitStatus> {\n if (!this.boostLimits?.cpus && !this.boostLimits?.memory) {\n return this.getLimitStatus(containerKey);\n }\n\n this.overrideLimits.delete(containerKey);\n this.boostedKeys.add(containerKey);\n const state = this.state.get(containerKey);\n if (state?.status === \"running\") {\n await this.applyResourceLimits(containerKey, state.containerName);\n }\n return this.getLimitStatus(containerKey);\n }\n\n async setLimits(containerKey: string, limits: ResourceLimits): Promise<SandboxLimitStatus> {\n this.boostedKeys.delete(containerKey);\n this.overrideLimits.set(containerKey, { ...this.limits, ...limits });\n const state = this.state.get(containerKey);\n if (state?.status === \"running\") {\n await this.applyResourceLimits(containerKey, state.containerName);\n }\n return this.getLimitStatus(containerKey);\n }\n\n getLimitStatus(containerKey: string): SandboxLimitStatus {\n const boosted = this.boostedKeys.has(containerKey);\n return { limits: this.effectiveLimits(containerKey), boosted };\n }\n\n getDefaultLimits(): ResourceLimits | undefined {\n return this.limits;\n }\n\n getBoostLimits(): ResourceLimits | undefined {\n return this.boostLimits;\n }\n\n async stop(containerKey: string): Promise<void> {\n const containerName = this.getContainerName(containerKey);\n try {\n await this.execFileImpl(\"docker\", [\"stop\", containerName]);\n this.setState(containerKey, \"stopped\", containerName);\n this.boostedKeys.delete(containerKey);\n this.overrideLimits.delete(containerKey);\n log.logInfo(`Container ${containerName} stopped (idle)`);\n } catch (err) {\n log.logWarning(\n `Failed to stop container ${containerName}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n async remove(containerKey: string): Promise<void> {\n const containerName = this.getContainerName(containerKey);\n const networkName = DockerContainerManager.networkName(containerKey);\n\n const removed = await this.forceRemoveContainer(\n containerName,\n `Container ${containerName} removed`,\n `Failed to remove container ${containerName}`,\n );\n if (!removed) {\n // The container may still be running with its old mounts. Keeping the\n // ownership state (and throwing) is the honest outcome: callers such\n // as credential refresh must not report a teardown that did not happen.\n throw new Error(`Failed to remove container ${containerName}`);\n }\n\n try {\n await this.execFileImpl(\"docker\", [\"network\", \"rm\", networkName]);\n log.logInfo(`Network ${networkName} removed`);\n } catch (err) {\n log.logWarning(\n `Failed to remove network ${networkName}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n\n await this.removeMigrateSnapshot(containerName);\n\n this.state.delete(containerKey);\n this.boostedKeys.delete(containerKey);\n this.overrideLimits.delete(containerKey);\n }\n\n async stopIdle(maxIdleMs: number): Promise<void> {\n const now = Date.now();\n const toStop: string[] = [];\n for (const [containerKey, containerState] of this.state) {\n if (containerState.status === \"running\" && now - containerState.lastUsed > maxIdleMs) {\n toStop.push(containerKey);\n }\n }\n await Promise.all(toStop.map((containerKey) => this.stop(containerKey)));\n }\n\n /**\n * Force-remove every managed container belonging to the given conversation\n * ids. The office layout migration renames the host directories a\n * container's workspace mount points at, so a surviving container would keep\n * writing through stale mounts while the runtime works in the new location.\n */\n async removeContainersForConversations(conversationIds: ReadonlySet<string>): Promise<void> {\n if (conversationIds.size === 0) return;\n const names = await this.listContainerNamesByLabel();\n await Promise.all(\n names.map(async (containerName) => {\n const details = await this.inspectContainerDetails(containerName);\n if (!details?.conversationId || !conversationIds.has(details.conversationId)) return;\n await this.forceRemoveContainer(\n containerName,\n `Removed container ${containerName} after office migration`,\n `Failed to remove container ${containerName} after office migration`,\n );\n }),\n );\n }\n\n /**\n * Arm the office-layout container migration. Containers whose binds still\n * reference legacy raw-id paths are moved to the office-key layout without\n * losing their writable layer: commit → remove → create with translated\n * binds, preserving everything installed inside. Idempotent per container\n * and resumable — the pre-removal binds ride on the snapshot image label,\n * so a crash between commit and create resumes from the snapshot.\n */\n armContainerLayoutMigration(translator: ContainerBindTranslator): void {\n this.bindTranslator = translator;\n }\n\n /**\n * Sweep every managed container through the layout migration, serially and\n * with a small gap, so the one-time cost never lands on the boot path or on\n * a message. Safe to fire-and-forget; each unit is idempotent.\n */\n async sweepContainerLayoutMigration(delayMs = 2000): Promise<void> {\n if (!this.bindTranslator) return;\n let names: string[];\n try {\n // Include snapshot names: a crash between commit and create leaves a\n // snapshot with no container, which must resume before the GC below\n // could mistake it for an orphan.\n const containers = await this.listContainerNamesByLabel();\n const snapshots = await this.listMigrateSnapshotContainerNames();\n names = Array.from(new Set([...containers, ...snapshots]));\n } catch (err) {\n log.logWarning(\"Container layout sweep could not list containers\", String(err));\n return;\n }\n for (const containerName of names) {\n try {\n await this.migrateContainerLayout(containerName);\n } catch (err) {\n log.logWarning(\n `Container layout migration failed for ${containerName}; leaving it in place`,\n err instanceof Error ? err.message : String(err),\n );\n }\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n // Snapshot images whose container has since been recreated from the base\n // image are no longer referenced; reclaim them.\n await this.removeDanglingMigrateImages();\n }\n\n /** Move one container to the office-key layout; no-op when already there. */\n private migrateContainerLayout(containerName: string): Promise<void> {\n const translator = this.bindTranslator;\n if (!translator) return Promise.resolve();\n const existing = this.layoutMigrations.get(containerName);\n if (existing) return existing;\n const pending = this.migrateContainerLayoutInner(containerName, translator).finally(() => {\n this.layoutMigrations.delete(containerName);\n });\n this.layoutMigrations.set(containerName, pending);\n return pending;\n }\n\n private async migrateContainerLayoutInner(\n containerName: string,\n translator: ContainerBindTranslator,\n ): Promise<void> {\n const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;\n\n let originalBinds: string[];\n const status = await this.inspectStatus(containerName);\n if (status === \"missing\") {\n // Resume path: a previous run committed and removed the container but\n // died before creating the replacement. The snapshot carries the\n // pre-removal binds on its label.\n const labeled = await this.readMigrateImageBinds(snapshotImage);\n if (labeled === undefined) return;\n originalBinds = labeled;\n } else {\n originalBinds = await this.inspectBindMounts(containerName);\n const translated = originalBinds.map(translator);\n if (this.sameBinds(translated.toSorted(), originalBinds.slice().toSorted())) {\n return; // already on the office layout\n }\n log.logInfo(`Migrating container ${containerName} to the office layout`);\n await this.execFileImpl(\"docker\", [\n \"commit\",\n \"-c\",\n `LABEL ${DockerContainerManager.MIGRATE_BINDS_LABEL_KEY}=${JSON.stringify(JSON.stringify(originalBinds))}`,\n containerName,\n snapshotImage,\n ]);\n await this.execFileImpl(\"docker\", [\"rm\", \"-f\", containerName]);\n }\n\n await this.createContainerFromSnapshot(containerName, originalBinds.map(translator));\n log.logInfo(`Container ${containerName} migrated to the office layout`);\n }\n\n /**\n * Create `containerName` from its layout snapshot with `bindSpecs`,\n * restoring the managed labels and recomputing the mount signature.\n * `create`, not `run`: idle containers stay stopped exactly as they were;\n * callers that need the container running start it themselves.\n */\n private async createContainerFromSnapshot(\n containerName: string,\n bindSpecs: string[],\n knownContainerKey?: string,\n ): Promise<void> {\n const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;\n // The sweep has only the container name and derives the key; the drift\n // path knows the real key (container names can be caller-supplied).\n const containerKey =\n knownContainerKey ?? this.containerKeyFromContainerName(containerName) ?? containerName;\n const networkName = await this.ensureNetwork(containerKey);\n const conversationId = await this.readImageLabel(\n snapshotImage,\n DockerContainerManager.CONVERSATION_ID_LABEL_KEY,\n );\n const labels = [\n \"--label\",\n DockerContainerManager.MANAGED_LABEL,\n \"--label\",\n DockerContainerManager.IMAGE_MODE_LABEL,\n \"--label\",\n `${DockerContainerManager.VAULT_ID_LABEL_KEY}=${containerKey}`,\n ];\n if (conversationId) {\n labels.push(\n \"--label\",\n `${DockerContainerManager.CONVERSATION_ID_LABEL_KEY}=${conversationId}`,\n );\n }\n labels.push(\n \"--label\",\n `${DockerContainerManager.MOUNT_SIGNATURE_LABEL_KEY}=${this.mountSignature(\n bindSpecs.map(bindSpecToMount),\n )}`,\n );\n await this.execFileImpl(\"docker\", [\n \"create\",\n \"--name\",\n containerName,\n \"--network\",\n networkName,\n \"--cap-drop\",\n \"ALL\",\n \"--security-opt\",\n \"no-new-privileges\",\n \"--pids-limit\",\n \"1024\",\n ...labels,\n ...this.resourceLimitArgs(this.effectiveLimits(containerKey)),\n ...bindSpecs.flatMap((bind) => [\"-v\", bind]),\n snapshotImage,\n \"sleep\",\n \"infinity\",\n ]);\n }\n\n /**\n * `docker commit` captures the empty directories Docker created as bind\n * targets, so a public office that stopped being mounted would linger in\n * the snapshot as an empty `/workspace/public/<key>`. Remove any entry\n * there that no current bind targets; only empty directories are removed,\n * so a real file could never be deleted by this pass.\n */\n private async removeStaleMountpoints(\n containerName: string,\n bindSpecs: readonly string[],\n ): Promise<void> {\n const keep = new Set(\n bindSpecs\n .map((bind) => bindSpecToMount(bind).target)\n .filter((target) => target.startsWith(\"/workspace/public/\"))\n .map((target) => target.slice(\"/workspace/public/\".length)),\n );\n const script = [\n \"[ -d /workspace/public ] || exit 0\",\n \"for d in /workspace/public/*; do\",\n ' [ -e \"$d\" ] || continue',\n ' case \" $KEEP \" in *\" ${d##*/} \"*) continue;; esac',\n ' rmdir \"$d\" 2>/dev/null || true',\n \"done\",\n ].join(\"\\n\");\n try {\n await this.execFileImpl(\"docker\", [\n \"exec\",\n \"-e\",\n `KEEP=${[...keep].join(\" \")}`,\n containerName,\n \"sh\",\n \"-c\",\n script,\n ]);\n } catch (err) {\n log.logWarning(`Could not clean stale mountpoints in ${containerName}`, String(err));\n }\n }\n\n /**\n * Recreate a drifted container with the desired mounts while keeping its\n * writable layer: commit — the new binds ride the snapshot label, so a\n * crash at any point resumes through the layout-migration path — then\n * remove, create from the snapshot, and start. Committing replaces any\n * older snapshot tag for this container; the untagged predecessor is\n * removed once the new container is up.\n */\n private async recreateContainerPreservingContents(\n containerKey: string,\n containerName: string,\n mounts: ContainerMount[],\n ): Promise<void> {\n const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;\n const bindSpecs = mounts.map((mount) => this.toBindSpec(mount));\n const previousImageId = await this.readImageId(snapshotImage);\n await this.execFileImpl(\"docker\", [\n \"commit\",\n \"-c\",\n `LABEL ${DockerContainerManager.MIGRATE_BINDS_LABEL_KEY}=${JSON.stringify(JSON.stringify(bindSpecs))}`,\n containerName,\n snapshotImage,\n ]);\n await this.execFileImpl(\"docker\", [\"rm\", \"-f\", containerName]);\n await this.createContainerFromSnapshot(containerName, bindSpecs, containerKey);\n await this.execFileImpl(\"docker\", [\"start\", containerName]);\n await this.removeStaleMountpoints(containerName, bindSpecs);\n const currentImageId = await this.readImageId(snapshotImage);\n if (previousImageId && previousImageId !== currentImageId) {\n try {\n await this.execFileImpl(\"docker\", [\"rmi\", previousImageId]);\n } catch (err) {\n log.logWarning(\n `Could not remove superseded snapshot image ${previousImageId}`,\n String(err),\n );\n }\n }\n }\n\n /** Resolved image id for a reference, or undefined when it does not exist. */\n private async readImageId(image: string): Promise<string | undefined> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\"inspect\", \"-f\", \"{{.Id}}\", image]);\n const id = stdout.trim();\n return id.length > 0 ? id : undefined;\n } catch {\n return undefined;\n }\n }\n\n /** Binds recorded on a snapshot image, or undefined when no snapshot exists. */\n private async readMigrateImageBinds(snapshotImage: string): Promise<string[] | undefined> {\n const raw = await this.readImageLabel(\n snapshotImage,\n DockerContainerManager.MIGRATE_BINDS_LABEL_KEY,\n );\n if (raw === undefined) return undefined;\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed) || parsed.some((bind) => typeof bind !== \"string\")) {\n throw new Error(`Snapshot image ${snapshotImage} carries malformed migrate binds`);\n }\n return parsed;\n }\n\n private async readImageLabel(image: string, key: string): Promise<string | undefined> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n `{{index .Config.Labels \"${key}\"}}`,\n image,\n ]);\n return this.normalizeDockerValue(stdout.trim());\n } catch {\n return undefined;\n }\n }\n\n /**\n * Delete a container's layout snapshot after an intentional removal, so a\n * missing container plus a surviving snapshot can only mean a crash in the\n * middle of the layout migration (the resume discriminator).\n */\n private async removeMigrateSnapshot(containerName: string): Promise<void> {\n try {\n await this.execFileImpl(\"docker\", [\n \"rmi\",\n `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`,\n ]);\n } catch {\n // No snapshot for this container — the common case.\n }\n }\n\n private async listMigrateSnapshotContainerNames(): Promise<string[]> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"images\",\n DockerContainerManager.MIGRATE_IMAGE_PREFIX,\n \"--format\",\n \"{{.Tag}}\",\n ]);\n return this.parseNameLines(stdout);\n } catch {\n return [];\n }\n }\n\n private async removeDanglingMigrateImages(): Promise<void> {\n let stdout: string;\n try {\n ({ stdout } = await this.execFileImpl(\"docker\", [\n \"images\",\n `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}`,\n \"--format\",\n \"{{.Repository}}:{{.Tag}}\",\n ]));\n } catch {\n return;\n }\n for (const image of this.parseNameLines(stdout)) {\n const containerName = image.slice(DockerContainerManager.MIGRATE_IMAGE_PREFIX.length + 1);\n const status = await this.inspectStatus(containerName);\n if (status !== \"missing\") {\n // Still referenced (until the container's next natural recreation\n // from the base image); keep the snapshot.\n const { stdout: imageRef } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n \"{{.Config.Image}}\",\n containerName,\n ]);\n if (imageRef.trim() === image) continue;\n }\n try {\n await this.execFileImpl(\"docker\", [\"rmi\", image]);\n log.logInfo(`Removed layout-migration snapshot image ${image}`);\n } catch (err) {\n log.logWarning(`Could not remove snapshot image ${image}`, String(err));\n }\n }\n }\n\n async reconcile(): Promise<void> {\n const discovered = new Set<string>();\n const labeledNames = await this.listContainerNamesByLabel();\n for (const name of labeledNames) discovered.add(name);\n const legacyNames = await this.listContainerNamesByPrefix();\n for (const name of legacyNames) discovered.add(name);\n\n this.state.clear();\n\n const inspected = await Promise.all(\n Array.from(discovered).map(async (containerName) => ({\n containerName,\n details: await this.inspectContainerDetails(containerName),\n })),\n );\n\n const legacyRemovals: Promise<void>[] = [];\n for (const { containerName, details } of inspected) {\n if (!details) continue;\n\n if (!details.conversationId) {\n legacyRemovals.push(this.removeLegacyContainer(containerName));\n continue;\n }\n\n const containerKey = this.containerKeyFromContainerName(containerName);\n if (!containerKey) {\n log.logWarning(`Skipping unmanaged-style container without container key`, containerName);\n continue;\n }\n\n // Containers keyed under the pre-office raw-conversation resource key\n // are unreachable now that resource identity is the office key: no\n // provision will ever address them again, so reap rather than adopt.\n if (containerKey === legacyConversationResourceKey(details.conversationId)) {\n legacyRemovals.push(\n this.forceRemoveContainer(\n containerName,\n `Removed container ${containerName} keyed by pre-office resource identity`,\n `Failed to remove legacy-keyed container ${containerName}`,\n ).then(() => undefined),\n );\n continue;\n }\n\n const status: ContainerStatus = details.running ? \"running\" : \"stopped\";\n const lastUsed = details.startedAtMs ?? Date.now();\n this.state.set(containerKey, { status, lastUsed, containerName });\n }\n await Promise.all(legacyRemovals);\n\n const running = Array.from(this.state.values()).filter((s) => s.status === \"running\").length;\n const stopped = this.state.size - running;\n log.logInfo(\n `Reconciled ${this.state.size} managed containers (running=${running}, stopped=${stopped})`,\n );\n }\n\n private setState(containerKey: string, status: ContainerStatus, containerName: string): void {\n this.state.set(containerKey, { status, lastUsed: Date.now(), containerName });\n }\n\n private getContainerName(containerKey: string): string {\n return (\n this.state.get(containerKey)?.containerName ??\n DockerContainerManager.containerName(containerKey)\n );\n }\n\n private mountArgs(mounts: ContainerMount[]): string[] {\n return mounts.flatMap((mount) => [\"-v\", this.toBindSpec(mount)]);\n }\n\n private toBindSpec(mount: ContainerMount): string {\n // The `:ro` suffix is part of the bind spec, so it also flows into\n // expectedBinds/mountSignature — flipping a mount's writability is drift\n // and recreates the container rather than leaving a stale writable bind.\n return `${mount.source}:${mount.target}${mount.readOnly ? \":ro\" : \"\"}`;\n }\n\n private async runContainer(\n containerKey: string,\n containerName: string,\n mounts: ContainerMount[],\n options: ProvisionOptions,\n ): Promise<void> {\n const networkName = await this.ensureNetwork(containerKey);\n log.logInfo(`Creating container ${containerName} from image ${this.image}`);\n const labels = [\n \"--label\",\n DockerContainerManager.MANAGED_LABEL,\n \"--label\",\n DockerContainerManager.IMAGE_MODE_LABEL,\n \"--label\",\n `${DockerContainerManager.VAULT_ID_LABEL_KEY}=${containerKey}`,\n ];\n if (options.conversationId) {\n labels.push(\n \"--label\",\n `${DockerContainerManager.CONVERSATION_ID_LABEL_KEY}=${options.conversationId}`,\n );\n }\n if (mounts.length > 0) {\n labels.push(\n \"--label\",\n `${DockerContainerManager.MOUNT_SIGNATURE_LABEL_KEY}=${this.mountSignature(mounts)}`,\n );\n }\n await this.execFileImpl(\"docker\", [\n \"run\",\n \"-d\",\n \"--name\",\n containerName,\n \"--network\",\n networkName,\n \"--cap-drop\",\n \"ALL\",\n \"--security-opt\",\n \"no-new-privileges\",\n \"--pids-limit\",\n \"1024\",\n ...labels,\n ...this.resourceLimitArgs(this.effectiveLimits(containerKey)),\n ...this.mountArgs(mounts),\n this.image,\n \"sleep\",\n \"infinity\",\n ]);\n }\n\n private effectiveLimits(containerKey: string): ResourceLimits | undefined {\n const override = this.overrideLimits.get(containerKey);\n if (override) return override;\n if (!this.boostedKeys.has(containerKey)) return this.limits;\n return { ...this.limits, ...this.boostLimits };\n }\n\n private resourceLimitArgs(limits: ResourceLimits | undefined): string[] {\n const args: string[] = [];\n if (limits?.cpus) args.push(\"--cpus\", limits.cpus);\n if (limits?.memory) {\n args.push(\"--memory\", limits.memory);\n // Keep Docker's no-extra-swap semantics explicit. Docker requires\n // memory-swap to be updated together when raising an existing memory\n // limit above the current swap limit.\n args.push(\"--memory-swap\", limits.memory);\n }\n return args;\n }\n\n private async applyResourceLimits(containerKey: string, containerName: string): Promise<void> {\n const limitArgs = this.resourceLimitArgs(this.effectiveLimits(containerKey));\n if (limitArgs.length === 0) return;\n const args = [\"update\", ...limitArgs, containerName];\n try {\n await this.execFileImpl(\"docker\", args);\n } catch (err) {\n log.logWarning(\n `Failed to apply resource limits to container ${containerName}`,\n err instanceof Error ? err.message : String(err),\n );\n reportUserFacingError(err, {\n domain: \"sandbox\",\n surface: \"sandbox_provision\",\n operation: \"apply_resource_limits\",\n severity: \"warning\",\n context: {\n sandboxType: \"image\",\n containerKey,\n containerName,\n limitArgCount: limitArgs.length,\n fatal: false,\n },\n });\n }\n }\n\n private async hasRuntimeDrift(\n containerKey: string,\n containerName: string,\n mounts: ContainerMount[],\n ): Promise<boolean> {\n if (await this.hasBindMountDrift(containerName, mounts)) {\n return true;\n }\n if (await this.hasMountSignatureDrift(containerName, mounts)) {\n return true;\n }\n return this.hasNetworkModeDrift(containerKey, containerName);\n }\n\n private async hasBindMountDrift(\n containerName: string,\n mounts: ContainerMount[],\n ): Promise<boolean> {\n const expected = this.expectedBinds(mounts);\n const actual = await this.inspectBindMounts(containerName);\n return !this.sameBinds(expected, actual);\n }\n\n private expectedBinds(mounts: ContainerMount[]): string[] {\n return mounts\n .map((mount) => this.toBindSpec(mount))\n .slice()\n .toSorted();\n }\n\n private sameBinds(expected: string[], actual: string[]): boolean {\n if (expected.length !== actual.length) {\n return false;\n }\n\n return expected.every((bind, index) => bind === actual[index]);\n }\n\n private async hasMountSignatureDrift(\n containerName: string,\n mounts: ContainerMount[],\n ): Promise<boolean> {\n if (mounts.length === 0) return false;\n const expected = this.mountSignature(mounts);\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n `{{index .Config.Labels \"${DockerContainerManager.MOUNT_SIGNATURE_LABEL_KEY}\"}}`,\n containerName,\n ]);\n const actual = this.normalizeDockerValue(stdout.trim());\n return actual !== expected;\n }\n\n private mountSignature(mounts: ContainerMount[]): string {\n const payload = mounts\n .map((mount) => ({\n source: mount.source,\n target: mount.target,\n fingerprint: this.mountSourceFingerprint(mount.source),\n }))\n .toSorted((left, right) =>\n `${left.target}\\0${left.source}`.localeCompare(`${right.target}\\0${right.source}`),\n );\n return createHash(\"sha256\").update(JSON.stringify(payload)).digest(\"hex\");\n }\n\n private mountSourceFingerprint(source: string): string {\n try {\n const stat = statSync(source);\n if (stat.isFile()) {\n // Files are atomically replaced (rename), which leaves the container\n // holding a stale inode — content changes must recreate the mount.\n return createHash(\"sha256\").update(readFileSync(source)).digest(\"hex\");\n }\n // Directories: a bind mount follows changes inside the directory live,\n // so only replacing the directory itself makes the mount stale.\n // Size/mtime churn from ordinary activity — event files coming and\n // going, children being created — must not read as drift. Identity is\n // dev:ino plus birth time, because ext4 recycles inode numbers\n // immediately and a same-path replacement can reuse the old one.\n return `${stat.isDirectory() ? \"dir\" : \"other\"}:${stat.dev}:${stat.ino}:${stat.birthtimeMs}`;\n } catch {\n return \"missing\";\n }\n }\n\n private async inspectBindMounts(containerName: string): Promise<string[]> {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n \"{{json .HostConfig.Binds}}\",\n containerName,\n ]);\n const payload = stdout.trim();\n const parsed = JSON.parse(payload.length > 0 ? payload : \"null\") as unknown;\n\n if (parsed === null) {\n return [];\n }\n\n if (!Array.isArray(parsed) || parsed.some((bind) => typeof bind !== \"string\")) {\n throw new Error(`Unexpected docker bind mount payload for container \"${containerName}\"`);\n }\n\n return [...parsed].toSorted();\n }\n\n private async hasNetworkModeDrift(containerKey: string, containerName: string): Promise<boolean> {\n const expected = DockerContainerManager.networkName(containerKey);\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n \"{{.HostConfig.NetworkMode}}\",\n containerName,\n ]);\n return stdout.trim() !== expected;\n }\n\n private async ensureNetwork(containerKey: string): Promise<string> {\n const networkName = DockerContainerManager.networkName(containerKey);\n try {\n await this.execFileImpl(\"docker\", [\"network\", \"inspect\", networkName]);\n return networkName;\n } catch (err) {\n if (!isDockerNotFoundError(err)) throw err;\n }\n await this.execFileImpl(\"docker\", [\n \"network\",\n \"create\",\n \"--driver\",\n \"bridge\",\n \"--label\",\n DockerContainerManager.MANAGED_LABEL,\n \"--label\",\n DockerContainerManager.IMAGE_MODE_LABEL,\n \"--label\",\n `${DockerContainerManager.VAULT_ID_LABEL_KEY}=${containerKey}`,\n networkName,\n ]);\n return networkName;\n }\n\n private async inspectStatus(containerName: string): Promise<ContainerStatus> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n \"{{.State.Running}}\",\n containerName,\n ]);\n return stdout.trim() === \"true\" ? \"running\" : \"stopped\";\n } catch (err) {\n if (isDockerNotFoundError(err)) return \"missing\";\n throw err;\n }\n }\n\n private async listContainerNamesByLabel(): Promise<string[]> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"ps\",\n \"-a\",\n \"--filter\",\n `label=${DockerContainerManager.MANAGED_LABEL}`,\n \"--filter\",\n `label=${DockerContainerManager.IMAGE_MODE_LABEL}`,\n \"--format\",\n \"{{.Names}}\",\n ]);\n return this.parseNameLines(stdout);\n } catch (err) {\n log.logWarning(\n \"Failed to list labeled managed containers\",\n err instanceof Error ? err.message : String(err),\n );\n return [];\n }\n }\n\n private async listContainerNamesByPrefix(): Promise<string[]> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"ps\",\n \"-a\",\n \"--filter\",\n `name=${DockerContainerManager.containerName(\"\")}`,\n \"--format\",\n \"{{.Names}}\",\n ]);\n return this.parseNameLines(stdout);\n } catch (err) {\n log.logWarning(\n \"Failed to list legacy managed containers\",\n err instanceof Error ? err.message : String(err),\n );\n return [];\n }\n }\n\n private parseNameLines(stdout: string): string[] {\n return stdout\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n }\n\n private async inspectContainerDetails(\n containerName: string,\n ): Promise<{ running: boolean; startedAtMs?: number; conversationId?: string } | undefined> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n `{{.State.Running}}\\t{{.State.StartedAt}}\\t{{index .Config.Labels \"${DockerContainerManager.VAULT_ID_LABEL_KEY}\"}}\\t{{index .Config.Labels \"${DockerContainerManager.CONVERSATION_ID_LABEL_KEY}\"}}`,\n containerName,\n ]);\n const [runningRaw, startedAtRaw, , conversationIdRaw] = stdout.trim().split(\"\\t\");\n const running = runningRaw === \"true\";\n const startedAtMs = this.parseDockerTimestamp(startedAtRaw);\n const conversationId = this.normalizeDockerValue(conversationIdRaw);\n return { running, startedAtMs, conversationId };\n } catch (err) {\n log.logWarning(\n `Failed to inspect container ${containerName} during reconcile`,\n err instanceof Error ? err.message : String(err),\n );\n return undefined;\n }\n }\n\n private normalizeDockerValue(value?: string): string | undefined {\n if (!value || value === \"<no value>\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n }\n\n private parseDockerTimestamp(value?: string): number | undefined {\n const normalized = this.normalizeDockerValue(value);\n if (!normalized || normalized.startsWith(\"0001-\")) return undefined;\n const parsed = Date.parse(normalized);\n return Number.isNaN(parsed) ? undefined : parsed;\n }\n\n private containerKeyFromContainerName(containerName: string): string | undefined {\n const prefix = DockerContainerManager.containerName(\"\");\n if (!containerName.startsWith(prefix)) return undefined;\n const containerKey = containerName.slice(prefix.length);\n return containerKey.length > 0 ? containerKey : undefined;\n }\n\n /** @returns true when the container is gone (removed or already missing). */\n private async forceRemoveContainer(\n containerName: string,\n successLog: string,\n failureLog: string,\n ): Promise<boolean> {\n try {\n await this.execFileImpl(\"docker\", [\"rm\", \"-f\", containerName]);\n log.logInfo(successLog);\n return true;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (/no such container/i.test(message)) return true;\n log.logWarning(failureLog, message);\n return false;\n }\n }\n\n private async removeLegacyContainer(containerName: string): Promise<void> {\n await this.forceRemoveContainer(\n containerName,\n `Removed legacy mikan container ${containerName} (pre-channel-isolation scheme)`,\n `Failed to remove legacy mikan container ${containerName}`,\n );\n }\n}\n"]}
1
+ {"version":3,"file":"provisioner.js","sourceRoot":"","sources":["../../src/sandbox/provisioner.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { legacyConversationResourceKey, sanitizeIdentitySegment } from \"./identity.js\";\nimport { createHash } from \"node:crypto\";\nimport { readFileSync, statSync } from \"node:fs\";\nimport { promisify } from \"node:util\";\nimport * as log from \"../log.js\";\nimport { reportUserFacingError } from \"../observability/index.js\";\n\nconst execFileAsync = promisify(execFile);\ntype ExecFileAsync = typeof execFileAsync;\n\ntype ContainerStatus = \"running\" | \"stopped\" | \"missing\";\n\nfunction isDockerNotFoundError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const stderr = (err as { stderr?: unknown }).stderr;\n const message = (err as { message?: unknown }).message;\n const haystack = `${typeof stderr === \"string\" ? stderr : \"\"}\\n${\n typeof message === \"string\" ? message : \"\"\n }`.toLowerCase();\n return (\n haystack.includes(\"no such network\") ||\n haystack.includes(\"no such container\") ||\n haystack.includes(\"no such object\") ||\n haystack.includes(\"network not found\") ||\n /network [^\\n]+ not found/.test(haystack) ||\n /error: no such [^\\n]+/.test(haystack)\n );\n}\n\ninterface ContainerState {\n status: ContainerStatus;\n lastUsed: number;\n containerName: string;\n}\n\nexport type {\n ContainerBindTranslator,\n ContainerMount,\n DockerContainerManagerOptions,\n ProvisionOptions,\n ResourceLimits,\n SandboxLimitStatus,\n} from \"../types.js\";\nimport type {\n ContainerBindTranslator,\n ContainerMount,\n DockerContainerManagerOptions,\n ProvisionOptions,\n ResourceLimits,\n SandboxLimitStatus,\n} from \"../types.js\";\n\n/** Parse `src:dst[:ro]` back into a ContainerMount for signature computation. */\nfunction bindSpecToMount(bindSpec: string): ContainerMount {\n const readOnly = bindSpec.endsWith(\":ro\");\n const spec = readOnly ? bindSpec.slice(0, -3) : bindSpec;\n const separator = spec.indexOf(\":\");\n return {\n source: spec.slice(0, separator),\n target: spec.slice(separator + 1),\n ...(readOnly ? { readOnly: true as const } : {}),\n };\n}\n\nexport class DockerContainerManager {\n private state = new Map<string, ContainerState>();\n private inflight = new Map<string, Promise<string>>();\n /** Active layout migration; unset means no translation ever applies. */\n private bindTranslator?: ContainerBindTranslator;\n private layoutMigrations = new Map<string, Promise<void>>();\n private static readonly MANAGED_LABEL = \"mikan.managed=true\";\n private static readonly IMAGE_MODE_LABEL = \"mikan.sandbox=image\";\n private static readonly VAULT_ID_LABEL_KEY = \"mikan.vault-id\";\n private static readonly CONVERSATION_ID_LABEL_KEY = \"mikan.conversation-id\";\n private static readonly MOUNT_SIGNATURE_LABEL_KEY = \"mikan.mount-signature\";\n private static readonly MIGRATE_IMAGE_PREFIX = \"mikan-migrate\";\n private static readonly MIGRATE_BINDS_LABEL_KEY = \"mikan.migrate-binds\";\n\n private readonly limits?: ResourceLimits;\n private readonly boostLimits?: ResourceLimits;\n private readonly boostedKeys = new Set<string>();\n private readonly overrideLimits = new Map<string, ResourceLimits>();\n private readonly execFileImpl: ExecFileAsync;\n\n constructor(\n private readonly image: string,\n options: DockerContainerManagerOptions = {},\n ) {\n this.limits = options.limits;\n this.boostLimits = options.boostLimits;\n this.execFileImpl = options.execFileImpl ?? execFileAsync;\n }\n\n static sanitizeSegment(value: string): string {\n return sanitizeIdentitySegment(value);\n }\n\n static containerName(containerKey: string): string {\n return `mikan-sandbox-${containerKey}`;\n }\n\n static networkName(containerKey: string): string {\n return `mikan-sandbox-net-${containerKey}`;\n }\n\n async provision(containerKey: string, options: ProvisionOptions = {}): Promise<string> {\n const existing = this.inflight.get(containerKey);\n if (existing) return existing;\n\n const pending = this.provisionInner(containerKey, options).finally(() => {\n this.inflight.delete(containerKey);\n });\n this.inflight.set(containerKey, pending);\n return pending;\n }\n\n private async provisionInner(containerKey: string, options: ProvisionOptions): Promise<string> {\n const containerName =\n options.containerName ?? DockerContainerManager.containerName(containerKey);\n const mounts = options.mounts ?? [];\n // A container still on the pre-office layout must move its writable layer\n // to the new mounts before the drift check below would recreate it from\n // the base image and discard everything installed inside.\n await this.migrateContainerLayout(containerName);\n const status = await this.inspectStatus(containerName);\n\n try {\n if (\n status !== \"missing\" &&\n (await this.hasRuntimeDrift(containerKey, containerName, mounts))\n ) {\n log.logInfo(`Container ${containerName} configuration changed; recreating container`);\n await this.recreateContainerPreservingContents(containerKey, containerName, mounts);\n log.logInfo(`Container ${containerName} recreated`);\n } else if (status === \"running\") {\n log.logInfo(`Container ${containerName} already running`);\n } else if (status === \"stopped\") {\n await this.execFileImpl(\"docker\", [\"start\", containerName]);\n log.logInfo(`Container ${containerName} started`);\n } else {\n await this.runContainer(containerKey, containerName, mounts, options);\n log.logInfo(`Container ${containerName} created`);\n }\n } catch (err) {\n this.state.delete(containerKey);\n throw err;\n }\n\n this.setState(containerKey, \"running\", containerName);\n await this.applyResourceLimits(containerKey, containerName);\n return containerName;\n }\n\n async boost(containerKey: string): Promise<SandboxLimitStatus> {\n if (!this.boostLimits?.cpus && !this.boostLimits?.memory) {\n return this.getLimitStatus(containerKey);\n }\n\n this.overrideLimits.delete(containerKey);\n this.boostedKeys.add(containerKey);\n const state = this.state.get(containerKey);\n if (state?.status === \"running\") {\n await this.applyResourceLimits(containerKey, state.containerName);\n }\n return this.getLimitStatus(containerKey);\n }\n\n async setLimits(containerKey: string, limits: ResourceLimits): Promise<SandboxLimitStatus> {\n this.boostedKeys.delete(containerKey);\n this.overrideLimits.set(containerKey, { ...this.limits, ...limits });\n const state = this.state.get(containerKey);\n if (state?.status === \"running\") {\n await this.applyResourceLimits(containerKey, state.containerName);\n }\n return this.getLimitStatus(containerKey);\n }\n\n getLimitStatus(containerKey: string): SandboxLimitStatus {\n const boosted = this.boostedKeys.has(containerKey);\n return { limits: this.effectiveLimits(containerKey), boosted };\n }\n\n getDefaultLimits(): ResourceLimits | undefined {\n return this.limits;\n }\n\n getBoostLimits(): ResourceLimits | undefined {\n return this.boostLimits;\n }\n\n async stop(containerKey: string): Promise<void> {\n const containerName = this.getContainerName(containerKey);\n try {\n await this.execFileImpl(\"docker\", [\"stop\", containerName]);\n this.setState(containerKey, \"stopped\", containerName);\n this.boostedKeys.delete(containerKey);\n this.overrideLimits.delete(containerKey);\n log.logInfo(`Container ${containerName} stopped (idle)`);\n } catch (err) {\n log.logWarning(\n `Failed to stop container ${containerName}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n async remove(containerKey: string): Promise<void> {\n const containerName = this.getContainerName(containerKey);\n const networkName = DockerContainerManager.networkName(containerKey);\n\n const removed = await this.forceRemoveContainer(\n containerName,\n `Container ${containerName} removed`,\n `Failed to remove container ${containerName}`,\n );\n if (!removed) {\n // The container may still be running with its old mounts. Keeping the\n // ownership state (and throwing) is the honest outcome: callers such\n // as credential refresh must not report a teardown that did not happen.\n throw new Error(`Failed to remove container ${containerName}`);\n }\n\n try {\n await this.execFileImpl(\"docker\", [\"network\", \"rm\", networkName]);\n log.logInfo(`Network ${networkName} removed`);\n } catch (err) {\n log.logWarning(\n `Failed to remove network ${networkName}`,\n err instanceof Error ? err.message : String(err),\n );\n }\n\n await this.removeMigrateSnapshot(containerName);\n\n this.state.delete(containerKey);\n this.boostedKeys.delete(containerKey);\n this.overrideLimits.delete(containerKey);\n }\n\n async stopIdle(maxIdleMs: number): Promise<void> {\n const now = Date.now();\n const toStop: string[] = [];\n for (const [containerKey, containerState] of this.state) {\n if (containerState.status === \"running\" && now - containerState.lastUsed > maxIdleMs) {\n toStop.push(containerKey);\n }\n }\n await Promise.all(toStop.map((containerKey) => this.stop(containerKey)));\n }\n\n /**\n * Force-remove every managed container belonging to the given conversation\n * ids. The office layout migration renames the host directories a\n * container's workspace mount points at, so a surviving container would keep\n * writing through stale mounts while the runtime works in the new location.\n */\n async removeContainersForConversations(conversationIds: ReadonlySet<string>): Promise<void> {\n if (conversationIds.size === 0) return;\n const names = await this.listContainerNamesByLabel();\n await Promise.all(\n names.map(async (containerName) => {\n const details = await this.inspectContainerDetails(containerName);\n if (!details?.conversationId || !conversationIds.has(details.conversationId)) return;\n await this.forceRemoveContainer(\n containerName,\n `Removed container ${containerName} after office migration`,\n `Failed to remove container ${containerName} after office migration`,\n );\n }),\n );\n }\n\n /**\n * Arm the office-layout container migration. Containers whose binds still\n * reference legacy raw-id paths are moved to the office-key layout without\n * losing their writable layer: commit → remove → create with translated\n * binds, preserving everything installed inside. Idempotent per container\n * and resumable — the pre-removal binds ride on the snapshot image label,\n * so a crash between commit and create resumes from the snapshot.\n */\n armContainerLayoutMigration(translator: ContainerBindTranslator): void {\n this.bindTranslator = translator;\n }\n\n /**\n * Sweep every managed container through the layout migration, serially and\n * with a small gap, so the one-time cost never lands on the boot path or on\n * a message. Safe to fire-and-forget; each unit is idempotent.\n */\n async sweepContainerLayoutMigration(delayMs = 2000): Promise<void> {\n if (!this.bindTranslator) return;\n let names: string[];\n try {\n // Include snapshot names: a crash between commit and create leaves a\n // snapshot with no container, which must resume before the GC below\n // could mistake it for an orphan.\n const containers = await this.listContainerNamesByLabel();\n const snapshots = await this.listMigrateSnapshotContainerNames();\n names = Array.from(new Set([...containers, ...snapshots]));\n } catch (err) {\n log.logWarning(\"Container layout sweep could not list containers\", String(err));\n return;\n }\n for (const containerName of names) {\n try {\n await this.migrateContainerLayout(containerName);\n } catch (err) {\n log.logWarning(\n `Container layout migration failed for ${containerName}; leaving it in place`,\n err instanceof Error ? err.message : String(err),\n );\n }\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n // Snapshot images whose container has since been recreated from the base\n // image are no longer referenced; reclaim them.\n await this.removeDanglingMigrateImages();\n }\n\n /** Move one container to the office-key layout; no-op when already there. */\n private migrateContainerLayout(containerName: string): Promise<void> {\n const translator = this.bindTranslator;\n if (!translator) return Promise.resolve();\n const existing = this.layoutMigrations.get(containerName);\n if (existing) return existing;\n const pending = this.migrateContainerLayoutInner(containerName, translator).finally(() => {\n this.layoutMigrations.delete(containerName);\n });\n this.layoutMigrations.set(containerName, pending);\n return pending;\n }\n\n private async migrateContainerLayoutInner(\n containerName: string,\n translator: ContainerBindTranslator,\n ): Promise<void> {\n const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;\n\n let originalBinds: string[];\n const status = await this.inspectStatus(containerName);\n if (status === \"missing\") {\n // Resume path: a previous run committed and removed the container but\n // died before creating the replacement. The snapshot carries the\n // pre-removal binds on its label.\n const labeled = await this.readMigrateImageBinds(snapshotImage);\n if (labeled === undefined) return;\n originalBinds = labeled;\n } else {\n originalBinds = await this.inspectBindMounts(containerName);\n const translated = originalBinds.map(translator);\n if (this.sameBinds(translated.toSorted(), originalBinds.slice().toSorted())) {\n return; // already on the office layout\n }\n log.logInfo(`Migrating container ${containerName} to the office layout`);\n await this.execFileImpl(\"docker\", [\n \"commit\",\n \"-c\",\n `LABEL ${DockerContainerManager.MIGRATE_BINDS_LABEL_KEY}=${JSON.stringify(JSON.stringify(originalBinds))}`,\n containerName,\n snapshotImage,\n ]);\n await this.execFileImpl(\"docker\", [\"rm\", \"-f\", containerName]);\n }\n\n await this.createContainerFromSnapshot(containerName, originalBinds.map(translator));\n // The snapshot's only job was bridging commit → create; the new container\n // already owns that content in its own writable layer; untagging it now\n // (rather than waiting for a \"natural recreation from the base image\"\n // that never happens — every recreation path here targets this same\n // snapshot family) is what makes migration actually one-time instead of\n // repeating on every future sweep that still finds the tag.\n await this.removeMigrateSnapshot(containerName);\n log.logInfo(`Container ${containerName} migrated to the office layout`);\n }\n\n /**\n * Create `containerName` from its layout snapshot with `bindSpecs`,\n * restoring the managed labels and recomputing the mount signature.\n * `create`, not `run`: idle containers stay stopped exactly as they were;\n * callers that need the container running start it themselves.\n */\n private async createContainerFromSnapshot(\n containerName: string,\n bindSpecs: string[],\n knownContainerKey?: string,\n ): Promise<void> {\n const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;\n // The sweep has only the container name and derives the key; the drift\n // path knows the real key (container names can be caller-supplied).\n const containerKey =\n knownContainerKey ?? this.containerKeyFromContainerName(containerName) ?? containerName;\n const networkName = await this.ensureNetwork(containerKey);\n const conversationId = await this.readImageLabel(\n snapshotImage,\n DockerContainerManager.CONVERSATION_ID_LABEL_KEY,\n );\n const labels = [\n \"--label\",\n DockerContainerManager.MANAGED_LABEL,\n \"--label\",\n DockerContainerManager.IMAGE_MODE_LABEL,\n \"--label\",\n `${DockerContainerManager.VAULT_ID_LABEL_KEY}=${containerKey}`,\n ];\n if (conversationId) {\n labels.push(\n \"--label\",\n `${DockerContainerManager.CONVERSATION_ID_LABEL_KEY}=${conversationId}`,\n );\n }\n labels.push(\n \"--label\",\n `${DockerContainerManager.MOUNT_SIGNATURE_LABEL_KEY}=${this.mountSignature(\n bindSpecs.map(bindSpecToMount),\n )}`,\n );\n await this.execFileImpl(\"docker\", [\n \"create\",\n \"--name\",\n containerName,\n \"--network\",\n networkName,\n \"--cap-drop\",\n \"ALL\",\n \"--security-opt\",\n \"no-new-privileges\",\n \"--pids-limit\",\n \"1024\",\n ...labels,\n ...this.resourceLimitArgs(this.effectiveLimits(containerKey)),\n ...bindSpecs.flatMap((bind) => [\"-v\", bind]),\n snapshotImage,\n \"sleep\",\n \"infinity\",\n ]);\n }\n\n /**\n * `docker commit` captures the empty directories Docker created as bind\n * targets, so a public office that stopped being mounted would linger in\n * the snapshot as an empty `/workspace/public/<key>`. Remove any entry\n * there that no current bind targets; only empty directories are removed,\n * so a real file could never be deleted by this pass.\n */\n private async removeStaleMountpoints(\n containerName: string,\n bindSpecs: readonly string[],\n ): Promise<void> {\n const keep = new Set(\n bindSpecs\n .map((bind) => bindSpecToMount(bind).target)\n .filter((target) => target.startsWith(\"/workspace/public/\"))\n .map((target) => target.slice(\"/workspace/public/\".length)),\n );\n const script = [\n \"[ -d /workspace/public ] || exit 0\",\n \"for d in /workspace/public/*; do\",\n ' [ -e \"$d\" ] || continue',\n ' case \" $KEEP \" in *\" ${d##*/} \"*) continue;; esac',\n ' rmdir \"$d\" 2>/dev/null || true',\n \"done\",\n ].join(\"\\n\");\n try {\n await this.execFileImpl(\"docker\", [\n \"exec\",\n \"-e\",\n `KEEP=${[...keep].join(\" \")}`,\n containerName,\n \"sh\",\n \"-c\",\n script,\n ]);\n } catch (err) {\n log.logWarning(`Could not clean stale mountpoints in ${containerName}`, String(err));\n }\n }\n\n /**\n * Recreate a drifted container with the desired mounts while keeping its\n * writable layer: commit — the new binds ride the snapshot label, so a\n * crash at any point resumes through the layout-migration path — then\n * remove, create from the snapshot, and start. The snapshot is untagged\n * once the new container is confirmed up: its only job was bridging\n * commit → create, and the container now owns that content in its own\n * writable layer, so nothing still needs the tag.\n */\n private async recreateContainerPreservingContents(\n containerKey: string,\n containerName: string,\n mounts: ContainerMount[],\n ): Promise<void> {\n const snapshotImage = `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`;\n const bindSpecs = mounts.map((mount) => this.toBindSpec(mount));\n await this.execFileImpl(\"docker\", [\n \"commit\",\n \"-c\",\n `LABEL ${DockerContainerManager.MIGRATE_BINDS_LABEL_KEY}=${JSON.stringify(JSON.stringify(bindSpecs))}`,\n containerName,\n snapshotImage,\n ]);\n await this.execFileImpl(\"docker\", [\"rm\", \"-f\", containerName]);\n await this.createContainerFromSnapshot(containerName, bindSpecs, containerKey);\n await this.execFileImpl(\"docker\", [\"start\", containerName]);\n await this.removeStaleMountpoints(containerName, bindSpecs);\n await this.removeMigrateSnapshot(containerName);\n }\n\n /** Binds recorded on a snapshot image, or undefined when no snapshot exists. */\n private async readMigrateImageBinds(snapshotImage: string): Promise<string[] | undefined> {\n const raw = await this.readImageLabel(\n snapshotImage,\n DockerContainerManager.MIGRATE_BINDS_LABEL_KEY,\n );\n if (raw === undefined) return undefined;\n const parsed = JSON.parse(raw) as unknown;\n if (!Array.isArray(parsed) || parsed.some((bind) => typeof bind !== \"string\")) {\n throw new Error(`Snapshot image ${snapshotImage} carries malformed migrate binds`);\n }\n return parsed;\n }\n\n private async readImageLabel(image: string, key: string): Promise<string | undefined> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n `{{index .Config.Labels \"${key}\"}}`,\n image,\n ]);\n return this.normalizeDockerValue(stdout.trim());\n } catch {\n return undefined;\n }\n }\n\n /**\n * Delete a container's layout snapshot after an intentional removal, so a\n * missing container plus a surviving snapshot can only mean a crash in the\n * middle of the layout migration (the resume discriminator).\n */\n private async removeMigrateSnapshot(containerName: string): Promise<void> {\n try {\n await this.execFileImpl(\"docker\", [\n \"rmi\",\n `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}:${containerName}`,\n ]);\n } catch {\n // No snapshot for this container — the common case.\n }\n }\n\n private async listMigrateSnapshotContainerNames(): Promise<string[]> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"images\",\n DockerContainerManager.MIGRATE_IMAGE_PREFIX,\n \"--format\",\n \"{{.Tag}}\",\n ]);\n return this.parseNameLines(stdout);\n } catch {\n return [];\n }\n }\n\n /**\n * Catch-up pass for snapshots the success path in\n * `migrateContainerLayoutInner` did not get to remove itself — e.g. a\n * crash between `createContainerFromSnapshot` and its own cleanup. A\n * snapshot is only still needed while its container remains \"missing\"\n * (the resume path in `migrateContainerLayoutInner` reads pre-removal\n * binds off it); once the container exists again in any state, the\n * snapshot has done its job regardless of whether that container's\n * `Config.Image` still points at it — removing a tag never deletes\n * layers a live container still uses.\n */\n private async removeDanglingMigrateImages(): Promise<void> {\n let stdout: string;\n try {\n ({ stdout } = await this.execFileImpl(\"docker\", [\n \"images\",\n `${DockerContainerManager.MIGRATE_IMAGE_PREFIX}`,\n \"--format\",\n \"{{.Repository}}:{{.Tag}}\",\n ]));\n } catch {\n return;\n }\n for (const image of this.parseNameLines(stdout)) {\n const containerName = image.slice(DockerContainerManager.MIGRATE_IMAGE_PREFIX.length + 1);\n const status = await this.inspectStatus(containerName);\n if (status === \"missing\") continue; // still needed for a future resume\n try {\n await this.execFileImpl(\"docker\", [\"rmi\", image]);\n log.logInfo(`Removed layout-migration snapshot image ${image}`);\n } catch (err) {\n log.logWarning(`Could not remove snapshot image ${image}`, String(err));\n }\n }\n }\n\n async reconcile(): Promise<void> {\n const discovered = new Set<string>();\n const labeledNames = await this.listContainerNamesByLabel();\n for (const name of labeledNames) discovered.add(name);\n const legacyNames = await this.listContainerNamesByPrefix();\n for (const name of legacyNames) discovered.add(name);\n\n this.state.clear();\n\n const inspected = await Promise.all(\n Array.from(discovered).map(async (containerName) => ({\n containerName,\n details: await this.inspectContainerDetails(containerName),\n })),\n );\n\n const legacyRemovals: Promise<void>[] = [];\n for (const { containerName, details } of inspected) {\n if (!details) continue;\n\n if (!details.conversationId) {\n legacyRemovals.push(this.removeLegacyContainer(containerName));\n continue;\n }\n\n const containerKey = this.containerKeyFromContainerName(containerName);\n if (!containerKey) {\n log.logWarning(`Skipping unmanaged-style container without container key`, containerName);\n continue;\n }\n\n // Containers keyed under the pre-office raw-conversation resource key\n // are unreachable now that resource identity is the office key: no\n // provision will ever address them again, so reap rather than adopt.\n if (containerKey === legacyConversationResourceKey(details.conversationId)) {\n legacyRemovals.push(\n this.forceRemoveContainer(\n containerName,\n `Removed container ${containerName} keyed by pre-office resource identity`,\n `Failed to remove legacy-keyed container ${containerName}`,\n ).then(() => undefined),\n );\n continue;\n }\n\n const status: ContainerStatus = details.running ? \"running\" : \"stopped\";\n const lastUsed = details.startedAtMs ?? Date.now();\n this.state.set(containerKey, { status, lastUsed, containerName });\n }\n await Promise.all(legacyRemovals);\n\n const running = Array.from(this.state.values()).filter((s) => s.status === \"running\").length;\n const stopped = this.state.size - running;\n log.logInfo(\n `Reconciled ${this.state.size} managed containers (running=${running}, stopped=${stopped})`,\n );\n }\n\n private setState(containerKey: string, status: ContainerStatus, containerName: string): void {\n this.state.set(containerKey, { status, lastUsed: Date.now(), containerName });\n }\n\n private getContainerName(containerKey: string): string {\n return (\n this.state.get(containerKey)?.containerName ??\n DockerContainerManager.containerName(containerKey)\n );\n }\n\n private mountArgs(mounts: ContainerMount[]): string[] {\n return mounts.flatMap((mount) => [\"-v\", this.toBindSpec(mount)]);\n }\n\n private toBindSpec(mount: ContainerMount): string {\n // The `:ro` suffix is part of the bind spec, so it also flows into\n // expectedBinds/mountSignature — flipping a mount's writability is drift\n // and recreates the container rather than leaving a stale writable bind.\n return `${mount.source}:${mount.target}${mount.readOnly ? \":ro\" : \"\"}`;\n }\n\n private async runContainer(\n containerKey: string,\n containerName: string,\n mounts: ContainerMount[],\n options: ProvisionOptions,\n ): Promise<void> {\n const networkName = await this.ensureNetwork(containerKey);\n log.logInfo(`Creating container ${containerName} from image ${this.image}`);\n const labels = [\n \"--label\",\n DockerContainerManager.MANAGED_LABEL,\n \"--label\",\n DockerContainerManager.IMAGE_MODE_LABEL,\n \"--label\",\n `${DockerContainerManager.VAULT_ID_LABEL_KEY}=${containerKey}`,\n ];\n if (options.conversationId) {\n labels.push(\n \"--label\",\n `${DockerContainerManager.CONVERSATION_ID_LABEL_KEY}=${options.conversationId}`,\n );\n }\n if (mounts.length > 0) {\n labels.push(\n \"--label\",\n `${DockerContainerManager.MOUNT_SIGNATURE_LABEL_KEY}=${this.mountSignature(mounts)}`,\n );\n }\n await this.execFileImpl(\"docker\", [\n \"run\",\n \"-d\",\n \"--name\",\n containerName,\n \"--network\",\n networkName,\n \"--cap-drop\",\n \"ALL\",\n \"--security-opt\",\n \"no-new-privileges\",\n \"--pids-limit\",\n \"1024\",\n ...labels,\n ...this.resourceLimitArgs(this.effectiveLimits(containerKey)),\n ...this.mountArgs(mounts),\n this.image,\n \"sleep\",\n \"infinity\",\n ]);\n }\n\n private effectiveLimits(containerKey: string): ResourceLimits | undefined {\n const override = this.overrideLimits.get(containerKey);\n if (override) return override;\n if (!this.boostedKeys.has(containerKey)) return this.limits;\n return { ...this.limits, ...this.boostLimits };\n }\n\n private resourceLimitArgs(limits: ResourceLimits | undefined): string[] {\n const args: string[] = [];\n if (limits?.cpus) args.push(\"--cpus\", limits.cpus);\n if (limits?.memory) {\n args.push(\"--memory\", limits.memory);\n // Keep Docker's no-extra-swap semantics explicit. Docker requires\n // memory-swap to be updated together when raising an existing memory\n // limit above the current swap limit.\n args.push(\"--memory-swap\", limits.memory);\n }\n return args;\n }\n\n private async applyResourceLimits(containerKey: string, containerName: string): Promise<void> {\n const limitArgs = this.resourceLimitArgs(this.effectiveLimits(containerKey));\n if (limitArgs.length === 0) return;\n const args = [\"update\", ...limitArgs, containerName];\n try {\n await this.execFileImpl(\"docker\", args);\n } catch (err) {\n log.logWarning(\n `Failed to apply resource limits to container ${containerName}`,\n err instanceof Error ? err.message : String(err),\n );\n reportUserFacingError(err, {\n domain: \"sandbox\",\n surface: \"sandbox_provision\",\n operation: \"apply_resource_limits\",\n severity: \"warning\",\n context: {\n sandboxType: \"image\",\n containerKey,\n containerName,\n limitArgCount: limitArgs.length,\n fatal: false,\n },\n });\n }\n }\n\n private async hasRuntimeDrift(\n containerKey: string,\n containerName: string,\n mounts: ContainerMount[],\n ): Promise<boolean> {\n if (await this.hasBindMountDrift(containerName, mounts)) {\n return true;\n }\n if (await this.hasMountSignatureDrift(containerName, mounts)) {\n return true;\n }\n return this.hasNetworkModeDrift(containerKey, containerName);\n }\n\n private async hasBindMountDrift(\n containerName: string,\n mounts: ContainerMount[],\n ): Promise<boolean> {\n const expected = this.expectedBinds(mounts);\n const actual = await this.inspectBindMounts(containerName);\n return !this.sameBinds(expected, actual);\n }\n\n private expectedBinds(mounts: ContainerMount[]): string[] {\n return mounts\n .map((mount) => this.toBindSpec(mount))\n .slice()\n .toSorted();\n }\n\n private sameBinds(expected: string[], actual: string[]): boolean {\n if (expected.length !== actual.length) {\n return false;\n }\n\n return expected.every((bind, index) => bind === actual[index]);\n }\n\n private async hasMountSignatureDrift(\n containerName: string,\n mounts: ContainerMount[],\n ): Promise<boolean> {\n if (mounts.length === 0) return false;\n const expected = this.mountSignature(mounts);\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n `{{index .Config.Labels \"${DockerContainerManager.MOUNT_SIGNATURE_LABEL_KEY}\"}}`,\n containerName,\n ]);\n const actual = this.normalizeDockerValue(stdout.trim());\n return actual !== expected;\n }\n\n private mountSignature(mounts: ContainerMount[]): string {\n const payload = mounts\n .map((mount) => ({\n source: mount.source,\n target: mount.target,\n fingerprint: this.mountSourceFingerprint(mount.source),\n }))\n .toSorted((left, right) =>\n `${left.target}\\0${left.source}`.localeCompare(`${right.target}\\0${right.source}`),\n );\n return createHash(\"sha256\").update(JSON.stringify(payload)).digest(\"hex\");\n }\n\n private mountSourceFingerprint(source: string): string {\n try {\n const stat = statSync(source);\n if (stat.isFile()) {\n // Files are atomically replaced (rename), which leaves the container\n // holding a stale inode — content changes must recreate the mount.\n return createHash(\"sha256\").update(readFileSync(source)).digest(\"hex\");\n }\n // Directories: a bind mount follows changes inside the directory live,\n // so only replacing the directory itself makes the mount stale.\n // Size/mtime churn from ordinary activity — event files coming and\n // going, children being created — must not read as drift. Identity is\n // dev:ino plus birth time, because ext4 recycles inode numbers\n // immediately and a same-path replacement can reuse the old one.\n return `${stat.isDirectory() ? \"dir\" : \"other\"}:${stat.dev}:${stat.ino}:${stat.birthtimeMs}`;\n } catch {\n return \"missing\";\n }\n }\n\n private async inspectBindMounts(containerName: string): Promise<string[]> {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n \"{{json .HostConfig.Binds}}\",\n containerName,\n ]);\n const payload = stdout.trim();\n const parsed = JSON.parse(payload.length > 0 ? payload : \"null\") as unknown;\n\n if (parsed === null) {\n return [];\n }\n\n if (!Array.isArray(parsed) || parsed.some((bind) => typeof bind !== \"string\")) {\n throw new Error(`Unexpected docker bind mount payload for container \"${containerName}\"`);\n }\n\n return [...parsed].toSorted();\n }\n\n private async hasNetworkModeDrift(containerKey: string, containerName: string): Promise<boolean> {\n const expected = DockerContainerManager.networkName(containerKey);\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n \"{{.HostConfig.NetworkMode}}\",\n containerName,\n ]);\n return stdout.trim() !== expected;\n }\n\n private async ensureNetwork(containerKey: string): Promise<string> {\n const networkName = DockerContainerManager.networkName(containerKey);\n try {\n await this.execFileImpl(\"docker\", [\"network\", \"inspect\", networkName]);\n return networkName;\n } catch (err) {\n if (!isDockerNotFoundError(err)) throw err;\n }\n await this.execFileImpl(\"docker\", [\n \"network\",\n \"create\",\n \"--driver\",\n \"bridge\",\n \"--label\",\n DockerContainerManager.MANAGED_LABEL,\n \"--label\",\n DockerContainerManager.IMAGE_MODE_LABEL,\n \"--label\",\n `${DockerContainerManager.VAULT_ID_LABEL_KEY}=${containerKey}`,\n networkName,\n ]);\n return networkName;\n }\n\n private async inspectStatus(containerName: string): Promise<ContainerStatus> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n \"{{.State.Running}}\",\n containerName,\n ]);\n return stdout.trim() === \"true\" ? \"running\" : \"stopped\";\n } catch (err) {\n if (isDockerNotFoundError(err)) return \"missing\";\n throw err;\n }\n }\n\n private async listContainerNamesByLabel(): Promise<string[]> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"ps\",\n \"-a\",\n \"--filter\",\n `label=${DockerContainerManager.MANAGED_LABEL}`,\n \"--filter\",\n `label=${DockerContainerManager.IMAGE_MODE_LABEL}`,\n \"--format\",\n \"{{.Names}}\",\n ]);\n return this.parseNameLines(stdout);\n } catch (err) {\n log.logWarning(\n \"Failed to list labeled managed containers\",\n err instanceof Error ? err.message : String(err),\n );\n return [];\n }\n }\n\n private async listContainerNamesByPrefix(): Promise<string[]> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"ps\",\n \"-a\",\n \"--filter\",\n `name=${DockerContainerManager.containerName(\"\")}`,\n \"--format\",\n \"{{.Names}}\",\n ]);\n return this.parseNameLines(stdout);\n } catch (err) {\n log.logWarning(\n \"Failed to list legacy managed containers\",\n err instanceof Error ? err.message : String(err),\n );\n return [];\n }\n }\n\n private parseNameLines(stdout: string): string[] {\n return stdout\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n }\n\n private async inspectContainerDetails(\n containerName: string,\n ): Promise<{ running: boolean; startedAtMs?: number; conversationId?: string } | undefined> {\n try {\n const { stdout } = await this.execFileImpl(\"docker\", [\n \"inspect\",\n \"-f\",\n `{{.State.Running}}\\t{{.State.StartedAt}}\\t{{index .Config.Labels \"${DockerContainerManager.VAULT_ID_LABEL_KEY}\"}}\\t{{index .Config.Labels \"${DockerContainerManager.CONVERSATION_ID_LABEL_KEY}\"}}`,\n containerName,\n ]);\n const [runningRaw, startedAtRaw, , conversationIdRaw] = stdout.trim().split(\"\\t\");\n const running = runningRaw === \"true\";\n const startedAtMs = this.parseDockerTimestamp(startedAtRaw);\n const conversationId = this.normalizeDockerValue(conversationIdRaw);\n return { running, startedAtMs, conversationId };\n } catch (err) {\n log.logWarning(\n `Failed to inspect container ${containerName} during reconcile`,\n err instanceof Error ? err.message : String(err),\n );\n return undefined;\n }\n }\n\n private normalizeDockerValue(value?: string): string | undefined {\n if (!value || value === \"<no value>\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n }\n\n private parseDockerTimestamp(value?: string): number | undefined {\n const normalized = this.normalizeDockerValue(value);\n if (!normalized || normalized.startsWith(\"0001-\")) return undefined;\n const parsed = Date.parse(normalized);\n return Number.isNaN(parsed) ? undefined : parsed;\n }\n\n private containerKeyFromContainerName(containerName: string): string | undefined {\n const prefix = DockerContainerManager.containerName(\"\");\n if (!containerName.startsWith(prefix)) return undefined;\n const containerKey = containerName.slice(prefix.length);\n return containerKey.length > 0 ? containerKey : undefined;\n }\n\n /** @returns true when the container is gone (removed or already missing). */\n private async forceRemoveContainer(\n containerName: string,\n successLog: string,\n failureLog: string,\n ): Promise<boolean> {\n try {\n await this.execFileImpl(\"docker\", [\"rm\", \"-f\", containerName]);\n log.logInfo(successLog);\n return true;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (/no such container/i.test(message)) return true;\n log.logWarning(failureLog, message);\n return false;\n }\n }\n\n private async removeLegacyContainer(containerName: string): Promise<void> {\n await this.forceRemoveContainer(\n containerName,\n `Removed legacy mikan container ${containerName} (pre-channel-isolation scheme)`,\n `Failed to remove legacy mikan container ${containerName}`,\n );\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminixiang/mikan",
3
- "version": "1.0.0-beta.69",
3
+ "version": "1.0.0-beta.70",
4
4
  "description": "Self-hosted AI coding agent for organizations: every Slack channel and DM gets its own sandboxed workspace, credentials, and memory.",
5
5
  "keywords": [
6
6
  "agent",