// Tool-layer contract types and frozen default tables (env allowlist, command rules,
// sandbox policy, limits, host config). No runtime logic lives here — the
// `resolveToolHostConfig` helper stays in src/tools/types.ts because it is layer logic, not a
// contract. `readonly` everywhere; optional props are `| undefined` because
// exactOptionalPropertyTypes is on. Imports end `.js`, double quotes, `type` keyword.
// Cross-platform name allowlist. Only names that are PRESENT in the parent are copied, so an
// absent Windows var on POSIX (or vice versa) is simply skipped.
//
// HOME and USERPROFILE are deliberately ABSENT (C5). Forwarding the developer's real home would let
// a subprocess read ~/.npmrc (npm tokens), ~/.git-credentials, and ~/.aws/… by standard home-dir
// lookup. runCommand instead injects an ephemeral, EMPTY per-run dir as HOME/USERPROFILE so those
// lookups resolve to nothing (ADR-0006 D2 Dimension 1).
export const DEFAULT_ENV_ALLOWLIST = Object.freeze([
    "PATH",
    "LANG",
    "LC_ALL",
    "LC_CTYPE",
    "TZ",
    "TERM",
    "TMPDIR",
    // Windows essentials so spawned tools resolve the shell-less executable correctly.
    "SystemRoot",
    "SystemDrive",
    "PATHEXT",
    "COMSPEC",
    "NUMBER_OF_PROCESSORS",
    "WINDIR",
]);
export const DEFAULT_SANDBOX_POLICY = {
    envAllowlist: DEFAULT_ENV_ALLOWLIST,
    network: "inherit",
    maxOutputBytes: 262_144,
    defaultTimeoutMs: 30_000,
    terminationGraceMs: 2_000,
};
// Minimal, justified default rules. Everything not listed is denied (deny-by-default).
export const DEFAULT_COMMAND_RULES = Object.freeze([
    {
        executable: "npm",
        // Read-only npm only. Mutating/package-installing subcommands are excluded by omission.
        allowedSubcommands: Object.freeze([
            "audit",
            "ls",
            "list",
            "outdated",
            "view",
            "info",
            "help",
            "ping",
        ]),
        // `-c`/`--call` execute a command string in a shell; deny outright (S-H2).
        denyFlags: Object.freeze(["-c", "--call"]),
    },
    {
        executable: "git",
        // READ-ONLY git only; push/reset/checkout/commit/merge/rebase/clean/config/remote denied.
        allowedSubcommands: Object.freeze([
            "status",
            "diff",
            "log",
            "show",
            "rev-parse",
            "ls-files",
            "describe",
            "blame",
            "cat-file",
        ]),
        // Global value flags that precede the subcommand (`git -C DIR <sub>`). Skipping them prevents
        // the value (DIR) from being read as the subcommand (S-H2).
        valueFlags: Object.freeze([
            "-C",
            "-c",
            "--git-dir",
            "--work-tree",
            "--namespace",
            "--exec-path",
        ]),
        // Deny git's code-execution / external-driver flags. `git -c diff.external=<cmd> diff` (and
        // --config-env/--ext-diff/--textconv) make git spawn an arbitrary command via its OWN shell,
        // defeating the Node spawn's shell:false; --exec-path redirects git to attacker-supplied sub-binaries.
        // hasDeniedFlag runs BEFORE subcommand resolution and matches both `--flag value` and
        // `--flag=value`. `-C`/--git-dir/--work-tree stay value-flags (location only, not execution).
        denyFlags: Object.freeze([
            "-c",
            "--config-env",
            "--exec-path",
            "--ext-diff",
            "--textconv",
            "--no-index",
            "--output",
            "--contents",
        ]),
    },
]);
export const DEFAULT_PATCH_LIMITS = {
    maxPatchBytes: 65_536,
    maxChangedLines: 2_000,
    maxFilesChanged: 50,
};
export const DEFAULT_TOOL_HOST_CONFIG = {
    sandbox: DEFAULT_SANDBOX_POLICY,
    commandRules: DEFAULT_COMMAND_RULES,
    patchLimits: DEFAULT_PATCH_LIMITS,
    applyEnabled: false,
    maxReadBytes: 262_144,
};
