Skip to content

fix(FN-7952): cut runtime services over to PostgreSQL#2109

Merged
gsxdsm merged 14 commits into
mainfrom
feature/postgres-cutover-runtime
Jul 15, 2026
Merged

fix(FN-7952): cut runtime services over to PostgreSQL#2109
gsxdsm merged 14 commits into
mainfrom
feature/postgres-cutover-runtime

Conversation

@gsxdsm

@gsxdsm gsxdsm commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Engine and dashboard traffic now stays on the authoritative PostgreSQL layer across execution, recovery, project discovery, planning sessions, analytics, and shutdown. The dashboard no longer presents a migration notice for a cutover that is already mandatory.

Design decisions

  • Runtime composition requires an async data layer instead of constructing a hidden SQLite fallback.
  • Engine workflow, mission, claim, and self-healing reads await their PostgreSQL-backed store contracts.
  • Project-scoped dashboard stores retain and close their backend owner exactly once.
  • The dashboard test quarantine entry remains paired with its Vitest exclusion, preserving the repository’s deletion-ratchet policy.

Validation

  • Core, Engine, Dashboard, CLI, and Desktop typechecks pass on the stacked branch.
  • pnpm test:gate passes all 478 gate tests.
  • This PR changes 62 files.

Stack

Related: #2105

Summary by CodeRabbit

  • New Features
    • Project discovery now recognizes projects using the .fusion/project.json marker.
    • Knowledge indexing and search are more reliable across project-scoped storage.
  • Bug Fixes
    • Improved session, audit timeline, approval, monitoring, and analytics data consistency.
    • Prevented stale planning-session updates and project-store shutdown races.
    • Ensured chat usage and CLI session status are saved before continuing.
  • UI Changes
    • Removed the storage migration notice banner now that the PostgreSQL transition is complete.
  • Reliability
    • Improved shutdown handling, workflow execution, and worktree behavior.

Make the async PostgreSQL data layer authoritative and migrate the minimum runtime composition seams needed to keep the repository buildable as the first layer of the cutover stack.

Fusion-Task-Id: FN-7952
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR completes PostgreSQL-oriented storage migration across dashboard and engine paths, replaces synchronous audit and knowledge-index APIs with async variants, coordinates project-store eviction, enforces persistence ordering, simplifies worktree hydration, removes the storage migration notice, and adds regression and integration coverage.

Changes

PostgreSQL storage and dashboard routing

