Skip to content

feat(projects): add fail-safe storage shadow migration - #223

Draft
matt2e wants to merge 1 commit into
mainfrom
jitter/migrate-project-storage
Draft

feat(projects): add fail-safe storage shadow migration#223
matt2e wants to merge 1 commit into
mainfrom
jitter/migrate-project-storage

Conversation

@matt2e

@matt2e matt2e commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • extract Berd's SQLite pool into shared persistence and fail closed on database corruption
  • add a passive, generation-safe shadow import of Goose project Markdown with durable content-addressed backups
  • persist projects, workspaces, migration receipts, and revisioned session associations without activating native ownership
  • reconcile after Goose mutations while throttling read-triggered scans

Safety boundary

Goose remains the authority for every product project read/write and for conversation/session lifecycle. This PR exposes no native-activation command and does not remove Goose's project prompt behavior. It builds and validates the storage/migration foundation only.

The importer scans the fixed Goose projects root, rejects symlinks and oversized input, fingerprints and backs up exact bytes, and commits project rows, workspaces, receipts, migration state, and phase together. Persisted generations reject stale completions and stale failures across app processes; missing or changed roots cannot erase a prior mirror. Existing corrupt Berd databases are preserved with a durable recovery marker and block startup instead of being silently replaced.

Validation

At commit d520c3b07a4b74326f09d499eaba49775f0c0697:

  • just check
  • just clippy (all four lanes, warnings denied)
  • Rust project migration tests: 19 passed
  • frontend project API tests: 14 passed
  • independent final review: no material findings

Full-suite baseline evidence:

  • Rust: 854/860 passed; the same six unchanged layout/provider fixture failures reproduce on origin/main
  • frontend: 7060 passed, 1 skipped, 1 failed; the unchanged telemetry launch-count failure also reproduces on origin/main

Native activation blockers

Native activation remains intentionally unavailable. Before Berd can become authoritative, the following must be resolved in a pinned Berd/Goose release:

  1. Recover and verify Goose commit 063694cf769269c1f151416605687991fdcbc496, currently pinned by Berd but unreachable from the configured upstream, so both project-prompt injection paths can be removed or capability-gated.
  2. Make project CRUD, session association, and dispatch-time prompt ownership cut over atomically, including create/fork crash correlation and fail-closed queued sends.
  3. Cover every session load/import/fork/provider-recovery overlay and define cross-window CAS/refetch behavior.
  4. Provide tested downgrade/reverse-export behavior and an explicit policy for prompt context already sent to external ACP providers.
  5. Add cross-language golden fixtures plus worst-case scan/SQLite-lock measurements, user-visible failure reporting, backup maintenance, and an explicit parent-directory swap threat-model decision.

The complete migration contract and twelve activation gates are documented in docs/project-storage-migration.md.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
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