{"version":3,"file":"types-D6X_aUIb.mjs","names":[],"sources":["../src/batteries/sandbox/paths.ts","../src/batteries/sandbox/types.ts"],"sourcesContent":["import { isInstanceOf } from '../../lib/utils/guards'\nimport { E_INVALID_SANDBOX_CONFIG, E_SANDBOX_PATH_ESCAPE } from './exceptions'\nimport type { SandboxFileSystem } from './contracts/file_system'\nimport type { PathTranslator } from './contracts/path_translator'\n\n/** Why a path was rejected outright, before any normalisation. */\nexport type SandboxPathRejection = 'nul' | 'home' | 'absolute-host' | 'device' | 'unc'\n\n/**\n * Classify an unambiguous host escape, or `undefined` when the path is acceptable.\n *\n * @remarks\n * The REASON is returned, not just a boolean, because the narrated outcome carries it and the model\n * acts on it: \"paths are workspace-relative\" is useless advice for a NUL byte, and a UNC form needs\n * a different correction from a `~`. Reporting every rejection as `escape` collapses five distinct\n * mistakes into one unhelpful message.\n *\n * ORDER IS LOAD-BEARING and matches the plan's step 1. Recognition runs on the CANONICAL separator\n * representation (both `/` and `\\` treated as separators) but still BEFORE any stripping, so a\n * slash-mixed form like `/\\server\\share` cannot slip past a naive prefix test and then become a\n * root-relative path once separators are collapsed. UNC is distinguished from merely-repeated\n * leading separators by having a NON-EMPTY first segment. Nothing is percent-decoded and nothing is\n * case-folded: a literal `%2e%2e` is a filename, not traversal.\n *\n * @param input - The model-supplied path, exactly as given.\n * @returns The rejection reason, or `undefined` to continue normalising.\n */\nexport const classifySandboxPathRejection = (input: string): SandboxPathRejection | undefined => {\n  const canonical = input.replaceAll('\\\\', '/')\n  if (canonical.includes('\\0')) return 'nul'\n  if (canonical.startsWith('~')) return 'home'\n  if (/^[A-Za-z]:/.test(canonical)) return 'absolute-host'\n  if (/^\\/{2,}[?.]\\//.test(canonical)) return 'device'\n  if (/^\\/{2,}[^/]+(?:\\/|$)/.test(canonical)) return 'unc'\n  return undefined\n}\n\n/** Return whether a path is an unambiguous host escape before normalisation. */\nexport const isRejectedSandboxPath = (input: string): boolean =>\n  classifySandboxPathRejection(input) !== undefined\n\nconst joinSandboxBackendPath = (root: string, relative: string): string =>\n  root === '/' ? `/${relative}` : `${root}${relative ? `/${relative}` : ''}`\n\n/** Normalise a model path; leading separators denote the sandbox root. */\nexport const normalizeSandboxPath = (input: string): string => {\n  const parts: string[] = []\n  for (const part of input.replaceAll('\\\\', '/').split('/')) {\n    if (!part || part === '.') continue\n    if (part === '..') {\n      if (parts.length === 0) throw new E_SANDBOX_PATH_ESCAPE([`Path rejected: ${input}`])\n      parts.pop()\n    } else parts.push(part)\n  }\n  return parts.join('/')\n}\n\n/**\n * Create a symlink guard for paths whose final component may not exist yet.\n * Stat failures are treated as absence, matching the sandbox regular-file helpers.\n */\nexport const createExistingSymlinkGuard = (\n  root: string,\n  fileSystem: SandboxFileSystem\n): ((relative: string) => Promise<void>) => {\n  const canonicalRoot = root.replaceAll('\\\\', '/').replace(/\\/+$/g, '') || '/'\n  return async (relative: string): Promise<void> => {\n    const parts = relative ? relative.split('/') : []\n    for (let index = 0; index <= parts.length; index += 1) {\n      const candidate = parts.slice(0, index).join('/')\n      try {\n        const metadata = await fileSystem.stat(joinSandboxBackendPath(canonicalRoot, candidate))\n        if (metadata.kind === 'symlink')\n          throw new E_SANDBOX_PATH_ESCAPE([`Path rejected: ${relative}`])\n      } catch (error) {\n        if (isInstanceOf(error, 'E_SANDBOX_PATH_ESCAPE', E_SANDBOX_PATH_ESCAPE)) throw error\n        break\n      }\n    }\n  }\n}\n\n/** Create a translator that applies the five-step, workspace-relative path policy. */\nexport const createPathTranslator = (\n  root: string,\n  fileSystem: SandboxFileSystem\n): PathTranslator => {\n  if (root.includes('\\0')) throw new E_INVALID_SANDBOX_CONFIG(['root contains NUL'])\n  if (!root.startsWith('/')) throw new E_INVALID_SANDBOX_CONFIG(['root must be absolute'])\n  const canonicalRoot = root.replaceAll('\\\\', '/').replace(/\\/+/g, '/').replace(/\\/$/, '') || '/'\n  const containmentPrefix = canonicalRoot === '/' ? '/' : `${canonicalRoot}/`\n  // The explicit annotation is load-bearing, not decoration: TypeScript only treats a call as\n  // terminating control flow when the callee is a function declaration or a `const` with an\n  // explicit type. Without it, every `reject(input)` below reads as a normal call and the\n  // assignment analysis for `relative` fails — which is exactly the error this restores.\n  const reject: (input: string) => never = (input) => {\n    throw new E_SANDBOX_PATH_ESCAPE([`Path rejected: ${input}`])\n  }\n  const toRelative = async (input: string): Promise<string> => {\n    const canonical = input.replaceAll('\\\\', '/')\n    if (isRejectedSandboxPath(input)) reject(input)\n    let relative: string\n    try {\n      relative = normalizeSandboxPath(canonical)\n    } catch {\n      reject(input)\n    }\n    const resolved = `${canonicalRoot}/${relative}`.replace(/\\/+/g, '/')\n    if (resolved !== canonicalRoot && !resolved.startsWith(containmentPrefix)) reject(input)\n    await assertNoSymlinkComponents(relative)\n    return relative\n  }\n  /** Refuse symlink components on the resolved path and every parent. */\n  const assertNoSymlinkComponents = async (relative: string): Promise<void> => {\n    const parts = relative ? relative.split('/') : []\n    for (let index = 0; index <= parts.length; index += 1) {\n      const candidate = parts.slice(0, index).join('/')\n      const metadata = await fileSystem.stat(joinSandboxBackendPath(canonicalRoot, candidate))\n      if (metadata.kind === 'symlink') reject(relative)\n    }\n  }\n  const translator: PathTranslator = {\n    toRelative,\n    toBackendPath: (relative: string) => joinSandboxBackendPath(canonicalRoot, relative),\n    redact: (text: string) =>\n      text\n        .replaceAll(canonicalRoot, '<sandbox-root>')\n        .replaceAll(/\\/(?:Users|home)\\/[^\\s/]+/g, '<host-user>'),\n    assertNoSymlinkComponents,\n  }\n  return translator\n}\n","import { passesSchema } from './validation'\nimport { validator } from '@nhtio/validation'\nimport { isObject } from '../../lib/utils/guards'\nimport { isRejectedSandboxPath, normalizeSandboxPath } from './paths'\n\n/**\n * Presentation/normalisation brand only; this is NOT a containment guarantee.\n * Every filesystem use must still pass through PathTranslator.toRelative().\n */\nexport type ModelPath = string & { readonly __sandboxModelPath: unique symbol }\n/** Opaque model-facing write root; constructed only by the path layer. */\nexport type ModelWriteRoot = ModelPath & { readonly __sandboxModelWriteRoot: unique symbol }\n/**\n * Create a presentation/normalisation path only; this is NOT a containment guarantee.\n * Every filesystem use must still pass through PathTranslator.toRelative().\n */\nexport const createModelPath = (value: string): ModelPath => {\n  if (isRejectedSandboxPath(value)) throw new TypeError('path is not a model path')\n  try {\n    return normalizeSandboxPath(value) as ModelPath\n  } catch {\n    throw new TypeError('path is not a model path')\n  }\n}\n/** Construct the model root representation used in model-facing outcomes. */\nexport const createModelWriteRoot = (value: string): ModelWriteRoot =>\n  createModelPath(value) as ModelWriteRoot\n/** Opaque epoch issued by the sandbox manager and consumed by readers. */\nexport class SandboxEpoch {\n  /**\n   * Nominal-typing brand. LOAD-BEARING, and `protected` deliberately rather than `#private`:\n   * TypeScript derives class nominality from private/protected MEMBERS, not from a protected\n   * CONSTRUCTOR, so without a member here the class is structurally `{}` and any bare object\n   * satisfies `SandboxEpoch` — which is exactly what an epoch token must not permit. A `#brand`\n   * would brand it equally well but reads as an unused local; a protected member does not, since\n   * a subclass could legitimately use it.\n   */\n  protected readonly brand: undefined = undefined\n  protected constructor() {}\n\n  /** Issue a fresh epoch token for a sandbox manager. */\n  static issue(): SandboxEpoch {\n    return new SandboxEpoch()\n  }\n}\n/** Issue a fresh epoch token without requiring a type assertion. */\nexport const createSandboxEpoch = (): SandboxEpoch => SandboxEpoch.issue()\n\n/** Assembly-facing policy. Reads allow by default; writes and network deny by default. */\nexport interface SandboxPolicy {\n  /** Filesystem rules; `disabled` is a kill switch and deliberately does not unify axis defaults. */\n  readonly filesystem: {\n    /** When true, no filesystem rules apply. */ readonly disabled?: boolean\n    /** Read rules use deny-then-allow precedence. */ readonly allowRead?: readonly string[]\n    readonly denyRead?: readonly string[]\n    /** Write rules use allow-only semantics; deny wins inside the allow list. */ readonly allowWrite?: readonly string[]\n    readonly denyWrite?: readonly string[]\n    /** Whether `.git/config` is included in the mandatory deny set. */ readonly allowGitConfig?: boolean\n    /** Git safe directories passed to spawned children. */ readonly gitSafeDirectories?: readonly string[]\n    /** Linux mandatory-deny scan depth. */ readonly mandatoryDenySearchDepth?: number\n  }\n  /**\n   * Network rules. An absent allow list means deny all unless disabled.\n   *\n   * @remarks\n   * `disabled` means that SRT's network configuration key is omitted entirely. SRT decides whether\n   * to create a network namespace from the presence of that key; its `NetworkConfigSchema` has no\n   * schema-valid allow-all domain pattern (`\"*\"` is explicitly rejected). Consequently disabled\n   * means no network namespace restriction, rather than an allow-all domain entry.\n   */\n  readonly network: {\n    /** Omit SRT's network key, avoiding `--unshare-net`, when true. */\n    readonly disabled?: boolean\n    readonly allowedDomains?: readonly string[]\n    readonly deniedDomains?: readonly string[]\n    /** Model-readable reasons for denied domains. */ readonly deniedDomainReasons?: Readonly<\n      Record<string, string>\n    >\n  }\n}\n\n/** Backend-derived rules used for admission and drift checks, not a model-facing policy. */\nexport interface DerivedRules {\n  /** Platform matcher; there is intentionally no `win32` arm. */\n  readonly matcher: {\n    readonly platform: 'darwin' | 'linux'\n    /** Linux mandatory-deny files are folded; ordinary policy lists are not. */\n    readonly caseInsensitive: boolean\n    readonly readGlobs: 'native' | 'expanded'\n    readonly writeGlobs: 'native' | 'dropped'\n  }\n  /** Reads are deny-then-allow; allowWithinDeny wins. */\n  readonly read: {\n    readonly denyOnly: readonly string[]\n    readonly allowWithinDeny: readonly string[]\n  }\n  /** Writes are allow-only; denyWithinAllow wins. */\n  readonly write: {\n    readonly allowOnly: readonly string[]\n    readonly denyWithinAllow: readonly string[]\n  }\n  /** Reproduced mandatory denies, with provenance because SRT does not expose this derivation. */\n  readonly mandatoryDeny: {\n    readonly form: 'glob' | 'expanded-paths'\n    readonly entries: readonly string[]\n    readonly allowGitConfig: boolean\n    readonly searchDepth: number\n    readonly dotGitWasDirectory?: boolean\n  }\n  /**\n   * Whether the live sandbox has filesystem policy switched off entirely.\n   *\n   * @remarks\n   * A kill switch, and the drift check treats it asymmetrically: `true → false` is a NARROWING and\n   * therefore permitted, while `false → true` is DRIFT — it bypasses every filesystem rule while every\n   * set comparison still passes, which is precisely why it is compared on its own rather than inferred\n   * from the path lists.\n   */\n  readonly filesystemDisabled: boolean\n  /** `disabled` is an ADK provenance discriminator, not an SRT field. */\n  readonly network: {\n    readonly disabled: boolean\n    readonly allowedDomains: readonly string[]\n    readonly deniedDomains: readonly string[]\n    readonly strictAllowlist: boolean\n  }\n  /** Unknown upstream keys are drift signals and fail closed. */\n  readonly unknownKeys: readonly string[]\n  /** Glob forms this derivation could not compile, distinct from pairwise undecidability. */\n  readonly undecidableGlobs: readonly string[]\n}\n\n/** Terminal traversal protocol. Done is mandatory so end-of-stream cannot masquerade as completion. */\nexport type Done =\n  | { kind: 'done'; complete: true }\n  | { kind: 'done'; complete: false; omitted: 'unexplored'; bound: 'maxDepth'; atDepth: number }\n  | { kind: 'done'; complete: false; omitted: 'over-limit'; bound: 'limit'; shown: number }\n/** List item frames followed by exactly one {@link Done}. */\nexport type ListFrame = { kind: 'item'; path: string; entryKind: 'file' | 'dir' } | Done\n/** Path-search item frames followed by exactly one {@link Done}. */\nexport type PathFrame = { kind: 'item'; path: string } | Done\n/** Content-hit frames contain the whole matched line, followed by exactly one {@link Done}. */\nexport type HitFrame = { kind: 'item'; path: string; line: number; text: string } | Done\n\n/** Limits for a hostile guest: exactly seven fields, resolved before spawning and passed to both realms. */\nexport interface GuestLimits {\n  /** Per-event UTF-8 cap. Default 8192; floor 32 leaves room for the cut marker. */ maxLogEventBytes: number\n  /** Retained event count. Default 1000; floor 1 because framing consumes an event. */ maxLogEvents: number\n  /** Post-settlement sequence drain. Default 250ms; floor 0, where zero means do not wait. */ logDrainMs: number\n  /** Codec traversal depth. Default 32; floor 4. */ codecMaxDepth: number\n  /** Codec node count. Default 10_000; floor 16. */ codecMaxNodes: number\n  /** Producer-side hostcall/hostresult envelope cap. Default 1_000_000; floor 4096. */ maxHostcallBytes: number\n  /** Guest terminal envelope cap. Default 10_000_000; floor 4096. */ maxTerminalPayloadBytes: number\n}\n\n/** Per-evaluation host RPC quotas, separate from the seven guest limits. */\nexport interface HostcallQuotas {\n  /** Per-call deadline in milliseconds; default 10_000, floor 1. */ hostcallTimeoutMs: number\n  /** Accepted calls per evaluation; default 1000, floor 1. */ maxHostcallsPerEvaluation: number\n  /** Simultaneous accepted calls; default 8, floor 1. */ maxConcurrentHostcalls: number\n}\n\n/** A thrown guest value, preserving whether encoder representation was complete. */\nexport type GuestThrown =\n  | {\n      kind: 'error'\n      message?: string\n      messageTruncated?: boolean\n      stack?: string\n      stackTruncated?: boolean\n    }\n  | { kind: 'value'; encoded: unknown; encoding: 'encoder' | 'partial' }\n  | { kind: 'opaque' }\n/** One bounded, sequence-stamped guest log event. */\n/**\n * One log event exactly as the trusted guest bootstrap's logger posts it.\n *\n * @remarks\n * The logger — our code inside the guest, never the snippet — stamps each event with a monotonic\n * per-call sequence and UTF-8-truncates it to `maxLogEventBytes` BEFORE posting. Bounding in the\n * guest is the load-bearing half: a host-side byte count is applied after structured clone has\n * already materialised the string, so a single oversized `console.log` would be in host memory\n * before any accounting could react.\n */\nexport type GuestLogEvent = {\n  /** Monotonic per-call sequence, authored by the bootstrap logger — never by the snippet. It is what lets the host prove delivery completeness against the declared `logCount`. */\n  seq: number\n  /** The logged text, already UTF-8-truncated in the guest when it exceeded `maxLogEventBytes`. */\n  text: string\n  /** `true` when this event was cut to fit `maxLogEventBytes`; the host renders it with the pinned sentinel suffix so a clipped line is never read as a complete one. */\n  truncated: boolean\n}\n/** Delivery and emission framing for guest logs. */\nexport type GuestLogFraming = (\n  | { logsComplete: true }\n  | { logsComplete: false; logsThrough: number }\n) & {\n  logs: GuestLogEvent[]\n  logsCapped: boolean\n}\n/** Settled guest evaluation; partial encoding is still successful execution. */\nexport type GuestOutcome = (\n  | { ok: true; result: unknown; encoding: 'encoder' | 'partial'; durationMs: number }\n  | { ok: false; thrown: GuestThrown; durationMs: number }\n) &\n  GuestLogFraming\n/** A guest evaluation handle; timeout kills and rejects rather than fabricating a result. */\nexport interface GuestHandle {\n  /** Evaluate source with the model-visible deadline. */\n  evaluate(source: string, o: { timeoutMs: number }): Promise<GuestOutcome>\n  /** Terminate the guest process or worker. */\n  kill(): Promise<void>\n}\n\n/** Defaults visible as model-facing tool arguments; guest limits are intentionally separate. */\nexport interface SandboxCallDefaults {\n  /** Default traversal depth: 20. */ maxDepth: number\n  /** Default shell timeout: 300 seconds. */ shellTimeoutSeconds: number\n  /** Default JavaScript timeout: 30 seconds. */ evaluateTimeoutSeconds: number\n}\n\n/** Default guest values, each paired with its own floor. */\nexport const guestLimitsDefaults: GuestLimits = {\n  maxLogEventBytes: 8192,\n  maxLogEvents: 1000,\n  logDrainMs: 250,\n  codecMaxDepth: 32,\n  codecMaxNodes: 10_000,\n  maxHostcallBytes: 1_000_000,\n  maxTerminalPayloadBytes: 10_000_000,\n}\n/** Minimum representable guest values. */\nexport const guestLimitFloors: GuestLimits = {\n  maxLogEventBytes: 32,\n  maxLogEvents: 1,\n  logDrainMs: 0,\n  codecMaxDepth: 4,\n  codecMaxNodes: 16,\n  maxHostcallBytes: 4096,\n  maxTerminalPayloadBytes: 4096,\n}\n/** Default host quotas. */\nexport const hostcallQuotasDefaults: HostcallQuotas = {\n  hostcallTimeoutMs: 10_000,\n  maxHostcallsPerEvaluation: 1000,\n  maxConcurrentHostcalls: 8,\n}\n/** Closed structural schema for {@link SandboxPolicy}. */\nexport const sandboxPolicySchema = validator\n  .any()\n  .required()\n  .custom((value, helpers) => {\n    if (value === null || typeof value !== 'object') return helpers.error('any.invalid')\n    const v = value as Record<string, unknown>\n    if (Object.keys(v).some((key) => !['filesystem', 'network'].includes(key)))\n      return helpers.error('any.invalid')\n    const isStrings = (item: unknown): item is readonly string[] =>\n      Array.isArray(item) && item.every((entry) => typeof entry === 'string')\n    const isReasons = (item: unknown): boolean =>\n      isObject(item) && Object.values(item).every((entry) => typeof entry === 'string')\n    const definitions: Record<string, Record<string, (item: unknown) => boolean>> = {\n      filesystem: {\n        disabled: (item) => typeof item === 'boolean',\n        allowRead: isStrings,\n        denyRead: isStrings,\n        allowWrite: isStrings,\n        denyWrite: isStrings,\n        allowGitConfig: (item) => typeof item === 'boolean',\n        gitSafeDirectories: isStrings,\n        mandatoryDenySearchDepth: (item) =>\n          typeof item === 'number' && Number.isInteger(item) && item >= 0,\n      },\n      network: {\n        disabled: (item) => typeof item === 'boolean',\n        allowedDomains: isStrings,\n        deniedDomains: isStrings,\n        deniedDomainReasons: isReasons,\n      },\n    }\n    for (const [section, members] of Object.entries(definitions)) {\n      const part = v[section]\n      if (part === null || typeof part !== 'object' || Array.isArray(part))\n        return helpers.error('any.invalid')\n      const record = part as Record<string, unknown>\n      if (Object.keys(record).some((key) => !members[key] || !members[key](record[key])))\n        return helpers.error('any.invalid')\n    }\n    return value\n  })\n/** Duck-type guard for {@link SandboxPolicy}. */\nexport const implementsSandboxPolicy = (value: unknown): value is SandboxPolicy =>\n  passesSchema(sandboxPolicySchema, value)\nconst limitSchema = (floors: GuestLimits | HostcallQuotas) =>\n  validator\n    .any()\n    .required()\n    .custom((value, helpers) => {\n      if (value === null || typeof value !== 'object' || Array.isArray(value))\n        return helpers.error('any.invalid')\n      if (\n        Object.keys(value).length !== Object.keys(floors).length ||\n        Object.keys(value).some((key) => !Object.hasOwn(floors, key))\n      )\n        return helpers.error('any.invalid')\n      for (const key of Object.keys(floors)) {\n        const n = (value as Record<string, unknown>)[key]\n        if (\n          typeof n !== 'number' ||\n          !Number.isFinite(n) ||\n          !Number.isInteger(n) ||\n          n < (floors as unknown as Record<string, number>)[key]\n        )\n          return helpers.error('any.invalid')\n      }\n      return value\n    })\n/** Schema enforcing every guest field's own floor. */\nexport const guestLimitsSchema = limitSchema(guestLimitFloors)\n/** Guard for resolved guest limits. */\nexport const implementsGuestLimits = (value: unknown): value is GuestLimits =>\n  passesSchema(guestLimitsSchema, value)\n/** Schema enforcing every host quota floor. */\nexport const hostcallQuotasSchema = limitSchema({\n  hostcallTimeoutMs: 1,\n  maxHostcallsPerEvaluation: 1,\n  maxConcurrentHostcalls: 1,\n})\n/** Guard for resolved host quotas. */\nexport const implementsHostcallQuotas = (value: unknown): value is HostcallQuotas =>\n  passesSchema(hostcallQuotasSchema, value)\n"],"mappings":"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"}