/** * Unit-key resolution and the reason a unit's transcript is absent — the read half of * `GET /runs/:id/units/:unitKey/output`. * * The endpoint used to answer `200 {"output": null}` for four different facts: an unknown * run, an unknown unit key, a unit that had not run yet, and a unit whose gate DENIED. The * last is the one an operator reaches for during triage, so the one case that most needs an * answer was the case that yielded nothing — with a success status and no error (FINDING-006). * * `null` here is never bare. Either the run/unit does not exist (the route 404s), or the unit * exists and this module says which of the remaining causes applies, in the unit's own terms. * * ## Why a rejected unit has no transcript * * This is not a gap in the endpoint — it is wicked-core's deny-dominates rule, working. Core * writes a `work_output` node ONLY when the unit's phase resolved approved * (`wicked-core/src/execute.rs`, "on approval: record the work-output node"; a * validator/evaluator deny lands there as `!approved` and writes none). A unit is `done` iff * it was approved and `rejected` otherwise (`wicked-core/src/pipeline.rs`), so * `rejected` ⇒ no stored output, by design: no output can leak past a deny. * * What survives a deny is the REASON, on the unit record itself — `denial_reason`, which * carries the gate's citation for a governance/validator deny and a bounded head+tail excerpt * of the worker's failure output for a step failure (`wicked-core/src/actor.rs`). That is what * this module points the operator at. It does NOT claim the transcript is recoverable * elsewhere: the streamed text rode `cliOutputDelta`, which `wicked-core/src/event_log.rs` * excludes from the durable log as high-volume, and no `work_output` node was written. */ import type { SessionView, WorkUnit } from '../core/types.js'; /** * The unit a caller's path segment names, or `null`. * * Matching runs against the run's ACTUAL unit records rather than string-concatenating * `:` and hoping core keyed it that way. Four spellings resolve, tried * most-specific first so a bare ord can never shadow a phase id: * * 1. the fully-qualified id `run-1:survey` * 2. the id suffix `survey` (workflow runs) / `u3` (free-text runs) * 3. the ordinal in `u` form `u3` * 4. the bare ordinal `3` * * Passes 3 and 4 exist because the id suffix and the ordinal diverge on workflow runs: the * unit at ord 3 is keyed `:domain`, so `3` and `u3` addressed nothing at all. An * operator reading `#3` off the run list had no working key for that unit. */ export declare function resolveUnit(run: SessionView, unitKey: string): WorkUnit | null; /** * Every key `resolveUnit` accepts for this run, in `ord` order — the body of the 404 for an * unknown key. A caller who guessed wrong gets the working keys back rather than a second * round of guessing; the operator on FINDING-006 tried three spellings and stopped. */ export declare function unitKeysFor(run: SessionView): string[]; /** * Why this unit's stored output is absent, in the unit's own terms. Call ONLY when the read * came back `null` — a unit with output has nothing to explain. * * Every branch names a DIFFERENT cause. Collapsing them into one message is the shape this * whole endpoint was filed for: an operator cannot act on "no output" without knowing whether * the unit was denied, has not run, or is a record core disagrees with. */ export declare function outputUnavailableReason(unit: WorkUnit): string; /** One captured attempt of one unit, from the run's durable event log. */ export interface CapturedAttempt { attempt: number; outputBytes: number | null; stepStatus: string | null; } /** Every `unitOutputCaptured` for `ord`, one per attempt (the last frame per attempt wins), ascending. */ export declare function capturedAttempts(events: readonly Record[], ord: number): CapturedAttempt[]; /** * The attempt the stored transcript belongs to: the LATEST captured attempt that folded (`ok`) * whose byte count matches the stored text, else the latest `ok` attempt (an engine that does not * report `outputBytes`), else `null` when the log cannot say. Frames with no `stepStatus` count as * folded only when no frame carries one. */ export declare function storedAttempt(attempts: readonly CapturedAttempt[], output: string): number | null; /** Why `attempt` has no transcript of its own while the stored one is `served`'s. */ export declare function attemptUnavailableReason(unit: WorkUnit, attempt: CapturedAttempt, served: number | null): string; //# sourceMappingURL=unit-output.d.ts.map