{
"scope": [
"apps/desktop/src/components/layout/AppShell.tsx",
"apps/desktop/src/components/terminal/TerminalPane.tsx",
"apps/desktop/src/components/terminal/TerminalTabView.tsx",
"apps/desktop/src/hooks/useAutoUpdateCheck.ts",
"apps/desktop/src/lib/api.test.ts",
"apps/desktop/src/lib/demo-backend.ts",
"apps/desktop/src/lib/persistence.test.ts",
"apps/desktop/src/lib/persistence.ts",
"apps/desktop/src/lib/vault-sync-contract.test.ts",
"apps/desktop/src/lib/vault-sync-contract.ts",
"apps/desktop/src/lib/vault-sync-runtime.test.ts",
"apps/desktop/src/routes/KeysPage.tsx",
"apps/desktop/src/routes/SettingsPage.tsx",
"apps/desktop/src/store/vault-sync-trust-store.test.ts",
"apps/desktop/src/store/vault-sync-trust-store.ts",
"apps/desktop/src/types/key.ts",
"changelog.d/129-complete-internal-termsnip-terminal-workspace-rename-sqlite-db-file-tauri-comman.md",
"scripts/backend-transport-test.sh",
"scripts/generate-tauri-icons.sh",
"scripts/native-dmg.sh",
"scripts/native-fixture-preflight.sh",
"scripts/native-notarize.sh",
"src-tauri/src/keychain_support.rs",
"src-tauri/src/main.rs",
"src-tauri/src/native_host_keys.rs",
"src-tauri/src/native_transport.rs",
"src-tauri/src/native_transport_fixtures.rs",
"src-tauri/tauri.conf.json",
"tests/e2e/onboarding.spec.ts",
"tests/integration/backend-auth.integration.test.ts",
"tests/integration/github-release-secrets.integration.test.ts",
"tests/integration/keygen-passphrase-leak.integration.test.ts",
"tests/integration/ssh.integration.test.ts",
"tests/integration/static-root-containment.integration.test.ts"
],
"depends_on": [],
"done_when": [
"the SQLite database is renamed termsnip.db -> terminalworkspace.db with a native copy-migration (old -> new only when new is absent), and the old file is retained for one release so rollback is possible",
"the copy-migration is CRASH-SAFE: whatever file the idempotence guard tests must be the LAST artifact created, so an interruption cannot leave a database present without its -wal/-shm sidecars. A crash mid-migration must either retry cleanly on next launch or leave the legacy database authoritative - never silently open a db whose un-checkpointed WAL was not carried over. This matters because #329 enabled WAL, so a populated -wal is the normal state, not an edge case",
"Tauri command prefix termsnip_* and events termsnip://* are renamed in lockstep across Rust (#[command] fns, invoke_handler, emit) and JS (invoke strings, listen), with the before/after command+event name SETS proven identical - a rename must not add or drop a name",
"zero residual termsnip_ command or termsnip:// event references remain, excluding the migration's intentional reads of the old database name",
"TEST EXPECTATIONS MAY MOVE: this rename forces literal-string updates in the test files named in scope (api.test.ts, persistence.test.ts, vault-sync-*.test.ts, vault-sync-trust-store.test.ts, tests/e2e/onboarding.spec.ts, tests/integration/*.integration.test.ts). This clause explicitly authorizes changing those expectations to the new names, and cites itself as the authorization; no other assertion may be weakened",
"bash scripts/validate.sh exits 0"
],
"validation": {
"local": [
"bash scripts/validate.sh"
],
"review": []
},
"checks": [
{
"type": "absent",
"for": 2,
"path": "src-tauri/src/main.rs",
"pattern": "termsnip_",
"why": "the command prefix must be gone from the Rust surface; a partial rename that leaves invoke_handler entries behind breaks the JS bridge silently"
},
{
"type": "absent",
"for": 2,
"path": "apps/desktop/src/lib/api.ts",
"pattern": "termsnip://",
"why": "the event namespace must be gone from the JS listener surface for the same reason, in the other direction"
},
{
"type": "grep",
"for": 0,
"path": "src-tauri/src/main.rs",
"pattern": "terminalworkspace\\.db",
"why": "the new database name must actually be referenced, not merely described in the ticket"
},
{
"type": "grep",
"for": 0,
"path": "src-tauri/src/main.rs",
"pattern": "termsnip\\.db",
"why": "the OLD name must ALSO survive, as the migration's source. Its absence means the copy-migration was dropped and existing users silently start with an empty database"
},
{
"type": "absent",
"for": 1,
"path": "src-tauri/src/main.rs",
"pattern": "fs::copy\\(&legacy_path, &terminal_workspace_path\\)[\\s\\S]{0,400}?copy_legacy_database_sidecar",
"why": "the defect shape from PR #336: main .db copied BEFORE the sidecars, while the guard tests the main .db. Its absence forces either sidecars-first or an atomic rename-in-last; a presence grep for 'rename' would not catch a reordering that still copies the guard file first"
}
]
}
Context
#115 renamed the data-facing identifiers (localStorage key namespace →
terminal-workspace-*, config bundleapp: "Terminal Workspace"/ v5) behind a tested forward-migration. Two internal identifier groups were deliberately deferred there because they are native-only, carry no user-facing benefit, and cannot be verified by the browser/demo test suite:sqlite:termsnip.db(persistence.ts,tauri.conf.jsonpreload,main.rs). Renaming needs a one-time native file-copy migration (copy old→new if new absent; keep old one release for rollback).termsnip_*(≈38 commands) + eventstermsnip://*(2) — an internal JS↔Rust contract. Renaming must be lockstep across Rust (#[tauri::command]fns +invoke_handler+emit) and JS (invokeTauriCommandstrings +listen).Why this is NOT ready (left in backlog)
cargo checkcatches Rust-internal mismatch (fn vs invoke_handler) but NOT JS↔Rust drift.tauri dev/build and confirm commands, events, sessions, and persisted data all work post-rename.Done-when (when promoted)