/**
 * The answer account — the typed shape `accountForAnswer` returns.
 *
 * ONE public name, `AnswerAccount`. Its family (a sentence, a pointer into the
 * record, a chip, a row …) is reached by indexed access —
 * `AnswerAccount['rows'][number]['lines'][number]` — rather than as a dozen more
 * exported names: every export is a page on the API site, and the site's export
 * file-count budget has cost a release before. The names below are exported from
 * this MODULE for the library's own files and tests; the barrel exports only
 * `AnswerAccount`, `AnswerAccountDeclarations` and `AnswerAccountShownLeaf`.
 *
 * Read the folder README for the laws (weakest voucher, "not recorded", leaves
 * only, own run only).
 */
/**
 * Who vouches for a fact or a sentence. Ranked for the weakest-input rule,
 * strongest first: `person` (the question only) > `library` (recorded by the
 * library itself) > `tool:<name>` (a tool's recorded declaration) > `model` (the
 * model's recorded declaration) > `app` (the app's declaration handed in when the
 * report is made — NOT on the record).
 */
export type AccountSource = 'person' | 'library' | `tool:${string}` | 'model' | 'app';
/** `recorded` ⇒ at least one pointer resolves into the record. */
export type FactStatus = 'recorded' | 'not-recorded' | 'not-applicable';
/** Why a fact the account looks for is not on the record. */
export type MissingReason = 
/** The event that would carry it is not in this recording. */
'no-event'
/** The library does not record this yet (standing, routing confidence). */
 | 'not-built'
/** The tool or app did not declare it (no short, no kind, no coverage, no shape). */
 | 'not-declared'
/** It happened in an earlier leg of a resumed answer. */
 | 'before-pause'
/** Present, but not in a shape the account reads (counted in `unread`). */
 | 'unreadable'
/**
 * It travelled as DATA beside the answer, not as text in it — a typed
 * answer's limits (`turn_end.answerCoverage`, read as `limitsData`).
 */
 | 'as-data'
/**
 * The record keeps it out: a redaction policy (an agent's `redact`) left its
 * placeholder where the value was.
 */
 | 'redacted';
/**
 * Where "show me" lands. Always a LEAF: `path` names one value, never a whole
 * payload. `path` is an RFC 6901 JSON pointer into the event's PAYLOAD, into the
 * state key's value, or into the history message — except the two derived
 * forms: `#emptiness` (a `{ rows, at }` count the account computed, never the
 * rows themselves) and `#meta/runId` (the event's own
 * run identity).
 */
export type RecordPointer = {
    readonly kind: 'event';
    readonly index: number;
    readonly type: string;
    readonly path: string;
    readonly runtimeStageId?: string;
} | {
    readonly kind: 'state';
    readonly key: string;
    readonly path: string;
} | {
    readonly kind: 'history';
    readonly index: number;
    readonly path: string;
    readonly toolCallId?: string;
} | {
    readonly kind: 'declaration';
    readonly owner: 'app';
    readonly field: string;
    readonly id?: string;
    readonly version?: string;
};
/** One fact the account read (or looked for and did not find). */
export interface AccountFact<T> {
    readonly value: T | null;
    readonly source: AccountSource;
    readonly status: FactStatus;
    readonly pointers: readonly RecordPointer[];
    readonly missing?: MissingReason;
    /** The value was cut to bound the account's size; the rest is in the record. */
    readonly clipped?: true;
}
/** A value a sentence was filled with. `from` resolves to `value` (clipped values: to its start). */
export interface SentenceVar {
    readonly value: string | number;
    readonly from?: RecordPointer;
    readonly source: AccountSource;
    /** The value was longer than 2,000 characters and was cut; the rest is in the record. */
    readonly clipped?: true;
}
/** The sentence's text split for styling — typed text, never HTML. */
export type SentencePart = {
    readonly text: string;
}
/** A tool or skill id, verbatim. */
 | {
    readonly code: string;
}
/** Words quoted from the record (the question as recorded). */
 | {
    readonly quote: string;
    readonly source: AccountSource;
}
/** A declared label — drawn strong, with its own voucher. */
 | {
    readonly label: string;
    readonly source: AccountSource;
};
/** Which template filled a sentence, and which version of its words. */
export interface TemplateRef {
    readonly id: string;
    readonly version: number;
}
/** One line of the account. */
export interface Sentence {
    /** The whole sentence, plain. */
    readonly text: string;
    readonly parts: readonly SentencePart[];
    readonly template: TemplateRef;
    readonly vars: Readonly<Record<string, SentenceVar>>;
    /** The weakest of the truth-deciding inputs' sources (a label part is presentation, not truth). */
    readonly source: AccountSource;
    readonly status: FactStatus;
    readonly pointers: readonly RecordPointer[];
    readonly missing?: MissingReason;
    /** Chips that belong to THIS line (a kind, "not recorded", "decided = delivered"). */
    readonly chips?: readonly Chip[];
    /** A bulleted item under the nearest line above it that is not an item (declared coverage, flagged values). */
    readonly item?: true;
}
export type ChipMark = 'said-by' | 'declared' | 'not-declared' | 'undeclared-empty' | 'decided-delivered' | 'decided-not-delivered' | 'not-recorded' | 'signals' | 'none-found' | 'before-pause' | 'kind';
export interface Chip {
    readonly mark: ChipMark;
    readonly text: string;
    readonly tone: 'plain' | 'ok' | 'warn' | 'bad';
    readonly template: TemplateRef;
}
export type RowId = 'asked' | 'understood' | 'checked' | 'not-checked' | 'found' | 'how-sure' | 'anything-wrong';
/** One of the seven rows, always present, in `RowId` order. */
export interface Row {
    readonly id: RowId;
    readonly heading: Sentence;
    /** The row's lines, in order. A line with `item: true` is a bullet under the line before it. */
    readonly lines: readonly Sentence[];
    /** "…and n more tool calls" when the calls were folded (the omitted ones are in `show me`). */
    readonly more?: Sentence;
    readonly chips: readonly Chip[];
    readonly status: FactStatus;
}
export type SignalId = 'decided-not-delivered' | 'existence-not-checked' | 'undeclared-empty-used' | 'undeclared-empty-in-view';
/** The three checks the account runs. */
export type CheckId = 'decided-delivered' | 'existence' | 'empty-results';
export interface Signal {
    readonly id: SignalId;
    readonly check: CheckId;
    readonly sentence: Sentence;
    readonly tone: 'warn' | 'bad';
}
/** A check that applies to this answer but could not be run on this record. */
export interface Unreachable {
    readonly check: CheckId;
    readonly missing: MissingReason;
    readonly sentence: Sentence;
}
/** How one tool call of THIS run went. */
export type CallOutcome = 'ran' | 'failed'
/** A rule refused it BEFORE the tool ran. */
 | 'refused'