Layer / File(s) Summary
Knowledge indexing and async dashboard storage
packages/dashboard/src/knowledge-index.ts, packages/dashboard/src/routes/*
Knowledge indexing, analytics, approvals, messaging, monitoring, signals, and agent routes now require project-scoped asynchronous PostgreSQL layers.
Project-store lifecycle coordination
packages/dashboard/src/project-store-resolver.ts, packages/dashboard/src/routes/register-project-routes.ts
Store creation and eviction now await watcher, close, and backend shutdown operations while preventing late cache insertion.
Session and persistence ordering
packages/dashboard/src/planning.ts, packages/dashboard/src/chat.ts, packages/engine/src/cli-agent/session-manager.ts
Session writes, token usage, and CLI session state are awaited; planning persistence is serialized per session.
Async audit and workflow retrieval
packages/dashboard/src/routes/register-*routes.ts, packages/engine/src/evaluator-evidence.ts, packages/core/src/__tests__/*
Run-audit, intervention timeline, workflow selection, and related reads use asynchronous store methods.
Engine lifecycle and worktree behavior
packages/engine/src/project-engine*.ts, packages/engine/src/worktree-*.ts, packages/engine/src/*reporter.ts
Engine shutdown persists node state, backend cleanup is single-use, automation requires PostgreSQL wiring, and shared PostgreSQL worktrees avoid SQLite hydration.
Migration cleanup and validation
packages/dashboard/app/components/*, packages/i18n/*, packages/*/__tests__/*, scripts/lib/test-quarantine.json
The storage migration notice is removed, setup and discovery expectations are updated, and async PostgreSQL lifecycle regressions are covered.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • Runfusion/Fusion#1683: Introduced related dashboard Command Center and SDLC modules later moved to async PostgreSQL storage.
  • Runfusion/Fusion#2082: Related planner-overseer intervention event and metadata changes.
  • Runfusion/Fusion#2108: Related asynchronous planner intervention timeline and PostgreSQL authority changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.24% 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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: migrating runtime services to PostgreSQL.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/postgres-cutover-runtime

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.

@greptile-apps

greptile-apps Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR moves runtime services to the PostgreSQL data layer. The main changes are:

  • Async PostgreSQL-backed execution, recovery, planning, analytics, and project discovery.
  • Serialized planning-session persistence and deletion.
  • Project-store ownership and shutdown coordination.
  • PostgreSQL integration coverage across core, engine, and dashboard.
  • Removal of the obsolete storage migration notice.

Confidence Score: 5/5

This looks safe to merge.

  • Planning-session deletes now wait behind earlier writes.
  • Authoritative delete failures remain observable when deletion cannot complete.
  • No remaining blocking issue was found in the updated fix paths.

Important Files Changed

Filename Overview
packages/dashboard/src/planning.ts Serializes session writes and authoritative deletes through a per-session persistence queue.
packages/dashboard/src/routes.ts Awaits planning-session cleanup and falls back to direct store deletion when planning cleanup does not complete.
packages/dashboard/src/tests/routes-planning.test.ts Adds coverage for write/delete ordering and PostgreSQL deletion failures.
packages/dashboard/src/project-store-resolver.ts Coordinates project-store creation, eviction, and backend shutdown ownership.

Reviews (5): Last reviewed commit: "test(FN-7952): preserve stacked PostgreS..." | Re-trigger Greptile

Comment thread packages/dashboard/src/planning.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/dashboard/src/routes/register-agent-runtime-routes.ts (1)

1480-1486: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Use the existing count query for pagination metadata
countRunAuditEvents already exists in packages/core/src/task-store/async-audit.ts, but TaskStore only exposes getRunAuditEventsAsync, so this route still loads every matching event just to compute totalCount/hasMore. Add a thin store wrapper or call the count helper here instead of materializing the full result set.

🤖 Prompt for 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.

In `@packages/dashboard/src/routes/register-agent-runtime-routes.ts` around lines
1480 - 1486, Replace the full-result call to scopedStore.getRunAuditEventsAsync
in the audit-events route with the existing countRunAuditEvents query, exposing
it through a thin TaskStore wrapper if needed. Pass the same runId, taskId,
domain, startTime, and endTime filters, and use the count directly for
totalCount/hasMore pagination metadata without materializing all events.
packages/dashboard/src/chat.ts (1)

2537-2547: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent false failures and duplicate messages on token-accounting errors.

Because recordTokenUsage is now awaited after the primary message has been successfully delivered or persisted, a database failure during token accounting throws an error that inadvertently breaks the local success flow. This leads to data inconsistencies and false UI errors despite the message already reaching the chat room.

  • packages/dashboard/src/chat.ts#L2537-L2547: Wrap this recordTokenUsage call in a try/catch block. If it throws, it currently falls into the outer catch block which incorrectly assumes the AI generation failed, leading it to re-persist accumulatedText as a duplicate message.
  • packages/dashboard/src/chat.ts#L1648-L1656: Wrap this recordTokenUsage call in a try/catch block. If telemetry fails, it currently skips successfulResponderIds.push(responder.id) and can cause a false RoomReplyGenerationError even though the message was delivered.
  • packages/dashboard/src/chat.ts#L1957-L1967: Wrap this recordTokenUsage call in a try/catch block to prevent telemetry errors from falsely bubbling up as a chat-breaking error for CLI sessions.
🤖 Prompt for 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.

In `@packages/dashboard/src/chat.ts` around lines 2537 - 2547, Wrap each
recordTokenUsage call in packages/dashboard/src/chat.ts at lines 2537-2547,
1648-1656, and 1957-1967 in its own try/catch. Handle token-accounting failures
without propagating them into the surrounding chat-generation error paths,
ensuring the delivered message remains successful, successfulResponderIds is
still updated, and CLI sessions do not fail due to telemetry errors.
🧹 Nitpick comments (3)
packages/dashboard/src/__tests__/project-store-resolver.test.ts (1)

230-236: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Signal delayed-watch entry directly instead of polling.

vi.waitFor introduces wall-clock polling even though this mock controls the exact seam. Expose and await a deferred watchStarted promise before triggering eviction.

As per coding guidelines, tests should use narrow seams and must not add real polling loops.

🤖 Prompt for 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.

In `@packages/dashboard/src/__tests__/project-store-resolver.test.ts` around lines
230 - 236, Replace the vi.waitFor polling in the “awaits an in-flight creation
and closes it without a late cache insertion” test with a deferred watchStarted
promise controlled by the delayed-watch mock. Await watchStarted to detect that
the watch has begun, then trigger evictAllProjectStores and release the delayed
watch while preserving the existing assertions and test behavior.

Source: Coding guidelines

packages/dashboard/src/routes/register-knowledge-routes.ts (1)

60-64: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Fetch pages and count concurrently.

Since querying pages and counting the total are independent database operations, they can be executed concurrently to reduce latency.

⚡ Proposed refactor
-      const pages = await queryKnowledgePagesAsync(layer, options);
-      res.json({
-        query: q,
-        pages,
-        total: await countKnowledgePagesAsync(layer),
-      });
+      const [pages, total] = await Promise.all([
+        queryKnowledgePagesAsync(layer, options),
+        countKnowledgePagesAsync(layer),
+      ]);
+      res.json({
+        query: q,
+        pages,
+        total,
+      });
🤖 Prompt for 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.

In `@packages/dashboard/src/routes/register-knowledge-routes.ts` around lines 60 -
64, Update the route handler around queryKnowledgePagesAsync and
countKnowledgePagesAsync to start both independent database operations
concurrently, await their results together, and use those results for pages and
total in res.json. Preserve the existing query and response fields.
packages/dashboard/src/routes/register-git-github.ts (1)

686-697: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove redundant TaskStore intersection types.

Both files define redundant intersection types (TaskStore & { getRunAuditEventsAsync: ... }). Since TaskStore natively defines getRunAuditEventsAsync (as seen being called natively without casts at register-task-workflow-routes.ts line 3045), these intersections can be removed to avoid clutter and stale typings.

  • packages/dashboard/src/routes/register-git-github.ts#L686-L697: Type scopedStore simply as TaskStore. (Note: The caller around line 880 of this file is also casting scopedStore with the old synchronous getRunAuditEvents?: ... signature, which can be cleaned up as well).
  • packages/dashboard/src/routes/register-task-workflow-routes.ts#L717-L725: Remove the storeWithRunAudit intersection cast entirely and just use scopedStore directly.
🤖 Prompt for 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.

In `@packages/dashboard/src/routes/register-git-github.ts` around lines 686 - 697,
Remove the redundant RunAuditEvents intersection types: in
packages/dashboard/src/routes/register-git-github.ts:686-697, type scopedStore
as TaskStore and clean up the caller near line 880 using the obsolete
synchronous signature; in
packages/dashboard/src/routes/register-task-workflow-routes.ts:717-725, remove
the storeWithRunAudit intersection cast and pass scopedStore directly, relying
on TaskStore.getRunAuditEventsAsync.
🤖 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 `@packages/dashboard/src/project-store-resolver.ts`:
- Around line 48-49: Make the eviction guards ownership-aware in the
project/global eviction flows using evictionRequested and evictAllInProgress:
deduplicate or track all concurrent eviction promises so each caller awaits the
shared cleanup, and only clear the guard after every overlapping barrier
completes. Update the related guard checks and cleanup paths without allowing
replacement stores to initialize while the previous backend is still shutting
down.

In `@packages/engine/src/__tests__/in-process-runtime.pg.test.ts`:
- Around line 37-48: Update the PostgreSQL setup around PG_TEST_URL_BASE,
pgDescribe, and adminExec to use a separately gated integration-test harness
rather than defaulting to localhost. Keep these tests excluded unless the
explicit PostgreSQL integration gate is enabled, and replace synchronous
execFileSync administration with an asynchronous command that enforces a timeout
and rejects on failure or timeout.
- Around line 76-114: Ensure the test teardown around InProcessRuntime.start,
central, and runtime uses try/finally or retains these handles for afterEach so
failures after startup still stop the runtime before central/database cleanup.
Preserve the existing idempotent runtime.stop assertions for the successful path
and prevent timers, watchers, or backend clients from surviving failed tests.

In `@packages/engine/src/cli-agent/session-manager.ts`:
- Line 500: Wrap the teardown update and `this.store.flush()` call in the
spawn-failure handling path with a best-effort `try/catch`, matching the
patterns in `handleExit` and `killLive`. Ensure any persistence error is
contained and the original PTY spawn error `err` remains the propagated failure.

In `@scripts/lib/test-quarantine.json`:
- Around line 184-187: Update the quarantine entry for
packages/dashboard/src/__tests__/routes-system.test.ts by adding a direct CI job
or archived-run URL to the reason, while preserving the existing failure details
and quarantine scope.

---

Outside diff comments:
In `@packages/dashboard/src/chat.ts`:
- Around line 2537-2547: Wrap each recordTokenUsage call in
packages/dashboard/src/chat.ts at lines 2537-2547, 1648-1656, and 1957-1967 in
its own try/catch. Handle token-accounting failures without propagating them
into the surrounding chat-generation error paths, ensuring the delivered message
remains successful, successfulResponderIds is still updated, and CLI sessions do
not fail due to telemetry errors.

In `@packages/dashboard/src/routes/register-agent-runtime-routes.ts`:
- Around line 1480-1486: Replace the full-result call to
scopedStore.getRunAuditEventsAsync in the audit-events route with the existing
countRunAuditEvents query, exposing it through a thin TaskStore wrapper if
needed. Pass the same runId, taskId, domain, startTime, and endTime filters, and
use the count directly for totalCount/hasMore pagination metadata without
materializing all events.

---

Nitpick comments:
In `@packages/dashboard/src/__tests__/project-store-resolver.test.ts`:
- Around line 230-236: Replace the vi.waitFor polling in the “awaits an
in-flight creation and closes it without a late cache insertion” test with a
deferred watchStarted promise controlled by the delayed-watch mock. Await
watchStarted to detect that the watch has begun, then trigger
evictAllProjectStores and release the delayed watch while preserving the
existing assertions and test behavior.

In `@packages/dashboard/src/routes/register-git-github.ts`:
- Around line 686-697: Remove the redundant RunAuditEvents intersection types:
in packages/dashboard/src/routes/register-git-github.ts:686-697, type
scopedStore as TaskStore and clean up the caller near line 880 using the
obsolete synchronous signature; in
packages/dashboard/src/routes/register-task-workflow-routes.ts:717-725, remove
the storeWithRunAudit intersection cast and pass scopedStore directly, relying
on TaskStore.getRunAuditEventsAsync.

In `@packages/dashboard/src/routes/register-knowledge-routes.ts`:
- Around line 60-64: Update the route handler around queryKnowledgePagesAsync
and countKnowledgePagesAsync to start both independent database operations
concurrently, await their results together, and use those results for pages and
total in res.json. Preserve the existing query and response fields.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7b5a8c41-2497-4b92-abfd-1e86654438fd

📥 Commits

Reviewing files that changed from the base of the PR and between 54e6e2f and 2ae07a0.

📒 Files selected for processing (62)
  • packages/core/src/__tests__/planner-overseer-events.test.ts
  • packages/dashboard/app/components/StorageMigrationNoticeBanner.css
  • packages/dashboard/app/components/StorageMigrationNoticeBanner.tsx
  • packages/dashboard/app/components/__tests__/StorageMigrationNoticeBanner.test.tsx
  • packages/dashboard/app/components/dashboard/DashboardBanners.tsx
  • packages/dashboard/src/__tests__/knowledge-index.pg.test.ts
  • packages/dashboard/src/__tests__/project-store-resolver.test.ts
  • packages/dashboard/src/__tests__/require-async-layer.test.ts
  • packages/dashboard/src/__tests__/routes-planning.test.ts
  • packages/dashboard/src/__tests__/routes-project-discovery.test.ts
  • packages/dashboard/src/__tests__/server-postgres-store-construction.test.ts
  • packages/dashboard/src/__tests__/setup-routes.test.ts
  • packages/dashboard/src/chat.ts
  • packages/dashboard/src/index.ts
  • packages/dashboard/src/knowledge-index.ts
  • packages/dashboard/src/monitor-trait.ts
  • packages/dashboard/src/otel-exporter.ts
  • packages/dashboard/src/planning.ts
  • packages/dashboard/src/project-store-resolver.ts
  • packages/dashboard/src/routes.ts
  • packages/dashboard/src/routes/monitor-routes.ts
  • packages/dashboard/src/routes/register-agent-core-routes.ts
  • packages/dashboard/src/routes/register-agent-runtime-routes.ts
  • packages/dashboard/src/routes/register-approval-routes.ts
  • packages/dashboard/src/routes/register-command-center-routes.ts
  • packages/dashboard/src/routes/register-git-github.ts
  • packages/dashboard/src/routes/register-knowledge-routes.ts
  • packages/dashboard/src/routes/register-messaging-scripts.ts
  • packages/dashboard/src/routes/register-project-routes.ts
  • packages/dashboard/src/routes/register-session-diff-routes.ts
  • packages/dashboard/src/routes/register-settings-memory-routes.ts
  • packages/dashboard/src/routes/register-signal-routes.ts
  • packages/dashboard/src/routes/register-task-workflow-routes.ts
  • packages/dashboard/src/routes/register-worktrunk-routes.ts
  • packages/dashboard/vitest.config.ts
  • packages/engine/src/__tests__/executor-fast-mode-workflows.test.ts
  • packages/engine/src/__tests__/in-process-runtime.pg.test.ts
  • packages/engine/src/__tests__/mission-execution-loop.test.ts
  • packages/engine/src/__tests__/planner-overseer-intervention-wiring.test.ts
  • packages/engine/src/__tests__/plugin-runner.test.ts
  • packages/engine/src/__tests__/project-engine-manager.test.ts
  • packages/engine/src/__tests__/reliability-interactions/engine-stop-aborts-execution.test.ts
  • packages/engine/src/__tests__/self-healing.test.ts
  • packages/engine/src/__tests__/workflow-authoritative-driver-async-selection.test.ts
  • packages/engine/src/__tests__/worktree-db-hydrate.test.ts
  • packages/engine/src/agent-heartbeat.ts
  • packages/engine/src/backlog-pressure-reporter.ts
  • packages/engine/src/cli-agent/__tests__/runtime-postgres.test.ts
  • packages/engine/src/cli-agent/session-manager.ts
  • packages/engine/src/cron-runner.ts
  • packages/engine/src/dependency-blocked-todo-reporter.ts
  • packages/engine/src/effective-settings.ts
  • packages/engine/src/evaluator-evidence.ts
  • packages/engine/src/project-engine-manager.ts
  • packages/engine/src/project-engine.ts
  • packages/engine/src/routine-runner.ts
  • packages/engine/src/unlinked-missions-advisory-reporter.ts
  • packages/engine/src/worktree-acquisition.ts
  • packages/engine/src/worktree-db-hydrate.ts
  • packages/i18n/locales/en/app.json
  • packages/i18n/src/resources.d.ts
  • scripts/lib/test-quarantine.json
💤 Files with no reviewable changes (5)
  • packages/dashboard/app/components/StorageMigrationNoticeBanner.css
  • packages/dashboard/app/components/tests/StorageMigrationNoticeBanner.test.tsx
  • packages/dashboard/app/components/StorageMigrationNoticeBanner.tsx
  • packages/i18n/src/resources.d.ts
  • packages/i18n/locales/en/app.json

Comment thread packages/dashboard/src/project-store-resolver.ts Outdated
Comment thread packages/engine/src/__tests__/in-process-runtime.pg.test.ts Outdated
Comment thread packages/engine/src/__tests__/in-process-runtime.pg.test.ts Outdated
Comment thread packages/engine/src/cli-agent/session-manager.ts Outdated
Comment thread scripts/lib/test-quarantine.json
Comment thread packages/dashboard/src/planning.ts
@gsxdsm gsxdsm force-pushed the feature/postgres-cutover-runtime branch from 8b9125d to 73ed302 Compare July 15, 2026 05:06
Base automatically changed from feature/postgres-cutover-stack to main July 15, 2026 05:13
@gsxdsm gsxdsm merged commit ba1e823 into main Jul 15, 2026
2 checks passed
@gsxdsm gsxdsm deleted the feature/postgres-cutover-runtime branch July 15, 2026 05:16
gsxdsm added a commit that referenced this pull request Jul 15, 2026
## Summary

CLI commands, daemon/dashboard startup, packaged desktop startup, and
live-data maintenance scripts now share the mandatory PostgreSQL
lifecycle. Operators no longer risk a command silently reading or
writing a disconnected SQLite shadow when PostgreSQL setup fails.

## Design decisions

- Every startup owner retains and awaits its PostgreSQL shutdown
callback, including partial-startup failure paths.
- CLI project context and lock-retry flows resolve through asynchronous
project stores.
- Maintenance scripts use the shared backend helper; explicit database
migration/inspection remains the only CLI surface allowed to read legacy
SQLite sources.

## Validation

- CLI and Desktop typechecks pass on the stacked branch.
- `pnpm test:gate` passes all 478 gate tests.
- This PR changes 54 files.

## Stack

- Depends on #2109, which depends on #2108.
- Bundled plugins and docs/release follow in later PRs.

Related: #2105


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* PostgreSQL is now the authoritative store for structured project and
task metadata.
* Projects can be recognized and initialized using
`.fusion/project.json`, without creating a legacy SQLite database.
  * CLI commands now retry transient PostgreSQL contention errors.

* **Bug Fixes**
* Improved cleanup when commands complete, fail, or run in the
background, preventing lingering resources.
  * Improved desktop, server, and session shutdown reliability.

* **Documentation**
* Updated storage and standalone binary guidance to reflect PostgreSQL
and legacy SQLite compatibility.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
gsxdsm added a commit that referenced this pull request Jul 15, 2026
## Summary

Operators and contributors now have one current contract for the
completed PostgreSQL cutover: PostgreSQL is mandatory runtime authority,
legacy SQLite files are read-only migration evidence, and rollback is
restore-based rather than a fallback toggle. The major changeset
communicates the same boundary to published CLI users.

## Operational guidance

- Documents the authoritative storage inventory and the five intentional
legacy SQLite readers.
- Defines maintenance-window migration, backup, restore-test, ownership,
and isolation checks.
- Clarifies lifecycle ownership for CLI, desktop, dashboard, engine, and
bundled plugins.
- Supersedes the earlier readiness review without deleting its
historical record.

## Validation

- Changeset format check passes.
- `pnpm test:gate` passes all 478 gate tests on the completed stack.
- Every file from the original oversized PR is represented in the
replacement stack; this PR changes 22 files.

## Stack

- Depends on #2111#2110#2109#2108.
- Merge bottom-up in that order.

Related: #2105
gsxdsm added a commit that referenced this pull request Jul 15, 2026
## Summary

Operators and contributors now have one current contract for the
completed PostgreSQL cutover: PostgreSQL is mandatory runtime authority,
legacy SQLite files are read-only migration evidence, and rollback is
restore-based rather than a fallback toggle. The major changeset
communicates the same boundary to published CLI users.

## Operational guidance

- Documents the authoritative storage inventory and the five intentional
legacy SQLite readers.
- Defines maintenance-window migration, backup, restore-test, ownership,
and isolation checks.
- Clarifies lifecycle ownership for CLI, desktop, dashboard, engine, and
bundled plugins.
- Supersedes the earlier readiness review without deleting its
historical record.

## Validation

- Changeset format check passes.
- `pnpm test:gate` passes all 478 gate tests on the completed stack.
- Every file from the original oversized PR is represented in the
replacement stack; this PR changes 22 files.

## Stack

- Depends on #2111#2110#2109#2108.
- Merge bottom-up in that order.

Related: #2105
gsxdsm added a commit that referenced this pull request Jul 15, 2026
## Summary

Operators and contributors now have one current contract for the
completed PostgreSQL cutover: PostgreSQL is mandatory runtime authority,
legacy SQLite files are read-only migration evidence, and rollback is
restore-based rather than a fallback toggle. The major changeset
communicates the same boundary to published CLI users.

## Operational guidance

- Documents the authoritative storage inventory and the five intentional
legacy SQLite readers.
- Defines maintenance-window migration, backup, restore-test, ownership,
and isolation checks.
- Clarifies lifecycle ownership for CLI, desktop, dashboard, engine, and
bundled plugins.
- Supersedes the earlier readiness review without deleting its
historical record.

## Validation

- Changeset format check passes.
- `pnpm test:gate` passes all 478 gate tests on the completed stack.
- Every file from the original oversized PR is represented in the
replacement stack; this PR changes 22 files.

## Stack

- Depends on #2111#2110#2109#2108.
- Merge bottom-up in that order.

Related: #2105
gsxdsm added a commit that referenced this pull request Jul 15, 2026
## Summary

Bundled plugins now persist shared runtime state in project-scoped
PostgreSQL tables instead of maintaining independent SQLite authority.
Reports, CLI Printing Press, Compound Engineering, Roadmap, Even
Realities, and WhatsApp all follow the same ownership and startup
contract as Fusion core.

## Design decisions

- Plugin schema hooks run through the host’s PostgreSQL owner and
enforce project isolation.
- The SDK exposes the host contract needed by bundled plugins without
importing engine internals.
- Legacy Roadmap ownership fixtures use the supported empty-owner
sentinel, preserving current composite primary/foreign keys while
exercising backfill behavior.
- The lockfile travels with the Even Realities PostgreSQL dependency so
packaged installs remain reproducible.

## Validation

- All six affected plugin builds pass.
- Affected plugin suites pass: 773 tests across Printing Press, Compound
Engineering, Even Realities, Reports, Roadmap, and WhatsApp.
- `pnpm test:gate` passes all 478 gate tests.
- This PR changes 40 files.

## Stack

- Depends on #2110#2109#2108.
- The documentation/release PR completes the stack.

Related: #2105


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Breaking Changes**
* PostgreSQL is now required for runtime storage; SQLite files are used
only as one-time migration inputs.
  * The legacy `FUSION_NO_EMBEDDED_PG` fallback has been removed.

* **New Features**
* Added project-isolated PostgreSQL storage for plugins, reports, tasks,
notifications, and other plugin data.
  * Added agent tools for reports and CLI service drafts.
  * Added PostgreSQL schema initialization support for plugin authors.

* **Bug Fixes**
  * Improved migration and recovery of legacy plugin state.
* Prevented cross-project data access and strengthened transactional
schema updates.

* **Documentation**
* Updated storage, migration, deployment, plugin authoring, CLI, and
dashboard guidance for PostgreSQL.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
gsxdsm added a commit that referenced this pull request Jul 15, 2026
## Summary

Engine and dashboard traffic now stays on the authoritative PostgreSQL
layer across execution, recovery, project discovery, planning sessions,
analytics, and shutdown. The dashboard no longer presents a migration
notice for a cutover that is already mandatory.

## Design decisions

- Runtime composition requires an async data layer instead of
constructing a hidden SQLite fallback.
- Engine workflow, mission, claim, and self-healing reads await their
PostgreSQL-backed store contracts.
- Project-scoped dashboard stores retain and close their backend owner
exactly once.
- The dashboard test quarantine entry remains paired with its Vitest
exclusion, preserving the repository’s deletion-ratchet policy.

## Validation

- Core, Engine, Dashboard, CLI, and Desktop typechecks pass on the
stacked branch.
- `pnpm test:gate` passes all 478 gate tests.
- This PR changes 62 files.

## Stack

- Depends on #2108.
- CLI/desktop/ops, plugins, and docs/release follow in later PRs.

Related: #2105


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Project discovery now recognizes projects using the
`.fusion/project.json` marker.
* Knowledge indexing and search are more reliable across project-scoped
storage.
* **Bug Fixes**
* Improved session, audit timeline, approval, monitoring, and analytics
data consistency.
* Prevented stale planning-session updates and project-store shutdown
races.
* Ensured chat usage and CLI session status are saved before continuing.
* **UI Changes**
* Removed the storage migration notice banner now that the PostgreSQL
transition is complete.
* **Reliability**
* Improved shutdown handling, workflow execution, and worktree behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
gsxdsm added a commit that referenced this pull request Jul 15, 2026
## Summary

CLI commands, daemon/dashboard startup, packaged desktop startup, and
live-data maintenance scripts now share the mandatory PostgreSQL
lifecycle. Operators no longer risk a command silently reading or
writing a disconnected SQLite shadow when PostgreSQL setup fails.

## Design decisions

- Every startup owner retains and awaits its PostgreSQL shutdown
callback, including partial-startup failure paths.
- CLI project context and lock-retry flows resolve through asynchronous
project stores.
- Maintenance scripts use the shared backend helper; explicit database
migration/inspection remains the only CLI surface allowed to read legacy
SQLite sources.

## Validation

- CLI and Desktop typechecks pass on the stacked branch.
- `pnpm test:gate` passes all 478 gate tests.
- This PR changes 54 files.

## Stack

- Depends on #2109, which depends on #2108.
- Bundled plugins and docs/release follow in later PRs.

Related: #2105


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* PostgreSQL is now the authoritative store for structured project and
task metadata.
* Projects can be recognized and initialized using
`.fusion/project.json`, without creating a legacy SQLite database.
  * CLI commands now retry transient PostgreSQL contention errors.

* **Bug Fixes**
* Improved cleanup when commands complete, fail, or run in the
background, preventing lingering resources.
  * Improved desktop, server, and session shutdown reliability.

* **Documentation**
* Updated storage and standalone binary guidance to reflect PostgreSQL
and legacy SQLite compatibility.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
gsxdsm added a commit that referenced this pull request Jul 15, 2026
## Summary

Bundled plugins now persist shared runtime state in project-scoped
PostgreSQL tables instead of maintaining independent SQLite authority.
Reports, CLI Printing Press, Compound Engineering, Roadmap, Even
Realities, and WhatsApp all follow the same ownership and startup
contract as Fusion core.

## Design decisions

- Plugin schema hooks run through the host’s PostgreSQL owner and
enforce project isolation.
- The SDK exposes the host contract needed by bundled plugins without
importing engine internals.
- Legacy Roadmap ownership fixtures use the supported empty-owner
sentinel, preserving current composite primary/foreign keys while
exercising backfill behavior.
- The lockfile travels with the Even Realities PostgreSQL dependency so
packaged installs remain reproducible.

## Validation

- All six affected plugin builds pass.
- Affected plugin suites pass: 773 tests across Printing Press, Compound
Engineering, Even Realities, Reports, Roadmap, and WhatsApp.
- `pnpm test:gate` passes all 478 gate tests.
- This PR changes 40 files.

## Stack

- Depends on #2110#2109#2108.
- The documentation/release PR completes the stack.

Related: #2105


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Breaking Changes**
* PostgreSQL is now required for runtime storage; SQLite files are used
only as one-time migration inputs.
  * The legacy `FUSION_NO_EMBEDDED_PG` fallback has been removed.

* **New Features**
* Added project-isolated PostgreSQL storage for plugins, reports, tasks,
notifications, and other plugin data.
  * Added agent tools for reports and CLI service drafts.
  * Added PostgreSQL schema initialization support for plugin authors.

* **Bug Fixes**
  * Improved migration and recovery of legacy plugin state.
* Prevented cross-project data access and strengthened transactional
schema updates.

* **Documentation**
* Updated storage, migration, deployment, plugin authoring, CLI, and
dashboard guidance for PostgreSQL.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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