KB-5762

05 — DOT-approved handler binding plan (handler_ref) 2026-06-23

4 min read Revision 1
c1-legohandler-bindinggoverned-migrationdot-approved

05 — DOT-approved handler binding plan (handler_ref)

Goal: flip apr_action_types.authorize_build_step.handler_ref from unimplementeddot-apr-execute:authorize_build_step without manual SQL / ad-hoc migration outside a DOT-approved path. If only manual SQL were possible ⇒ C1_AUTH_HANDLER_HOLD_BINDING_PATH_NOT_DOT_APPROVED. It is NOT — two DOT-approved paths exist; the primary is reliable.

PATH 1 (PRIMARY) — operator governed migration (authority-approved path of record)

  • The 4 implemented handlers were all bound via _dot_origin='MIGRATION' — i.e., the project's governed migration mechanism, authority-approved. Binding authorize_build_step the SAME way is the §3.4 "operator governed migration that is documented as authority-approved" path. It is not ad-hoc raw SQL: it is the migration path that established every working handler.
  • Artifact: staged-artifacts/migration/bind-authorize_build_step-handler.staged.sql — a single idempotent UPDATE … WHERE handler_ref='unimplemented', an in-txn readback assertion, and a documented rollback. Staged, not applied.
  • Ordering (hard): apply ONLY AFTER the handler code is deployed (file 04). Binding first is harmless (dispatch falls to *) SKIP:handler_unknown, fail-closed) but the action won't run.
  • Governance note: the binding is a one-time setup. It does NOT weaken per-grant governance — EVERY grant still requires the high-risk quorum (1 human president + 2 ai_council, proposer excluded, no rejects) re-proved at apply time by trg_apr_block_unimplemented. Binding the routing key ≠ authorizing a grant.

PATH 2 (ALTERNATIVE, pure-DOT) — governed update_item APR — UNRELIABLE here

  • In principle: apr_action_types IS a Directus collection, so a governed update_item APR (handler dot-apr-execute:update, PATCH /items/apr_action_types/authorize_build_step {handler_ref:'dot-apr-execute:authorize_build_step'}) is a fully DOT-100% path.
  • Blocked in practice: directus_fields has 0 rows for apr_action_types, and this Directus instance drops unregistered fields on write (documented in dot-apr-propose v2.0.1 changelog: "Directus drops unregistered fields"). A PATCH would likely drop handler_ref and persist nothing. ⇒ do NOT use unless an operator first registers handler_ref as a Directus field AND proves the PATCH persists (readback). Until then, PATH 1 is the path of record.
  • Note: update_item is risk=low ⇒ its own quorum is weak (total≥1). Binding a high-risk governance handler via a low-risk action is a governance smell; PATH 1 (migration, authority-reviewed) is cleaner for a binding of this sensitivity.

NOT a binding path

  • dot-apr-types-register — read this turn (VPS SSOT). It registers a PG table → Directus collection+fields; it does NOT touch apr_action_types.handler_ref. It is irrelevant to binding.
  • Raw psql -c "UPDATE apr_action_types…" outside the governed migration mechanism — this IS the forbidden "manual SQL / ad-hoc migration" and is explicitly NOT used.

Decision

Binding path = PATH 1 (operator governed migration), ordered after code deploy, with rollback. This is DOT-approved per §3.4 ⇒ C1_AUTH_HANDLER_HOLD_BINDING_PATH_NOT_DOT_APPROVED does not fire. It is an operator step (disclosed; the agent env has no governed write/registrar/exec channel — RO SELECT, allowlisted read, docs-only write, RO docker), executed later under owner approval.

Back to Knowledge Hub knowledge/dev/laws-new/reports/c1-authorize-build-step-handler-minimal-lego-patch/05-dot-approved-handler-binding-plan-2026-06-23.md