import type { CortexStore } from '../db/store.js'; import { computeGitListedCensus } from '../capture/census.js'; /** * The command ledger (FR-15, Story 4.4): has this exact command already been * run against this exact tree, and how did it end? * * **The census is the evidence; head is metadata.** A verdict is asserted only * when the command's directory re-fingerprints to the recorded census (AD-6: * evidence in hand, never a proxy — and never mtime). The recorded `head_oid` * renders and is never compared: a rebase over a byte-identical tree changes * head and nothing about what the command would do, so comparing it could only * manufacture false misses. * * **Verdict ladder.** No record → `miss`. Census mismatch, growth beyond the * recorded figures, or a missing directory → `miss`; invalidation is a verdict, * never a row mutation (the FR-21 read-only rule), so restoring the exact bytes * honestly re-validates the record. Anything unprovable — no git, an unreadable * entry, an unresolvable scope root, a command that cannot even be identified → * `unknown` (AD-6). Scope isolation (AC #7) is the exact-key lookup's * `scope_key` equality; there is deliberately NO subsumption across directories. * * **Why `failed-at` is a verdict and not silence.** The outcome is read from * the host transcript's structured `is_error` boolean, so a failure is evidence * exactly as much as a pass is. Reporting it saves re-running a command purely * to rediscover that it still fails. * * **The query walks with the RECORD's own census figures as its limits**, not * the environment ceilings: exceeding the recorded file count or byte total * mid-walk proves growth (a change → miss) without hashing the rest, bounds the * work by what was recorded, and makes the answer independent of any later * change to the ceilings. */ export { COMMAND_MAX_LENGTH, COMMAND_SAFE_CHARS, SAFE_RUN_SCRIPTS, canonicalCommand, commandKey, isCacheableCommand, isDeterministicElement, normalizeCommand, normalizeCommandDir, splitAndChain, } from '../capture/command-key.js'; export type { CommandIdentity } from '../capture/command-key.js'; /** * A cap, not a budget — excess is refused and named. Lower than the read and * search ledgers' 16 because each distinct directory costs a `git ls-files` * subprocess plus a full re-hash; commands asked about together almost always * share one directory, which is memoized within a call. */ export declare const COMMAND_LEDGER_MAX_QUERIES = 8; /** AC #6: each rendered line fits 25 tokens, enforced as chars/4. */ export declare const COMMAND_LEDGER_TOKENS_PER_QUERY = 25; export type CommandLedgerVerdict = 'passed-at' | 'failed-at' | 'miss' | 'unknown'; export interface CommandLedgerQuery { command: string; /** Directory the command would run in; omitted means the scope root. */ dir?: string; } export interface CommandLedgerResult { /** The command exactly as asked, so a caller can correlate. */ command: string; commandKey: string; verdict: CommandLedgerVerdict; /** Present only on `passed-at` / `failed-at`. */ headOid: string | null; recordedAt: string | null; } export interface CommandLedgerDeps { census: typeof computeGitListedCensus; } export declare function queryCommandLedger(store: CortexStore, scopeKey: string, queries: CommandLedgerQuery[], deps?: CommandLedgerDeps): CommandLedgerResult[]; export declare function renderCommandLedgerLine(result: CommandLedgerResult): string; /** * `requested` names the drops. Silently returning 8 answers to a question about * 12 makes four commands indistinguishable from "not asked about" — the * wrong-answer direction AD-6 forbids, and the rule both other ledgers follow. */ export declare function renderCommandLedger(results: CommandLedgerResult[], requested?: number): string; //# sourceMappingURL=command-ledger.d.ts.map