/**
 * The resumed leg's DECIDE vocabulary — everything the resume engine needs to read a decide outcome and
 * carry it into the continuation, none of which is a step the driver calls with an Input:
 *  · was the decision NEGATIVE (a delivered refusal consumes its gate; no reopen compensation may fire);
 *  · is a replayed winner the SAME decision as the persisted one (reopen-by-reason guard,
 *    with the structural JSON equality it needs);
 *  · which call a CONTENT-ASK checkpoint parks on, and the one-shot answering face a decide's answer is
 *    bound to for the redeemed call;
 *  · the capture-time domain checks on a decide's TEXT payloads, and the label a rejected value gets;
 *  · WHO decided: the host's decision facts, validated once and minted into the settlement record once, for every
 *    decide that records its decider (a tool approval's and a plan pause's);
 *  · the continuation prompt itself.
 *
 * Pure over its arguments (the answering face is the one closure, and it closes over its own arguments
 * only). Run-loop machinery (layer 1), named without the `resume-` family prefix: that prefix marks a
 * driven rung of the resume decision ladder, which this is not.
 */
import { type AskOrigin } from "../ask-origin.js";
import { type OnQuestion, type QuestionAnswer } from "../ask-question.js";
import { type Checkpoint, type ResolvedOutcome, type ResumeOutcome } from "../checkpoint-store.js";
import { type GateOutcome, type HostDecisionFacts } from "../gate-outcome.js";
import type { ResumeRun } from "./contracts.js";
/**
 * Was this resume driven by a NEGATIVE human decision (plan_review/dry_run_review
 * `reject`, policy_ask `deny`)? Such a decision consumes its gate by being DELIVERED: there is no owed
 * action whose non-start could waste it, so the reopen compensation (both the throw-path and the
 * settle-path arm) must never fire for it — reopening re-asks a gate the human already refused, and on
 * the plan_review reject leg it minted a zombie gate beside the re-plan's NEW park (the session then
 * reported the same decidePath locked no matter how many times the human decided).
 */
export declare function resumeDecisionWasNegative(resume: ResumeRun): boolean;
/**
 * Structural deep equality of two JSON-serializable values (order-independent over object keys). Used ONLY
 * by the Runner's `resumeStream` reopen-by-reason guard to confirm an `env_failed` re-resume
 * replays the EXACT persisted winner (its `updatedInput` payload included). This is a same-runtime
 * value-vs-value comparison of two payloads that already round-trip JSON in the durable store — it is NOT
 * the cross-runtime `boundInputHash` canonicalization (out of scope for slice 1b), which
 * the spec deliberately keeps server-minted-opaque to avoid false mismatches.
 */
export declare function deepJsonEqual(a: unknown, b: unknown): boolean;
/** Two resume winners are the SAME decision iff they bind the same call,
 *  the same allow/deny verdict, the same (deep-equal) `updatedInput` rewrite AND the same (deep-equal)
 *  content-ask `answer`. An `env_failed` re-resume must replay an identical winner; any divergence is a
 *  re-vote (rejected).
 *
 *  ORDER MATTERS — `incoming` is the decide being replayed, `persisted` is the row's recorded winner. The
 *  `reason` dimension is compared ASYMMETRICALLY (see below), so the two arguments are not interchangeable. */
export declare function sameWinner(incoming: ResolvedOutcome, persisted: ResolvedOutcome): boolean;
/** The tool call a CONTENT-ASK checkpoint parks on — the pending `tool_approval` call of the reserved
 *  question tool — or `undefined` when this checkpoint parks on anything else (a side-effecting tool's
 *  approval, a resource slice, a review pause). The single predicate both the answer-binding guard and the
 *  answering-face injection key on, so "is this decide answering a question?" is asked exactly one way. */
export declare function pendingContentAskCallId(cp: Checkpoint): string | undefined;
/**
 * Bind a decide's content-ask answer as the resumed leg's answering face (ruled 2026-08-04) — the same
 * shape the documented live arm builds by hand (`{ ...taskConfig, onQuestion: async () => answer }`), so
 * the redeemed call executes against the SAME tool and the SAME untrusted-answer fence rather than a
 * second, parallel answer path.
 *
 * ONE-SHOT, bound to the redeemed call id: a decide answers the question the operator was shown, and
 * nothing else. Should the resumed leg ask a NEW question, this face must not replay the previous answer
 * to it (the questions differ; the fence's `selected ⊆ options` would strip the selections and the
 * operator's note would be re-delivered out of context). It falls through to whatever answering face the
 * resume already had, and — with none — refuses, which the tool reports to the model as "no answer was
 * obtained", its honest headless outcome. In the durable topology this fallthrough is normally
 * unreachable: a second question is adjudicated `ask` and parks for its own decide before executing.
 */
export declare function answerFaceForRedeemedCall(answer: QuestionAnswer, redeemedCallId: string, base: OnQuestion | undefined, 
/** Digest of the question batch the operator was shown, so redemption cannot be claimed by a
 *  DIFFERENT question that happens to arrive under the same call id. */
redeemedQuestionsHash: string): OnQuestion;
/**
 * A label for a REJECTED deployment-supplied value, safe to put in an error message. Never coerces:
 * `String(x)` on an object with no `toPrimitive` path (a null-prototype record, a throwing
 * `Symbol.toPrimitive`) throws, which would replace this module's typed refusal with a raw TypeError —
 * the malformed input escaping the very classification the refusal exists to give.
 */
