/** * The single authority for the `RemediationItem` status lifecycle. * * `RemediationItemState.status` is the canonical state of a remediation item; * every classification of it (terminal? skip? in-progress?) and every mapping * derived from it (coverage disposition, outcomes-contract status) is defined * HERE and imported elsewhere. Nothing outside this module may re-enumerate the * status values: the exhaustive `Record` maps below * make adding a status a compile error at each unhandled mapping rather than a * silent drift across the close / coverage / dispatch code paths. */ import type { RemediationOutcomeStatus } from "audit-tools/shared"; import type { PerFindingDisposition } from "./disposition.js"; /** * Every status a remediation item can hold, in lifecycle order: the in-progress * states (`pending`…`verified`), the success states (`resolved`, * `resolved_no_change`), the failure state (`blocked`), the awaiting-answer state * (`needs_clarification` — a worker hit scoping/judgment ambiguity mid-run and * paused the item for a clarification round rather than blocking it), the * settled-no-act states (`deemed_inappropriate`, `ignored`), and the * tool-gave-up state (`abandoned`). * * `abandoned` exists so that EVERY item ends terminal. A run that exhausts its * retry bound, fails its final gate, or is halted by the operator still has to * end, and a no-human host must never livelock waiting for a triage that will * not come. Before it existed, such items were left in a non-terminal status and * the close phase rendered them as a partial-completion outcome — which silently * broke the invariant that remediation ends binary. It is deliberately DISTINCT * from `ignored`: `ignored` is a settled human decision not to act, `abandoned` * is the tool giving up. Collapsing them would erase which one happened. WHY the * run ended non-clean is recorded once, at run level, in `closing_context` — * not smeared across every item. */ export declare const ITEM_STATUSES: readonly ["pending", "tested", "tested_successfully", "refactored", "verified", "resolved", "resolved_no_change", "blocked", "needs_clarification", "deemed_inappropriate", "ignored", "abandoned"]; export type RemediationItemStatus = (typeof ITEM_STATUSES)[number]; /** Whether the item is still mid-flight (see {@link IN_PROGRESS_STATUS}). */ export declare function isInProgressStatus(status: string): boolean; /** Whether a status is terminal — no further implement work, and a worker result must never resurrect it. `blocked` and `needs_clarification` are NOT terminal. */ export declare function isTerminalStatus(status: string): boolean; /** * Whether a status is VERIFIED-COMPLETE: the node produced and verified its * declared output (`resolved` / `resolved_no_change`). A skipped node * (`ignored` / `deemed_inappropriate`) and a `blocked` node are explicitly NOT * verified-complete — INV-RS-01: a SKIP disposition never satisfies a dependency * edge, so a dependent of a skipped/blocked node stays ineligible. */ export declare function isVerifiedCompleteStatus(status: string | undefined): boolean; /** Whether a status is a SKIP — a settled decision not to act (terminal but never verified-complete, INV-RS-01). */ export declare function isSkipStatus(status: string): boolean; /** * Whether an item ended WITHOUT succeeding and without a settled decision not to * act — `blocked` (triage exhausted, still non-terminal), `needs_clarification` * (unanswered), or `abandoned` (the force-close backstop gave up). Any of the * three means the run did not fully succeed, so it must never be "landed green" * with its artifacts deleted as if complete. * * Single-sourced because the green-close guard previously tested the `blocked` * literal directly: when the force-close seam moved to `abandoned`, a literal * test would have silently stopped matching and let a force-closed run land * green — and `needs_clarification` was absent from every partition entirely, * so a run stuck on an unanswered clarification could compute `anyBlocked` as * `false` and land green over an unanswered question (COR-d518cd60). */ export declare function isUnsuccessfulEndStatus(status: string): boolean; /** Map an item status to its per-finding coverage disposition. */ export declare function statusToDisposition(status: string): PerFindingDisposition; /** * Resolve a finding's real disposition: the module-recorded `override` when * present (CDC-25/26 — a producing module's own-phase record that this * finding's true disposition is `verified_already_fixed` or `refuted`, not the * generic status-derived one), otherwise the ordinary {@link statusToDisposition} * derivation. `RemediationItemState.status` stays a closed 12-member enum with * no `verified_already_fixed`/`refuted` values of its own — the two new * disposition members are reached ONLY through an explicit override, never * inferred from status, so `statusToDisposition`'s existing 12-key table (and * every caller that reads it directly) is unaffected by this widening. */ export declare function resolveDisposition(status: string, override?: PerFindingDisposition): PerFindingDisposition; /** * Whether `disposition` is one of the two CDC-25 members whose distinction * from an ordinary `resolved`/`resolved_no_change` close depends on recorded * evidence rather than the item-status enum — `verified_already_fixed` and * `refuted` REQUIRE a complete verification-evidence triple * (INV-ISC-EVIDENCE-EMITTED) before the writer may emit them as a terminal * disposition; the original five never carried that requirement and keep not * carrying it, so this predicate scopes the new gate to exactly the two * dispositions that need it. */ export declare function requiresVerificationEvidence(disposition: PerFindingDisposition): boolean; /** Map a coverage disposition to its outcomes-contract status. */ export declare function dispositionToOutcomeStatus(disposition: PerFindingDisposition): RemediationOutcomeStatus; //# sourceMappingURL=itemStatus.d.ts.map