Skip to content

fix(project): stage new saves without clobbering known-good files - #970

Draft
seonghobae wants to merge 24 commits into
developfrom
fix/project-save-atomic-publication-962
Draft

fix(project): stage new saves without clobbering known-good files#970
seonghobae wants to merge 24 commits into
developfrom
fix/project-save-atomic-publication-962

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Advances #962 with bounded crash-safety and native project filesystem trust-boundary repairs.

Exact current identity

Implemented boundary

Non-clobbering new-project publication

New project bytes are bounded, staged beside the selected destination, fully written and sync_all()'d before publication. hard_link publishes the already-synced inode only when the selected destination is absent, so an existing known-good project is never truncated by this slice. Oversized or empty candidate content fails before publication.

Fresh filesystem analysis found that the previous publisher still followed a symlinked/reparse-point direct parent directory, allowing a selected path such as linked-parent/setlist.bscope to publish into that link's target. The canonical branch contains the RED filesystem regression and GREEN direct-parent fail-closed repair. A deliberately rejected lexical-all-ancestors hypothesis remains out: blanket lexical rejection would break legitimate platform-managed symlink prefixes rather than bind the selected save authority.

This does not claim descriptor-bound ancestor identity, parent-directory fsync/rollback, safe overwrite, backup rotation, autosave, migration, or recovery; those remain later #962 work.

Bounded project loading

Project loading reads through one capped file handle with a MAX_PROJECT_FILE_BYTES + 1 ceiling and fails before UTF-8 projection when the 5 MiB limit is exceeded. A directly selected symlink is rejected, and the selected path must preserve file identity around handle acquisition. Unix compares device/inode identity. Windows opens reparse points without following them and requires stable file metadata around acquisition.

Protected-base integration and changelog integrity

The previous branch tree had diverged from protected develop at #783 and its CHANGELOG.md had also truncated shipped 0.1.0/0.1.4 history. Commit 0c991df26abaef4abc21a245ce041bc91ed421db restored the complete protected changelog plus this PR's four project-persistence fixes. Merge commit 5caf24898d3e6b85b87c0c6f602c1764257d0def then integrated protected develop@7ad56cf... without force-push. Fresh comparison from protected develop to this exact head contains only the intended four PR files: CHANGELOG.md, apps/desktop/src-tauri/src/main.rs, apps/desktop/src-tauri/src/project_persistence.rs, and apps/desktop/src-tauri/tests/project_persistence_parent_symlink.rs.

Exact-current verification

Fresh checks have been dispatched for exact head 5caf24898d3e6b85b87c0c6f602c1764257d0def. At the latest refetch there is no terminal failure, but required repository/central checks are still queued or otherwise non-terminal. Queued/skipped/predecessor evidence is non-passing, so no GREEN or merge-readiness claim is made.

Remaining #962 scope

Still out of this bounded slice: safe overwrite with known-good backup, parent-directory durability/rollback semantics, descriptor-bound ancestor identity for save publication, autosave/journal recovery, public schema/version migration, startup recovery UX, fuzz/property coverage of the future schema, and full fault injection across cancellation/disk-full/permission/crash cases.

Merge gate

Keep Draft and unmerged until one unchanged resulting exact head has focused/full Tauri tests plus every applicable repository and central CI/build/release/security/SAST/SBOM/supply-chain/coverage/review gate terminal-success, exact required owned coverage/docstrings, zero valid unresolved findings, a qualifying independent non-author last-push approval, and ordinary protected-branch acceptance without bypass. Queued, pending, skipped-required, failed, cancelled, stale, predecessor-head, model-only, self/author, or administrative-bypass evidence is non-passing.

@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@opencode-agent opencode-agent Bot added priority: medium Normal-priority or P2 work status: draft Draft pull request type: bug Defect or incorrect behavior labels Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: medium Normal-priority or P2 work status: draft Draft pull request type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant