/** * IG1-crew-1: the governance MODE a seat runs under — what fences its tool calls — read from the * class the ENGINE derives (`governance_class` on the registry roster, IG1-core-3: * `acp_input_governance | os_sandbox | none`). Crew re-derives none of the engine's rules; it adds * only what the engine cannot know from a seat record: the ACP version pin crew probes * (`version_pin`, core#581), the scope kind of the run/ask, and the fence crew applies itself (the * bound run's worktree plus `LaunchOptions.extraWriteRoots`). * * Pure: no I/O, no clock. The roster (`roster-standing.ts`), `/diagnostics`, the ask path's record * (`ask-paths.ts`) and the eligibility rule (`seat-standing.ts chatSeatAdmission`) all call this. * * `governance_mode` is a crew reading, never an engine field: it is in `CREW_ONLY_SEAT_FIELDS` * (`core/engine-roster.ts`), so a studio round-trip of the roster never hands it to the engine. */ /** The engine's governance class names (IG1-core-3 `GovernanceClass::as_wire`). */ export type EngineGovernanceClass = 'acp_input_governance' | 'os_sandbox' | 'none'; /** `admitted` — an ACP adapter sends every tool call through the engine's gate; `os_sandbox` — an * OS write floor contains the seat (not a per-call gate, not a read or network jail); `none` — * nothing but the command-text fences. */ export type GovernanceModeKind = 'admitted' | 'os_sandbox' | 'none'; /** What the mode rests on: the admitted adapter, the seat record's `acp.os_sandbox`, the seat's * own sandbox (codex `--sandbox`), the engine's repository boundary around a bound run, or nothing. */ export type GovernanceModeSource = 'acp_input_governance' | 'seat_record' | 'self' | 'repo_boundary' | 'none'; /** The three scope kinds a seat can be convened for — the same keys as `chat_admission`: * `unscoped` (no repository), `scoped` (several repositories or a project — the run binds none), * `scoped_bound` (one repository — the run is bound to its worktree; every build run is this). */ export type GovernanceScopeKind = 'unscoped' | 'scoped' | 'scoped_bound'; export interface SeatGovernanceFence { write_roots: string[]; read_roots: string[]; /** No floor crew or the engine arms jails the network. */ network: 'open'; } export interface SeatGovernanceMode { mode: GovernanceModeKind; /** The engine's class as read (`null` when the engine reported none). */ class: EngineGovernanceClass | null; source: GovernanceModeSource; /** Why, in the operator's words. */ reason: string; fence: SeatGovernanceFence; } /** The registry fields the mode reads (a `RosterSeat` satisfies it). */ export interface GovernanceSeatInput { key: string; /** The headless invocation the engine launches (its first token is the executable). */ headless_invocation?: unknown; binary?: unknown; governance_class?: unknown; trust_flags?: unknown; acp?: { os_sandbox?: unknown; verified_version?: unknown; } | null; version_pin?: { matched?: unknown; pinned?: unknown; observed?: unknown; } | null; } /** The roots a fence names. Defaults are labels, not paths: the roster describes a seat before any * run exists; a run's record passes its real worktree. */ export interface GovernanceFenceRoots { worktree?: string; extraWriteRoots?: readonly string[]; } /** The CLI that actually runs for `seat` (C5, codex c5-crew-r3): the executable of its headless * invocation (quote-aware first token), else its binary, else its key — basename, lower-case, no * extension — as the engine resolves it, so a `claude` seat running `pi` is judged as pi. */ export declare function runRoot(seat: GovernanceSeatInput): string; /** * The mode a seat runs under for a scope kind (C5, matching wicked-core#950). * * - Container floor (the default): claude reads `admitted` (its gate hook inside the seat * container); every other seat reads `os_sandbox` / `repo_boundary` (the seat container). * - Interim host floor: claude reads `admitted` (its gate hook); codex reads `os_sandbox` / * `self` only with its own bounded `--sandbox`; every other seat reads `none` (the engine * refuses its governed work: `needs_container_floor`). Class `none` or no class reads `none`. */ export declare function seatGovernanceMode(seat: GovernanceSeatInput, scope: GovernanceScopeKind, roots?: GovernanceFenceRoots): SeatGovernanceMode; /** The mode per scope kind — `RosterSeat.governance_mode` (the same keys as `chat_admission`). */ export declare function seatGovernanceModes(seat: GovernanceSeatInput): Record; /** One seat's governance standing on `/diagnostics.seatGovernance.seats` (crew#742). */ export interface SeatGovernanceDiagnostic { cli: string; enabled_for_council: boolean; /** `acp` — an ACP adapter (`[cli.acp]`); `wrapped` — the CLI runs wrapped in a PTY. */ transport: 'acp' | 'wrapped'; /** The seat record arms the OS sandbox itself (`acp.os_sandbox`). */ os_sandbox: boolean; class: EngineGovernanceClass | null; /** `enforced` — admitted and (when pinned) the pin verified; `claimed` — admitted, pin not yet * probed; `unenforced` — no per-call gate holds this seat. */ input_governance: 'enforced' | 'claimed' | 'unenforced'; governance_mode: Record; } export interface DiagnosticSeatInput extends GovernanceSeatInput { enabled_for_council?: unknown; acp?: { os_sandbox?: unknown; verified_version?: unknown; acp_input_governance?: unknown; } | null; } export declare function seatGovernanceDiagnostics(seats: readonly DiagnosticSeatInput[]): SeatGovernanceDiagnostic[]; /** A `/health.warnings` entry (the wire's `HealthWarning`). */ export interface SeatGovernanceWarning { kind: 'seats.ungoverned' | 'seats.os-floor-unarmable'; severity: 'warning'; message: string; } /** * The pre-run warnings crew#742 asks for: a seat whose bound-run mode is `none` runs ungoverned; * floor seats that rest on the repository boundary on a host with no launcher to arm it * (`hostBoundary: null` — no `sandbox-exec` / `bwrap` on PATH) run advisory. Both warnings are about * governed WORK, so they cover the seats that can run it (`workEligible`: keys whose * `seat_eligible_for_work` is not `false`), not the council flag — a ballot-only seat never runs work. */ export declare function seatGovernanceWarnings(seats: readonly SeatGovernanceDiagnostic[], hostBoundary: string | null, workEligible: ReadonlySet): SeatGovernanceWarning[]; //# sourceMappingURL=seat-governance.d.ts.map