File Provider: embed and activate writable File Provider - #44
Conversation
Configure Remux with the accepted shared App Group root and explicit application and shared Keychain access groups. Keep the credential service identity centralized while allowing the existing Keychain store to target either access group through the accepted structured query path. Preserve the exact accepted F1 test boundary: shared-root resolution, explicit access-group query construction, and shared configuration lookup. The focused suite first failed at the expected missing symbols, then passed 3 tests with 0 failures and 0 skips. A Remux simulator build also succeeded. Generate the app entitlement, plist values, and Xcode project membership from the accepted configuration with XcodeGen 2.44.1; consecutive generations were deterministic. Shared-state migration, live application/shared Keychain separation, and all File Provider extension wiring remain deferred to F2 and later branches.
Copy profiles, credentials, and hostname-bound trust into the shared container without deleting application-local source state. Verify copied credentials and repository/trust snapshots before atomically writing the migration marker, so failed attempts remain retryable and completed attempts are idempotent. Expose only the application/shared Keychain store factory at this layer. Migration construction, authoritative shared-repository selection, and lifecycle activation remain intentionally absent for the final app-integration layer. Preserve the SSH setup rollback-only trust APIs while adding bulk migration access and binding accepted trust to both server identity and hostname. Verification: accepted tests produced the expected missing-helper compile RED; the focused migration, shared-storage, and trusted-host suites passed 11 tests with 0 failures and 0 skips; the Remux simulator build succeeded. XcodeGen 2.44.1 was deterministic, runtime production delta is 124 lines, and all complete blobs/hunks match their accepted provenance.
Transplant the accepted inactive File Provider domain model exactly as reviewed. Eligible records require a saved SSH credential and trusted host identity matching both server ID and hostname. UUID-derived domain identifiers remain stable, display-name changes reconcile as remove/add pairs, and a FIFO actor gate serializes concurrent callers. Keep this leaf deliberately unreachable: it links FileProvider.framework into the app target but adds no dependency factory, live instance, RootModel or lifecycle invocation, host-mutation hook, extension target, or compatibility path. Registry and storage failures propagate after the gate is released; no new retry or cleanup behavior is introduced. The accepted three-test blob covers eligibility, deterministic add/rename/remove behavior with concurrent reconciliation serialized to one mutation, and host-change removal until replacement hostname trust. The tests-first build failed at the expected missing F3 types. The final focused suite passed 3/3 with no failures or skips, and the Remux iPhone 17 simulator build succeeded. XcodeGen 2.44.1 generated the same PBX blob twice.
Move transport startup tracing into a dedicated source that supplies the accepted no-op implementation when REMUX_FILE_PROVIDER_EXTENSION is active. Keep Ghostty tracing out of extension-conditioned SSH cleanup and SFTP setup, and expose root-key construction from the server and resolved-auth pair needed by extension callers. Regenerate deterministic app-target membership for the new source with XcodeGen 2.44.1. The existing SSH transport and exec selectors pass 74/74 and the normal iPhone 17 simulator build succeeds through XcodeBuildMCP with the required compiler wrappers. No test file changes are included. Global conditioned CLI builds remain a separate target-local extension gate because the setting propagates into SwiftPM dependencies and fails inside Crypto before Remux is compiled.
Define structured SFTP file type, metadata, directory-entry, readable-file, and read-only client values for listings and downloads. Bound downloads to monotonic chunks and ensure success, timeout, and cancellation close child handles and clean partial files. Reuse the existing connection lease and operation-timeout boundaries. Evidence: TerminalPreviewFileLoaderTests passed 7/7 at baseline; the focused suites retained the expected missing-read-layer compile failure before production and then passed 15/15; the normal iPhone 17 simulator build passed. XcodeGen 2.44.1 produced deterministic test membership.
Implement strict exclusive SFTP upload creation together with explicit directory creation, rename, file removal, and empty-directory removal operations. Normalize Citadel write statuses into typed permission and unsupported-mutation errors. Close remote upload handles on cancellation without issuing later mutations, and keep terminal attachments on the shared SFTP upload behavior. Evidence: the write tests produced a compile failure on the absent contracts before the source changes; all 38 focused tests passed afterward; the normal Remux iPhone 17 simulator build passed with isolated DerivedData and the required compiler probes; exact blob, scope, line-count, project-file, and diff checks passed.
Reconstruct the accepted remote-item model as one reviewable F7 commit directly on the strict SFTP write transport boundary. This moves only the immutable accepted bytes for canonical relative paths, File Provider identifier encoding, contained symlink projection, remote-item metadata/versioning, and their 12 focused tests. Accepted provenance: - FileProviderRemotePath.swift: 16813f6 - FileProviderRemoteItem.swift: 859c016 - FileProviderRemoteItemTests.swift: f8527a8 - source commits: df3cd2c, f2f82db, and 9fcd3fd Verification: - parent File Provider storage/domain suites: 10/10 passing - tests-first RED: FileProviderRemoteItemTests failed only for the absent accepted model types - GREEN: FileProviderRemoteItemTests 12/12 passing - normal iPhone 17 simulator build passed - XcodeGen 2.44.1 was deterministic across two generations - project.yml remains byte-identical to the parent - the 12 generated PBX membership lines are an accepted-oracle subset This deliberately excludes FileProviderRemoteService changes, stable opaque identity work, writable projection contracts, File Provider extension activation, compatibility behavior, and any newly authored product or test logic.
Reconstruct the accepted F8 identity boundary as a direct child of the contained remote-item leaf. This is a move-only commit: the production and test files retain their immutable accepted blob bytes, and the project membership is the deterministic XcodeGen output. Move FileProviderRemotePath.swift blob 4f097dc, FileProviderItemProjection.swift blob 5d99e0f, FileProviderItemIdentity.swift blob 6894a71, and FileProviderRemoteItemTests.swift blob b9bf198. The identity value blob composes accepted commits a8ea8cd, e9f19c9, and 1f85860; the projection blob composes a6cc7d3 and a8ea8cd. The F7 focused baseline passed 12/12. Moving only the accepted F8 test blob produced the expected compile RED for the missing identity type and codec API. After moving the three production blobs, the same suite passed 12/12 and a normal iPhone 17 simulator build succeeded. XcodeGen 2.44.1 was deterministic across two runs, and all eight generated PBX additions are present in the accepted oracle. This leaf intentionally excludes writable projection capabilities, snapshot or mutation behavior, extension activation, live-host qualification, compatibility work, and any newly authored glue or tests.
Reconstruct the accepted snapshot-generation store and F6-compatible File Provider error mapper as one atomic review leaf. The accepted snapshot tests call the mapper, while the mapper consumes FileProviderSnapshotStoreError, so separating them would require an authored temporary seam. Move exact accepted blobs 159f2cb and 26fc78b with exact test blobs 2e43e56 and e1d0586. XcodeGen 2.44.1 deterministically adds only the 16 accepted source and test membership lines. Evidence: the F8 baseline passed 12/12; tests-first boundary discovery exposed the missing mapper dependency; the combined accepted tests then failed for only the absent store and mapper; the earlier accepted mapper proved non-exhaustive against the already-accepted F6 write transport; the exact F6-compatible mapper resolved that compile dependency; the final combined suites passed 22/22 and a normal iPhone 17 simulator build succeeded. This coherent 592-line production unit is the documented first-pass exception to the 500-line ceiling. It excludes local mutation commits, receipts, identity reservations, relocations, deleted identities, and later writable error cases owned by F10 and F13. No product, test, or project behavior was authored.
Move the accepted mutation-journal layer onto the bounded snapshot-generation parent without rewriting behavior. Snapshot mutations now persist identity reservations, relocations, deletions, refreshed directories, replay receipts, and opt-in pending signals as one generation or not at all. The commit contains only the exact accepted FileProviderSnapshotStore blob 5c319ca and exact 23-test blob dd23955, sourced from immutable commits e9f19c9, 234e3cf, 962c8b8, 28135e5, and 999e676. Relative to F9 it is +255/-1 production and +278/-0 tests; project.yml and the PBX project remain byte-identical. Verification: the F9 combined baseline passed 22/22; the accepted tests-first state failed only on missing mutation-journal APIs and associated types; the final snapshot and mapper suites passed 31/31; and the normal Remux simulator build succeeded.
Reconstruct the accepted per-domain operation coordinator as an atomic stack layer on the exact F10 mutation-journal parent. The coordinator preserves same-directory refresh coalescing, serial refresh/mutation ordering, waiter-owned cancellation, and the existing DEBUG behavior gates without adding later enumeration or signaling contracts. The production and test files are byte-identical to accepted blobs c527084 and 50abd44. Their provenance is the immutable accepted sequence 5109406, e8ec5cf, and b0b0b27, with accepted test stabilization from 5396170 and 43c75ce. XcodeGen contributes only the eight expected project-membership lines; project.yml is unchanged. Verification before commit: F10 snapshot/error-mapper baseline 31/31; test-first compile RED confined to absent coordinator/polling types; coordinator GREEN 6/6; combined F10+F11 regression 37/37; normal Remux iPhone simulator build succeeded.
Reconstruct the reviewed remote-read boundary from accepted bytes. The remote service and its tests come from the archived read-only implementation, while the Citadel provider composes the accepted read-only operation signature with the reconciled shared SSHAuthenticationMethodFactory call. Keep the provider scoped to RemuxSFTPReadOnlyClient and do not restore the obsolete RemuxSSHAuthenticationMethodFactory wrapper. Seed only the two accepted contract tests for password authentication and root-key construction. The replicated-extension-core test is intentionally omitted here and remains deferred to F21. This commit adds only the two production files, two test files, and deterministic XcodeGen membership. Verification covered the 37-test F11 baseline, an expected test-first compile failure on absent F12 types, the 51-test focused and SFTP regression gate, and a normal Remux simulator build.
Reconstruct F13 strictly by moving the immutable accepted source and test blobs named in the File Provider stack plan. Add the request, validator, and initial SDK-item contracts; extend the accepted error mapper and writable item projection; and carry the exact validator, mapper, and remote-item test boundaries. The accepted tests moved first and produced the expected compile-only RED for the absent mutation validator contracts. After moving the accepted production bytes, the focused validator, mapper, and remote-item gate passed 30 tests, the retained F12 remote-service and shared-contract regression gate passed 13 tests, and the normal Remux simulator build succeeded. Regenerate the Xcode project with XcodeGen 2.44.1. project.yml remains byte-identical and the project file contains exactly the 16 accepted-oracle membership additions. No product behavior, test behavior, compatibility code, glue, formatting cleanup, or remote state was authored or mutated.
Add the accepted read-side enumeration layer. FileProviderEnumeratorCore owns initial refresh, anchored deltas, working-set aggregation, and acknowledgement only after signal delivery. FileProviderPollingLoop owns immediate polling, start-to-start cadence, and invalidation that detaches sleepers and drains or cancels in-flight refresh work. This is a move-only reconstruction from immutable accepted bytes: enumerator blob 7cf2e7a, polling blob ee5fc49, and 1,332-line contract-test blob d5d5458. XcodeGen contributes only the eight accepted project-membership lines. Evidence: the F13 baseline passed 19 tests; the tests-first compile failed only on absent enumerator and polling contracts; the focused contract suite passed 23 tests; the combined contract, coordinator, and remote-service gate passed 40 tests; and the normal Remux simulator build succeeded. project.yml and both standalone regression suites remain byte-identical.
Reconstruct Task F15 from accepted immutable history on exact F14 parent 2d5796f060017c2e53b12640909992c90a3a562f. The remote service and Citadel provider are the pinned final blobs; the two test files are the pinned F15 intermediate compositions. No product behavior, tests, glue, compatibility, migration, cleanup, or formatting were authored. This layer owns one short-lived writable SFTP lease for contained item, list, create-directory, upload, rename, file removal, and empty-directory removal operations. It rejects escaping parents and symlink mutation sources, and preserves lifetime ownership so cancellation cannot complete before the registered child operation is cancelled and drained. Tests were moved first. The RED build failed only for absent withMutationAccess, FileProviderRemoteMutationAccess, and writable provider conformance. The final focused remote suite passed 17 tests, including six new mutation-session tests; the combined remote, contract, and SFTP regression gate passed 78 tests with no failures or skips; and the normal Remux simulator build succeeded. Direct boundary: production +247/-3 and tests +471/-7 across exactly four modified paths. Remux.xcodeproj/project.pbxproj and project.yml remain byte-identical to F14. The accepted F21 invalidation test and later mutation-core behavior remain deferred.
Reconstruct the accepted F16 create-only mutation core on the exact F15 parent. The core reserves opaque identity before remote creation, uses strict temporary-upload and rename sequencing, and commits authoritative snapshot state and replay receipts only at the accepted boundary. Move only immutable accepted bytes: FileProviderMutationCore.swift is exact blob f83882b; FileProviderMutationCoreTests.swift is exact composed blob 0ed2348 from natural blob 51fb63c ranges 1-228, 327-328, 337-346, and 351-514. XcodeGen 2.44.1 adds only the eight deterministic accepted-oracle source and test membership lines; project.yml is unchanged. Tests first failed only for absent FileProviderMutationCore and FileProviderCreateMutationError contracts. The accepted implementation then passed FileProviderMutationCoreTests 12/12 and the combined mutation-core, snapshot-store, and operation-coordinator gate 41/41. A normal Remux iPhone 17 iOS 26.5 simulator build also succeeded. The accepted suite covers replay, collision and symlink rejection, upload/rename cleanup, progress, cancellation before rename, and authoritative commit after rename.
Reconstruct the accepted F17 rename/move boundary as exact immutable-history bytes. The mutation core is the accepted 339-line a699e5a blob, with metadata-only modify handling that preserves opaque identity, relocates known descendants, refreshes both affected parents, partitions pending fields, validates base versions and destinations, and records replay receipts across cancellation. The tests are the accepted 783-line cc45a1e blob composed from 4a3206f ranges 1-228, 317-629, 638-664, and 669-883. The five replicated-core tests remain deferred to F21; content replacement and deletion remain deferred to F18 and F19. Evidence: clean F16 baseline passed 12/12; tests-first compilation failed only on the absent F17 modify contracts and contextual cascades; focused F17 passed 26/26; mutation plus snapshot and coordinator regressions passed 55/55; and the normal Remux simulator build succeeded. Direct deltas are source +156/-2 and tests +384/-5. project.yml and the PBX remain byte-identical.
Reconstruct the accepted F18 mutation slice without authored behavior, tests, glue, compatibility, migration, cleanup, or project changes. FileProviderMutationCore owns content replacement inside the existing serialized mutation path. The accepted implementation uploads through a protected temporary sibling, commits the final rename before removing the old source, preserves opaque identity, and records the authoritative version, snapshot, and replay receipt atomically. Accepted failure paths remove the exact temporary upload while preserving the prior destination; cancellation before commit cleans up without recording a receipt, while cancellation after the commit boundary returns authoritative state. Moved exact immutable-history bytes: source blob 11b527e (408 lines, +76/-7), and test blob b646f74 (1,117 lines, 39 tests, +338/-4), composed from natural blob 92ded1f ranges 1-253, 342-939, 948-974, and 979-1217. project.yml and the PBX project remain parent-identical. Evidence: the clean F17 mutation baseline passed 26/26. Moving tests first produced direct missing-F18 failures and then waited at the absent upload callback, proving the cancellation contract was not yet implemented. With the accepted source present, the focused mutation suite passed 39/39, the combined mutation/snapshot/coordinator gate passed 68/68, the normal Remux Debug iPhone 17 simulator build succeeded, and git diff --check was clean.
Reconstruct the accepted F19 deletion boundary as a move-only commit on the exact F18 parent. The production and test files are byte-identical to their pinned immutable-history blobs; no product or test behavior was authored, adapted, reformatted, or reviewed anew. Project metadata remains parent-identical.\n\nThis commit adds the accepted non-recursive deletion contract: regular files and empty directories can be removed, while nonempty directories, root items, symlinks, special files, stale versions, and permission failures preserve the authoritative state. Receipt replay and cancellation after the remote commit retain their accepted behavior.\n\nVerification moved the exact 48-test slice first. Against F18 it failed only because FileProviderMutationCore.delete and FileProviderDeleteMutationError were absent. After moving the exact accepted source blob, all 48 FileProviderMutationCoreTests passed.
Complete the accepted F19 mutation-core boundary as a second move-only commit. The source and tests are byte-identical to the pinned accepted blobs composed from immutable history; no product or test behavior was authored, adapted, reformatted, or re-reviewed. Project metadata remains unchanged from the delete commit.\n\nThis commit normalizes the accepted stale-version policy across mutation paths. When fail-on-conflict is absent, stale content returns the authoritative item for fetch and stale metadata returns the authoritative item without fetch; explicit conflict behavior remains covered by the retained suite.\n\nVerification moved the exact 50-test slice first. Against the delete tip, 48 tests passed and only the two new stale-version policy tests failed by receiving conflict errors. After moving the exact final core blob, all 50 focused tests and all 79 combined mutation, snapshot-store, and operation-coordinator tests passed, and the normal Remux simulator build succeeded.
Introduce the accepted request-ownership layer as one atomic, move-only stack commit. Move the final 171-line controller blob once and extend the contract slice by the exact accepted 202-line four-test suffix; no product or test behavior was authored, adapted, refactored, or reformatted. Register FileProviderRequestController only in the main application target with the four accepted deterministic PBX membership lines. Leave project.yml byte-identical and retain the separate extension-target membership for the later extension-scaffolding branch. Verification: the untouched parent passed 23 contract tests; the tests-first run failed only at the four unresolved controller references; the accepted source then passed all 27 contract tests. A normal Remux simulator build succeeded, git diff --check was clean, and the source and test blobs matched 06945b4 and 678d58d.
Reconstruct F21 as the single accepted read/write feature on top of the cancellation-safe request lifecycle. Move the final 325-line replicated extension core intact rather than replaying its historical read-only intermediate and later mutation fixups. Restore the exact accepted contract, remote-service, and mutation integration slices. They cover projected lookup and fetch behavior, progress and cleanup, failed mutation mapping, invalidation ordering, authoritative mutation callbacks, coordinator sharing, and requested identifier errors. Add only the four accepted main-app PBX membership lines; project.yml remains parent-identical. Verification: the untouched F20 baseline passed 123 focused tests. With tests moved first, compilation failed only because FileProviderReplicatedExtensionCore was absent. After moving the accepted production blob, the combined contract, remote-service, mutation, snapshot, and coordinator gate passed 142 tests with zero failures or skips, and the normal Remux iPhone 17 simulator build succeeded.
Move the accepted File Provider SDK request bridge and its final projection into the review stack without changing the previously reviewed bytes. The adapter translates create, modify, and delete SDK inputs into the existing structured mutation requests while the SDK item projects writable metadata. The tests-first gate began from the exact F21 parent with 48 focused and remote-item regression tests passing. Installing the exact six-test/helper extension first produced the intended missing FileProviderSDKRequestAdapter compile failure. After moving the exact 96-line source blob, all 54 focused and regression tests passed and a normal Remux simulator build succeeded without warnings or errors. This commit changes only FileProviderSDKItem.swift (+59/-0) and RemuxFileProviderContractTests.swift (+184/-0). FileProviderRemoteItemTests.swift, the PBX project, and project.yml remain parent-identical. No compatibility layer, refactor, reformat, authored product behavior, or remote mutation is included.
Move the accepted 474-line enumerator and replicated-extension bridge together with the exact plist, entitlements, unembedded target specification, and generated shared-scheme entry. The target composes the existing File Provider domain services with the inherited SSHAuthenticationMethodFactory and remains intentionally independent of the Remux app target. Generate the project with XcodeGen 2.44.1. The seven-path F23 boundary keeps project.yml at 6f28c96c273c98ceaf85239be6dcb46de1f07d59, the shared scheme at da7d5d2, and the no-test intermediate PBX at ee2a4a7985706c2ee632679977d6ae9ea6d06fef. It adds neither an app dependency nor an Embed App Extensions phase. The accepted configuration XCTest is deliberately deferred to F24 with its four generated PBX membership lines. Accepted history introduced embedding in d8e30c3 before the test in 68750a0, then rewrote that test for writes in cc19780. At this unembedded boundary the hosted test correctly failed because RemuxFileProvider.appex lives at the product root rather than beside RemuxTests.xctest inside Remux.app/PlugIns; a TEST_HOST/BUNDLE_LOADER override could not resolve the app modules transitive C dependencies. Deferring the exact test makes its F24 embedding RED meaningful and preserves the final accepted bytes without churn. Verification before commit: the untouched F22 baseline passed 40 File Provider contract tests and built Remux; the configuration test produced the expected absent-appex RED; the normal F23 full gate passed 1,105 tests and failed only that deferred configuration test. After deferral, a direct arm64 simulator RemuxFileProvider target build succeeded in isolated build roots, all 40 contract tests passed, and the shared Remux simulator build succeeded. The built product-root plist reports both upload pipeline depths as one, supports enumeration, uses dev.remux.app.file-provider, and omits the read-only key.
Embed the writable File Provider extension in the app and activate its lifecycle from the application dependency graph. Run shared-storage migration before application reads, reconcile domains after the initial load and accepted server or host-key mutations, and preserve the existing guarded SSH setup flows. Add the extension configuration contract, root-model lifecycle coverage, and writable SFTP qualification coverage. The disposable-host mutation case remains explicitly environment-gated so ordinary unit runs never mutate a real server; live Files and host qualification remain a separate acceptance gate. Generate the project from project.yml with XcodeGen 2.44.1, adding the app dependency and embed phase while leaving the shared scheme unchanged. The resulting extension declares serial upload pipelines and shares the app group and keychain access group with Remux. Verification before commit: focused SFTP tests passed 18 with one expected live-host skip; the unfiltered suite passed 1,118 with that same skip; normal simulator and target-local extension builds succeeded; embedded bundle, plist, and processed entitlement inspection passed; and the configuration qualification helper completed while preserving its three manual live gates.
|
Warning Review limit reached
Next review available in: 59 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (55)
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31a9e18481
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| try Task.checkCancellation() | ||
| try await access.renameItem(from: temporary, to: destination) | ||
| committed = true |
There was a problem hiding this comment.
Replace occupied targets without relying on basic SFTP rename
When .contents changes without a rename, destination is the existing source path, so this attempts to rename the temporary upload over an occupied target. The production client delegates to plain SFTPClient.rename, and many SFTP servers reject a basic rename when the destination already exists; the later source-removal branch also does nothing when both paths match. On those servers every normal save of an existing file fails after upload, so replacement needs an overwrite-capable operation or a safe fallback for occupied targets.
Useful? React with 👍 / 👎.
| guard let canonicalTarget = try? await client.realPath(atPath: canonicalEntry), | ||
| let relativeTarget = try? safeLinkResolver.resolve( | ||
| canonicalTarget, | ||
| home: canonicalHome, | ||
| for: path | ||
| ) | ||
| else { | ||
| continue |
There was a problem hiding this comment.
Propagate transient failures while resolving symlinks
When a listed directory contains symlinks, any failure from realPath—including a timeout, dropped SSH session, or other connectivity error—is swallowed by these try? expressions and the symlink is silently omitted. The resulting partial list is then recorded as authoritative by FileProviderEnumeratorCore.refresh, causing previously known links to be reported as deleted and to receive new identities when connectivity returns; only errors proving that a link is missing or escapes the home directory should be skipped.
Useful? React with 👍 / 👎.
| let deleted = previousByPath.keys | ||
| .filter { currentByPath[$0] == nil } | ||
| .compactMap { previousByPath[$0]?.itemIdentifier } |
There was a problem hiding this comment.
Compute relocation deltas by stable identity
For a local rename or move, commit deliberately relocates the item while retaining its identity, but this delta treats the old path as deleted and the new path as updated. An observer whose anchor spans that mutation therefore receives both didUpdate and didDeleteItems for the same identifier, which can remove or force re-creation of the moved item. Deletions and updates need to be compared by stable identity, while still allowing remotely detected renames—which receive new identities—to remain delete-plus-create.
Useful? React with 👍 / 👎.
Reviewability experiment
This is the tail of an attempt to make the File Provider work more reviewable. If this stack or this boundary does not feel right, please say so instead of spending effort reviewing an unhelpful presentation—we can reshape the history first.
This is a history/presentation rewrite of the already-tested implementation. It does not add new product behavior.
Intended review slice
codex/file-provider-review/extension-bridgecodex/file-provider-review/app-integrationThe commits in this branch are the atomic commits intended for this slice:
Stack mechanics
All PRs in this stack intentionally target
main. The branches themselves remain sequential, so GitHub may show earlier ancestry in a later PR until its parents merge. Please review the commit range above as the intended slice and merge these PRs in order; after a parent lands, GitHub will reduce the next PR diff to its incremental changes.Verification
The final rewritten leaf was verified with 1164 tests passed, 0 failed, and 1 skipped.
xcodegen generateproduced no project diff, and the final tree is identical to the previously tested simplified result.