import type { Config } from "../config.js";
/**
 * Codex CLI flag preflight (mock-hidden-gap audit, 2026-05-27, gap 5).
 *
 * Why this exists: `execCodex` (codex-cli.ts) drives auto-relay by spawning
 * `codex exec resume <id> -c sandbox_mode=… --skip-git-repo-check -o <file> <msg>`.
 * The unit tests mock `child_process`, so they only prove the args we *intend* to
 * pass — NOT that the real `codex exec resume` subcommand accepts them. That gap
 * already caused three production breaks (`--color`, `--sandbox`, `--full-auto`
 * were each rejected by `exec resume` at exit 2 — see codex-cli.ts comments and
 * memory `cli-flag-subcommand-verification`).
 *
 * This preflight, run at startup when COGENT_PLATFORM=codex, (1) verifies the
 * `codex` binary resolves, and (2) runs `codex exec resume --help` and asserts
 * every flag we emit is documented by the installed CLI. A drift (new codex
 * version renames/drops a flag) surfaces as a loud startup warning instead of a
 * silent exit-2 on the first auto-relay.
 */
/**
 * The long-form flags `execCodex` emits on the `exec resume` subcommand. Keep
 * this in sync with `execCodex`/`sandboxArgs` in codex-cli.ts. We assert the
 * long forms (the short `-c`/`-o` always co-document with `--config`/
 * `--output-last-message` in codex help output).
 */
export declare const EXPECTED_CODEX_RESUME_FLAGS: ReadonlyArray<{
    flag: string;
    usedFor: string;
}>;
export interface CodexFlagAnalysis {
    missing: string[];
    checked: string[];
}
/**
 * Pure decision logic: given the text of `codex exec resume --help`, return which
 * expected flags are absent. Unit-testable with no spawning.
 */
export declare function analyzeCodexHelp(helpText: string): CodexFlagAnalysis;
/**
 * Verify the codex binary exists and that `codex exec resume` accepts the flags
 * auto-relay emits. Never throws — a preflight failure must not stop startup; we
 * only want the problem visible in the logs. Returns the analysis, or null if the
 * help text could not be obtained (binary missing / call failed).
 */
export declare function preflightCodex(codexPath: string): Promise<CodexFlagAnalysis | null>;
/**
 * Whether the host can initialize the Codex OS sandbox (an unprivileged Linux
 * user namespace, via bubblewrap). `blocked` is the failure that makes every
 * `codex exec resume` report "not finished" (bwrap: setting up uid map:
 * Permission denied). `na` = not applicable (bypass mode, or non-Linux host).
 */
export type SandboxProbeStatus = "ok" | "blocked" | "unknown" | "na";
export interface SandboxProbeResult {
    status: SandboxProbeStatus;
    detail: string;
}
/**
 * Pure decision logic: interpret the probe signals into a status. Unit-testable
 * with no spawning. `unshareOk` undefined = the `unshare` binary was unavailable,
 * so we fall back to the kernel sysctl signals.
 */
export declare function interpretSandboxProbe(s: {
    platform: NodeJS.Platform;
    mode: Config["COGENT_CODEX_SANDBOX"];
    unshareOk?: boolean;
    apparmorRestrict?: string | null;
    usernsClone?: string | null;
}): SandboxProbeResult;
/**
 * Pure: map an `unshare -Ur true` execFile rejection to a userns signal. Returns
 * `false` (blocked) ONLY for a genuine permission-denied refusal — the process
 * ran, exited non-zero, and stderr shows the userns op was denied (real
 * Ubuntu-24.04/hardened case, e.g. "write failed /proc/self/uid_map: Operation
 * not permitted"). Everything else is INCONCLUSIVE → `undefined`: a timeout/kill
 * (`err.killed`, `code` null), a spawn error (ENOENT/EACCES/EAGAIN — `code` is a
 * string errno), or a CLI usage error (a busybox `unshare` that lacks `-Ur`,
 * which exits non-zero for an unrelated reason). An inconclusive result makes the
 * caller fall through to the kernel sysctls and ultimately "unknown" (which never
 * engages the bypass) — the line between failing SAFE and failing OPEN on a
 * transient startup hiccup on a sandbox-capable host.
 */
export declare function classifyUnshareError(err: {
    killed?: boolean;
    code?: string | number | null;
    stderr?: string;
} | null | undefined): boolean | undefined;
/**
 * Gather sandbox-capability signals for the host and interpret them. Never throws.
 * Probes `unshare -Ur true` (the exact op bubblewrap needs); if `unshare` is
 * missing, falls back to reading the userns sysctls. Skips the probe (returns
 * `na`) for `bypass` mode or non-Linux hosts.
 */
export declare function probeSandboxStatus(config: Config): Promise<SandboxProbeResult>;
/**
 * Startup sandbox preflight — surface the Codex OS-sandbox capability LOUDLY so
 * a blocked host never silently loops on "not finished". Never throws. Returns
 * the probe result so startup can apply the COGENT_CODEX_SANDBOX_FALLBACK
 * recovery. Fallback-aware: when auto-recovery is on (the default) a blocked host
 * is a WARN (Cogent will bypass the dead sandbox so tasks run); when an operator
 * has opted out it is an ERROR (tasks will fail until they fix the host).
 */
export declare function preflightCodexSandbox(config: Config): Promise<SandboxProbeResult>;
/**
 * Pure: does this `~/.codex/config.toml` text declare a STANDALONE
 * `[mcp_servers.cogent]` server? That name collides with the `cogent@cogent`
 * plugin's OWN MCP server (both named `cogent`) — Codex collapses the two by name
 * and MCP startup fails ("MCP client for cogent failed to start … connection
 * closed: initialize response"). Latent until 3.19.2 made the plugin actually
 * start. See docs/update-and-troubleshooting.md + memory
 * `codex-app-server-wake-shipped-3.20.0`.
 *
 * Matches only the TOML TABLE HEADER (anchored to line start, optional leading
 * whitespace) so a `#`-comment or prose mention never trips it, and requires the
 * server name to be exactly `cogent` (so `[mcp_servers.cogent-cli]` and other
 * names are ignored). A bare `[mcp_servers.cogent]` OR any subtable
 * (`[mcp_servers.cogent.env]`, `[mcp_servers.cogent.tools.x]`) counts.
 */
export declare function detectCodexCogentServerCollision(configTomlText: string): boolean;
/** Absolute path to the codex config, honouring CODEX_HOME (falls back to ~/.codex). */
export declare function codexConfigPath(codexHomeDir?: string): string;
/**
 * Startup preflight: warn LOUDLY if the codex config defines a standalone
 * `[mcp_servers.cogent]` that collides with the plugin's own `cogent` server.
 * Never throws (a missing/unreadable config is simply "no collision"). Runs for
 * every codex bridge (plugin users included), so plugin-only users who never
 * launch via `cogent-codex` still get flagged. Returns true iff a collision was
 * found.
 */
export declare function preflightCodexServerCollision(codexHomeDir?: string): Promise<boolean>;
//# sourceMappingURL=codex-preflight.d.ts.map