/** A person was asked and declined. */
 | 'declined' | 'not-dispatched'
/** A start with no recorded end — the record does not say how it ended. */
 | 'unknown';
/**
 * Whether the result the MODEL read was empty, and who says so — the one
 * emptiness reader's vocabulary (`core/agent/emptiness.ts` ·
 * `readEmptiness`), shared with the standing fold. `clarify` (a described
 * result that handed back a question and no data) joined it with that reader;
 * readers of this union skip a value they do not know.
 */
import type { Emptiness } from '../core/agent/emptiness.js';
export type { Emptiness };
export interface ToolCallFact {
    /** Cut at 200 characters (a model-chosen id is data, and the account is bounded). */
    readonly toolCallId: string;
    /** Cut at 200 characters; `''` when no event names the tool (then `unnamed`). */
    readonly toolName: string;
    /** No event of the call names its tool: the call is counted, judged and said to be unnamed. */
    readonly unnamed?: true;
    readonly outcome: CallOutcome;
    /** The rule that refused a `refused` call (a middleware, a permission rule id). */
    readonly refusedBy?: string;
    /** An AFTER-tool deny: the tool ran, the model read the rule's refusal. */
    readonly withheldBy?: string;
    readonly emptiness: Emptiness;
    /** Rows counted in the model's view (a counted rowset only). */
    readonly rows?: number;
    /** `app` when the emptiness rests on the app's declared `rowsAt`. */
    readonly emptinessSource?: 'library' | 'app';
    /**
     * Where in the value the model read the count was taken — a JSON pointer
     * (`/rows`; `/result/rows` through a declared boundary; `/result/datasets/rows/rows`
     * when the rows went to the artifact store and the dataset ticket left in their
     * place counts them). "Show me" points there.
     */
    readonly countedAt?: string;
    /**
     * A described result's data, counted per kind from the envelope the record
     * keeps (the `tools.semantics_declared` event) — the model read its
     * projection, which carries no marker.
     */
    readonly described?: {
        readonly facts?: number;
        readonly series?: number;
        readonly edges?: number;
    };
    /** The result was read through a declared `coverage()` boundary. */
    readonly bounded?: true;
    /** Whose view the emptiness was read from. */
    readonly view?: 'result' | 'model-result' | 'model-result-record-only';
    readonly coverage?: {
        readonly kind: 'absent' | 'coverage';
        /** The tool's own words, cut at 200 characters (the "It found" line prints up to 2,000). */
        readonly lookedFor?: string;
        readonly checked: number;
        readonly notChecked: number;
        readonly cannotCover: number;
        readonly kinds: number;
        readonly tryInsteadTool?: string;
    };
    readonly expectation?: {
        readonly basis: string;
        readonly expect?: string;
    };
    readonly pointers: readonly RecordPointer[];
}
/**
 * A call answered BEFORE a pause, on a resumed leg — read from the committed
 * state this record holds, never from that part's events (which the record
 * does not hold): what came back, from its message in `history`, and what its
 * tool declared, from its `coverageDeclared` rows. Whether it failed or was
 * refused by a rule is in those events, so it carries no outcome.
 */
