Skip to content

fix: prevent duplicate access alerts to the same recipient - #896

Merged
tdurieux merged 9 commits into
mainfrom
fix/recipient-access-alerts
Oct 13, 2026
Merged

tdurieux merged 9 commits into
mainfrom
fix/recipient-access-alerts

Conversation

@tdurieux

@tdurieux tdurieux commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Production recorded duplicate access-alert attempts to three recipient addresses because each resource had its own send guard. Ordinary GitHub sign-in could also reopen alerts while access remained broken.

An atomic MongoDB guard now permits one attempt per normalized recipient across repositories, pull requests, gists and accounts. Sign-in leaves the guard intact. An explicit reconnect or resource change must be followed by a successful fresh GitHub read of the triggering resource before another alert is allowed. Cached reads do not confirm recovery. Optional email-recovery lookup failures fall back to the upstream read; upstream failures still propagate without another read. Source, ownership and reset revisions fence stale reads and attempts. Recovery during provider delivery is retained and applied after completion, unless a newer reset or source change invalidates it.

All asynchronous preparation remains in the leased pending state. The recipient transition first reserves sending. Dispatch then commits atomically on the owner document, checking its reset revision and lease in that same write, immediately before contacting Resend. Cancellation competes with this commitment, and interrupted uncommitted reservations remain reclaimable. Prepared dispatch records are pruned after lease expiry, and completed records are cleared. Recovery recorded during an active reset is applied when reset finishes or its lease expires, without requiring another fresh read. Cancellation invalidates a resource revision before removing its own generation/attempt metadata, preventing a delayed sender from recreating a reclaimed claim. Interrupted pending claims are reclaimed after 60 seconds; interrupted cleanup resumes on startup or a later attempt. Unknown provider outcomes remain guarded. Removed or expired resources and disabled owners can retire completed guards.

Redacted audit records precede dispatch; immutable completion events precede terminal guard updates. Writes use bounded retries, and startup or a later notification reconciles known completions. Each attempt has a Resend idempotency key. Audit records contain neither addresses nor repository names.

Before new instances serve traffic, an indexed, checkpointed migration retains every existing claim behind the recipient guard. A resource-specific recovery atomically marks only its claim recovered. Other claims still block the address, and a newer reset restores its matching claims. Concurrent instances wait for the healthy migration lease and can take over after expiry.

The deployment script builds first, stops and verifies all legacy application writers, runs offline reconciliation preparation, then starts the new streamers and API. The recipient protocol image label distinguishes subsequent rolling upgrades. Legacy detection includes stopped containers and retries with FORCE=0. This first upgrade pauses traffic while claims migrate and permits up to 15 minutes for migration startup. Manual upgrade and rollback requirements are documented. Migration sends no email.

Validation:

  • Full suite: 1,211 passed; 258 environment-gated tests skipped.
  • Recipient MongoDB integration: 66 passed, including reset-before-insertion, paused preparation, crash cleanup, in-flight recovery, newer reset/source invalidation, atomic owner dispatch, lease-delayed recovery, and stale resource revision refresh after reclamation.
  • Existing GitHub App MongoDB integration: 54 passed. Seven deployment regressions cover upgrade ordering and failure handling.
  • 88 focused notification and performance tests passed, including four recovery-lookup failure regressions. Two affected real-Mongo file recovery tests were rerun successfully.
  • Build and type checks passed. Lint passed with five existing warnings. Compiled offline reconciliation passed a repeated-run MongoDB cleanup smoke test.

@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-13T12:48:27.505365Z b078d1a Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36b8573c34

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/Repository.ts Resolved
Comment thread src/core/Repository.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

All six findings from the previous review are addressed in ed99a80. Please review the current head, including unchanged-refresh and uncached-file recovery, exact-attempt pre-dispatch cleanup, pre-dispatch audit persistence, disabled-owner guard retirement, and indexed resumable startup migration. Full suite: 1,200 passing; 22 recipient MongoDB tests passing; build, TypeScript and lint passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed99a809dc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

Both new P1 findings are fixed in ae6276a: interrupted pending claims can be safely reconciled after their lease expires, and concurrent startup instances wait beyond the former 300-poll limit while the migration lease is healthy. Please review the current head. Full suite: 1,200 passed; recipient MongoDB suite: 28 passed; existing GitHub App MongoDB suite: 54 passed; build, TypeScript and lint passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ae6276a470

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/source/GitHubStream.ts Resolved
@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

