KB-36F1

Phase 2 — Heartbeat Activation (silent-gap surfaced)

5 min read Revision 1
dieu45phase2heartbeatsilent-gappassive-marker2026-05-26

Heartbeat Activation — silent-gap surfaced via passive marker

Design choice

Per User decision #5 (no always-on daemon) and the §15.5 silent-gap status, Phase 2 implements the passive marker pattern:

  1. Flip queue.heartbeat.enabled from false to true (gate flip — heartbeat protocol armed). No worker started.
  2. Insert exactly ONE passive row into queue_heartbeat for the legacy route worker (iu_outbound_default), bound to its real last activity timestamp from iu_route_worker_cursor.last_run_at.
  3. Add fn_queue_heartbeat_register_passive as the canonical operator entry point for the same pattern (future legacy executors).

This surfaces the silent gap to operators without falsely marking a silent worker as healthy.

Why NOT enable queue.worker.enabled

Heartbeat is governance, not worker activity. Phase 2's scope is the safety/runtime governance layer before routing real workflows into job_queue. Workers are Phase 3+.

Why executor_kind='PG_worker'

The queue_heartbeat.executor_kind CHECK constraint pins kind to the §11.5 7-value MOT-excluded vocab: {DOT, Agent, Hermes, Codex, PG_worker, external_worker, future_Kestra_adapter}. CHECK widening is forbidden. The closest fit for iu_outbound_default (a PG-function-based route worker invoked externally via fn_iu_route_worker_run) is PG_worker.

Passive marker row

INSERT INTO queue_heartbeat (
    executor_name='iu_outbound_default',
    executor_kind='PG_worker',
    last_tick_at=<real iu_route_worker_cursor.last_run_at = 2026-05-22 11:31:41.928657+00>,
    last_tick_status='warn',
    ticks_total=0,
    metadata={
      "marker":"legacy_silent_passive",
      "source":"iu_route_worker_cursor.iu_outbound_default",
      "registered_at":"2026-05-26",
      "registered_by":"dieu45_phase2_mig_051",
      "note":"Passive marker. Records last observed activity of pre-Dieu45 route worker. Not an active claim. Surfaces silent gap to v_queue_health and fn_queue_stale_check. Heartbeat protocol armed but worker not started.",
      "authoritative_cursor_last_run_at":<...>,
      "phase":"phase2_governance"
    }
)

Surfacing of the silent gap

Post-apply, on a quiescent system:

SELECT executors_fresh, executors_warning, executors_stale FROM v_queue_health;
 executors_fresh | executors_warning | executors_stale
-----------------+-------------------+-----------------
               0 |                 0 |               1
SELECT fn_queue_stale_check();
{
  "stale_count": 1,
  "evaluated_at": "2026-05-26T13:52:55…+00:00",
  "stale_executors": [{
    "is_stale": true,
    "age_seconds": 354073,
    "ticks_total": 0,
    "last_tick_at": "2026-05-22T11:31:41.928657+00:00",
    "executor_kind": "PG_worker",
    "executor_name": "iu_outbound_default",
    "last_tick_status": "warn"
  }],
  "threshold_seconds": 300
}

The silent gap is now operator-visible. Severity in v_queue_health is calculated as:

  • fresh if age_seconds <= stale_threshold
  • warning if <= 2 * stale_threshold
  • stale otherwise

iu_outbound_default is stale because age_seconds (≈354k)600s.

fn_queue_heartbeat_register_passive — operator helper

Signature:

fn_queue_heartbeat_register_passive(
    p_executor_name      text,
    p_executor_kind      text,
    p_last_observed_at   timestamptz,
    p_actor              text,
    p_note               text DEFAULT NULL
) RETURNS jsonb

Behavior:

  • Gated by queue.heartbeat.enabled=true.
  • Requires executor_name and actor.
  • Idempotent insert only — refuses if executor already present (reason='already_registered').
  • Sets last_tick_status='warn' and a metadata block with marker='legacy_silent_passive'.

Refusal verified in proof step 11a:

{"reason": "already_registered", "refused": true,
 "last_tick_at": "2026-05-22T11:31:41.928657+00:00",
 "executor_name": "iu_outbound_default"}

What is NOT done

  • fn_queue_heartbeat_tick not invoked from any daemon or cron. The function is armed and ready to accept ticks from a future authorized caller.
  • queue.worker.enabled remains false.
  • No automatic refresh of last_tick_at for the passive marker. By design it should stay at the worker's true last activity until an authorized caller (e.g., a Phase 3 external operator ping that has actually scanned the cursor and confirmed activity) updates it.

Risk register (DP4 references)

ID Risk Mitigation in Phase 2
DP4-R1 Operator misreads passive marker as health last_tick_status='warn', metadata.note explicitly says "Not an active claim"
DP4-R2 Legacy worker resumes silently without updating marker Marker last_tick_at is bound to iu_route_worker_cursor.last_run_at; Phase 3 caller will reconcile
DP4-R3 Threshold drift hides slow-stale executors queue.heartbeat.stale_threshold_seconds=300 unchanged; tunable without code change
Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-dieu45-phase-2-heartbeat-activation-lease-governance/02-heartbeat-activation.md