export interface BeforePauseFact {
    readonly toolName: string;
    readonly toolCallId: string;
    /** What came back, as the model read it — the tool's own bytes, by the one emptiness reader. */
    readonly emptiness?: Emptiness;
    readonly rows?: number;
    readonly emptinessSource?: 'library' | 'app';
    /**
     * Where in the value the model read before the pause the count was taken — a JSON pointer
     * (`/rows`; `/result/rows` through a declared boundary; `/result/datasets/rows/rows`
     * when the rows went to the artifact store and the dataset ticket left in their
     * place counts them). "Show me" points there.
     */
    readonly countedAt?: string;
    /** What its tool declared, from the committed `coverageDeclared` rows; absent when it declared nothing. */
    readonly coverage?: {
        readonly kind: 'absent' | 'coverage';
        readonly lookedFor?: string;
        readonly checked: number;
        readonly notChecked: number;
        readonly cannotCover: number;
        readonly kinds: number;
    };
    readonly pointers?: readonly RecordPointer[];
}
/** An earlier answer's tool result that was in front of the model when it answered. */
export interface InViewFact {
    readonly toolName: string;
    readonly toolCallId: string;
    /** Messages a person wrote (`isSaidByPerson`) after the result, up to and including the current one. Always >= 1. */
    readonly distance: number;
    /** A window strategy was configured, so the distance is a floor. */
    readonly windowed: boolean;
    readonly emptiness: Emptiness;
    readonly rows?: number;
    readonly emptinessSource?: 'library' | 'app';
    /**
     * Where in the value the model read the count was taken — a JSON pointer
     * (`/rows`; `/result/rows` through a declared boundary; `/result/datasets/rows/rows`
     * when the rows went to the artifact store and the dataset ticket left in their
     * place counts them). "Show me" points there.
     */
    readonly countedAt?: string;
    readonly pointers: readonly RecordPointer[];
}
export interface RoutingFacts {
    readonly configured: AccountFact<{
        readonly routing?: string;
        readonly continuity?: string;
        readonly scorer?: string;
    } | 'none'>;
    readonly verdict: AccountFact<{
        readonly by: string;
        readonly from?: string;
        readonly to?: string;
        readonly decisive?: boolean;
        readonly scorer?: string;
    }>;
    readonly scores: AccountFact<{
        readonly top: number;
        readonly next: number;
        readonly nextId: string;
        readonly allOthersEqual: boolean;
    }>;
    readonly confidence: AccountFact<number>;
    readonly appDecision: AccountFact<{
        readonly skillId: string;
    }>;
    readonly delivered: AccountFact<readonly string[]>;
    /** ≤ 12, ids and rule names cut at 200 (the model's `read_skill` argument is model-chosen). */
    readonly refusals: readonly {
        readonly requestedId: string;
        readonly by: string;
        readonly kind: 'rule' | 'person';
    }[];
    readonly refusalsOmitted?: number;
}
export interface EvidenceFact {
    readonly posture: string;
    readonly candidates: number;
    readonly lookedUp?: number;
    /** The values not found, each cut at 200 characters. */
    readonly unsupported: readonly string[];
    /** `unsupported` is at the event's cap (12), so the true count may be higher. */
    readonly capped: boolean;
    readonly action: string;
    readonly afterRevision: boolean;
    readonly truncated?: boolean;
}
/** A typed answer's limits as the account reads them: how many items each list holds. */
export interface LimitsDataFact {
    readonly checked: number;
    readonly notChecked: number;
    readonly cannotCover: number;
    /** Values a tool's rule assumed this turn (the inputs layer). */
    readonly assumed: number;
}
/** The typed facts every sentence is filled from. */
export interface AnswerFacts {
    readonly routing: RoutingFacts;
    readonly calls: readonly ToolCallFact[];
    /** Calls past the 50-call cap, counted, not listed. */
    readonly callsOmitted?: number;
    /**
     * On a resumed leg: the calls answered before the pause, read from the
     * committed state this record holds (≤ 50, names cut at 200) — what came
     * back (history) and what each tool declared (`coverageDeclared`).
     */
    readonly beforePause: readonly BeforePauseFact[];
    readonly beforePauseOmitted?: number;
    /** ≤ 50, newest first; every one of them is judged by the checks. */
    readonly inView: readonly InViewFact[];
    readonly inViewOmitted?: number;
    readonly evidence: AccountFact<EvidenceFact>;
    /**
     * The answer's standing, folded from the run's committed state by the one
     * fold (`core/agent/assessment/assess.ts` · `assessAnswer`) — the owner's
     * words: `known` · `consistent` (checks ran, none fired — never "verified") ·
     * `not-sure` · `ask` (the run paused on a question for a person) ·
     * `not-assessed` (nothing on the record could be checked). `not-recorded`,
     * with no word, when the recording carries no committed state, or shows no
     * answer (no `turn_end`) and no pause — there is no answer to rate.
     */
    readonly standing: AccountFact<'known' | 'consistent' | 'not-sure' | 'ask' | 'not-assessed'>;
    /**
     * The library-appended section of a PROSE answer, when the framework added
     * one: the limits block (`.limitsTravelWithTheAnswer()`), the "Assumed"
     * block (the inputs layer) and the standing line (`.answerLayer({
     * standingLine: true })`), in the order they were appended — split off the
     * answer at the separator, so `answer` is the model's own text. A TYPED
     * answer carries no such text: its limits travel as data, so this reads
     * `not-recorded` with `missing: 'as-data'` and `limitsData` holds them.
     */
    readonly limitsBlock: AccountFact<string>;
    /**
     * A TYPED answer's limits, as the run recorded them beside it
     * (`turn_end.answerCoverage` — `.limitsTravelWithTheAnswer()` with an output
     * schema): how many items each list holds, with a pointer to every item.
     * `not-applicable` when the answer carried no limits as data (a prose
     * answer carries them in `limitsBlock`).
     */
    readonly limitsData: AccountFact<LimitsDataFact>;
    readonly errors: {
        readonly failed: number;
        readonly refused: number;
        readonly declined: number;
        readonly notDispatched: number;
        readonly withheld: number;
    };
    readonly checks: {
        readonly reachable: readonly CheckId[];
        readonly unreachable: readonly CheckId[];
        readonly notApplicable: readonly CheckId[];
    };
}
/** Facts about the run the account read. */
export interface RunFact {
    readonly runId: string;
    readonly turnNumber?: number;
    readonly model?: string;
    readonly resumedLeg: boolean;
}
/**
 * One answer's account: facts, each with who vouches for it and where it lives
 * in the record, and the fixed sentences rendered from them.
 */
