import type { ModelSubstitutionObservation } from "@claudexor/schema"; /** * The daemon's bounded, self-expiring memory of typed model-substitution * observations: "this account answered a model operation's request for model M * with another model". * * The vendor state behind it is per account, lasts tens of minutes and is * invisible in the quota meter, while the pool's choice is deterministic by * headroom — without this memory the caller's next operation lands on the same * account. A live observation only ORDERS the pool for that requested model * (INV-135); it never excludes a row, never touches a pin or a preferred * account, and the engine still performs one generation per operation * (INV-014). * * Deliberately IN-MEMORY, like the `CredentialUnusableLedger` beside it: a * restart forgets every mark, so each account rediscovers its own episode at * the cost of one operation. A result that arrives after its subject was * cleared records a fresh mark, because an observation carries no credential * generation; the cost is ordering, never exclusion. * * Clearing contract: * 1. self-expiry — every row is stamped here with the one retention above; * 2. NO success-clear: inside an episode the same account still serves the * requested model now and then, which would erase the mark within seconds; * 3. a credential-generation change voids the verdicts about the changed * generation, at the unusable ledger's call sites: a login/logout clears the * WHOLE ledger (`noteCredentialChange`), a control-API profile mutation * clears PER SUBJECT (`clearSubject`). Secret mutations also clear every * matching registry subject, including subscription OAuth rows; * 4. no mark is recorded while a login may be rewriting that harness's * credential store (the daemon's setup-lifecycle window, #363); the * window's close clears the ledger. */ export declare class ModelSubstitutionLedger { private readonly now; private readonly mutating; private rows; constructor(now?: () => Date, mutating?: (harnessId: string) => boolean); /** Validate and stamp, newest-wins per (subject, requested model). */ record(value: Omit): void; /** Every un-expired observation (the read side of account resolution). */ live(): readonly ModelSubstitutionObservation[]; /** Credential generation changed wholesale (login/logout): every verdict * about the old generation is void. */ noteCredentialChange(): void; /** ONE account's credential changed (a control-API profile mutation): only * ITS verdicts are void, across every requested model. */ clearSubject(harnessId: string, profileId: string): void; private prune; } //# sourceMappingURL=model-substitution-ledger.d.ts.map