feat(mount): add deterministic pull-only sync - #431
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe change adds ChangesPull-only synchronization
Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: ⚪ Minimal · up to This PR adds a pull-only synchronization mode and exposes it across the CLI and SDK; no actionable merge-blocking risk remains after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant MountCLI
participant Syncer
participant RemoteWorkspace
participant LocalFilesystem
MountCLI->>Syncer: configure pull-only mode
Syncer->>RemoteWorkspace: reconcile remote changes
RemoteWorkspace-->>Syncer: return remote content
Syncer->>LocalFilesystem: write read-only files
Syncer-->>MountCLI: report pull-only state
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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 |
Relayfile Eval ReviewRun: Passed: 4 | Needs human: 0 | Reviewable: 0 | Missing output: 0 | Failed: 0 | Skipped: 0 Human Review CasesNo reviewable human-review cases captured Relayfile output. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a007973b0d
ℹ️ 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".
There was a problem hiding this comment.
All reported issues were addressed across 9 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 7 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Problem
Chief mounts several Relayfile provider subtrees with read-only scopes: GitHub, Notion, and Digests. Relayfile currently offers mirror mode (pull plus writeback) and write-only mode, but no remote-to-local-only mode.
Running those read-scoped subtrees in mirror mode still enters write-producing paths such as local reconciliation, durable outbox dispatch, and digest writes. The provider rejects those attempts with 403. Because the cycle fails before Relayfile records a successful reconcile and advances its durable state, the next supervisor interval repeats expensive recovery/full-tree work instead of staying on the cheap incremental path.
This is especially damaging for the GitHub projection: the local tree is roughly 1.5 GiB and 141,000 files in the affected Chief installation. Repeated scans and materialization make the system mount and interactive work crawl. Live credentials are not the problem; the credentials are intentionally read-scoped. The missing primitive is a deterministic mode that permits remote reads while making every remote mutation impossible.
Increasing the interval or request timeout would only reduce the frequency of the loop. Inferring read-only behavior from individual token checks is also insufficient because Relayfile has multiple independent mutation paths. The mode must be enforced centrally and defensively at every writer.
Fix
Review feedback addressed
--mode=fuse --sync-mode=pull-onlybefore acquiring a mount lease or dispatching a runner, and the TypeScript SDK rejects the combination before making an HTTP request. Use poll mode for pull-only mounts.Lstat, logged, and skipped. A directory or symlink replacement can no longer wedge the transition, and symlinks are never followed by chmod.Why this is deterministic
The safety property comes from the selected sync mode, not from an LLM decision, network error interpretation, or a best-effort scope check. Pull-only short-circuits every remote mutation entry point, while read-side reconciliation remains unchanged.
Drawbacks and sandbox impact
0444is a usability guard, not a security boundary. A privileged sandbox process can chmod a file, but the daemon still will not write it back. A later remote refresh may overwrite that local edit.--flush-outbox-onceor--push-local-onceto deliver handler output are incompatible with pull-only and will fail loudly. Pull-only is appropriate for context/research sandboxes; action-capable sandboxes need mirror mode or a separate read-only lifecycle that skips writeback cleanup.The current
AgentWorkforce/sandboxlauncher does not pass a sync mode and therefore remainsmirror. Its lifecycle explicitly detects local changes and upgrades teardown to--push-local-once, so enabling pull-only there requires an explicit lifecycle policy change rather than changing a default.QA
go test ./...npm test -- --run src/setup.test.ts src/mount-launcher.test.ts(69 SDK tests)npm run typecheck(packages/sdk/typescript)git diff --checkThe regression suite proves that:
End-to-end dogfood check
relayfile-mountwith--mode poll --sync-mode pull-onlyagainst a read-scoped subtree..relay/state.jsonreportssyncMode: "pull-only".