KB-3809

04 — agent_api Dispatcher / Runner

3 min read Revision 1
dot-agent-apidispatcher2026-06-04

04 — agent_api Dispatcher / Runner (Workstream C)

Delivered LIVE: fn_process_agent_api_dispatch(p_dot_code, p_correlation_id, p_actor, p_mode, p_write_observation, p_idempotency_root) → jsonb. Generic, fail-closed, cannot execute a DOT.

Behaviour (in order, all fail-closed)

  1. Runtime gate — refuse unless execute_enabled=false ∧ real_run_enabled=false ∧ dry_run_only=true (re-read each call).
  2. Mode guard — REAL_RUN refused outright; mode must be PLAN_ONLY/VERIFY_ONLY/DRY_RUN.
  3. Correlation required.
  4. Contract must exist for dot_code.
  5. DOT must exist in dot_tools.
  6. Fixture present + output namespace DRYRUN-NS:%.
  7. DRY_RUN refused if endpoint_ref IS NULL — the structural block against faking a dry-run.
  8. Optional prepared observation: writes via fn_process_run_observe + fn_process_component_observe, evidence_type=SIMULATED_DRY_RUN only, source_system='agent_api_dispatch_planonly', evidence_ref.preparedness='DRY_RUN_PREPARED_BLOCKED_NO_ENDPOINT'. Idempotent on the idempotency root.
  9. Returns a JSON summary incl. validated, endpoint_present, true_dry_run_possible, blocker.

Why SIMULATED_DRY_RUN and not a new DRY_RUN_PREPARED type

The evidence_type domain stays {REAL_RUN, DRY_RUN, SIMULATED_DRY_RUN, BACKFILLED_EVIDENCE}. Preparedness is recorded in evidence_ref — exactly the prior macro's no-inflation decision. The dispatcher therefore can never push a candidate past simulated/plan_only_tested.

Generality

Dispatch is by contract row, not a per-code switch. It refuses: missing contract, missing fixture, non-DRYRUN-NS: namespace, REAL_RUN, production runtime, and DRY_RUN-without-endpoint. It supports the macro's mode flags (--plan-only, --verify-only, --dry-run, --no-execute/--write-observation) as function arguments; the staged plan_only_runner.example.sh shape from the prior macro maps onto it, and all guarantees are enforced server-side so a CLI cannot bypass them.

What it is NOT

It is not an agent_api endpoint. It has no network/LLM call, no execution body. When endpoint_ref is bound in a future macro, the same dispatcher gains the ability to call it and (only then) record DRY_RUN.

Status

Dispatcher LIVE. Proven fail-closed (doc 06). Reversible via v5_rollback.sql.

Back to Knowledge Hub knowledge/dev/reports/architecture/dot-agent-api-contract-dispatcher-dryrun-ui-registration-2026-06-04/04-agent-api-dispatcher-runner.md