ForgeKitFORGEKIT

Build Log

Close Verified Work Reliably

September 23, 2026

A real owner's request got stuck overnight showing a false completion message — traced through six real defects to a race-safe closure write.

owner-loopproduction-incidentconcurrencyalloycanvas-1
Real defects found and fixed
Tests passing
Commits

Timeline

Start
Alloy dev server + bounded signal investigations
UI Layout and Owner Loop Lifecycle signal audits, no new gates warranted
Interrupt
Canvas1 blocked job not showing on interventions page
Led into Court's stuck request — 'It's done and already live' shown falsely overnight
Root cause 1
Bare substring match on 'api' inside 'reshaping'
assertOwnerFacingLanguage fixed with word-boundary regex
Root cause 2-6
Exit-code contract, SHA identity, message honesty, success-value consistency, real tests
Each caught by direct user review of the prior fix, not self-discovered
Close
Race guard: closure_attempted_at + null-safe comparison
Replaced closure_attempt_run_id, which couldn't detect same-run races; 2 targeted tests added

What shipped

Fixed word-boundary bug in assertOwnerFacingLanguage (forgekit-os/scripts/finalize-owner-intent.mjs) that blocked a legitimate resolution note containing 'api' inside 'reshaping'

Fixed finalize-owner-intent.mjs never clearing stale closure_status on a later successful retry

Fixed 6 real owner-facing UI locations (canvas-1 through canvas-4, medinaCHF coordinator view) that falsely claimed 'already live' for genuinely-unverified outcomes — now checks publicationStatus and uses honest 'still checking' wording

Fixed a verification-refusal branch using bare `return;` (exit 0) instead of process.exit(1), which made refusal indistinguishable from success at the dispatcher's exit-code-only check

Fixed candidate/evidence SHA identity collapsing into one column across both finalize-owner-intent.mjs and dispatch-owner-loop-requests.mjs (fixed 3 times before landing correctly distinct)

Converged closure_status success representation on 'finalized' (was NULL in one writer, 'finalized' in the other)

Extracted decideClosureWrite() as real, production-used pure logic with 7 behavioral tests, replacing a structural test that only checked variable names

Replaced closure_attempt_run_id race guard with closure_attempted_at + null-safe IS NOT DISTINCT FROM comparison, in both finalize-owner-intent.mjs's repair branch and dispatch-owner-loop-requests.mjs's attemptFinalizeAndRecordClosure — closure_attempt_run_id doesn't change across same-Actor-run retries, so it couldn't detect a race within one run

Added isNotDistinctFrom as its own pure, tested predicate plus 2 targeted tests (same-Actor-run-ID race, null closure-attempt case)

Fixed dispatch-owner-loop-requests.mjs's row-fetching SELECT, which never selected closure_attempted_at at all

Restructured the failure-write branch to skip sending a failure escalation when the guarded write itself was rejected (superseded/unchanged), per explicit instruction not to notify for a write that was never actually recorded

Fixed an OS & Gate Logic spin-classifier false positive (spin-categories.mjs) — a self-referential audit spin was miscounted into UI Layout via a bare 'opacity' keyword match

Wrote forgekit-os/charges/signals-cockpit-two-section-redesign-2026-09-23.md — handoff Charge for the paused, uncommitted Signals Cockpit two-section redesign (717 lines across 4 files + new findings.ts, typechecks clean, not yet tested/reviewed/committed)