Skip to content

fix(email): serialize urgency checkpoint delivery - #5655

Closed
RaresKeY wants to merge 1931 commits into
odysseus-dev:devfrom
RaresKeY:fix/email-urgency-checkpoint-merge
Closed

fix(email): serialize urgency checkpoint delivery#5655
RaresKeY wants to merge 1931 commits into
odysseus-dev:devfrom
RaresKeY:fix/email-urgency-checkpoint-merge

Conversation

@RaresKeY

@RaresKeY RaresKeY commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

Serialize overlapping email-urgency checkpoint decisions without moving async delivery onto a worker event loop. A cancellation-aware cross-process lock now orders the read/decision/publish sequence, while delivery continues on the application loop and checkpoint files are replaced atomically.

Checkpoint reconciliation is scoped to accounts fully covered by the current scan. Account-scoped or failed-account runs preserve unrelated successful delivery state instead of causing later duplicate notifications. Per-account generations also fence delivery and merge work from an older scan after a newer same-account checkpoint commits.

Target branch

  • This PR targets dev, not main.

Linked Issue

Fixes #5645

Part of #5637

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)
  • New feature (non-breaking — adds new behaviour)
  • Breaking change (changes or removes existing behaviour)
  • Refactor / cleanup (behaviour unchanged)
  • Documentation only
  • CI / tooling / configuration

Checklist

  • I searched open issues and open PRs — this urgency checkpoint race is not already owned.
  • This PR targets dev.
  • My changes are limited to urgency run coordination, checkpoint merging, and focused regressions.
  • I ran the app end-to-end. Deterministic scheduler, loop, cancellation, and state tests were used instead of live IMAP and notification services.

How to Test

  1. Run:

    python -m pytest -q tests/test_email_urgency_checkpoint.py tests/test_email_oauth.py tests/test_note_reminder_email_oauth.py
  2. Start two same-owner urgency actions together and verify the second observes the first checkpoint before deciding to deliver.

  3. Cancel a run while it waits or delivers and verify it neither continues in a detached worker loop nor publishes a success checkpoint.

  4. Run disjoint account-scoped scans and a failed-account scan; verify unrelated account checkpoints remain intact.

  5. Poll browser notifications concurrently and verify an appended reminder is not discarded.

Exact-head validation passes 142 email, urgency, reminder, scheduler, and owner-scope tests, including active-account registration, authoritative cleanup fencing, newer-addition, newer-removal, partial/full, mixed-account, cancellation, and browser-queue orderings. The late-cleanup race also passes 20 consecutive isolated repetitions. Python compilation and diff checks pass.

Visual / UI changes — REQUIRED if you touched anything that renders

No visual or frontend files changed.

  • Screenshot or short clip — not applicable; no rendering changed.
  • Style match — no UI change.
  • No new component patterns.
  • I am not an LLM agent submitting a bulk PR. Contributor attestation remains for the human author.

