From c448162b9622365ef67ebe17562c45a4af41e14b Mon Sep 17 00:00:00 2001 From: Dotta Date: Sun, 25 Oct 2026 23:08:08 -0500 Subject: [PATCH] refactor(server): expose retryable accepted-response recovery failures Co-Authored-By: Paperclip --- ...2026-10-24-recurring-server-sleep-stack.md | 11 +++++++++ ...ative-response-presentation-sleep-audit.md | 16 +++++++++++++ .../chat-channels.integration.test.ts | 9 ++++++++ .../native-runtime/native-run-finalizer.ts | 23 +++++++++++++------ 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/doc/plans/2026-10-24-recurring-server-sleep-stack.md b/doc/plans/2026-10-24-recurring-server-sleep-stack.md index 0f3e6b7f1f0..437c0d0fff4 100644 --- a/doc/plans/2026-10-24-recurring-server-sleep-stack.md +++ b/doc/plans/2026-10-24-recurring-server-sleep-stack.md @@ -2283,3 +2283,14 @@ must remain intact. The existing external-chat baseline passed 33 selected cases The old action-required check on #17576 is Superagent Security Scan. Its existing voice-review findings and the older E2E failures remain outstanding. Work on the rest of the original stack continues; none of these gates are waived. + +Slice 48's first owner-contract change now passes the same 33 real-PostgreSQL +response cases plus server typecheck. The strict recovery entry point propagates +operational errors; existing callers keep their logging/boolean contract. No +response worker has been wired and no response polling is removed yet. + +The Superagent action-required gate on #17576 was traced to review 5643793631, +inline finding 4371283330: repeated connection/health writes reload the full live +voice-session inventory. This is the already-recorded bounded-discovery issue, +not a missing credential or permission. It still needs a code/test repair and +fresh review; the gate must not be bypassed. diff --git a/doc/plans/2026-10-25-native-response-presentation-sleep-audit.md b/doc/plans/2026-10-25-native-response-presentation-sleep-audit.md index b637f0dd6d4..a0d3a1138e6 100644 --- a/doc/plans/2026-10-25-native-response-presentation-sleep-audit.md +++ b/doc/plans/2026-10-25-native-response-presentation-sleep-audit.md @@ -107,3 +107,19 @@ The monitor-continuation and control-plane-port suites currently require embedde PostgreSQL directly. Qualify a validated external-test path if needed before using their results on this host; do not count skipped or initialization-failed suites. No sleep or migrated-worker behavior is established by this baseline. + +## Initial owner-contract change + +`recoverCommittedNativeChatResponse` now exposes the existing transaction and +returns false for settled/ineligible/authorization-denied state, while propagating +operational failures. The existing `repairCommittedNativeChatResponse` wrapper +retains logging and false-on-error behavior for current callers. Authority checks, +lock order, target materialization, and commit signaling remain in the same owner. +The commit signal itself contains subscriber errors, so the wrapper does not hide +a previously propagated publication error. + +The same 33-case real-PostgreSQL selection passes after this change, with added +assertions that the new entry point rejects under actual source-action lock +contention and returns false for the existing authorization/binding fences. The +server typecheck passes (`/tmp/sleep48-contract-typecheck.log`). Worker discovery, +producer notifications, startup wiring, and periodic removal are not implemented. diff --git a/server/src/__tests__/chat-channels.integration.test.ts b/server/src/__tests__/chat-channels.integration.test.ts index 6743fe2e146..1f710a4ce09 100644 --- a/server/src/__tests__/chat-channels.integration.test.ts +++ b/server/src/__tests__/chat-channels.integration.test.ts @@ -248,6 +248,7 @@ import type { import { finalizeNativeRun, repairCommittedNativeChatResponse, + recoverCommittedNativeChatResponse, } from "../services/native-runtime/native-run-finalizer.js"; import { NativeRunCoordinatorStore } from "../services/native-runtime/native-run-coordinator-store.js"; import { reconcileNativeFinalizations } from "../services/native-runtime/native-finalization-reconciler.js"; @@ -71948,6 +71949,11 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => { }) : context.repair(), ).resolves.toBe(false); + await expect(recoverCommittedNativeChatResponse(db, { + companyId: mutation === "cross_company" ? randomUUID() : context.fixture.companyId, + issueId: context.issue.id, + runId: mutation === "cross_run" ? randomUUID() : context.runId, + })).resolves.toBe(false); await expect( db .select() @@ -72611,6 +72617,9 @@ describeEmbeddedPostgres("chat channel control-plane integration", () => { try { await locked; await expect(context.repair()).resolves.toBe(false); + await expect(recoverCommittedNativeChatResponse(db, { + companyId: context.fixture.companyId, issueId: context.issue.id, runId: context.runId, + })).rejects.toThrow(); await expect( db .select() diff --git a/server/src/services/native-runtime/native-run-finalizer.ts b/server/src/services/native-runtime/native-run-finalizer.ts index 8d0e75ecf4f..c9eeafb47f0 100644 --- a/server/src/services/native-runtime/native-run-finalizer.ts +++ b/server/src/services/native-runtime/native-run-finalizer.ts @@ -843,6 +843,21 @@ async function acceptedResponseDigestMatches( export async function repairCommittedNativeChatResponse( db: Db, input: { companyId: string; issueId: string; runId: string }, +): Promise { + try { + return await recoverCommittedNativeChatResponse(db, input); + } catch (error) { + logger.warn( + { runId: input.runId, error }, + "Committed chat response is awaiting presentation retry", + ); + return false; + } +} + +export async function recoverCommittedNativeChatResponse( + db: Db, + input: { companyId: string; issueId: string; runId: string }, ): Promise { let agentId: string | null = null; let materialized = false; @@ -1095,13 +1110,7 @@ export async function repairCommittedNativeChatResponse( }); } catch (error) { if (error instanceof CommittedChatResponseAuthorizationError) return false; - // Keep transient failures visible and retryable without reclassifying the - // committed run or acknowledging a publication that never committed. - logger.warn( - { runId: input.runId, error }, - "Committed chat response is awaiting presentation retry", - ); - return false; + throw error; } if (materialized && agentId) publishChatPublicationCommitSignal({