Add crash-resume re-attach integration tests
Summary
Closes the test gap left by the resume-by-ticket feature. The full-pipeline resume E2E (KubernetesResumeCheckpointE2ETests) swaps in CapturingExecutionStrategy, which replaces HalibutMachineExecutionStrategy entirely — so DispatchOrReattachAsync / TryReattachAsync (the actual re-attach wiring) were never exercised above the unit tier. Unit tests pin the AgentHasUsableScript decision and the DB-backed store in isolation; nothing proved the end-to-end path where a ticket persisted by a prior (crashed) run is read back by a fresh strategy instance, the agent is probed with that same ticket, and the script is observed to completion without a duplicate StartScript.
These integration tests drive the real strategy + real observer + real DB-backed InFlightScriptStore, mocking only the Halibut RPC transport via a per-scope IHalibutClientFactory override (Rule 12 medium-mock — the agent's unknown-ticket contract is itself unit-pinned). The persisted checkpoint row carries the ticket across a simulated restart (the strategy resolves a fresh store from a new DI scope reading the same Postgres DB).
Scenarios:
- Re-attach to a Complete script → no duplicate dispatch; ticket cleared after.
- Re-attach to a still-running script → observed to completion; every probe targets the recorded ticket.
-
Stale ticket (agent returns
Complete + UnknownResult(-1)) → clears stale + exactly one fresh dispatch with a new ticket. - No recorded ticket → fresh dispatch (re-attach can only ever avoid a duplicate).
Test plan
-
4 new tests pass against real Postgres ( HalibutResumeReattachTests). -
IntegrationTests project builds clean; tests deterministic (no real Halibut/timing). -
Test-only change — no production code touched.
Note: two pre-existing UpgradeDispatchLockReconcilerIntegrationTests (Redis) fail on a local host without Redis; unrelated to this change and green in CI.