Skip to content

Epic #542: binding epoch, self-authenticating attach, durable acked delivery, one idle detector (ADR 0067) - #580

Merged
nikhilunni merged 1 commit into
mainfrom
epic/542-binding-epoch
Jul 6, 2026
Merged

nikhilunni merged 1 commit into
mainfrom
epic/542-binding-epoch

Conversation

@nikhilunni

Copy link
Copy Markdown
Contributor

Implements #542 (epic: binding epoch + self-authenticating harness attach + durable acked delivery + one idle detector). ADR 0067 authored Proposed-first and flipped to Accepted with the commit chain, per convention. One commit per phase.

What this does

Phase 1 — binding epoch + self-authenticating attach (migration 0083)
PG owns sessions.binding_epoch, minted coordinator-side at every fresh-spawn bind and carried as an attach token (ENGRAM_SANDBOX_ID + ENGRAM_BINDING_EPOCH, stamped by the backend at spawn — FC/VZ/Process uniformly). The hub validates every attach against a host-durable binding record (<work_dir>/bindings/<session>.json, monotonic in the epoch) — never an in-memory map. A restarted host-agent accepts survivor re-dials with zero rebuild pass (#447 closed by construction; rebind_survivor_sessions deleted); a stale generation is rejected Superseded and exits (the fbd3794c 8-fake-resume loop is unrepresentable).

Phase 2 — coordinator-durable outbox, SendPrompt 202 (migration 0084)
Prompts/answers become session_outbox rows: receipt + echo + one INSERT + NOTIFY + immediate return. The delivery driver resumes the session behind the enqueue, forwards oldest-first, self-heals the unbound desync, and redelivers until the confirming harness event acks the row at the emit choke point. The e35ed1f eaten-message class is gone; the host replay buffers, 10s attach wait, deliver_with_reattach poll, 60s HOLD loop, and the orchestrator's "mention me again" are deleted.

Phase 3 — one idle detector, PG shell pin (migration 0085)
The PG event-log scanner (was the "L3 backstop") becomes THE detector with the host detector's exact semantics (soft 300s/hard 1800s TTLs, 10s cadence, disk brake, default-off pressure-aware gating — now reading heartbeat-persisted hosts.utilization). Shell pins become a shell_pinned_until column stamped by the relays (issue #219 leak class structurally gone). Deleted: the host eviction tick, hub TTL scan, candidates POST path, desync watchdog + rehandshake RPC + HarnessCommand::Rehandshake, shell-pin RPCs. Heartbeat gains harness_attached as a disagreement alarm (metric), never a healer.

Phase 4 — hub down to one leaf mutex; actor-ization moot
With seven of eight maps deleted across the phases, the planned actor rewrite would wrap one never-nested mutex in machinery. Recorded in the ADR as moot-by-deletion.

Deploy notes (⚠️ read before merge)

Divergences from the issue (all recorded in ADR 0067's log)

  1. Epoch minted coordinator-side pre-spawn (not inside assign_session_sandbox) — the token rides spawn env, which exists before the sandbox does.
  2. The epoch fences process lineage, not VM identity — agentd C1-reattaches live harnesses on teleport, so live moves re-point the record at the same epoch; token sandbox_id is informational.
  3. Phases 3/4 swapped (purge before actor), and the actor itself is moot-by-deletion.
  4. The fixup-round's outbox/prompt_received coordination honored: the event stays the SLO receipt anchor.

Testing

Baselines this targets (2026-07-01 evidence): 49 sandbox not found/7d → 0 for the binding-desync fraction; SendPrompt ack decoupled from the 12.2s-p50/89s-p95 resume; eaten follow-up messages → redelivered-until-acked.

🤖 Generated with Claude Code

https://claude.ai/code/session_014jJi2vqAaxt3Q5UKxbe4Gx

@github-actions

github-actions Bot commented Jul 6, 2026 •

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow CI / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed⏩ skipped⏩ skipped❌ failed (5)Jul 6, 2026, 3:55 PM

nikhilunni added a commit that referenced this pull request Jul 6, 2026
AgentSpec.binding_epoch + HarnessAttachAck.reject + the harness Cli
token args in test fixtures that macOS clippy cannot see (the
documented cfg(target_os) blind spot) — caught by the musl
cross-check. Belongs to epic #542's change; cherry-picked down to
epic/542-binding-epoch so PR #580's FC lane heals.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@nikhilunni
nikhilunni force-pushed the epic/542-binding-epoch branch 2 times, most recently from e80f2d2 to 37edcb9 Compare July 6, 2026 15:45
…livery (#542)

Squashed re-integration of epic #542 onto current main. ADR 0067→0070,
WIRE 9→10 (both collided with merges that landed after this branched).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jJi2vqAaxt3Q5UKxbe4Gx
@nikhilunni
nikhilunni force-pushed the epic/542-binding-epoch branch from 37edcb9 to 8378fcf Compare July 6, 2026 15:54
@nikhilunni
nikhilunni marked this pull request as ready for review July 6, 2026 16:09
@nikhilunni
nikhilunni merged commit 374992c into main Jul 6, 2026
17 checks passed
@nikhilunni
nikhilunni deleted the epic/542-binding-epoch branch July 6, 2026 16:10
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.

Epic: binding epoch + self-authenticating harness attach + durable acked delivery + one idle detector

1 participant