/** * v2.11.0 Group F (Tier 9) — D5: full-auto self-decision gate. * * Single source of truth for "should this code path auto-proceed or * pause for an AskUserQuestion round-trip?" The D5 design (per * `.peaks/memory/2026-06-26-v2-11-full-auto-self-decision.md`) requires: * * - `full-auto` and `24h` modes → auto-proceed (recommended = chosen) * - `assisted` and `strict` modes → pause for confirmation * - 3 hard-floor categories ALWAYS ask, regardless of mode: * 1. Irreversible external side effects (git push, npm publish, …) * 2. Authentication / credential usage * 3. Multi-day investment decisions (release tag, breaking change) * * Karpathy §2: no inline `mode === 'full-auto'` checks scattered across * files — this module is the only place. Karpathy §3: this file is * surgical to the D5 design; do not extend with unrelated mode helpers. * * Re-uses `SkillPresenceMode` from `skill-presence-service.ts` so the * 4 mode values stay in lockstep with the rest of the runtime. */ import { type CodeMode, type CommitBoundaryActionId, type GatedStepId } from './mode-gate-types.js'; export { CODE_MODES, COMMIT_BOUNDARY_ACTIONS, COMMIT_BOUNDARY_PATTERNS, GATED_STEPS } from './mode-gate-types.js'; export type { CodeMode, CommitBoundaryActionId, GatedStepId } from './mode-gate-types.js'; export type HardFloorCategory = 'irreversible-external-side-effect' | 'authentication-credential' | 'multi-day-investment' /** * explicit full-auto boundary = commit only. Per user-given rule * from `.peaks/memory/2026-06-28-full-auto-boundary.md`: full-auto * ends at commit. push / tag / npm publish / global install are * commit-BOUNDARY side effects — they extend the commit to an * external system, and full-auto must NOT auto-perform them even * if every other mode says yes. Always pauses. */ | 'commit-boundary-side-effect'; export declare const HARD_FLOOR_CATEGORIES: readonly HardFloorCategory[]; /** * produced this decision. The LLM-side caller (peaks-code body) reads * this to distinguish "you paused because the user must choose the * mode" (`mode-selection-itself`) from "you paused because the mode * you already chose is assisted/strict" (`mode-driven`) from "you * paused because a hard-floor category always wins" (`hard-floor`). * * - `'mode-selection-itself'` — the gate IS the mode/context * selection step itself (step-1-mode-select, * step-0.5-openspec-opt-in, step-0.7-resume-detection). Even * `full-auto` mode pauses here; otherwise the user's first turn * would auto-lock the mode without their consent. * - `'mode-driven'` — the gate paused because the active * mode is assisted/strict (the existing default). * - `'hard-floor'` — the gate paused because a * hard-floor category always wins (irreversible external side * effect / auth / multi-day investment). */ export type GateKind = 'mode-selection-itself' | 'mode-driven' | 'hard-floor'; export interface GateDecision { readonly shouldPause: boolean; /** Human-readable rationale; surfaces in `peaks code should-pause --json` */ readonly reason: string; /** Hard-floor override applied? Surfaces in audit log when true */ readonly hardFloorCategory?: HardFloorCategory; /** Slice 2026-06-28-code-mode-bypass-fix: kind of gate that produced * this decision. Always present; defaults to `'mode-driven'` for the * assisted/strict pause branch. */ readonly gateKind: GateKind; } export declare function isCodeMode(value: string): value is CodeMode; export declare function isHardFloorCategory(value: string): value is HardFloorCategory; export declare function isCommitBoundaryAction(value: string): value is CommitBoundaryActionId; /** * `true` when the current mode should auto-proceed (skip the * AskUserQuestion round-trip). Mirrors D5.a: "recommended = chosen * in full-auto / 24h; always log, never silently skip". * * (parallel fan-out is now the default execution strategy in every * mode); `24h` replaces it as the second auto-proceed peer. */ export declare function shouldAutoProceed(mode: CodeMode): boolean; export declare function shouldPauseAtGate(opts: { mode: CodeMode; step: GatedStepId; hardFloorCategory?: HardFloorCategory | undefined; /** * mode. Reserved for the 5 commit-boundary side effects * (push/tag/publish/global install) that are past the user's * full-auto boundary. The hard-floor override ALWAYS wins — even * over the mode-driven auto-proceed branch. */ commitBoundaryAction?: boolean | undefined; }): GateDecision; /** * Format a one-line audit message for the auto-decisions log. * Karpathy §3: this is a pure formatter; it does NOT touch the file * system. The CLI / LLM is responsible for appending. */ export declare function formatAutoProceedLogLine(opts: { mode: CodeMode; step: GatedStepId; recommendedOption: string; hardFloorCategory?: HardFloorCategory | undefined; }): string; /** * commit-boundary action pattern. Returns the action id of the * first match, or `null` when none match. The CLI / LLM caller * passes the command through this function and forwards the * result to `shouldPauseAtGate({ commitBoundaryAction: true })` to * force the hard-floor pause. */ export declare function detectCommitBoundaryAction(command: string): CommitBoundaryActionId | null;