Skip to content

Derive PostgreSQL presence from connection leases - #21

Merged
Deathcharge merged 3 commits into
mainfrom
codex/postgres-presence-v0.13
Aug 11, 2026
Merged

Derive PostgreSQL presence from connection leases#21
Deathcharge merged 3 commits into
mainfrom
codex/postgres-presence-v0.13

Conversation

@Deathcharge

@Deathcharge Deathcharge commented Aug 11, 2026

Copy link
Copy Markdown
Owner

What changed

  • migrate PostgreSQL coordination storage to schema v7 with process-generation fencing
  • derive durable presence.joined and presence.left events from committed connection lease changes
  • preserve typing-before-leave ordering during explicit disconnect and bounded crash reclamation
  • keep stale sockets non-live across stable instance-ID reuse while retaining them for convergence
  • bound admission-path stale cleanup and leave remaining recovery to the background sweeper
  • remove the superseded schema-v6 lease index during migration
  • add clean-install, v6 migration/backfill/index replacement, restart, exact-count, deterministic-order, and bounded crash-sweep coverage
  • require cryptography 50.x after PYSEC-2026-3552 identified cryptography>=44,<50 as vulnerable
  • update the roadmap, architecture contract, and changelog

Why

Stable instance names can be reused after a process lease expires. Instance-ID checks alone could make old socket rows appear live again, and deleting those rows during registration lost the information needed to converge presence after a crash. A per-registration UUID generation makes old rows immediately non-live while allowing a bounded sweeper to produce the missing transitions transactionally.

The first CI attempt also surfaced a newly published vulnerability in the resolved cryptography release; upstream 50.0.0 is fixed and supports the full project Python matrix.

Impact

This is internal PostgreSQL topology groundwork for v0.13. Public presence and typing fan-out remain gated until sender exclusion and application wiring are proven. Existing schema-v6 rows are backfilled transactionally with the matching owner generation, and their superseded index is removed.

Validation

  • local: Ruff format/lint, mypy, and 139 non-PostgreSQL regressions under cryptography 50.0.0
  • CI run 59: dependency audit, coverage, package build, Twine, and installed-wheel smoke
  • CI run 59: live PostgreSQL 18 schema/migration/concurrency suite
  • CI run 59: hardened Compose container smoke
  • CI run 59: TypeScript client check/test/package/audit
  • CI run 59: Windows and Python 3.10–3.14 matrix
  • CodeRabbit: all four actionable review threads marked addressed in 4cb9454

All current CI jobs pass at head 4cb945401ab2dd66c608552902c1db6f1eefc87c.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added reliable presence join and leave transitions with exact active-connection counts.
    • Added bounded recovery for crashed or expired connections.
    • Added protection against stale connections after instance restarts.
    • Typing indicators now stop before departure events are processed.
  • Bug Fixes

    • Prevented expired or outdated connections from restoring presence or sending typing updates.
    • Improved recovery of presence state after lease expiration.
  • Security & Operations

    • Updated security guidance and refreshed the cryptography requirement.
    • Added migration support for existing PostgreSQL databases.

Walkthrough

PostgreSQL schema v7 adds instance-generation fencing to connection leases. Lease lifecycle operations now emit exact presence transitions, reject stale ownership, and support bounded crash sweeping with typing cleanup before departures. Migration tests cover generation backfills.

Changes

Generation-Fenced Presence

Layer / File(s) Summary
Schema generation and migration
samsarix_chat_engine/postgres.py, tests/test_postgres_store.py, docs/MULTI_INSTANCE_ARCHITECTURE.md
Schema v7 adds cursor and lease generations, rotates generations after expired leases, updates the lease index, and backfills legacy rows.
Generation-aware lease lifecycle
samsarix_chat_engine/postgres_connections.py, tests/test_postgres_presence.py, CHANGELOG.md
Acquisition, renewal, release, and occupancy counting require matching generations. Successful lifecycle operations emit PresenceTransition records with exact room counts.
Typing cleanup and bounded sweeping
samsarix_chat_engine/postgres_typing.py, samsarix_chat_engine/postgres_connections.py, tests/test_postgres_presence.py, tests/test_postgres_typing.py
Typing eligibility rejects stale leases. Expired-lease sweeping uses bounded batches and removes typing state before presence departures.
Operational and release records
CHANGELOG.md, ROADMAP.md, docs/MULTI_INSTANCE_ARCHITECTURE.md, pyproject.toml
Documentation records generation fencing and bounded sweeping. Optional dependency groups require cryptography>=50,<51.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant PostgresConnectionRegistry
  participant PostgreSQL
  participant TypingState
  participant PresenceObserver
  Client->>PostgresConnectionRegistry: acquire or release connection
  PostgresConnectionRegistry->>PostgreSQL: validate instance generation
  PostgreSQL-->>PostgresConnectionRegistry: lease and active count
  PostgresConnectionRegistry->>PresenceObserver: emit presence transition
  PostgresConnectionRegistry->>PostgreSQL: reap bounded stale leases
  PostgreSQL->>TypingState: stop typing
  PostgreSQL->>PresenceObserver: emit departure transition
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: deriving PostgreSQL presence from connection leases.
Description check ✅ Passed The description directly explains the schema migration, lease-derived presence, generation fencing, tests, security update, and validation.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/postgres-presence-v0.13

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Deathcharge
Deathcharge marked this pull request as ready for review August 11, 2026 04:01

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Line 33: Update the changelog entry for PYSEC-2026-3552 to describe the
complete affected range as cryptography>=44.0.0,<50.0.0, while retaining that
the asymmetric-authentication, test, and development dependency groups now
require cryptography>=50,<51.

In `@samsarix_chat_engine/postgres_connections.py`:
- Around line 134-136: Define the module-level _ADMISSION_SWEEP_LIMIT constant
near the other constants and replace the limit=1_000 argument in try_acquire’s
_delete_expired call with this bound. Leave the background reap_expired flow
responsible for deleting any remaining expired leases.

In `@samsarix_chat_engine/postgres.py`:
- Around line 494-501: Update the migration sequence around the connection lease
index creation to first drop public.samsarix_connection_leases_instance, then
create samsarix_connection_leases_instance_generation. Preserve the existing IF
NOT EXISTS behavior for the replacement index.

In `@tests/test_postgres_presence.py`:
- Around line 164-179: Update the reap_expired test to capture the transitions
returned by a batched call using limit=10, then assert their connection_id
values are in sorted order. Keep the existing event-type and active-connection
assertions unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e3e4d442-add8-44bc-b146-179505c562af

📥 Commits

Reviewing files that changed from the base of the PR and between 41f6981 and 3f6e286.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • ROADMAP.md
  • docs/MULTI_INSTANCE_ARCHITECTURE.md
  • pyproject.toml
  • samsarix_chat_engine/postgres.py
  • samsarix_chat_engine/postgres_connections.py
  • samsarix_chat_engine/postgres_typing.py
  • tests/test_postgres_presence.py
  • tests/test_postgres_store.py
  • tests/test_postgres_typing.py

Comment thread CHANGELOG.md Outdated
Comment thread samsarix_chat_engine/postgres_connections.py
Comment thread samsarix_chat_engine/postgres.py
Comment thread tests/test_postgres_presence.py Outdated
@Deathcharge
Deathcharge merged commit e4b8a92 into main Aug 11, 2026
11 checks passed
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