pewdiepie-archdaemon and others added 30 commits June 27, 2026 21:17
Keep an unhealthy MemoryVectorStore instance available for health reporting instead of discarding it as disabled. This lets health checks report a degraded/down vector-store state while preserving focused regression coverage for initializer behavior.
EmirCobanOfficial and others added 23 commits July 14, 2026 08:33
…mporter (#5261)

* Harden skill importer against SSRF: block private targets + revalidate redirects per hop

The skill importer validated only the initial URL with the lenient SSRF guard
(block_private=False) and then fetched with follow_redirects=True, so a 3xx to
an internal/metadata address (169.254.169.254, 127.0.0.1, RFC-1918) was still
connected to — inconsistent with the hardened services/search/content.py
:_get_public_url path.

Add a _get_checked() helper that follows redirects manually and re-runs the
SSRF guard with block_private=True on every hop, and route all three fetch
sites (skills.sh unwrap, _fetch_bytes, _list_github_dir) through it. GitHub's
own redirects and the final-host _assert_github_url checks are preserved.

Adds hermetic regression tests (IP-literal hosts, faked HTTP layer) and updates
the existing mock signature for the new block_private kwarg.

Defense-in-depth: the endpoint is admin-gated (require_admin) and admins are
trusted per THREAT_MODEL.md, so this is not a cross-boundary vulnerability.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: enforce follow_redirects=False invariant in mock client

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Add Arch-specific package installation and NVIDIA runtime configuration
to the Docker setup guide. Cover passthrough verification, the NVIDIA
Compose overlay, and the distinction between GPU passthrough and
CUDA-backed model serving

Refs #831
…7-odysseus

chore: sync upstream changes from odysseus-dev/odysseus
fix(docker): bump Docker CLI to a patched release
fix(docker): bump Docker CLI to a patched release
* feat(models): define capability schema and readers

* fix(models): harden Google catalog probing

Restrict native catalog probing to the Gemini host, keep provider keys out of request URLs, filter non-chat model resources, and preserve the manual refresh default in the built-in Google add flow.
…(#5474)

* security(url-safety): reject RFC 6598 shared address space in strict mode

Strict mode (block_private=True) is a full SSRF lockdown, but it only
rejected is_private and is_loopback targets. CPython does not classify RFC
6598 shared/CGNAT space (100.64.0.0/10) as is_private (it is "shared", not
"private"), so a public redirect into 100.64.0.1 passed the per-hop guard
and still issued the request to a potentially internal CGNAT service.

not is_global would also exclude it, but only on CPython 3.11.10+/3.12.4+/
3.13+; the CI matrix runs 3.11/3.12, so reject the range explicitly to stay
correct across patch levels and the 3.14 runtime image. Default local-first
mode is unchanged. Adds strict-mode coverage for shared, non-global, and
public targets.

* docs(url-safety): correct CGNAT is_global rationale in strict-mode comment

The prior comment claimed `not is_global` catches 100.64.0.0/10 only on
CPython 3.11.10+/3.12.4+/3.13+. That is inaccurate for CGNAT: is_global
is False for 100.64.0.1 on every supported version (verified 3.10-3.14).
The version-fragility applies to other ranges gh-113171 touched, not CGNAT.
The explicit range reject is still the right choice; restate the reason as
is_private not covering shared space, and not coupling strict mode to
is_global's broader, cross-version definition. No behavior change.
…… (#5491)

* fix(llm): enhance fallback logic to handle empty completions and improve metadata handling

* fix(llm): stream tool call deltas immediately
Slice 2f of the route-domain reorganization (#4082/#4071, per
specs/architecture-runtime-inventory.md §6.3). Moves note_routes.py into
routes/note/, leaving a backward-compat sys.modules shim at the old path.
Pure file reorganization, no behavior change.

The shim uses sys.modules replacement (same pattern as the merged gallery
#4903, research #4975, memory #5007, history #5090, and contacts #5227
slices) so that `import routes.note_routes`, `from routes.note_routes import
X`, `importlib.import_module(...)`, and the `import ... as note_routes` +
`monkeypatch.setattr(note_routes, "SessionLocal", ...)` pattern used by
test_note_reminder_fire_scope.py / test_notes_fail_closed_auth.py all
operate on the same module object the application uses.

The canonical module does NOT depend on the shim — routes/note/note_routes.py
imports only from core/, src/, and stdlib. The outbound email cross-domain
imports (routes.email_routes._get_email_config, routes.email_helpers.
_send_smtp_message) are function-local lazy imports that keep resolving
through the email module's own path (email is not yet migrated).

One source-introspection test site repointed to the new canonical path:
- test_model_helper_owner_scope.py (shared with history; history entry
  already repointed in #5090, note entry repointed here)

Adds tests/test_note_routes_shim.py to pin the sys.modules shim contract
(legacy and canonical paths resolve to the same module object; monkeypatch
via legacy alias reaches the canonical module).

Verified: compileall clean; full suite 4487 passed, 3 skipped.
@github-actions github-actions Bot added the ready for review Description complete — ready for maintainer review label Jul 20, 2026
@RaresKeY
RaresKeY marked this pull request as ready for review July 21, 2026 12:21
@RaresKeY RaresKeY added the bug Something isn't working label Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ready for review Description complete — ready for maintainer review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

email: serialize urgency checkpoints and partial-state merging