/** * User-authored SOP (standard operating procedure) skill types — Feature A. * * A SOP is a user-defined workflow: ordered phases plus gates that guard entry * into a phase. Gates are first-class, addressable objects (stable id) so a * later metering layer (Feature B) can count them; Slice 1 only models and * validates them — no registry, no enforcement. */ export type SopGateCheckType = 'file-exists' | 'grep' | 'command'; export type SopGateCheck = { type: 'file-exists'; path: string; } /** * grep: by default passes when `pattern` is FOUND in `file`. Set `absent: true` * to invert — pass when the pattern is NOT found. `absent` expresses "must not * contain X" (e.g. no leftover TODO) as a pure-text check, with no command gate * and no `--allow-commands` escalation. * * Set `stripMeta: true` to evaluate the regex on a meta-stripped copy of the * file (HTML comments + fenced code blocks + `/* … *​/` block comments * removed). This lets content-publishing SOPs avoid the "literal-word trap" * where the author discussing the gate's behavior in the post would itself * trigger the gate. Default `false` preserves byte-identical behavior. */ | { type: 'grep'; file: string; pattern: string; absent?: boolean; stripMeta?: boolean; } | { type: 'command'; run: string[]; expectExitZero?: boolean; }; export type SopGate = { /** Stable id, unique within the SOP. Addressed by `peaks sop check --gate `. */ id: string; /** The phase whose entry this gate guards; must be one of the SOP's phases. */ phase: string; check: SopGateCheck; }; /** * Binds a concrete irreversible Bash action to a phase: running a command that * matches `bash` (a JS regex) counts as performing that phase's action, so the * phase's gates must pass first. Enforced un-bypassably by the PreToolUse hook * (`peaks gate enforce`). Optional — a SOP without guards still works exactly as * before; enforcement is an opt-in overlay. */ export type SopPhaseGuard = { /** The phase whose gates must pass before the matching command may run. Must be a declared phase. */ phase: string; /** JS regular expression tested against the Bash `tool_input.command`. */ bash: string; }; export type SopManifest = { /** SOP id; namespaced separately from built-in peaks-* skills. */ id: string; name: string; description?: string; /** Ordered, unique phase names. */ phases: string[]; gates: SopGate[]; /** Optional Bash-action guards enforced by the PreToolUse hook (opt-in). */ guards?: SopPhaseGuard[]; }; /** * A registered gate's workspace-level identity. `ref` (`/`) is * unique across the workspace; `transition` (`:`) is the binding * a future enforcement layer (Slice 3) consults. Built-in peaks-* gates are * never recorded here. */ export type RegisteredGate = { ref: string; gateId: string; sopId: string; phase: string; transition: string; }; export type RegisteredSop = { id: string; path: string; gates: RegisteredGate[]; }; export type SopRegistry = { version: 1; sops: RegisteredSop[]; /** Total gate count across all registered SOPs — the workspace pool a metering layer would read. */ gateCount: number; }; export type SopCheckResult = 'pass' | 'fail' | 'blocked'; export declare const SOP_GATE_CHECK_TYPES: ReadonlyArray; /** SOP id grammar: lowercase kebab, must start alphanumeric. */ export declare const SOP_ID_PATTERN: RegExp;