Skip to content

[Feat] Record harness reconnect lifecycle as diagnostic breadcrumbs - #149

Merged
daniel-lxs merged 1 commit into
developfrom
feat/reconnect-breadcrumbs
Jul 10, 2026
Merged

[Feat] Record harness reconnect lifecycle as diagnostic breadcrumbs#149
daniel-lxs merged 1 commit into
developfrom
feat/reconnect-breadcrumbs

Conversation

@daniel-lxs

Copy link
Copy Markdown
Member

PR 3 of the observability plan (rail #140, death certificate #145/#147). Four breadcrumbs on the diagnostic rail, recorded by ReconnectableHarness:

kind when details
harness_disconnected underlying harness lost its event stream sessionId
harness_restart_requested deliberate restart (harness-initiated or external) source, reason, sessionId
harness_reconnected respawn succeeded attempt, maxAttempts, sessionId
harness_reconnect_exhausted gave up after max attempts maxAttempts, sessionId

Paired with the exit certificate, a process bounce is now fully reconstructable per task: certificate says why the process died, breadcrumbs say what the worker did about it. Deliberate restarts are labeled with their reason, so certificate-less restart breadcrumbs are self-explanatory.

Guarantees

Same discipline as the rest of the rail: recorder injected as an optional dependency, all calls fire-and-forget through the never-throw recorder, zero behavior change to reconnect logic (verified by the existing 11 reconnect tests passing untouched). Events fire only on lifecycle transitions — nothing per-message or per-tool.

Tests

3 new (disconnect→reconnect pair, exhaustion with attempt count, external request with reason). Full run-task + harnesses suites: 431 pass; typecheck / eslint / prettier / knip clean.

Waiting for bot review + Dan before merge.

🤖 Generated with Claude Code

A transcript that went strange mid-task gives no hint that the harness
bounced underneath it. ReconnectableHarness now records durable
diagnostic events at its lifecycle transitions: unexpected disconnect,
restart requests (harness-initiated and external, with their reason),
successful reconnect with the attempt count, and reconnect exhaustion.
Together with the exit certificate this makes a process bounce fully
reconstructable from task run events.

Recording is optional and observer-only: the recorder is injected by
create-harness, every call is fire-and-forget, and lifecycle behavior
is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@roomote-roomote

roomote-roomote Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

No code issues found. See task

Reviewed the four reconnect breadcrumbs recorded by ReconnectableHarness (harness_disconnected, harness_restart_requested, harness_reconnected, harness_reconnect_exhausted) and their wiring through create-harness. The recorder is injected as an optional dependency, every call is fire-and-forget through the never-throw recorder, and lifecycle behavior is unchanged. Verified there is no double-recording on the external afterCurrentTurn path, since the concrete OpenCode harness does not implement the optional requestReconnect, so that branch is not taken and restartCurrentHarness runs instead. Breadcrumbs fire only on lifecycle transitions, and the three new tests cover the disconnect→reconnect pair, exhaustion, and external-reason paths.

@daniel-lxs
daniel-lxs merged commit 34b2e77 into develop Jul 10, 2026
1 check passed
@daniel-lxs
daniel-lxs deleted the feat/reconnect-breadcrumbs branch July 10, 2026 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant