From 3967c67e9d12fe805d092bdf2a029f347db89753 Mon Sep 17 00:00:00 2001 From: Dotta Date: Sun, 25 Oct 2026 06:03:00 -0500 Subject: [PATCH] docs: audit Teams abandoned-attempt recovery Co-Authored-By: Paperclip --- ...2026-10-24-recurring-server-sleep-stack.md | 6 +++ ...0-25-teams-attempt-recovery-sleep-audit.md | 43 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 doc/plans/2026-10-25-teams-attempt-recovery-sleep-audit.md 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 968f73c1f38..e3c124bd27f 100644 --- a/doc/plans/2026-10-24-recurring-server-sleep-stack.md +++ b/doc/plans/2026-10-24-recurring-server-sleep-stack.md @@ -1371,3 +1371,9 @@ failures. Publication and fresh remote checks/review remain required. Parent #17586 Actions/security/Greptile pass at 250fca6cff; Paperclip Review is still running. The original full inventory, older E2E failure, deletion-policy finding and master reconciliation remain outstanding. No stack PR is merged. + + +Slice 26 is published as [#17590](https://github.com/paperclipai/paperclip/pull/17590) +at 5ddb4543ed, based on #17586. It is attached; remote gates remain required. +Slice 27 begins the separate Teams abandoned transport-attempt audit. The full +original inventory, older findings and final master reconciliation remain open. diff --git a/doc/plans/2026-10-25-teams-attempt-recovery-sleep-audit.md b/doc/plans/2026-10-25-teams-attempt-recovery-sleep-audit.md new file mode 100644 index 00000000000..c8bb6026354 --- /dev/null +++ b/doc/plans/2026-10-25-teams-attempt-recovery-sleep-audit.md @@ -0,0 +1,43 @@ +# Teams abandoned transport-attempt recovery sleep audit + +Baseline: consent expiry PR #17590 at 5ddb4543ed. +Branch: codex/sleep-27-teams-attempt-recovery. +Status: owner audit; implementation and verification pending. + +## Reason and source of truth + +This slice owns only abandoned Teams transport claims. Existing transfer phases +consent_sending, uploading, file_info_sending and conflict with a non-null +attemptExpiresAt carry the obligation. claim() saves attemptId and a 90-second +attempt expiry before provider I/O. Normal settlement clears the attempt. A +conflicting callback can retain an in-flight attempt until it expires. + +Recovery rechecks the row under the publication/transfer lock order, clears the +expired claim, and moves a sending phase to its matching unknown outcome. Conflict +stays conflict. It must never resend, manufacture a receipt or treat time as proof +that provider I/O did not occur. Unknown outcome rows without a deadline are +passive review evidence. Unused consent remains owned by #17590. + +## Producers and boundary + +teamsFileTransferService central update() owns claims, settlement, cancellation, +conflict and operator resolution. Add an awaited attempt signal there, within the +existing transaction. Insert creates consent_pending, not an attempt. Caller-owned +resolution must retain outer transaction settlement. Direct SQL/other processes +remain outside the local signal contract. Startup reconstructs saved attempts. + +Use the existing scoped deadline helper in the Teams folder. Expose only a narrow +per-transfer recovery method and worker registration. Shared app wiring supplies +admission gates; provider policy stays in Teams. Remove scheduleTeamsFileMaintenance +and its call from processPublicationMaintenance after both duties have owners. +Keep the explicit combined diagnostic recovery method compatible. + +## Verification required + +Prove real claim activation and settlement, three sending phases and conflict, +quiet unused/unknown/completed history, saved deadline across restart, no early +SQL, precision, projection rollback, lock contention and fair backlog, first work +during drain, nested rollback/outer commit, changes before deadline, and shutdown. +Exercise production wiring and ensure no periodic Teams scan remains. Keep +provider calls outside transactions and prove recovery makes no new provider call. +No change to external alarms, on-use authority or Cloud sleep eligibility.