/** * Output Budget engine (ADR-0007). * * Pure projection library for the whole-envelope `--max-chars` budget. * The engine is shape-agnostic: command layers hand it a data payload * envelope, a char budget, and an ordered ladder of shrinking rules * expressing that command's priority table (never-cut fields are * expressed by omission — no rule ever touches them; trim-early rules * precede drop-late rules). * * Ladder contract: rules apply in array order, each to fixpoint, until * `measurePayload(projection) <= budget`. A rule is exhausted when it * returns the identical projection or one that does not strictly reduce * the measured size; the walk then advances to the next rule. When * every rule is exhausted and the projection still exceeds the budget, * the result clamps to that floor envelope with `compaction.note: * "floor"` — the budget never throws and never destroys data. * * `compaction` is present ONLY when shrinking happened and carries the * applied `budget`; the `ref` slot stays absent at this layer (the * persistence layer fills it with the artifact requestId). * * Rules must be pure: they receive the current projection and return a * smaller one without mutating their input (the untrimmed envelope is * persisted verbatim when compaction fires). */ /** One ordered step of a budget ladder. */ export interface LadderRule { readonly name: string; /** * Return a smaller projection, or the input unchanged when this rule * can shrink no further. Must not mutate `projection`. */ apply(projection: T): T; } /** Ordered shrinking rules; earlier rules are cheaper losses. */ export type BudgetLadder = readonly LadderRule[]; /** * Issue #105 (ADR-0007 follow-up): `--max-chars` is owned by the * dispatcher seam (`applyCommandOutputBudget` + ladder) on every * surface. A deep-import caller passing `maxChars` to a command handler * or Explorer entry point must fail loud — the retired per-field * truncation is gone, and silently ignoring the option (or silently * applying a second, undeclared budgeting system) is the accept-and-drop * class. Presence throws; the value is irrelevant. */ export declare function rejectSmuggledMaxChars(options: unknown, fnName: string): void; /** True when any walk has already shrunk this envelope (marker protocol). */ export declare function wasBudgetWalked(value: object): boolean; /** Shrink record stamped inside the data payload when the budget fires. */ export interface BudgetCompaction { readonly budget: number; readonly ref?: string; readonly note?: "floor"; } export interface BudgetOutcome { readonly projection: T; readonly compaction?: BudgetCompaction; } /** * Canonical serialization for budget measurement: JSON with object keys * sorted recursively (insertion-order independent) and array order * preserved. Assumes acyclic plain JSON data, matching what the output * layer prints. */ export declare function serializePayload(value: unknown): string; /** * Serialized payload length in chars (UTF-16 code units — the same unit * `--max-chars` truncation uses). Deterministic: structurally equal * values measure identically regardless of key insertion order. */ export declare function measurePayload(value: unknown): number; /** * Chars reserved for the `compaction {budget, ref}` stamp the handler * seam adds to every budgeted projection AFTER `applyBudget` returns * (ADR-0007 D6: the field lives inside the data payload). Upper bound * of `,"compaction":{"budget":,"ref":"YYYYMMDDThhmmssZ-hex"}` at the * compact-JSON measurement the engine uses — deterministic, offline, * and honest at the seam: the walked projection plus this reserve fits * the budget in data mode (ADR-0007: "measurement is serialized payload * length"). Output wrappers (`-O json`'s success/timestamp envelope, * pretty indentation, text presentations) are presentation chrome the * ADR scopes OUT of the measured payload; README documents the budget * as applying to the payload. */ export declare const COMPACTION_STAMP_RESERVE = 84; /** * Project `envelope` onto `budget` chars by walking `ladder`. Pure: the * input is never mutated and an envelope that already fits is returned * by reference with no `compaction`. Negative and NaN budgets normalize * to 0 (floor clamp); an infinite budget always fits. * * The walk reserves {@link COMPACTION_STAMP_RESERVE} chars for the * mandatory stamp, so a returned projection plus its `compaction` field * fits `budget` — the dispatcher no longer overshoots by appending the * stamp unmeasured. */ export declare function applyBudget(envelope: T, budget: number, ladder: BudgetLadder): BudgetOutcome; //# sourceMappingURL=output-budget.d.ts.map