import type { CortexStore, LedgerDirectionTotals } from '../db/store.js'; /** * FR-9: the P&L report behind `cortex stats` (Story 3.6). * * Built here rather than inline in the CLI so the report is testable and the * B-6 budget is measurable in-process — the 3.3 precedent: the CLI end-to-end * cost on this platform is dominated by Node boot and store open (~500 ms * floor), so "within 200 ms" is a claim about this path, and the CLI cost is * recorded separately, never folded into it. * * Everything here READS. No session is created, no item is touched, no ledger * row is booked: a surface for revealing what ranking holds must not change * that ranking by being used (FR-21's rule), and a terminal render injects * nothing into any context (the documented 3.5 state for CLI commands). * `renderMemoryLine` is deliberately not reused for the top-10 list — it * wants reference validation, which persists corrected statuses (a write) and * costs filesystem time this surface's budget does not owe. */ /** AC #2 names ten; a knob would be scope creep. */ export declare const MOST_RETRIEVED_LIMIT = 10; /** Fixed width for the text segment of a top-10 line; the count, kind and labels are never what gets cut. */ export declare const STATS_ITEM_TEXT_MAX = 100; export interface StatsTokenBlock extends LedgerDirectionTotals { /** saved − injected. Unrealized and estimated are excluded (AC #3 / AD-8). */ net: number; /** * saved / injected, floored to hundredths — never rounded, because * `toFixed` would report 996/1000 as parity ("under-reporting is * acceptable, over-reporting is fatal", FR-9 PM note). `null` when nothing * was injected: no denominator is "no measurement", not zero and not * infinity. */ ratio: number | null; } export interface StatsMostRetrievedEntry { id: string; kind: string; accessCount: number; /** Rendered per the stored-strings-are-content discipline (D6). */ line: string; } export interface StatsReport { session: { /** Most recent primary across the working scope keys; null when none exists. */ id: string | null; startedAt: string | null; /** True only when a child session actually contributed ledger tokens. */ includesSubagents: boolean; /** Totals over the primary's whole tree; null when no session exists. */ totals: StatsTokenBlock | null; }; scope: { scopeKeys: string[]; totals: StatsTokenBlock; /** * Ledger rows no scope view can reach — NULL-scope sessions (the column * was added by migration with no backfill) and rows whose session is * gone. Rendered as one line when non-zero so the `estimated` history * FR-8 kept cannot silently vanish on a legacy store; never counted into * any total above. */ unattributed: LedgerDirectionTotals; }; items: { total: number; byState: Record; neverRetrieved: number; mostRetrieved: StatsMostRetrievedEntry[]; }; /** * Whether verified read substitution is enabled for the project being * reported on (Story 4.5), or `unknown` when no project root was supplied. * * Read-only: a `statSync` on a marker file. `stats` creates nothing and * touches nothing (the FR-21 rule, pinned by a run-twice byte-identical * test), and asking whether a file exists does not change that. */ substitution: 'on' | 'off' | 'unknown'; } export interface StatsReportOptions { /** * Project root whose substitution flag to report. The CLI passes * `process.cwd()`; omitting it yields `unknown`, which renders a statement * about evidence rather than about the mechanism. */ projectRoot?: string; } export declare function buildStatsReport(store: CortexStore, opts?: StatsReportOptions): StatsReport; export declare function renderStatsReport(report: StatsReport): string; //# sourceMappingURL=stats.d.ts.map