KB-7B3F

02 — Reusable Runner Safety Patterns (Runner Safety Contract)

3 min read Revision 1
dot-agent-apirunner-patternssafety-contract2026-06-04

02 — Reusable Runner Safety Patterns → Runner Safety Contract

Extracted from the three verified runners already in production (see prior macro doc 02). The agent_api dispatcher reuses these proven patterns rather than inventing a new ad-hoc script.

Source runners and what each contributes

Runner Layer Reusable pattern
iu-cutter-v0.6 + o7_live_dryrun_runner.py (job:cut) host Python Mode.DRYRUN enum; __execution_enabled__ is False kill-switch asserted-never-assigned; RO DB role; Mode.LIVE → ProductionExecutionNotAuthorized; in-memory simulator; 366/366 regression baseline
dot_iu_command_run IU-command DB plan/apply/verify run_mode; mutating flag; gate_snapshot; gate refusals fire; idempotency via params_digest
dot-hc-executor host bash --dry-run/--only-check/--self-test; dispatch by executor_type (no per-code switch); RO-SQL-only token denylist; lockfile + heartbeat

Standard Runner Safety Contract (the 9 rules)

  1. Mode enum — explicit {PLAN_ONLY, VERIFY_ONLY, DRY_RUN, (REAL_RUN gated off)}.
  2. Kill-switch — runtime toggle re-read every call; refuse unless dry-run-only.
  3. Dry-run isolation — output only to a fixture/test namespace (DRYRUN-NS:).
  4. Read-only guard — no mutation of business tables; observation tables only.
  5. Idempotency — stable idempotency key; re-call returns same id, inserts 0 rows.
  6. Output namespace — enforced prefix; production namespaces refused.
  7. Fail-closed — every missing precondition raises; no silent pass.
  8. Preflight guard — contract + fixture + DOT-existence checked before any write.
  9. Observation/log write — record via the existing fail-closed observe functions.

What is reusable for agent_api vs not

  • Reusable: all 9 rules above; the dot-hc-executor "dispatch by type, not by code" generality; dot_iu_command_run plan/verify/gate-snapshot grain; the kill-switch + RO posture.
  • Not reusable: the execution body. iu-cutter executes a real (simulated) cut; dot-hc-executor runs real RO SQL. The agent_api layer has no invocation body at all (no endpoint), so the dispatcher can only validate + prepare — it cannot supply the missing execution.

Conclusion

fn_process_agent_api_dispatch implements rules 1–9 server-side (a CLI cannot bypass them). The single gap the contract layer cannot close itself is rule-0: a real no-mutation invocation entrypoint. That is the endpoint blocker.

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