export declare function describeSuppliedValue(value: unknown): string;
/** The decide lane a capture serves — the outcome gate word of an arm that carries the facts (the lane only words the refusals). */
export type DecideLane = Extract<ResumeOutcome, {
    hostDecision: HostDecisionFacts;
}>["gate"];
/** The member every durable decide refuses when a caller supplies it: the settlement record is core's mint. */
export declare const SUPPLIED_RECORD_KEY: readonly [string, string];
/** Refuse a decide that carries a key it may not (each with the sentence that says why). Presence is the whole test —
 *  no value read here is ever consumed, so a stateful accessor has no seam to open; `Reflect.get` keeps the read
 *  dynamic without naming a refused key as a property. */
export declare function refuseSuppliedKeys(decide: object, keys: ReadonlyArray<readonly [string, string]>): void;
/** What a decide says it decided, in the lane's own words: `word` is the verdict as the caller spelled it (for the
 *  sentence), `allows` whether it is the ALLOW direction (a tool approval's `allow`; a plan pause's `approve` / `edit`). */
export interface DecideVerdict {
    readonly word: string;
    readonly allows: boolean;
}
/**
 * Read and judge the host's decision facts — the ONE validation for every durable decide. `raw` is the caller's
 * `hostDecision`, read ONCE by the lane (this function reads `decidedBy` and `approver` once each, off it).
 *  - the facts are REQUIRED: absence (or a non-object) is refused — absence is not a fact about the wait, and core
 *    does not guess one;
 *  - `decidedBy` is a member of the closed set ({@link isHostDecider}); the sweep's word is the host's SLA sweep and
 *    a sweep resolves only rows whose deadline is an SLA resolve-deny (facet `A`, read through `facetOf`) — on any other row
 *    the word would file a record of an event that row's contract says cannot happen;
 *  - WHO MAY ALLOW the row: not the sweep's word (a wait nobody answered), and not the policy on a row that demands a
 *    person (`policyCannotAnswer`, the synchronous seat's rule);
 *  - the attribution passes the shared screen (a bounded plain string) — refused rather than dropped.
 */
export declare function captureHostDecision(cp: Checkpoint, raw: unknown, lane: DecideLane, verdict: DecideVerdict): HostDecisionFacts;
/** The origin word of the ask a pending row holds: a tool approval's was stamped on the park by the gate; a plan
 *  pause's is its kind (nothing persisted — the row's kind is the whole fact). Undefined for a row that holds no ask. */
export declare function parkedOriginOf(cp: Checkpoint): AskOrigin | undefined;
/**
 * THE mint for a durable decide's settlement record — the last pre-CAS station of both decide lanes: the host's
 * facts joined with the row's origin (invariant I1: a settlement names its origin), one record for the row's
 * resolved outcome. `allowed` is the allow direction; the refusal's `note` is the decider's own text (filed on a
 * person's refusal only). A row minted before the origin was persisted carries none, and the record cannot be
 * minted honestly for it: refused by version floor (the row stays pending), never guessed.
 */
export declare function mintDecideRecord(cp: Checkpoint, facts: HostDecisionFacts, verdict: {
    readonly allowed: boolean;
    readonly note: string | undefined;
}): GateOutcome;
/**
 * Capture-time domain check for a decide outcome's TEXT payloads — the review lanes' `editedPlan` /
 * `reason` and the approval lane's deny `reason`. All are persisted (the recorded winner's payload,
 * compared when an `env_failed` reopen replays it) and all are fenced into the model-facing
 * continuation reminder. The declared wire type is a string; a value outside it reads one way in this
 * process and another after a JSON round-trip, and reaches the reminder as whatever its stringification
 * happens to be. Worse, the pre-CAS tag-hygiene check and the fence BOTH reach the value through
 * `String.prototype.replace`: an object carrying its own `replace` is therefore read twice and may
 * answer differently each time — the check passing on text it never inspected. Refused pre-CAS so the
 * row stays `pending` for a well-formed decide, exactly like the other capture-time domain refusals,
 * and BEFORE the hygiene check so no guard ever consults a value outside the domain. The rejected field
 * is named in the message only — `CheckpointError`'s structured `detail.field` is a closed set covering
 * the approval lane's payload names, and widening it is a wire-surface change of its own.
 */
export declare function assertOutcomeText(value: string | undefined, field: "editedPlan" | "reason"): void;
/**
 * The continuation prompt for a resumed run. The vendored harness only exposes
 * `prompt(text)` (it always appends a user message — there is no "continue from tool results" entry), so
 * resume re-enters via a `<system-reminder>`-wrapped user message that tells the model the gated decision
 * was applied. The "user message wart" is accepted (API-valid, and clearer than a silent continuation).
 * `fullShellReachable` is the resumed leg's own roster fact, read by {@link reorientClause}; `delegatedChild` is
 * the leg's effective delegation fact, which picks the posture of a person's refusal of a tool use.
 */
export declare function resumeContinuation(resume: ResumeRun, mark: string | undefined, fullShellReachable: boolean, delegatedChild: boolean): string;
