feat(gateway): C8 PM-decision gate windowed satisfaction

_check_pm_decision_required now requires the latest journal:decision
within pm_decision_window_seconds (default 300). Older decisions no
longer satisfy the gate. Adds JournalService.latest_decision_at.

Future-tighten (out of scope): per-verb-group consumption tracking
would need persistent state — Choreographer is per-request today.
This commit is contained in:
Renn F
2026-05-12 06:27:33 +02:00
parent 89eacf028e
commit 41ef7f6b4e
38 changed files with 631 additions and 29 deletions
+14
View File
@@ -342,6 +342,20 @@ class Settings(BaseSettings):
"override via ROBOCO_STALE_CLAIM_REAP_SECONDS"
),
)
# Wave C8 (2026-05-12). Pre-gateway parity: PMs wrote a fresh
# journal:decision around each decision point, not once at task
# creation. The PM-decision tracing gate (delegate, unblock,
# escalate_up, escalate_to_ceo) treats decisions older than this
# window as missing, forcing a new note(scope='decision', ...) on
# each pass through the gate.
pm_decision_window_seconds: int = Field(
default=300,
ge=1,
description=(
"Recency window (seconds) for PM journal:decision to satisfy "
"gating verbs; override via ROBOCO_PM_DECISION_WINDOW_SECONDS"
),
)
spawn_cooldown_seconds: int = Field(
default=60,
ge=1,