export interface AnswerAccount {
    readonly kind: 'agentfootprint/answer-account';
    readonly shape: 1;
    readonly templates: {
        readonly set: 'answer-account';
        readonly version: number;
    };
    readonly run: AccountFact<RunFact>;
    readonly question: AccountFact<string>;
    readonly answer: AccountFact<string>;
    readonly facts: AnswerFacts;
    /** Always the seven, in `RowId` order. */
    readonly rows: readonly Row[];
    /** Priority order. */
    readonly signals: readonly Signal[];
    readonly unreachable: readonly Unreachable[];
    readonly summary: {
        readonly sentence: Sentence;
        readonly tone: 'ok' | 'warn' | 'bad' | 'unknown';
    };
    /** Rows passed over as unreadable, including a sentence whose fill failed. */
    readonly unread: number;
    /** Events of another run, never read. */
    readonly foreign: number;
    /** `unfiltered` only when no run id is known — the account then reads every event. */
    readonly scope: 'own-run' | 'unfiltered';
}
/**
 * Data the APP declares when the report is made — not on the record. Everything
 * filled from it is vouched `app`.
 */
export interface AnswerAccountDeclarations {
    readonly id?: string;
    readonly version?: string;
    /** Plain labels for skills whose runs carry no declared title. The record wins when it has one. */
    readonly skills?: Readonly<Record<string, {
        readonly label?: string;
    }>>;
    /** Where the rows of an OBJECT-shaped result live. Top-level key only. */
    readonly tools?: Readonly<Record<string, {
        readonly rowsAt?: string;
    }>>;
    /** The app decides entries itself, outside the library's routing. */
    readonly routing?: {
        readonly appDecides?: boolean;
    };
}
/**
 * One "show me" leaf as it leaves the server: a JSON leaf, a DERIVED emptiness
 * count (never the rows), or why it is withheld.
 */
export type AnswerAccountShownLeaf = {
    readonly value: string | number | boolean | null;
} | {
    readonly rows: number;
    readonly at: string;
} | {
    readonly withheld: 'not-shown-here' | 'too-large' | 'not-found' | 'foreign';
};
//# sourceMappingURL=types.d.ts.map