/** The four states a tool card may show for the approval that guarded it. */ export type ApprovalState = 'waiting' | 'approved' | 'rejected' | 'unknown'; /** How well the state is known. Ordered from strongest to weakest. */ export type ApprovalProvenance = 'live' | 'policy' | 'durable' | 'inferred'; /** The approval field of one tool row. Display-only: never persisted by us. */ export interface ToolApproval { state: ApprovalState; provenance: ApprovalProvenance; /** True when a rule/reviewer decided it rather than a person (`policy`). */ auto?: boolean; /** Why — the classifier's or the reviewer's reason, when one was given. */ reason?: string; } /** * One approval fact onto a card's current field. * * `next` wins on state when it is at least as strong as what is already there. A * live decision is not overwritten by the durable event of the *same* decision * (which arrives right behind it on the live path and says strictly less), and an * inference never replaces anything but an inference. * @param current - the field as it stands, if any. * @param next - the fact being applied. * @returns the field the card should carry. */ export declare function mergeApproval(current: ToolApproval | undefined, next: ToolApproval): ToolApproval; /** * A recorded outcome as a card state. * * `cancelled` and `unavailable` are deliberately **unknown**, not `rejected`: the * reader's Esc, or a Host that had no approval channel, is not the human refusing * the tool, and printing a refusal they did not make is exactly the kind of * comfortable lie this field exists to prevent. * @param outcome - the `approval/decided` outcome, as recorded. * @returns the state the card shows. */ export declare function approvalStateFromOutcome(outcome: string): ApprovalState; /** * Whether a tool result proves an approval was **refused** when no audit events * survived. * * Only the Harness's own refusal sentences count. A generic denial (`denied by * policy`, `blocked`) does *not* prove an approval was ever needed, and the whole * point of the `inferred` provenance is that it is used only where the text can * carry it: the phrase below is what `dsh-tools` writes when `approval.request()` * came back `rejected` or `cancelled`, so it cannot appear for a tool that was * refused by a rule instead. * * It can never produce `approved` — running successfully is not evidence that * anyone approved anything (a tool with no approval requirement runs too). * @param text - the tool result's text. * @returns `rejected` when the text is that refusal, undefined otherwise. */ export declare function inferredApprovalFromResult(text: string): ApprovalState | undefined; /** A one-word label for the card chip. */ export declare function approvalStateKey(state: ApprovalState): string; /** * The provenance note shown beside the state. * * `live` and `durable` say nothing extra: a person's own decision and the log of * it are the same fact at two moments. `policy` and `inferred` do, because the * reader is being told something weaker and has to be able to tell. */ export declare function approvalProvenanceKey(approval: ToolApproval): string | undefined; /** * The expanded card's own line for the approval. * * It names the state, the strength of the evidence, and the reason when one * survived: `live`/`durable` need no apology, `policy` is marked automatic, and * `inferred` says outright that the card is reading the log rather than quoting it. * @param approval - the card's approval field. * @returns the sentence, already translated. */ export declare function approvalDetailText(approval: ToolApproval): string; /** Whether two approval fields would render identically. */ export declare function sameApproval(left: ToolApproval | undefined, right: ToolApproval | undefined): boolean;