Skip to content

feat(storage): prove native filesystem publication semantics #779

Description

@DecisionNerd

Parent

Canonical close gate: #776.

Problem

GraphForge does not have one reusable Rust implementation that proves the native locking, atomic namespace publication, file-flush, platform namespace-durability, and locked-identity semantics required by ADR 0013 on Linux, macOS, and supported Windows NTFS volumes. The implementation must not relax the unsafe-code policy of graphforge-storage.

Objective

Provide the bounded native filesystem probe backend consumed by project admission, with explicit platform behavior and stable typed outcomes.

Requirements

  • Implement native Linux, macOS, and Windows NTFS probe backends behind one Rust-owned interface.
  • Preserve graphforge-storage unsafe-code policy by isolating platform FFI in a narrowly scoped published first-party crate if required.
  • Prove exclusive locking, same-filesystem atomic creation/replacement, file flush, stable locked-file identity, and the platform-native namespace durability barrier.
  • On POSIX, use the documented file and directory fsync contract.
  • On Windows NTFS, create/open the staging file with FILE_FLAG_WRITE_THROUGH, flush file contents, and rename through the same handle with SetFileInformationByHandle / FILE_RENAME_INFO; use ReplaceIfExists = FALSE for no-replace and the documented replace form for replacement.
  • Do not use ReplaceFileW or FlushFileBuffers on a directory handle as Windows durability proof. Reconcile source/target identity and names after every namespace-operation error before returning.
  • Reject ReFS as unproven, along with links, hard-link substitution, traversal, special files, cross-device replacement, network/removable volumes, and unknown filesystem classes.
  • Bound artifact count, names, bytes, cleanup, and emitted metadata.
  • Return stable typed outcomes suitable for GF_UNSUPPORTED_FILESYSTEM mapping.
  • Document the trusted-storage assumption: GraphForge cannot prove durability when hardware falsely acknowledges write-through completion.

Acceptance Criteria

  • Native probe backends pass required Linux, macOS, and Windows NTFS CI.
  • Windows ReFS and all other unsupported/unproven classes return the stable rejection before project mutation.
  • Failure injection covers lock, write, file flush, replacement, namespace durability, identity revalidation, and cleanup.
  • Windows tests cover write-through handle creation, atomic no-replace, atomic replacement, competing destinations, and ambiguous-error reconciliation.
  • Probe artifacts are private, bounded, content-free, and cannot become project authority.
  • Cargo, Bazel, release, license, and notice inventories include any new published first-party crate.
  • graphforge-storage retains its existing unsafe-code prohibition.

BDD Completion Scenarios

  • Given a supported local filesystem, when the native probe completes, then every required publication primitive is proven and all bounded artifacts are removed.
  • Given Windows NTFS on write-through-capable storage, when GraphForge flushes a staging file and renames it through its write-through handle, then the probe treats the documented NTFS data-and-rename metadata barrier as complete.
  • Given Windows ReFS or another unsupported/unproven filesystem, when the probe runs, then it returns a stable typed rejection without touching a project root.
  • Given a Windows namespace operation reports failure, when GraphForge reconciles source and target identities and names, then it reports the observed outcome and leaves no false success or unbounded artifact.

Non-Goals

Project-root creation coordination, lifecycle call-site integration, and public publisher routing; those belong to sibling #780. ReFS durability and guarantees for storage hardware that dishonestly acknowledges write-through are explicitly out of scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    coreCore source code changesenhancementNew feature or requesttestingTest coverage and testing infrastructure

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions