Skip to content

feat: establish workspace v2 ownership - #1945

Merged
NicholaiVogel merged 108 commits into
mainfrom
feat/1935-workspace-refresh
Sep 26, 2026
Merged

NicholaiVogel merged 108 commits into
mainfrom
feat/1935-workspace-refresh

Conversation

@NicholaiVogel

@NicholaiVogel NicholaiVogel commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Establishes the versioned workspace v2 ownership model from #1935 while preserving explicit v1 compatibility. Fresh workspaces separate durable data, canonical transcripts, runtime state, rebuildable cache, the manual import inbox, managed import originals, and secrets. Existing workspaces gain a stopped, resumable, preservation-first migration instead of a reset or parallel memory lifecycle.

This is one integrated implementation across the resolver, migration engine, import pipeline, transcript authority, Git preservation, protection reporting, CLI/API/dashboard surfaces, and documentation.

Closes #1935

Changes

  • Adds the canonical versioned workspace resolver and v2 defaults:
    • data/signet.db
    • data/imports/
    • transcripts/
    • runtime/
    • cache/
    • files/
  • Keeps v1 mappings and persisted/custom path overrides explicit; unsupported layout versions fail closed.
  • Treats files/ as a bounded durable import inbox, not a configured or continuously watched Source.
  • Converges dashboard uploads and manual drops on one scoped, idempotent admission ledger and existing imported-source normalization path.
  • Retains exact imported originals in resolver-owned durable storage and recovers published outcomes without redispatching completed work.
  • Routes transcript JSONL through the canonical transcript importer and removes normal-capture Markdown transcript duplication while preserving indexed transcript evidence.
  • Adds a stopped, leased, resumable migration journal with writer draining, descriptor-rooted destination mutation, SQLite snapshot/WAL preservation, destination verification, safe rollback fencing, explicit cleanup acceptance, and a Workspace settings recovery action for eligible interrupted copies.
  • Preserves root and nested Git repositories, user working state, .gitignore ownership, and .sigignore behavior without turning Git into universal protection.
  • Computes protection from current canonical component digests and projects the same status through CLI, API, dashboard, and restore receipts.
  • Adds migration, setup, import, transcript, Git, protection, restore, dashboard, and event-loop contract coverage.
  • Documents the workspace v2 ownership and upgrade behavior.

Type

  • feat — new user-facing feature (bumps minor)
  • fix — bug fix
  • refactor — restructure without behavior change
  • chore — build, deps, config, docs
  • perf — performance improvement
  • test — test coverage

Packages affected

  • @signet/core
  • @signet/daemon
  • @signet/cli / dashboard
  • @signet/sdk
  • @signet/connector-*
  • @signet/web
  • predictor
  • Other: workspace specifications and generated event-loop audit

Screenshots

Captured from the candidate dashboard build in an isolated local fixture. Dashboard API responses and interrupted-migration status are synthetic; the status is supplied through a renderer-only Desktop bridge fixture. No migration or rollback was started.

  • Home: storage move strip in the header
  • Mobile Home: storage move strip at 320px
  • Data & files settings: interrupted move and recovery

Migration Notes (if applicable)

  • Migration is idempotent
  • Rollback / compatibility note included in PR description

Migration acquires an OS-backed lease, drains registered writers, snapshots SQLite consistently, copies and verifies destination state, then advances the layout pointer. Before the destination accepts durable writes, rollback restores the prior pointer and untouched source. After destination writes begin, automatic rollback is fenced and requires explicit forward reconciliation. Legacy data and Git state remain preserved until explicit cleanup acceptance.

Testing

  • Full repository bun test
  • bun run typecheck
  • bun run test:hermetic --timeout=20000 --max-concurrency=4 platform/core surfaces/cli surfaces/dashboard surfaces/desktop — 1,270 passed; 2 failures are pre-existing and reproduce on the PR base 6496e141 (stale connector SVG selector and onboarding import-route assertion)
  • bun run lint — not cleanly verified; changed-file Biome check passes without errors
  • Focused suites: migration engine, CLI migration, descriptor filesystem, writer barrier, desktop migration, dashboard migration/settings/Home/Sources, and SQLite extension path — all passed; latest migration/settings/Home UI follow-up: 12/12 tests
  • Independent adversarial reviews of migration candidate 3533c0363 and UX follow-up 6a43559b9 — ship verdicts, no actionable findings
  • Built core, daemon, CLI, dashboard, staged desktop runtime, and desktop main bundle; workspace typecheck passed
  • Exercised the migration runner's rollback action against a disposable fixture; dashboard screenshot state is synthetic and no migration/rollback was run during capture

Still underway before merge:

  • resolve the existing merge conflicts with current main before merge
  • exact-head live v1-to-v2 migration, restore, and daemon-readiness matrix
  • cross-platform verification (current execution was Linux)

Behavior and safety notes

  • External Sources remain user-owned and indexed in place; they are not copied into files/ or managed import storage.
  • Transcript JSONL never enters generic document provenance or whole-file indexing.
  • Root and nested Git repositories are preserved rather than rejected, rewritten, or retired.
  • Protection is green only when applicable receipt digests match current canonical component evidence.
  • Runtime and rebuildable cache state do not become durable authorities.
  • Secret values are never included in migration journals, receipts, diagnostics, or this PR.

AI disclosure

  • No AI tools were used in this PR
  • AI tools were used

Notes

This PR is open now to keep the complete #1935 implementation visible as one review surface. The remaining verification items above are blockers for merge, not deferred implementation PRs.

);
if (resumed.status !== 0) throw new Error(`migration resume failed: ${resumed.stderr.slice(-2000)}`);
expect(JSON.parse(resumed.stdout)).toMatchObject({ status: "completed", destination });
if (interruptedTemporaryPath === undefined) throw new Error("migration temporary path was not captured");
Assisted-by: Hermes-Agent:gpt-5.6-luna
- db-owner close(): beginDrain then tear down immediately; shutdown must
  not wait on the in-flight job deadline (restores the shutdown-drain and
  IPC-clean test contracts)
- cli health: restore the v2 workspace database fallback (schema and
  memory counts read from the canonical layout) beneath the daemon-owned
  workspaceStats path
@NicholaiVogel
NicholaiVogel force-pushed the feat/1935-workspace-refresh branch from 6565afd to 3c53c11 Compare September 25, 2026 23:45
- event-loop + legacy-sync-db baselines regenerated against the rebased
  tree (main retired ledger sites; counts 152->149, 788-site inventory)
- audit test expectations updated to the regenerated counts
- strip remaining explanatory comments in migration sources per
  comments:check
The rebased tree kept an older pre-commit variant; main's version scopes
Biome/typechecks to affected workspaces and supersedes the local
--no-errors-on-unmatched tweak (the ignore behavior it worked around is
now handled by isBiomeCandidate exclusions).
node:sqlite is restricted to exact database-owner modules; route the
backupTo snapshot through the workspace sqlite wrapper (VACUUM INTO),
matching workspace-protection's snapshot path.
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.

Feature request: refresh workspace ownership, protection, and migration

1 participant