Pixir.Delegate.CriticalPath (pixir v0.1.13)

Copy Markdown View Source

Pure critical-path estimates for Delegate launch admission.

Subagent estimates use ceil(task_count / max_threads) scheduling waves multiplied by the resolved uniform child budget. Workflow estimates sum the largest effective step budget in each planned dependency wave. Omitted step budgets use the runtime Subagent default, while both omitted and explicit budgets are capped by the normalized workflow timeout for the current estimate and wave_budgets_ms. suggested_timeout_ms is the least sufficient fixed point after that cap moves: it sums each wave's uncapped declared/default maximum, and can therefore exceed the current estimate only when the current workflow timeout binds. The estimate details carry the resolved caller horizon, whether that wait horizon was explicitly supplied rather than defaulted from the delegate timeout, the normalized declared workflow timeout, and whether that workflow timeout was explicitly declared before default injection, separately from their effective minimum. Rejection recovery chooses the wait-horizon knob when it was explicit and the delegate-timeout knob when it was derived. An explicit workflow timeout is combined with that caller knob only when it also binds. An omitted workflow timeout instead remains a delegate-derived ceiling: with an explicit wait horizon, recovery independently widens the wait and/or delegate timeout that binds; with a derived wait horizon, widening the delegate timeout alone moves both values. Maps from older callers that lack binding-source evidence retain the prior classification. Relaunching once at the suggestion is sufficient. Separately from admission, capped_step_budgets/4 names every explicitly declared step budget an explicitly declared workflow timeout caps, so the dry-run can predict the runtime closed_by_workflow_timeout cancellation instead of leaving it implicit in the gap between estimated_critical_path_ms and suggested_timeout_ms. That warning is purely advisory: it never moves would_reject, an admission verdict, or an exit code. Workflow wave maxima deliberately form a conservative batch-admission sum; a work-conserving scheduler can realize less wall time by starting newly unblocked work before a whole batch finishes. Admission still fails closed on that sum. Retries, provider jitter, and orchestration overhead are intentionally excluded.

Summary

Functions

Human-readable capped-step-budget lines, one per offending step.

Build the additive, machine-readable capped-step-budget warning, or nil when empty.

Name every explicitly declared step budget the declared workflow timeout caps.

Estimate uniform-budget Subagent scheduling waves.

Estimate a Workflow using the runtime default for omitted step budgets.

Estimate a Workflow; current arithmetic is capped, while suggestion is its fixed point.

Return the four stable horizon values shared by advisory, rejection, and override.

Build the canonical fail-closed horizon error from an enriched estimate.

Types

estimate()

@type estimate() :: %{
  :estimated_critical_path_ms => pos_integer(),
  :waves => pos_integer(),
  :suggested_timeout_ms => pos_integer(),
  optional(:json_pointer) => String.t(),
  optional(:path) => [String.t() | non_neg_integer()],
  optional(:step_index) => non_neg_integer(),
  optional(:per_wave_budget_ms) => pos_integer(),
  optional(:wave_budgets_ms) => [pos_integer()]
}

Functions

capped_step_budget_summary(entries)

@spec capped_step_budget_summary([map()]) :: String.t()

Human-readable capped-step-budget lines, one per offending step.

capped_step_budget_warning(entries)

@spec capped_step_budget_warning([map()]) :: map() | nil

Build the additive, machine-readable capped-step-budget warning, or nil when empty.

The warning is advisory only: it never changes would_reject, the admission verdict, or the exit code of an accepted plan. Its recovery guidance covers both directions (raise the workflow timeout, or lower the offending step budgets) and reuses the exact runtime remedy token the workflow-timeout fold publishes so dry-run and fold vocabulary stay greppable together.

capped_step_budgets(steps, declared_workflow_timeout_ms, declared_workflow_timeout_explicit, steps_path \\ ["steps"])

@spec capped_step_budgets([map()], pos_integer() | nil, boolean(), [String.t()]) :: [
  map()
]

Name every explicitly declared step budget the declared workflow timeout caps.

Returns [] unless the workflow timeout was explicitly declared in the spec: a defaulted/derived workflow timeout is a delegate-derived ceiling already covered by the horizon guard, not an operator-declared conflict. Steps that omitted timeout_ms declare no conflicting intent and are skipped even though the Subagent default they fall back to may exceed the workflow timeout. Steps whose declared budget is less than or equal to the declared workflow timeout are not capped.

steps_path is the 0-based location prefix of the step list as the caller submitted it, so machine callers can patch the pointer they actually sent: ["steps"] for a flat spec and ["workflow", "steps"] for the nested shell form, which the runner flattens before estimation.

estimate_subagents(task_count, max_threads, child_budget_ms)

@spec estimate_subagents(pos_integer(), pos_integer(), pos_integer()) ::
  {:ok, estimate()} | {:error, map()}

Estimate uniform-budget Subagent scheduling waves.

estimate_workflow(steps, waves, workflow_timeout_ms)

@spec estimate_workflow([map()], [[non_neg_integer()]], pos_integer()) ::
  {:ok, estimate()} | {:error, map()}

Estimate a Workflow using the runtime default for omitted step budgets.

estimate_workflow(steps, waves, workflow_timeout_ms, omitted_step_budget_ms)

@spec estimate_workflow([map()], [[non_neg_integer()]], pos_integer(), pos_integer()) ::
  {:ok, estimate()} | {:error, map()}

Estimate a Workflow; current arithmetic is capped, while suggestion is its fixed point.

horizon_values(details)

@spec horizon_values(map()) :: map()

Return the four stable horizon values shared by advisory, rejection, and override.

rejection(details)

@spec rejection(map()) :: map()

Build the canonical fail-closed horizon error from an enriched estimate.