vigiles API reference
    Preparing search index...

    Interface VerifyPluginGuardsOptions

    interface VerifyPluginGuardsOptions {
        adapter?: HarnessAdapter;
        capabilities?: EventCapabilityTable;
        categories?: readonly DisasterCategory[];
        cwd?: string;
        egress?: { allow: readonly string[] };
        env?: Record<string, string>;
        event?: string;
        events?: readonly DisasterEvent[];
        recordEgress?: boolean;
        sandbox?: SandboxMode;
        timeoutMs?: number;
        trusted?: boolean;
    }

    Hierarchy

    • Omit<RunHookOptions, "condition" | "protocol">
      • VerifyPluginGuardsOptions
    Index

    Properties

    adapter?: HarnessAdapter

    The harness to read the repo as. Defaults to Claude Code, so an existing Claude Code repo needs nothing. The condition grammar and the block protocol both come from this adapter's hookProtocol.

    capabilities?: EventCapabilityTable

    The harness's event capability table — what each event HONOURS — used to compute HookRunResult.delivery. Defaults to the table of the registered adapter whose hookProtocol IS protocol (so the default protocol gets its own harness's table, and no other). A harness with no table is judged only where the protocol's own injectableEvents proves delivery, and is unknown elsewhere.

    categories?: readonly DisasterCategory[]

    Restrict the battery to these categories (default: the whole catalog).

    cwd?: string

    Working directory for the process. Default: a value won't be set.

    egress?: { allow: readonly string[] }

    Allowlisted egress: let the hook actually reach the network, but ONLY the listed hosts, with the boundary at the packet layer (an nft allowlist inside the sandbox netns, fed by slirp4netns) — so a raw socket to an off-list host is dropped too, which a recordEgress/HTTP_PROXY allowlist cannot guarantee. Use it to test a hook/skill whose setup needs a real npm install from a registry you expect, and nothing else. Implies confinement (it needs the netns), and refuses if bubblewrap + slirp4netns

    • nft aren't available. The hosts are resolved to IPs at launch; results land in HookRunResult.egress (the allowlisted hosts that were reached, with allowed: true) and HookRunResult.egressDropped (how much off-list traffic was blocked). See docs/sandboxing.md.
    env?: Record<string, string>

    Extra env vars (merged over process.env). {cwd} in values is left as-is.

    event?: string

    The event each disaster is delivered as (default "PreToolUse").

    events?: readonly DisasterEvent[]

    Override the battery entirely.

    recordEgress?: boolean

    Record the hook's network egress. Implies confinement (the recorder lives in the sandbox netns, so this forces a sandboxed run and refuses if no sandbox is available). A recording proxy on loopback captures every host:port a proxy-honoring tool (npm/pip/curl/fetch) tries to reach — surfaced as HookRunResult.egress — while the netns still blocks it (nothing actually leaves). Use it to test what a hook/skill phones home to, or which registry an install would hit. Raw-socket egress is blocked but not recorded (it never reaches the proxy) — the block is the boundary, the record is best-effort observability over it.

    sandbox?: SandboxMode

    Confine the hook under bubblewrap (Linux). When unset, the mode follows RunHookOptions.trusted: a trusted hook runs directly (false), an untrusted one is confined-or-refused ("auto"). Set it explicitly to override: "auto"/"strict" force confinement (a no-egress namespace with a cleared environment — your opts.env is added back — or a refusal if no bwrap is available), and false is the opt-out that runs even untrusted code unconfined. macOS/Windows have no bwrap, so "auto"/"strict" throw there — see src/sandbox.ts.

    timeoutMs?: number

    Per-run timeout ms. Default 10000.

    trusted?: boolean

    Provenance of the hook command. true (default) means YOU authored it — the usual case at this tier, a command written inline in the test — so it runs directly. false marks it foreign (a vendored third-party hook script), which makes confinement the DEFAULT: with no explicit sandbox, an untrusted hook behaves as sandbox: "auto" — confined under bubblewrap, or refused if none is available — so foreign code is never run unconfined by accident. This mirrors the harness tier, where trust follows plugin/pluginDir provenance (specTrusted in src/sandbox.ts); the unit tier takes a raw command string with no provenance signal, so you declare it here.

    Why this is opt-in (untrusted) and not always-on: the sandbox isn't always available (Linux + working userns only — forcing it would refuse a hook you wrote on macOS/hardened CI), it's deliberately hostile (no egress, --clearenv, empty HOME, read-only fs — a false failure for trusted code that needs the network or an env var), trust follows provenance (you already vouched for inline code), and direct exec is ms vs. the confined path's setup+spawn. See docs/sandboxing.md ("Why confinement is opt-in"). Use sandbox: "strict" to force confinement even on trusted code.