All three findings from the last review are addressed in d6222ff. First upgrades now stop and verify all legacy writers before migration via the image protocol label and deploy script. Migration preserves every legacy resource claim per recipient, and recovery removes only matching claims. Fresh truncated-file metadata reads now confirm recovery with the same source/generation fences. Please review the current head. Validation: full suite 1,204 passed; recipient MongoDB 32 passed; GitHub App MongoDB 54 passed; deployment tests 4 passed; build, TypeScript, shell syntax and lint passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d6222ff9ea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

All four latest findings are fixed in 5a4fd20. Legacy upgrades explicitly prepare rollback reconciliation after writers stop; recovery is one atomic document update with retained evidence restored by newer resets; provider completion is persisted first with bounded retries and startup/notification reconciliation; retirement includes the observed reset revision. Please review the current head. Validation: full suite 1,205 passed; recipient MongoDB 43 passed; GitHub App MongoDB 54 passed; focused notification/deployment 67 passed; compiled reconciliation CLI smoke test, build, TypeScript, lint and shell syntax passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a4fd20a50

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/deploy.sh Resolved
Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

All three latest findings are fixed in e1db135. Legacy detection now triggers reconciliation even with an already-built replacement and FORCE=0. Unsent release durably cancels the attempt, clears only its matching generation/attempt legacy fields, and resumes interrupted cleanup. Legacy metadata is written only after a reset-revision-fenced dispatch transition. Please review the current head. Validation: full suite 1,207 passed; recipient MongoDB 51 passed; GitHub App MongoDB 54 passed; focused notification/deployment 69 passed; compiled CLI cleanup smoke test, build, TypeScript, lint and shell syntax passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e1db135fa9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

Please review current head caedced. Fixed the three latest findings: persistent owner reset fencing before guard insertion, deferred fresh recovery during provider delivery, and keeping all asynchronous pre-provider work in the leased pending state with resource revision fencing during cancellation. Validation: full suite 1,207 passing / 250 environment skips, 58 recipient MongoDB tests, 54 existing GitHub App integration tests, build/type checks, lint (five existing warnings), and compiled reconciliation CLI smoke test.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: caedcede8e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/owner-notifications.ts Resolved
Comment thread src/core/owner-notifications.ts Resolved
@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

Please review current head 16ec0cd. Fixed the latest reset/dispatch race with an authoritative dispatch commitment on the same owner document as the reset revision and lease. Uncommitted sending reservations remain reclaimable, and cancellation competes with that same owner commitment. Recovery saved during an active reset now reapplies after lease cleanup or expiry. Also fixed and reproduced stale resource revisions when an old claim is reclaimed between snapshot and guard insertion. Validation: full suite 1,207 passing / 258 environment skips; 66 recipient MongoDB tests; 54 GitHub App tests; build/types; lint with five existing warnings; compiled migration CLI repeated-run smoke test.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 16ec0cd4aa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/core/source/GitHubStream.ts Resolved
@tdurieux

Copy link
Copy Markdown
Owner Author

@codex review

Please review current head b078d1a. Fixed the latest finding by catching only the optional repository recovery-metadata lookup and executing the upstream work directly when it fails. Added four regressions proving successful downloads/metadata probes continue and actual upstream errors still propagate with exactly one read. Validation: 1,211 full-suite tests pass / 258 environment skips; 88 focused notification/performance tests pass; two affected real-Mongo recovery tests pass; build/types and lint pass with five existing warnings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: b078d1a252

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@tdurieux
tdurieux merged commit 445a479 into main Oct 13, 2026
3 checks passed
@tdurieux
tdurieux deleted the fix/recipient-access-alerts branch October 13, 2026 12:55
@tdurieux

Copy link
Copy Markdown
Owner Author

Merged and deployed 445a479 after the clean Codex review and successful CI. All five application containers are healthy on the recipient-v1 image, with zero restarts. Migration retained all 77 baseline access-alert claims across 73 recipient guards. Email settings, protected files and infrastructure were verified unchanged. Public homepage, health check and options endpoint return 200 in the browser. The five-minute production log check observed 1,727 completed requests, zero completed 5xx responses and zero fatal errors. Memory remained below container limits, and sampled CLOSE_WAIT sockets were zero. Existing missing-file and GitHub-access warnings remain; no notification errors or new email attempt events were recorded during verification.

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