feat(postgres): multi-project isolation for the shared embedded-PG cluster (task project_id, Approach A)#2007
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
…conflicts) Conflict resolution: base (feature/postgres) wins on every fix both sides made independently — Blocker 1 transitionPending recovery (base uses the async-transition-pending.ts helpers), the changed-columns lost-update port in atomicWriteTaskJson/WithAudit, the async getBranchGroup engine chain, drainMergeQueue project-root cwd, bypassFailedPreMergeReviewStep (FN-7720 audit contract), pausedReason, thinkingLevel (base also persists it via the PG chat_sessions column), and the v0.57 CLI restructure. Fork's multi-project isolation (Approach A) is kept and integrated with the base's newer code: - changed-columns fallback upserts now thread layer.projectId - first-boot SQLite auto-migration scopes its emptiness check to the bound project and stamps project_id on migrated tasks/archived_tasks rows (strict taskProjectScope would otherwise never surface them) - tasks.project_id / archived_tasks.project_id added to EXPECTED_PROJECT_COLUMNS so existing embedded-PG databases self-heal the new partition column on boot Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Greptile SummaryThis PR adds multi-project isolation for the shared embedded PostgreSQL setup. The main changes are:
Confidence Score: 4/5This is close, but the archive isolation gap should be fixed before merging.
packages/core/src/postgres/schema/project.ts and the archive table/helpers
|
| Filename | Overview |
|---|---|
| packages/core/src/postgres/schema/project.ts | Adds live task, config, and legacy archived-task partition columns, but the canonical archive storage path remains unpartitioned. |
| packages/core/src/postgres/startup-factory.ts | Binds backend task stores to project IDs and updates legacy migration stamping for project-scoped rows. |
| packages/core/src/task-store/async-persistence.ts | Stamps and filters live task rows with the bound project ID. |
| packages/core/src/task-store/async-settings.ts | Moves bound project config operations to the new project_id key. |
| packages/core/src/task-store/async-search.ts | Adds project scoping to full-text and fallback task search. |
| packages/core/src/task-store/async-merge-coordination.ts | Scopes merge lease acquisition through the owning task's project. |
Reviews (3): Last reviewed commit: "feat(postgres): multi-project isolation ..." | Re-trigger Greptile
…uster (task project_id, Approach A) Squashed net change of TrinaryCompute/postgres-v057 rebased onto feature/postgres so the PR is a single linear commit (GitHub rebase-merge cannot replay the original merge-commit history). - project_id partition key on project.tasks / project.archived_tasks (schema, baseline DDL, EXPECTED_PROJECT_COLUMNS self-heal), stamped on every insert/upsert via the layer-bound projectId - taskProjectScope folded into every scan: readLiveTaskRows (composing with the SQL column filter + pagination), counts, merge-lease candidate scan, search, allocator - per-project config rows (project_id-keyed upserts) + test-harness seed - startup factory binds the AsyncDataLayer to options.projectId; first-boot SQLite auto-migration scopes its emptiness check per-project and stamps project_id on migrated rows - ProjectManager: live global-concurrency listener (concurrency:changed) applied to the shared semaphore immediately Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…2007 review P1) archive.archived_tasks is one shared table across every project on the embedded cluster, and the archived board read it unfiltered — project A's archived list/count surfaced project B's rows. Now: - project_id column on archive.archived_tasks (schema + baseline DDL + index), stamped by both archive writers from the bound layer projectId - listArchivedTaskEntriesPage / getArchivedRowCount / listArchivedTasks / filterArchived / searchArchivedTasks(+Like/Tsvector) take an optional projectId and filter to it; the archived-board impl threads layer.projectId; id-keyed get/delete stay unscoped (globally unique ids) - drift self-heal generalized to schema-qualified entries so existing databases gain archive.archived_tasks.project_id on boot - regression test in store-list.pg.test.ts (gate) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Archive isolation P1 — fixed on
|
Rebase
feature/postgresonto v0.57 + fix embedded-PG task→merge blockers + multi-project isolationBuilds on the embedded-PostgreSQL migration (#1793). Rebases it onto v0.57.0, fixes the blockers that stopped an autonomous task → merge cycle from completing in embedded-PG mode, and closes the multi-project isolation gap. Builds clean (core/engine/dashboard, 0 tsc errors); validated live on a 6-project instance.
Rebase
mainwas 154 commits ahead offeature/postgres; 43 conflicts resolved (kept the async-Drizzle PG rewrite, ported main's behavior changes into it).Blocker fixes (one family:
cwdvsrootDir)recoverStaleTransitionPendingImplthrewSQLite … not available in backend mode→ added the missingbackendModebranch.startup-factory.tsdroppedoptions.rootDir(store rooted atprocess.cwd()); nowif (projectId && !rootDir).drainMergeQueue()bound git toprocess.cwd(); nowstore.getRootDir() ?? config.workingDirectory.Multi-project isolation
project.taskshad noproject_id(SQLite isolated per-file; consolidating to shared PG tables dropped that partition). Addedproject_id+ index, threaded the filter through the claim query / scheduler / merger / dedup / list API / id sequence.Per-project config isolation + live concurrency hot-reload
project.configwas a single shared row (CHECK id=1) → sharedtaskPrefix/caps + a cross-project mega-context on every triage. Addedproject_idPK +configScope(). Validated: distinct per-project prefixes; triage input 243K → 41–91K tokens.ProjectManagersubscribes toconcurrency:changed) —PUT /api/global-concurrencyapplies live, no restart.Happy to split any of these out if the maintainers prefer smaller PRs.