FN-7739: retry locked store access in backup/mcp/db CLI commands

Audits and hardens `fn backup`, `memory-backup`, `mcp`, and `db vacuum` CLI commands so they retry a locked board database instead of hanging, and reliably close store handles on every exit path.

- Add retryOnLock + closeProjectStore/asLocalProjectContext pattern to backup.ts, memory-backup.ts, mcp.ts, and db.ts (following the FN-7731/FN-7738 pattern)
- Close cached, uncached CWD-fallback, and ad-hoc MCP secrets TaskStores on every exit path (success, error, early-return)
- Retry MCP settings writes and DB VACUUM on lock contention, honoring FUSION_CLI_LOCK_RETRY_MS
- Add lock-retry regression test suites for backup, db, mcp, and memory-backup commands
- Update docs/cli-reference.md with the new retry/lock behavior
- Add changeset (patch) documenting the fix

Files changed:
 .changeset/fn-7739-cli-cmd-lock-retry.md           |   7 +
 docs/cli-reference.md                              |  17 +
 .../commands/__tests__/backup-lock-retry.test.ts   | 202 +++++++++++
 packages/cli/src/commands/__tests__/backup.test.ts |  15 +
 .../src/commands/__tests__/db-lock-retry.test.ts   | 182 ++++++++++
 packages/cli/src/commands/__tests__/db.test.ts     |  15 +
 .../src/commands/__tests__/mcp-lock-retry.test.ts  | 234 ++++++++++++
 packages/cli/src/commands/__tests__/mcp.test.ts    |  14 +
 .../__tests__/memory-backup-lock-retry.test.ts     | 201 +++++++++++
 .../src/commands/__tests__/memory-backup.test.ts   |  15 +
 packages/cli/src/commands/backup.ts                | 252 +++++++++----
 packages/cli/src/commands/db.ts                    |  62 +++-
 packages/cli/src/commands/mcp.ts                   | 391 +++++++++++++++------
 packages/cli/src/commands/memory-backup.ts         | 179 +++++++---
 14 files changed, 1538 insertions(+), 248 deletions(-)

Fusion-Task-Id: FN-7739

Fusion-Task-Lineage: 6dbab086-2bf8-4cd4-950b-04fe39131933

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-09 11:30:16 -07:00
parent bab42b40dd
commit 5304af8d0e
14 changed files with 1542 additions and 252 deletions

View File

@@ -609,6 +609,23 @@ already-completed side effect. The resolved `TaskStore` — whether resolved
from the registered/default project or the uncached CWD-fallback project —
is always closed on exit so the CLI process exits promptly.
FN-7739 extends the same pattern to `fn backup *` (`create`/`list`/
`restore`/`cleanup`), `fn memory-backup *` (`create`/`list`/`restore`),
`fn mcp *` (`list`/`add`/`edit`/`remove`/`enable`/`disable`/`import`/
`export`/`validate`), and `fn db vacuum`. `fn backup`/`fn memory-backup`
retry their `getSettings()` board read; `fn mcp` retries project-scope
`updateSettings` writes (mutations) and reads, and closes BOTH the cached
project `TaskStore` and the ad-hoc uncached secrets `TaskStore` opened by
`--secret-ref`/`--create-secret-*` resolution when no project is in scope;
`fn db vacuum` retries the VACUUM call itself (VACUUM requires an exclusive
lock, the canonical transient-lock case) and closes the resolved store
BEFORE each `process.exit()` call, since `runDbVacuum` always exits
explicitly and a pending `finally` does not run after `process.exit()`. MCP
global-scope settings live in the file-backed `GlobalSettingsStore`
(`~/.fusion/settings.json`, no SQLite handle) and are intentionally left
with no close and no lock-retry. All of the above honor the same
`FUSION_CLI_LOCK_RETRY_MS` deadline override.
### Execution and status
```bash