/** * Lane gate: G8/G10 enforcement for a LANE-BOUND `pi` session (launched with * `PI_WORKTREE_LANE=`). RuntimeBuilder wraps the session's file-mutation tools (edit / * write / bash) with {@link WorktreeLaneGate.checkMutation}; a lane that the active policy marks * sync_required fails closed with the exact recovery step until it rebases main. * * Honesty boundary: edit/write checks are structural for Pi children because the wrapper lives * under the tool layer. Bash remains a deliberate host-trust boundary; this gate only rejects * integration-sensitive Git forms and never claims to sandbox arbitrary process code. Foreign * CLIs stay cooperative-only, with the land CAS (G3) as their backstop. * * Determinism: the gate re-derives from git only when the epoch file actually changed (mtime * fence) or while blocked; verdicts in between are cached. No polling, no timers. */ import type { WorktreeSyncPolicy } from "./codes.ts"; import { type WorktreeSyncEngineDeps } from "./git-engine.ts"; export type LaneBashVerdict = { verdict: "allowed"; } | { verdict: "allowed_even_when_sync_required"; } | { verdict: "main_mutation_refused"; reason: string; }; /** * Classify one bash command line for a lane-bound session (G10 + the sync_required allowlist). * Tokenization is whitespace-naive by design -- deterministic and reviewable; shell-quoting * tricks can evade it, which is the documented cooperative boundary (the land CAS cannot be * evaded). Command POSITION still matters: `git` only begins an invocation at the start of the * command or immediately after a shell separator (`&&`, `||`, `;`, `|`) -- a bare `git` token * elsewhere (e.g. as a plain argument to `echo`) is not an invocation. Rules: * - `git push` anywhere: refused (main moves only through the land gate; pushing is owner-only). * - `git -C ` / `--git-dir` combined with a mutating subcommand: refused (escaping the * lane worktree to operate on another checkout, e.g. the hub). * - `git branch -f/-M/-D
` / `git update-ref refs/heads/
`: refused. * - Everything else: allowed; a read/commit-shaped git subcommand additionally stays allowed * while the lane is sync_required (committing WIP is the prescribed step BEFORE syncing). */ export declare function classifyLaneBashCommand(command: string, mainBranch: string): LaneBashVerdict; /** Symlink-safe containment check (G-path): does `targetPath` resolve inside `worktreePath`? */ export declare function isPathOutsideLane(targetPath: string, worktreePath: string): boolean; /** Resolve a user-supplied relative lane path and reject symlink/parent escapes. */ export declare function resolveLaneMutationPath(worktreePath: string, candidate: string): string | undefined; export interface WorktreeLaneGateConfig { laneKey: string; engineDeps: () => WorktreeSyncEngineDeps; policy: () => WorktreeSyncPolicy; } export type LaneMutationCheck = { allowed: true; } | { allowed: false; code: string; message: string; }; /** * The G8 gate object RuntimeBuilder holds per lane-bound session. `checkMutation` is called by * the wrapped edit/write/bash tools before every mutating execution. */ export declare class WorktreeLaneGate { private readonly config; private _ctx; private _epochFileMtimeMs; private _cachedAllowed; constructor(config: WorktreeLaneGateConfig); private resolveContext; /** Cheap fence: has the epoch file changed since the last allowed verdict? */ private epochChanged; checkMutation(toolName: string, bashCommand?: string, targetPath?: string): Promise; } //# sourceMappingURL=lane-gate.d.ts.map