/** * Decision store — CRUD for .openlore/decisions/pending.json */ import { type LedgerActor } from './ledger.js'; import type { PendingDecision, DecisionStore, DecisionStatus } from '../../types/index.js'; export declare function decisionsDir(rootPath: string): string; export declare function loadDecisionStore(rootPath: string): Promise; export declare function saveDecisionStore(rootPath: string, store: DecisionStore): Promise; /** * Concurrency-safe read-modify-write of the decision store. Loads, applies * `mutate` (a pure id-keyed merge such as {@link upsertDecisions} / * {@link patchDecision}), and commits under compare-and-swap so two concurrent * writers never lose a decision — on a conflict the mutate is re-applied to the * newer store. (harden-memory-integrity-invariant) * * Every committed status transition (and creation) is trailed on the append-only * decision ledger, attributed to `actor` (change: add-decision-autopilot). The * diff is taken against the exact snapshot the winning mutate ran on, so a CAS * retry never double-logs. Default actor 'sync' marks a system write; callers * acting for a human, an agent, or the autopilot pass that explicitly. */ export declare function updateDecisionStore(rootPath: string, mutate: (store: DecisionStore) => DecisionStore, actor?: LedgerActor): Promise; /** * Merge incoming decisions into the store, deduplicating by id. * Existing decisions are never overwritten. */ export declare function upsertDecisions(store: DecisionStore, incoming: PendingDecision[]): DecisionStore; /** * Merge incoming decisions into the store, always overwriting by id. * Use this for consolidation output — consolidated decisions share IDs with * their original drafts (makeDecisionId is deterministic), so upsertDecisions * would silently no-op after patchDecision marks the originals rejected. */ export declare function replaceDecisions(store: DecisionStore, incoming: PendingDecision[]): DecisionStore; /** Patch a single decision by id. Returns the updated store (not yet saved). */ export declare function patchDecision(store: DecisionStore, id: string, patch: Partial): DecisionStore; /** * Apply a consolidation result to the store: mark each superseded draft `rejected`, * then merge the verified + phantom decisions with {@link replaceDecisions} (NOT * upsert). Consolidated decisions reuse their source drafts' deterministic ids, so an * upsert would treat the id as already-present and silently no-op — the draft would * never transition to its verified/phantom status. Pure; the caller persists the result * through the CAS path. (The CLI consolidation path performs the equivalent merge inline.) */ export declare function applyConsolidationResult(store: DecisionStore, result: { verified: PendingDecision[]; phantom: PendingDecision[]; supersededIds: string[]; }): DecisionStore; export declare function getDecisionsByStatus(store: DecisionStore, status: DecisionStatus): PendingDecision[]; export declare function getDecisionCount(store: DecisionStore): number; /** Status blocks the commit gate until resolved. */ export declare function isBlockingStatus(status: DecisionStatus): boolean; /** Status requires a --sync run before committing. */ export declare function requiresSync(status: DecisionStatus): boolean; /** Statuses excluded from the "activeDecisions" gate guard. */ export declare const INACTIVE_STATUSES: ReadonlySet; /** * Explicit status-transition table for promotion to `approved`. Promotion is * the one status change that approve_decision and sync_decisions perform, and * the one a human verdict must gate. A decision may be promoted to `approved` * only from one of these statuses. * * Two statuses are deliberately excluded and can never be promoted to `approved` * as a side-effect of any operation: * - `rejected`: a recorded human verdict. Reversing it requires an explicit * re-record (which returns the decision to `draft`), never a promote/sync. * - `synced`: already written to the spec files; not re-promoted. */ export declare const PROMOTABLE_TO_APPROVED: ReadonlySet; /** * Guard the `→ approved` transition. If promoting the decision is illegal from * its current status, return an error message naming that status and the human * step required to make the promotion legal; otherwise return `null`. Shared by * every promotion site (approve_decision, sync_decisions, the API sync, the CLI * `--approve`) so all refuse the same transitions identically — one table, one * verdict, no door left unlocked. * * This governs WHICH transitions are legal; the compare-and-swap commit of a * legal one is governed separately (`harden-decision-consolidation`). */ export declare function illegalPromotionToApproved(id: string, status: DecisionStatus, reviewNote?: string): string | null; /** Drop all inactive decisions — their content is already in ADRs / spec.md. */ export declare function purgeInactiveDecisions(store: DecisionStore): DecisionStore; /** Stable 8-char ID derived from session + domain + title. */ export declare function makeDecisionId(sessionId: string, domain: string, title: string): string; /** Generate a new session ID for a commit cycle. */ export declare function newSessionId(): string; //# sourceMappingURL=store.d.ts.map