Skip to content

refactor(fs): decompose projectFsStore preservation/recovery orchestration without changing authority semantics #554

Description

@qnbs

Context

During the #515-A Storage-Core convergence, services/fs/projectFsStore.ts was intentionally only partially decomposed. Pure legacy identity/provenance logic moved into services/fs/legacyProjectIdentity.ts, but the store remains a large preservation-critical orchestration unit containing project CRUD, legacy migration/provenance, snapshot restoration, quarantine/recovery and deletion behavior.

The remainder was explicitly accepted as non-blocking structural debt rather than extending an already-large data-integrity PR merely to satisfy a file-size target. No dedicated follow-up issue was created at that time.

This issue is that follow-up owner.

Goal

Improve auditability and maintainability through mechanical, behavior-preserving extraction while keeping the already-proven preserve-first authority contracts intact.

This is not permission to redesign Storage-Core.

Current concentration to inventory

At minimum classify the current FsProjectStore responsibilities:

  • project shape/coarse load validation;
  • project load/save and atomic persistence orchestration;
  • legacy filesystem identity migration;
  • legacy Binder/Codex auxiliary ownership/provenance;
  • snapshot restore target/owner validation;
  • quarantine/preservation reservation and move semantics;
  • project deletion and fail-closed cleanup;
  • auto-snapshot triggering;
  • Core validation shadow hooks;
  • import/export normalization interactions.

For each responsibility decide whether it is:

PURE_HELPER_EXTRACTABLE
POLICY_MODULE_EXTRACTABLE
STORE_ORCHESTRATION_KEEP
CORE_MIGRATION_CANDIDATE
MUST_STAY_COLOCATED_FOR_ATOMICITY

Mandatory invariants

Any extraction must preserve the exact current semantics established by the #515-A lineage:

Project identity

  • safe/path identity remains one deterministic authority;
  • invalid/legacy identity cannot redirect a legitimate project silently;
  • missing-ID legacy behavior stays distinguishable from corruption.

Legacy auxiliary routing

  • Binder/Codex ownership remains evidence-based;
  • routing-sensitive operations remain operation-consistent across await boundaries;
  • no extraction may reintroduce routing TOCTOU or recursive-lock deadlock.

Snapshot restore

  • validated target determines WHERE;
  • independently proven snapshot ownership determines WHETHER;
  • snapshot payload cannot redirect the target;
  • stale best-effort markers cannot become authority;
  • live project target revalidation remains intact.

Quarantine

  • source is never deleted before preservation destination succeeds;
  • collision reservation/retry remains deterministic;
  • source disappearance/preservation uncertainty remains truthfully classified;
  • ambiguous auxiliary data is never assigned to an arbitrary project.

Delete

  • uncertain identity/existence inspection fails closed;
  • incomplete auxiliary cleanup cannot report success;
  • data remains retryable/preserved on failure.

Preferred extraction order

Favor pure or policy-focused modules first, for example conceptually:

  1. project load-shape / persisted-identity helpers;
  2. legacy auxiliary evidence/provenance policy not already in legacyProjectIdentity.ts;
  3. snapshot ownership/target policy helpers;
  4. quarantine destination/reservation policy helpers;
  5. deletion outcome/policy helpers.

Keep the store as the orchestration boundary where co-location is required for serialization/atomicity.

Do not split code solely by line count into arbitrary files.

Reviewability discipline

Use small mechanical PRs with strong before/after tests. For each extraction:

  • no behavior change hidden in move-only work;
  • preserve public API unless there is a separately justified design change;
  • compare exact focused tests before/after;
  • avoid concurrent roadmap work in the same PR;
  • update architecture/ownership comments only when actual authority moves.

A file-size guideline is a maintainability signal, not justification to weaken data-integrity semantics.

Acceptance criteria

  • Current FsProjectStore responsibility map is documented.
  • Pure/policy logic is extracted into cohesive modules where safe.
  • Store retains only orchestration that genuinely benefits from co-location.
  • No project identity, snapshot ownership, quarantine, routing or deletion invariant regresses.
  • Deterministic interleaving/recovery tests remain green and move with their semantic owner where appropriate.
  • No Storage-Core authority switch occurs as a side effect of refactoring.
  • Resulting module sizes are materially more reviewable; any remaining large orchestration is explicitly justified rather than hidden.
  • security(core/R-15): renderer-neutral encrypted desktop storage, durable migration & identity binding #445/Core migration boundaries are respected; future Rust ownership is not duplicated in TypeScript merely for cleanup.

Non-goals

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions