~bigbes/agents-dev · parade

main · last commit 13 days ago · 7g0stsfu

← Back to the parade

ah-nyl.15 fix: adopt-guard livelock + neither-state timeout arm (final verification findings) Past Stand

status: closed P0 bug
bd reopen ah-nyl.15
Created byEugene Blikh
Ownerbigbes@gmail.com
Created2026-07-13T02:43:36Z
Started2026-07-13T02:43:37Z
Updated2026-07-13T03:01:04Z
Closed2026-07-13T03:01:04Z
Description
Final composed-semantics verification (@ 825238d) returned FIX-FIRST with two findings, both pre-analyzed with exact fixes. Scope: internal/reconcile/ ONLY.

V1 HIGH (reconcile.go:524): adoptOrFail's finished-row branch guard `run.State == RunStateFinished && !st.Running` fires on ANY non-Running status including hard Completed for the NEXT attempt (exit.json{K+1} present but the K+1 row was never persisted — crash before CreateRun or persist failure whose compensating kill raced a fast-exiting pi). Result (empirically proven by the verifier): terminal record -> alignCardToRecord silently bounces ready->failed on every human re-drag, K+1's real result never persisted/commented, Start never issued, stale exit.json never cleaned — livelock against the human. FIX (verifier-tested in scratch against the full suite): change the guard to `!runtimeEvidence(st)` so hard Completed evidence falls through to the adopt branch (which persists the K+1 row from the evidence and finalizes with its true outcome). Add regression test: finished row K + probe returns hard Completed{attempt K+1, exit 0} -> adopts+finalizes K+1 (row created, in_review, one comment), then K+2 claimable; also the terminal-record variant (card in ready, terminal rec, completed evidence -> adopt path, NOT silent bounce).

V2 MEDIUM (reconcile.go:409-421): check() switch has no arm for the neither-state (st.Running==false && st.Completed==false — live session, meta gone/mismatched; reachable when the worktree is rm -rf'd mid-run, MetaAttempt=0). Today: no finalize, no timeout, forever — run wedged in in_progress past any deadline (verifier proved 31min past a 30m timeout, zero kills). FIX: add a third arm — when neither-state persists and now > run.StartedAt + cfg.Timeout: runner.Kill + finalize with OutcomeTimeout (same path as the Running-timeout arm); before the deadline, log at warn (observation degraded) and do nothing. Regression test: running row, status neither (MetaAttempt 0), fake clock past deadline -> Kill called, finalized timeout, card failed; before deadline -> no action.

V3 INFO (reconcile_test.go:36): statusCrashed fixture sets MetaAttempt 0, but the real runner reports the surviving meta's attempt on crash inference (0 only when the worktree is gone). Update the fixture/helpers so crashed statuses carry a realistic MetaAttempt (parameterize; keep a worktree-gone variant with 0) — hygiene so future MetaAttempt consumers are tested against real shapes.

Constraints: internal/reconcile/ only; testify+culpa; go build/vet/test -race -count=1 ./internal/reconcile/... (never ./...); commit 'reconcile: adopt completed evidence, timeout the neither-state' staging only internal/reconcile; hooks bypassed (git -c core.hooksPath=/tmp/nohooks commit); no push; no .beads/.

Depends on

  • ah-nyl — Stage 1 MVP: poll-driven happy path parent-child closed

Depended on by

Nothing depends on this issue.

No comments.

Close reason

landed 30292cb: adopt-guard via runtimeEvidence + same-tick finalize of hard completed evidence, neither-state timeout arm w/ shared timeoutKill, fixture hygiene; negative controls confirmed
  • Eugene Blikh added under epic ah-nyl · 2026-07-13T05:43:35Z
  • Eugene Blikh created the issue · 2026-07-13T05:43:35Z
  • Eugene Blikh changed status to in_progress · 2026-07-13T05:43:36Z
  • Eugene Blikh closed the issue · 2026-07-13T06:01:03Z
    landed 30292cb: adopt-guard via runtimeEvidence + same-tick finalize of hard completed evidence, neither-state timeout arm w/ shared timeoutKill, fixture hygiene; negative controls confirmed
  • Eugene Blikh added label milestone:stage-1 · 2026-07-20T03:08:46Z
  • Eugene Blikh removed label milestone:stage-1 · 2026-07-20T03:10:20Z
Stored rows — what this pane was built from, as read
issues 1 row
id ah-nyl.15
content_hash 26d73898c2195a2502a4cc9764f09b4e985bd97a0e976a09926b5c4133e47e19
title fix: adopt-guard livelock + neither-state timeout arm (final verification findings)
description Final composed-semantics verification (@ 825238d) returned FIX-FIRST with two findings, both pre-analyzed with exact fixes. Scope: internal/reconcile/ ONLY. V1 HIGH (reconcile.go:524): adoptOrFail's finished-row branch guard `run.State == RunStateFinished && !st.Running` fires on ANY non-Running status including hard Completed for the NEXT attempt (exit.json{K+1} present but the K+1 row was never persisted — crash before CreateRun or persist failure whose compensating kill raced a fast-exiting pi). Result (empirically proven by the verifier): terminal record -> alignCardToRecord silently bounces ready->failed on every human re-drag, K+1's real result never persisted/commented, Start never issued, stale exit.json never cleaned — livelock against the human. FIX (verifier-tested in scratch against the full suite): change the guard to `!runtimeEvidence(st)` so hard Completed evidence falls through to the adopt branch (which persists the K+1 row from the evidence and finalizes with its true outcome). Add regression test: finished row K + probe returns hard Completed{attempt K+1, exit 0} -> adopts+finalizes K+1 (row created, in_review, one comment), then K+2 claimable; also the terminal-record variant (card in ready, terminal rec, completed evidence -> adopt path, NOT silent bounce). V2 MEDIUM (reconcile.go:409-421): check() switch has no arm for the neither-state (st.Running==false && st.Completed==false — live session, meta gone/mismatched; reachable when the worktree is rm -rf'd mid-run, MetaAttempt=0). Today: no finalize, no timeout, forever — run wedged in in_progress past any deadline (verifier proved 31min past a 30m timeout, zero kills). FIX: add a third arm — when neither-state persists and now > run.StartedAt + cfg.Timeout: runner.Kill + finalize with OutcomeTimeout (same path as the Running-timeout arm); before the deadline, log at warn (observation degraded) and do nothing. Regression test: running row, status neither (MetaAttempt 0), fake clock past deadline -> Kill called, finalized timeout, card failed; before deadline -> no action. V3 INFO (reconcile_test.go:36): statusCrashed fixture sets MetaAttempt 0, but the real runner reports the surviving meta's attempt on crash inference (0 only when the worktree is gone). Update the fixture/helpers so crashed statuses carry a realistic MetaAttempt (parameterize; keep a worktree-gone variant with 0) — hygiene so future MetaAttempt consumers are tested against real shapes. Constraints: internal/reconcile/ only; testify+culpa; go build/vet/test -race -count=1 ./internal/reconcile/... (never ./...); commit 'reconcile: adopt completed evidence, timeout the neither-state' staging only internal/reconcile; hooks bypassed (git -c core.hooksPath=/tmp/nohooks commit); no push; no .beads/.
design
acceptance_criteria
notes
status closed
priority 0
issue_type bug
assignee NULL
estimated_minutes NULL
created_at 2026-07-13T02:43:36Z
created_by Eugene Blikh
owner bigbes@gmail.com
updated_at 2026-07-13T03:01:04Z
closed_at 2026-07-13T03:01:04Z
closed_by_session
external_ref NULL
spec_id
compaction_level 0
compacted_at NULL
compacted_at_commit NULL
original_size NULL
sender
ephemeral 0
wisp_type
pinned 0
is_template 0
mol_type
work_type
source_system
metadata �{}
source_repo
close_reason landed 30292cb: adopt-guard via runtimeEvidence + same-tick finalize of hard completed evidence, neither-state timeout arm w/ shared timeoutKill, fixture hygiene; negative controls confirmed
event_kind
actor
target
payload
await_type
await_id
timeout_ns 0
waiters
hook_bead
role_bead
agent_state
last_activity NULL
role_type
rig
due_at NULL
defer_until NULL
no_history 0
started_at 2026-07-13T02:43:37Z
is_blocked 0
dependencies 1 row
id 01c80144-a50d-599a-8582-9946898d4a59
issue_id ah-nyl.15
type parent-child
created_at 2026-07-13T05:43:35Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id ah-nyl
depends_on_wisp_id NULL
depends_on_external NULL
events 5 rows
id 019f595b-cb67-7dd3-acb8-3ff323d23f19
issue_id ah-nyl.15
event_type created
actor Eugene Blikh
old_value
new_value
comment NULL
created_at 2026-07-13T05:43:35Z
id 019f595b-cdd0-786c-b6a6-c176256d528a
issue_id ah-nyl.15
event_type status_changed
actor Eugene Blikh
old_value {"id":"ah-nyl.15","title":"fix: adopt-guard livelock + neither-state timeout arm (final verification findings)","description":"Final composed-semantics verification (@ 825238d) returned FIX-FIRST with two findings, both pre-analyzed with exact fixes. Scope: internal/reconcile/ ONLY.\n\nV1 HIGH (reconcile.go:524): adoptOrFail's finished-row branch guard `run.State == RunStateFinished \u0026\u0026 !st.Running` fires on ANY non-Running status including hard Completed for the NEXT attempt (exit.json{K+1} present but the K+1 row was never persisted — crash before CreateRun or persist failure whose compensating kill raced a fast-exiting pi). Result (empirically proven by the verifier): terminal record -\u003e alignCardToRecord silently bounces ready-\u003efailed on every human re-drag, K+1's real result never persisted/commented, Start never issued, stale exit.json never cleaned — livelock against the human. FIX (verifier-tested in scratch against the full suite): change the guard to `!runtimeEvidence(st)` so hard Completed evidence falls through to the adopt branch (which persists the K+1 row from the evidence and finalizes with its true outcome). Add regression test: finished row K + probe returns hard Completed{attempt K+1, exit 0} -\u003e adopts+finalizes K+1 (row created, in_review, one comment), then K+2 claimable; also the terminal-record variant (card in ready, terminal rec, completed evidence -\u003e adopt path, NOT silent bounce).\n\nV2 MEDIUM (reconcile.go:409-421): check() switch has no arm for the neither-state (st.Running==false \u0026\u0026 st.Completed==false — live session, meta gone/mismatched; reachable when the worktree is rm -rf'd mid-run, MetaAttempt=0). Today: no finalize, no timeout, forever — run wedged in in_progress past any deadline (verifier proved 31min past a 30m timeout, zero kills). FIX: add a third arm — when neither-state persists and now \u003e run.StartedAt + cfg.Timeout: runner.Kill + finalize with OutcomeTimeout (same path as the Running-timeout arm); before the deadline, log at warn (observation degraded) and do nothing. Regression test: running row, status neither (MetaAttempt 0), fake clock past deadline -\u003e Kill called, finalized timeout, card failed; before deadline -\u003e no action.\n\nV3 INFO (reconcile_test.go:36): statusCrashed fixture sets MetaAttempt 0, but the real runner reports the surviving meta's attempt on crash inference (0 only when the worktree is gone). Update the fixture/helpers so crashed statuses carry a realistic MetaAttempt (parameterize; keep a worktree-gone variant with 0) — hygiene so future MetaAttempt consumers are tested against real shapes.\n\nConstraints: internal/reconcile/ only; testify+culpa; go build/vet/test -race -count=1 ./internal/reconcile/... (never ./...); commit 'reconcile: adopt completed evidence, timeout the neither-state' staging only internal/reconcile; hooks bypassed (git -c core.hooksPath=/tmp/nohooks commit); no push; no .beads/.\n","status":"open","priority":0,"issue_type":"bug","owner":"bigbes@gmail.com","created_at":"2026-07-13T02:43:36Z","created_by":"Eugene Blikh","updated_at":"2026-07-13T02:43:36Z"}
new_value {"status":"in_progress"}
comment NULL
created_at 2026-07-13T05:43:36Z
id 019f596b-c8c6-7c73-9212-282cd251efc3
issue_id ah-nyl.15
event_type closed
actor Eugene Blikh
old_value
new_value landed 30292cb: adopt-guard via runtimeEvidence + same-tick finalize of hard completed evidence, neither-state timeout arm w/ shared timeoutKill, fixture hygiene; negative controls confirmed
comment NULL
created_at 2026-07-13T06:01:03Z
id 019f7cda-9081-7ad1-b648-7bb3c2fc16f1
issue_id ah-nyl.15
event_type label_added
actor Eugene Blikh
old_value NULL
new_value NULL
comment Added label: milestone:stage-1
created_at 2026-07-20T03:08:46Z
id 019f7cdc-00a9-753f-a590-4a4d90371746
issue_id ah-nyl.15
event_type label_removed
actor Eugene Blikh
old_value NULL
new_value NULL
comment Removed label: milestone:stage-1
created_at 2026-07-20T03:10:20Z