import type { ArtifactBundle } from "../io/artifacts.js"; import type { AuditState } from "../types/auditState.js"; import type { AdvanceAuditOptions, AdvanceAuditResult } from "./advanceTypes.js"; export type { AdvanceAuditOptions, AdvanceAuditResult } from "./advanceTypes.js"; /** * Hard ceiling on the internal drain loop. The regen frontier is finite (each * deterministic step satisfies at least one obligation and no deterministic * executor re-opens an upstream one), so the loop terminates naturally when the * next step is a host-delegation boundary / complete / no-runner. This bound is * a belt-and-braces guard against an unforeseen re-opening cycle — larger than * the deterministic obligation frontier can ever be, so it never trips on a * healthy run. Chain-length/index-agnostic: it caps iterations, not a fixed * executor index. * * Enforced from inside the drain obligations' `execute` (see `runDrainStep` * below) because this cap is about DISPATCH SLOTS — how many steps one call may * hand out — which is a fact about the audit drain, not about the engine's * transition counting. The engine bound derived from it * (`engineMaxTransitions`) is the outer backstop, and both now stop the fold * gracefully, so the two differ in what they COUNT rather than in how harshly * they fail. */ export declare const MAX_DRAIN_STEPS = 64; /** * The engine bound, DERIVED from the graceful cap rather than written as a * literal at the call site. Raising `MAX_DRAIN_STEPS` therefore can never * silently move the fold past the bound — there is no second number to * remember to re-derive. * * The derivation itself (the headroom, and the rule that the bound is the cap * plus it) lives in the shared obligation engine, which owns the bounded-call * invariant for BOTH orchestrators. This function is the audit draw of that one * statement, not a second copy of it. */ export declare function engineMaxTransitions(cap?: number): number; export interface PriorityOrderingViolation { /** The slice-projected downstream artifact. */ downstream: string; /** The upstream artifact whose edge into it is slice-projected. */ upstream: string; reason: string; } /** * Check the ordering guarantee above against a priority order. Empty ⇒ the * guarantee holds. Defaults to the live `PRIORITY`; a caller may pass a * candidate order (which is how the guarantee is red-green validated: an order * that puts a downstream's obligation ahead of its slice-projected upstream's * must come back non-empty). */ export declare function findPriorityOrderingViolations(priority?: readonly string[]): PriorityOrderingViolation[]; /** * The identity of the executor that ACTUALLY threw, carried ON the error. * * `advanceAudit` DRAINS — one call folds through successive obligations — so a * caller that re-derives the failing identity from its own pre-drain * `decideNextStep` selection names the drain's FIRST obligation no matter which * fold step failed. That misattribution is not hypothetical: a * `synthesis_executor` blowup was recorded against `runtime_validation_executor` * (which had already succeeded), and sent the investigation to the wrong file. * The fix is structural — the identity travels with the error instead of being * reconstructed by a caller that cannot know it. */ export declare class ExecutorFailure extends Error { /** The executor whose runner threw. */ readonly executor: string; /** The obligation it was resolving (`forced:` for a forced dispatch). */ readonly obligation: string | null; constructor(message: string, params: { executor: string; obligation: string | null; cause?: Error; }); } /** * Find the failing-executor identity on `error` or anywhere down its `cause` * chain. Chain-walking (rather than a bare `instanceof` on the outermost error) * so an intermediate wrapper added later cannot silently reinstate the * misattribution it replaced. */ export declare function findExecutorFailure(error: unknown): ExecutorFailure | undefined; export interface AdvanceHeartbeat { /** Update the phase label the next beat reports (the selected obligation). */ setLabel: (label: string) => void; stop: () => void; } export declare function startAdvanceHeartbeat(intervalMs?: number): AdvanceHeartbeat; /** * `derive` for one PRIORITY id: the same holistic `deriveAuditState` scan * `decideNextStep` runs, narrowed to this id's own missing/stale/satisfied * state. A pruned/absent obligation (e.g. `friction_capture_current`, which * `deriveAuditState` never emits — see `executorRunners.ts`) is satisfied, so * the scan can never select it — preserving today's "unreachable" behavior. * * MEMOIZED per bundle object identity: `findNextObligation` calls every def's * `derive` on the SAME bundle each scan (one scan per fold iteration), and * `deriveAuditState` runs the full `computeStaleArtifacts` content-hash pass — * without the cache each scan would recompute it |PRIORITY| times (~8-9x the * hand loop's per-iteration derivation count). The cache is a per-`advanceAudit` * -call `WeakMap` created in `advanceAudit` (never module-level, so a caller * that mutates a bundle in place between calls can never observe a stale * entry); bundle identity changes exactly at each `transition` * (`runSingleAdvanceStep` builds a fresh `finalizedBundle`), so the memo * yields exactly one derivation per scanned bundle. Pure memoization — WHAT is * derived is unchanged, and `deriveAuditState` itself is deterministic in the * bundle (no time/randomness inputs). */ export declare function deriveObligationState(id: string, cache: WeakMap): (bundle: ArtifactBundle) => "missing" | "stale" | "satisfied"; /** * Advance the audit by ONE bounded step, then SAFELY DRAIN the deterministic * regen frontier within the SAME call: run the first bounded step, then keep * running consecutive deterministic runner-backed steps (re-deriving * decideNextStep + computeStaleArtifacts each iteration) until the next step is a * host-input pause, a no-runner handoff, or the run is complete. A whole staleness * cascade (e.g. a schema-version migration that re-stales every downstream * artifact) thus resolves in a single call and emits a single consolidated * staleness stderr record at the boundary — instead of one host round-trip (and * one record) per regenerated artifact. * * The drain is the DEFAULT (there is no opt-in flag). It is FOLD-AWARE: the stop * predicate is the single-sourced `nextStepPausesForHostInput` (via * `nextStepIsDrainableRegen`), consumed by BOTH this loop and the `next-step` * fold, so the drain halts at EVERY operator-interactive pause — including the * fold-level ones a registry-only `isHostDelegationExecutor` gate is blind to: the * analyzer-install consent fold and the low-confidence edge-reasoning fold (both * surfaced by the `graph_enrichment_executor`, which is registered deterministic). * * A forced `preferredExecutor` still runs EXACTLY ONE step: an explicit executor * request is a targeted single action, never a drain trigger — it bypasses the * shared engine entirely (the PRIORITY scan is irrelevant to a forced dispatch), * mirroring how the CLI fold's `runOmittableGate` handlers also dispatch a forced * executor directly rather than routing it through `advance()`. */ export declare function advanceAudit(bundle: ArtifactBundle, options?: AdvanceAuditOptions): Promise; //# sourceMappingURL=advance.d.ts.map