Skip to content

fix: address PR 185 review follow-ups#186

Merged
khaliqgant merged 2 commits into
mainfrom
codex/pr185-feedback-followup
May 21, 2026
Merged

fix: address PR 185 review follow-ups#186
khaliqgant merged 2 commits into
mainfrom
codex/pr185-feedback-followup

Conversation

@khaliqgant

Copy link
Copy Markdown
Member

Summary

  • Persist decoded-byte content hashes on file records and reuse stored hashes for tree/event responses instead of hashing file content during each list call.
  • Backfill missing content hashes when persisted state is loaded, including fork overlay files.
  • Add the export path OpenAPI pattern constraint and log non-missing local snapshot errors during bootstrap hash probes.

Validation

  • go test ./internal/relayfile ./internal/mountsync
  • go test ./...
  • scripts/check-contract-surface.sh

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@khaliqgant has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 55 minutes and 13 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7ceeb471-dc72-4962-9502-3e7ea0e48bc2

📥 Commits

Reviewing files that changed from the base of the PR and between d897034 and fa29f1e.

📒 Files selected for processing (1)
  • internal/relayfile/store_content_hash_test.go
📝 Walkthrough

Walkthrough

This PR adds ContentHash field tracking to relayfile File objects, integrating it throughout write operations, tree listings, event generation, and startup state initialization. The PR also adds logging to mount sync bootstrap path and tightens OpenAPI validation.

Changes

ContentHash Field and Integration

Layer / File(s) Summary
ContentHash Schema and Helper Functions
internal/relayfile/store.go
File struct gains optional ContentHash JSON field; four internal helpers introduced: contentHashForEncodedContent computes hash with optional base64 decoding, storedContentHashForFile prefers stored value, ensureStoredContentHash backfills missing hashes, and contentHashForFile wraps the encode path.
Write Operations: ContentHash Computation
internal/relayfile/store.go
WriteFile creation and updates, BulkWrite, and WriteForkFile now compute ContentHash using contentHashForEncodedContent and store the result in File objects.
Tree Listings and Event Generation: Using Stored ContentHash
internal/relayfile/store.go
ListTree and listTreeFromFiles populate TreeEntry.ContentHash from stored values using storedContentHashForFile; recordWriteLocked and applyProviderUpsertLocked use stored hashes when generating Event.ContentHash instead of recomputing.
State Load: Backfilling ContentHash
internal/relayfile/store.go
During store initialization, loaded workspace files and fork overlay entries are normalized to ensure every File has ContentHash populated using ensureStoredContentHash, enabling subsequent operations to rely on stored hashes.
Test Coverage for ContentHash Behavior
internal/relayfile/store_test.go
TestListTreeUsesStoredContentHash verifies tree listings surface manually-set stored hashes; TestLoadFromDiskBackfillsContentHash verifies state load backfills missing ContentHash from encoded content.
OpenAPI Schema: ContentHash and Path Pattern
openapi/relayfile-v1.openapi.yaml
FileReadResponse schema gains optional contentHash property describing SHA-256 of decoded file bytes; exportWorkspace path parameter gains pattern constraint requiring leading slash.

Mount Sync Logging

Layer / File(s) Summary
Bootstrap Probe Error Logging
internal/mountsync/syncer.go
Added log message when local hash probe fails for reasons other than file-not-found during bootstrap read skipping decision.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • AgentWorkforce/relayfile#185: Both PRs involve ContentHash-based operations in the bootstrap path—fix: speed up mount bootstrap fallback #185 implements contentHash-based skipping and parallel bootstrap reads using the ContentHash plumbing that this PR establishes in store.go and OpenAPI.
  • AgentWorkforce/relayfile#166: Both PRs modify internal/mountsync/syncer.go bootstrap behavior—this PR adds error logging to trySkipBootstrapRead, while #166 overhauls bootstrap timeouts and fast-path gating.

Poem

🐰 A hash for each file, now stored with care,
No recompute thrills—the value's right there!
From writes to listings, it travels so fast,
Backfilled on load, this foundation will last! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title references PR 185 follow-ups but lacks specificity about the actual changes made in the changeset. Consider a more descriptive title like 'Persist and reuse content hashes for relayfile operations' to clearly indicate the primary changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description is directly related to the changeset, covering content hash persistence, backfilling, OpenAPI constraints, and logging improvements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/pr185-feedback-followup

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 and usage tips.

