import type { Finding, ItemSpec, RemediationBlock } from "../state/types.js"; import type { RemediationState } from "../state/store.js"; export type FindingRiskTier = "safe" | "substantive" | "context_dependent"; /** One-line explanation of why the risk rule matched, shown to the reviewing LLM. */ export interface FindingClassification { tier: FindingRiskTier; reason: string; } /** * Host-handoff eligibility (INV-RS-01): a block is eligible only when EVERY * dependency reached a VERIFIED-COMPLETE disposition — every dependency item is * `resolved` / `resolved_no_change`. A SKIP (`ignored` / * `deemed_inappropriate`) or `blocked` dependency never satisfies the edge, so * its dependent stays outside the emitted host workload and is later marked * blocked rather than applied against a missing upstream surface. * * An unknown dependency id is not waited on forever: a dangling edge cannot * strand the whole DAG. */ export declare function dependencyVerifiedComplete(block: RemediationBlock, state: RemediationState): boolean; /** * Whether every unsatisfied dependency edge of `block` traces to an item that is * merely AWAITING A CLARIFICATION ANSWER, rather than to one that genuinely * failed. This is the discriminator the dead-end sweep needs. * * {@link dependencyVerifiedComplete} answers only "may this block be handed off now", * and a `needs_clarification` prerequisite fails it exactly the way a skipped or * blocked one does. Conflating them is safe only while an unanswered question * freezes the entire run. Once the question is DEFERRED to the end of the * implement phase (so siblings keep working), the dead-end sweep reaches the * dependents of an unanswered question and would mark them `blocked` — silently * converting "awaiting an answer" into "upstream failed", a worse bug than the * freeze. A node this predicate accepts is left `pending` instead and re-decided * after the batched clarification round: an answer that re-opens the upstream * makes the node eligible; an answer that disposes the upstream (a SKIP) makes * this predicate false, so the ordinary sweep dead-ends the node then, with the * accurate reason. * * Transitive, because the hold propagates down a chain (A→B→C with C awaiting * leaves both B and A held), and cycle-guarded, so a cyclic edge is never * reported as awaiting and still dead-ends exactly as it does today. */ export declare function dependencyAwaitingClarification(block: RemediationBlock, state: RemediationState, seen?: ReadonlySet): boolean; /** * Determine whether free-form triage rationale requests another attempt. */ export declare function rationaleAsksForRetry(rationale: string | undefined): boolean; export declare function classifyFindingRisk(finding: Finding, spec: ItemSpec): FindingClassification; //# sourceMappingURL=stepUtils.d.ts.map