Build Log
Alloy Cross-Machine Runner Presence Fix
August 1, 2026
Found and fixed the root cause of a live 'Runner: Never seen' bug on Railway: presence/claim matching compared absolute filesystem paths between two different machines, which structurally can never match.
Timeline
What shipped
Diagnosed a live 'Runner: Unavailable — Never seen' report on alloy.forgekits.build (Railway) despite the exact same runner process registering successfully against localhost
Added temporary diagnostic logging to app/w/[slug]/ignite/page.tsx to trace the real values Railway's server process was computing, since the bug was invisible to tsc and to every existing test
Root-caused via Railway's own live logs: the server (Linux container, cwd /app/products/alloy) and the runner (Windows, local machine) were both resolving correct paths independently, but getRunnerPresence's SQL prefix-match compared absolute paths between the two machines — a structural impossibility, not a bug in either side's path resolution
Confirmed this was the exact unsolved question docs/platform/railway-alloy-recommendation.md had already flagged: 'Runner's multi-user architecture is undecided... 1 deployment <-> 1 Runner <-> 1 owner <-> 1 local filesystem model'
Designed and implemented the scoped fix: createControlledExecution now takes an explicit productFolderPath (repo-relative, identical on every machine) and derives workspaceKey from it instead of the absolute cwd
Simplified getRunnerPresence to match on (ownerId, workspaceId) alone, dropping the cross-machine-broken cwd/path prefix check entirely — a runner serves its whole registered root, not one specific Product path
Simplified claimNextCommand's eligibility check by removing a second, now-redundant EXISTS clause that also compared workspace_key via prefix match
Updated every real call site: lib/actions.ts's 3 createControlledExecution calls (conductArc, runHarvest, startExecution), all getRunnerPresence callers, and the getActiveExecutionForTarget caller in lib/execution-context.ts
Updated all 4 test/script files tsc flagged as missing the new required field: harvest-execution.integration.test.ts, prove-arc-control-model.ts, prove-execution-authority.ts, prove-forge-conduct.ts
Found and fixed a real test bug while re-running the isolation suite: an earlier test's leftover Workspace-A runner row was now visible under the new (ownerId, workspaceId)-only matching, which the old cwd-scoped matching had accidentally masked — fixed by deleting and restoring an equivalent lease around the getRunnerPresence test
Removed the temporary diagnostic logging from the Ignite page once root-caused and fixed
Committed with fresh Access Control Gate evidence (real authority-check description, not a rubber-stamp), merged railway-proof into master's fix via master -> railway-proof merge, pushed, and confirmed the fix live on Railway with Zeb
Separately committed a pre-existing, complete Corpus (Historical Corpus Engine) v2 architecture doc and its Anvil/Strike/pattern-registry journal entries that were sitting uncommitted in the working tree from earlier in this session's history