…cile

Persists ContentHash on the File struct so reconcile no longer rehashes
every read. Backfills on disk load for older snapshots. Prerequisite for
bootstrap skip-on-hash (#183).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

@github-actions

github-actions Bot commented May 21, 2026

Copy link
Copy Markdown

Relayfile Eval Review

Run: .relayfile/evals/runs/2026-05-21T13-07-26-468Z-HEAD-provider
Mode: provider
Git SHA: 46660d0

Passed: 4 | Needs human: 0 | Reviewable: 0 | Missing output: 0 | Failed: 0 | Skipped: 0

Human Review Cases

No reviewable human-review cases captured Relayfile output.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/relayfile/store.go (1)

3904-3937: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Persist the migration after backfilling missing ContentHash values.

Lines 3910-3937 only update the in-memory snapshot. If the process restarts before any later write/save, the backend still contains empty contentHash fields, so every legacy file and fork overlay gets rehashed again on the next boot and the migration never becomes durable.

Proposed fix
 func (s *Store) loadFromDisk() error {
 	if s.stateBackend == nil {
 		return nil
 	}
 	snapshot, err := s.stateBackend.Load()
@@
 	if snapshot == nil {
 		return nil
 	}
+	dirty := false
 	if snapshot.Workspaces != nil {
 		s.workspaces = snapshot.Workspaces
 		for _, ws := range s.workspaces {
 			if ws.Files == nil {
 				ws.Files = map[string]File{}
 			}
 			for path, file := range ws.Files {
-				ws.Files[path] = ensureStoredContentHash(file)
+				updated := ensureStoredContentHash(file)
+				if updated.ContentHash != file.ContentHash {
+					dirty = true
+				}
+				ws.Files[path] = updated
 			}
@@
 	if snapshot.Forks != nil {
 		s.forks = snapshot.Forks
 		for _, fork := range s.forks {
 			if fork.Overlay == nil {
 				fork.Overlay = map[string]ForkOverlayEntry{}
 			}
 			for path, entry := range fork.Overlay {
 				if entry.File == nil {
 					continue
 				}
-				file := ensureStoredContentHash(*entry.File)
+				original := *entry.File
+				file := ensureStoredContentHash(original)
+				if file.ContentHash != original.ContentHash {
+					dirty = true
+				}
 				entry.File = &file
 				fork.Overlay[path] = entry
 			}
 		}
 	}
@@
 	s.revCounter = snapshot.RevCounter
 	s.opCounter = snapshot.OpCounter
 	s.eventCounter = snapshot.EventCounter
+	if dirty {
+		return s.saveLocked()
+	}
 	return nil
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/relayfile/store.go` around lines 3904 - 3937, After backfilling
missing ContentHash values via ensureStoredContentHash for s.workspaces and
s.forks, persist the updated in-memory snapshot to the backend so the migration
is durable: invoke the store's snapshot persistence method (e.g., call
s.saveSnapshot(...) or implement and call s.persistSnapshot(...) immediately
after the loops that update s.workspaces and fork.Overlay), handle and log any
error and retry/fail fast as appropriate so the updated contentHash values are
written to the backend rather than only kept in memory.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/relayfile/store.go`:
- Around line 3904-3937: After backfilling missing ContentHash values via
ensureStoredContentHash for s.workspaces and s.forks, persist the updated
in-memory snapshot to the backend so the migration is durable: invoke the
store's snapshot persistence method (e.g., call s.saveSnapshot(...) or implement
and call s.persistSnapshot(...) immediately after the loops that update
s.workspaces and fork.Overlay), handle and log any error and retry/fail fast as
appropriate so the updated contentHash values are written to the backend rather
than only kept in memory.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 35d5de67-20b2-4726-8124-b31247644973

📥 Commits

Reviewing files that changed from the base of the PR and between 38dbcc7 and d897034.

📒 Files selected for processing (4)
  • internal/mountsync/syncer.go
  • internal/relayfile/store.go
  • internal/relayfile/store_test.go
  • openapi/relayfile-v1.openapi.yaml

@khaliqgant khaliqgant merged commit bbedf61 into main May 21, 2026
9 checks passed
@khaliqgant khaliqgant deleted the codex/pr185-feedback-followup branch May 21, 2026 13:08
@khaliqgant khaliqgant restored the codex/pr185-feedback-followup branch May 21, 2026 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant