Phase 2 — Heartbeat Activation (silent-gap surfaced)
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:
- Flip
queue.heartbeat.enabledfromfalsetotrue(gate flip — heartbeat protocol armed). No worker started. - Insert exactly ONE passive row into
queue_heartbeatfor the legacy route worker (iu_outbound_default), bound to its real last activity timestamp fromiu_route_worker_cursor.last_run_at. - Add
fn_queue_heartbeat_register_passiveas 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:
freshifage_seconds <= stale_thresholdwarningif<= 2 * stale_thresholdstaleotherwise
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_nameandactor. - Idempotent insert only — refuses if executor already present (
reason='already_registered'). - Sets
last_tick_status='warn'and a metadata block withmarker='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_ticknot invoked from any daemon or cron. The function is armed and ready to accept ticks from a future authorized caller.queue.worker.enabledremainsfalse.- No automatic refresh of
last_tick_atfor 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 |