Harden Cloud Agent env secrets and email_records.is_read migration - #1381
Merged
seonghobae merged 12 commits intoAug 20, 2026
Conversation
The retired 'emails' table (replaced by 'email_records' during the email model reconciliation) was still referenced by fresh-DB setup, breaking both 'alembic upgrade head' and bootstrap_db against a clean database: - schema_backfill_sql() created a dead 'ix_emails_owner_date ON emails' index (used by migration 0001 and bootstrap_db) -> UndefinedTableError. - migration 0011_email_read_state did 'ALTER TABLE emails ADD COLUMN is_read' unconditionally; guard it on the table existing (matching the has_table/ has_column pattern used by later revisions) since email_records already carries is_read from the model metadata. - give email_records.is_read a server_default so create_all/bootstrap_db match the migration intent and raw inserts that omit is_read (postgres smoke seeds) don't hit a NOT NULL violation. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
The owner import quota advisory lock built its owner key as
f'{user_id}\x00{organization_id}' and passed it to hashtext() as a text bind
param. PostgreSQL text cannot encode NUL (0x00), so every email import 500'd on
real Postgres with CharacterNotInRepertoireError (mocked/SQLite unit tests skip
the advisory-lock path, hiding it). Derive a NUL-free sha256 digest instead and
update the tests to assert the NUL-free contract.
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
…tgres/pgvector) Repo-managed .cursor/environment.json plus idempotent install/start scripts: - install.sh: system packages (postgresql-16 + pgvector, python venv/build tools), backend venv + pinned requirements, frontend pnpm@11.5.3 deps. - start.sh: bring up the Postgres cluster, generate a per-VM dev .env with random secrets on first boot, ensure the app DB + pgvector extension, and apply alembic migrations. - terminals run the backend (start_backend.py) and frontend (next dev). Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Reject empty DATABASE_URL role secrets and apply ALTER USER through dollar-quoted psql stdin. Install hashed requirements so the baked environment matches the CI supply-chain contract. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Keep 0011 as a retired-emails no-op downgrade and add 0018 so existing email_records tables get NOT NULL DEFAULT true without interpolated DDL. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Pin the import quota lock key to an independent SHA-256 digest and point operators at the next boot/import action. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
8 tasks
Contributor
|
PR governance metadata gate is not ready for
|
seonghobae
marked this pull request as ready for review
August 19, 2026 16:06
seonghobae
changed the base branch from
develop
to
fix/email-shared-send-rate-limit
August 20, 2026 08:47
Contributor
|
Current-head review request for PR #1381. HEAD: 503f62d This PR is intentionally stacked after the shared email-send rate-bucket migration so Alembic revision |
seonghobae
merged commit Aug 20, 2026
754cea8
into
fix/email-shared-send-rate-limit
1 of 2 checks passed
seonghobae
deleted the
cursor/bc-6ba03a0c-13df-4248-a679-e55574a1ec39-156e
branch
August 20, 2026 10:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Landing vehicle for the Cloud Agent environment work in #1378 after CodeRabbit
CHANGES_REQUESTEDon40690170283357ea6478fd49b6a7a84cdd5aaeeb.Keeps the fresh-DB and NUL-free import-lock fixes, then closes the review gaps:
.cursor/start.shno longer interpolates theDATABASE_URLrole secret intopsql -c. Empty secrets fail closed.ALTER USERis dollar-quoted onpsqlstdin viabackend/scripts/reconcile_local_postgres_role.pyso quotes never reach argv..cursor/install.shinstallsrequirements-hashes.txtwith--require-hashes.0011_email_read_statedowngrade is a no-op so a pre-existing retiredemails.is_readis not dropped.0018_email_record_read_stateguardsemail_records.is_read NOT NULL DEFAULT trueon existing databases. Freshcreate_allalready has the modelserver_default.hashtext()anti-pattern.Do not merge #1378. Prefer this branch.
Fixes the review findings on #1378.
Type of change
Verification
cd backend PYTHONWARNINGS=error DISABLE_BACKGROUND_WORKERS=1 python -m pytest \ tests/test_email_import_quota_lock_key.py \ tests/test_reconcile_local_postgres_role.py \ tests/test_cloud_agent_environment.py \ tests/test_alembic_migrations.py \ tests/test_bootstrap_db.py::test_schema_backfill_adds_email_indexes \ tests/test_emails_api.py::test_import_email_files_serializes_quota_with_postgres_owner_lock \ tests/test_emails_api.py::test_import_email_files_rejects_when_owner_quota_is_exhausted -q python -m ruff check scripts/reconcile_local_postgres_role.py services/email_import_service.py tests/test_email_import_quota_lock_key.py tests/test_reconcile_local_postgres_role.py tests/test_cloud_agent_environment.py tests/test_alembic_migrations.py alembic/versions/0011_email_read_state.py alembic/versions/0018_email_record_read_state.py bash -n ../.cursor/start.sh ../.cursor/install.shLocal result: 36 passed, ruff clean, bash
-nclean. NoTimeout/Fatal/Warn/Deniedoutput.Checklist