Build Log
The Owner Loop's recovery path had never worked; a stranded request proved it
2026-09-28
What shipped
forgekit-os/scripts/lib/neon-admin-connection.mjs — the one sanctioned DDL escalation (neonctl → neondb_owner), with assertNotCI(); both column migrations now share it instead of each carrying a broken credential path
forgekit-os/scripts/inspect-owner-loop-request.mjs — cross-app read-only triage replacing the medinachf-only inspect-admin-intent.mjs; --all --stuck-only gives the whole fleet oldest-first with elapsed wait, and recommendAction() names the exact next command per row state
forgekit-os/scripts/foreman/rules/awaiting-human-too-long.mjs — Foreman rule for requests waiting on a person past a measured threshold (2 days: canvas-1's 41 closed requests have p90 0.45d, max 1.98d)
forgekit-os/scripts/classify-request-state.mjs — added awaiting_reply and shaping branches above the blocked case, recognizing both app shapes; constraint 6 added to the module's own honesty contract
docs/owner-loop-stuck-request-triage.md — symptom→tool map keyed on row state, the multi-step recovery sequences, which scripts cannot run locally, and an assessed list of what is genuinely missing
.github/workflows/actor-spawn.yml — kick step now if: always() (was success() || cancelled()), and stages run-id for the Actor
.github/workflows/owner-loop-dispatch.yml — removed the workflow_run trigger that could never fire
forgekit-os/scripts/actor-terminal-skeleton.mjs — 32→25 authored answers per run, regression-locked by a test
forgekit-os/scripts/accept-pending-candidate.mjs — synthesizes a pending-acceptance record for a candidate that shipped but was never verified, only on git-ancestry proof
products/alloy/lib/owner-loop-status/ + components — waiting-time dimension on the Owner Loop Status page (STALE_AFTER_DAYS, staleCountInWindow, per-row elapsed wait)