Summary
While diagnosing "Linear data shows in Nango but not in my local mirror," I found one functional sync bug (the local mirror does not advance to newer remote revisions, even with a forced full reconcile) plus a set of CLI/UX footguns in relayfile mount/start — one of which is dangerous (it can re-home the mirror onto an arbitrary directory and start enqueuing it as writebacks).
Filing them together since they were all surfaced by the same investigation.
Environment: relayfile CLI (poll mode), workspace rw_fc7b534b, macOS. Mirror dir …/relayfile/relayfile-mount.
1. (P1, functional) Local mirror does not pull newer remote revisions — even with RELAYFILE_FORCE_FULL_RECONCILE=1
The cloud workspace has records that never reach the local mirror. This is not just lag — a forced full reconcile completes cleanly (mount sync cycle completed, no errors) without pulling them.
Evidence (Linear):
| Record |
Remote (relayfile tree) |
Local mirror |
linear/projects/779cbfda-0f49-4a92-97cb-214633bc914b.json |
present, rev_46580, readable via relayfile read |
missing (dir has only empty _index.json) |
linear/issues/AR-28…json |
rev_44031 |
present |
linear/issues/AR-30/AR-31/AR-32 |
rev_46579 / rev_56089 etc. |
missing |
Remote has 16 Linear issues; local has 13. Everything above ~rev_44031 is not pulled. The cloud side is fine (Nango syncs succeed; relayfile tree/relayfile read return the records). The break is the cloud → local-mirror hop.
Repro:
- Leave a workspace mirror unsynced for a while (daemon stopped).
- Confirm cloud has newer records:
relayfile tree <ws> linear/issues shows revs newer than what's local.
- Start the daemon:
relayfile mount <ws> <dir> --background.
- Restart forcing a full reconcile:
RELAYFILE_FORCE_FULL_RECONCILE=1 relayfile mount <ws> <dir> --background.
- Newer records (
AR-30/31/32, the project) still never appear locally; relayfile status keeps showing linear … lagging … last event 13h ago.
Why it matters: the local mirror silently diverges from cloud truth. Agents/humans reading the mirror see a stale world with no error surfaced.
Suspected cause: regular cycles do incremental, event-cursor-based pulls; since Linear's last tracked event is ~13h old, newer records (ingested without a newer cursor event) are never pulled. And RELAYFILE_FORCE_FULL_RECONCILE did not rescue it, so the "full reconcile" path also isn't enumerating/pulling these remote files. Possibly related to #2 below (index-driven enumeration).
2. (P2, data) _index.json is empty for linear/projects and linear/teams even in the cloud
The record files exist beside it, but the index aggregation is []:
relayfile tree rw_fc7b534b linear/projects
file /linear/projects/_index.json size=3 rev=rev_46181 ← "[]"
file /linear/projects/779cbfda-…json size=1899 rev=rev_46580 ← real record
Contrast linear/issues/_index.json (size=496, populated). Same for linear/teams/_index.json ([]) despite a team record + by-id/by-name aliases existing.
This matters because the activity-summary skill instructs agents to start from indexes/digests before walking provider trees — an empty index hides existing records. May also be the root of #1 if the reconcile enumerates provider dirs via _index.json rather than the actual tree.
3. (P1, dangerous UX) relayfile mount with no LOCAL_DIR mirrors the current directory and persists it as localDir
Running relayfile mount (no dir arg) from the repo root:
- mirrored the entire repo (node_modules,
.next caches, the 63 MB workflow-runs.jsonl, compiled binaries) → wall of skipping oversized local file … and context deadline exceeded;
- started treating repo files as local changes to enqueue as writebacks to the cloud workspace;
- pulled cloud provider dirs into the repo root (
google-mail/, .skills/, digests/this-week.md, .relay/, .relayfile-mount-state.json);
- overwrote the workspace's saved
localDir in ~/.relayfile/workspaces.json to point at the repo root.
Only the context deadline exceeded (before any enqueue) prevented pushing repo contents into the workspace.
Expected: with no LOCAL_DIR, fall back to the configured localDir; refuse / loudly warn if CWD is not the known mirror; never silently re-home the mirror.
4. (P2, UX) relayfile start is a foreground alias for mount, but help frames it as the daemon partner of stop/restart
Help text: "start — Alias for mount; pairs naturally with stop and restart." This implies start launches a managed background daemon. It does not — it runs in the foreground; you must pass --background. Result: relayfile start leaves a foreground process that relayfile stop cannot find (no running mount found).
5. (P2, UX) relayfile status reports daemon: not running while a foreground mount is actively running
A live foreground relayfile mount/start process (confirmed via ps, burning CPU) shows as daemon: not running because status only tracks --background daemons. Misleading during diagnosis.
6. (P3, UX) relayfile tree linear/projects → confusing 403 workspace mismatch
relayfile tree [WORKSPACE] [PATH] parsed linear/projects as the workspace positional, yielding error: http 403 forbidden: workspace mismatch instead of treating it as a path or reporting "unknown workspace." A path-looking first arg should be detectable, or the error should name the bad workspace.
7. (P3, UX) "skipping oversized local file" log is unbounded and repeats every cycle
When pointed at a tree with large artifacts, the same full list of skipped files is re-emitted every sync cycle with no dedup/summary, burying the actual error (context deadline exceeded). Suggest logging once, or a per-cycle summary count.
Suggested priorities
Summary
While diagnosing "Linear data shows in Nango but not in my local mirror," I found one functional sync bug (the local mirror does not advance to newer remote revisions, even with a forced full reconcile) plus a set of CLI/UX footguns in
relayfile mount/start— one of which is dangerous (it can re-home the mirror onto an arbitrary directory and start enqueuing it as writebacks).Filing them together since they were all surfaced by the same investigation.
Environment:
relayfileCLI (poll mode), workspacerw_fc7b534b, macOS. Mirror dir…/relayfile/relayfile-mount.1. (P1, functional) Local mirror does not pull newer remote revisions — even with
RELAYFILE_FORCE_FULL_RECONCILE=1The cloud workspace has records that never reach the local mirror. This is not just lag — a forced full reconcile completes cleanly (
mount sync cycle completed, no errors) without pulling them.Evidence (Linear):
relayfile tree)linear/projects/779cbfda-0f49-4a92-97cb-214633bc914b.jsonrev_46580, readable viarelayfile read_index.json)linear/issues/AR-28…jsonrev_44031linear/issues/AR-30/AR-31/AR-32rev_46579/rev_56089etc.Remote has 16 Linear issues; local has 13. Everything above ~
rev_44031is not pulled. The cloud side is fine (Nango syncs succeed;relayfile tree/relayfile readreturn the records). The break is the cloud → local-mirror hop.Repro:
relayfile tree <ws> linear/issuesshows revs newer than what's local.relayfile mount <ws> <dir> --background.RELAYFILE_FORCE_FULL_RECONCILE=1 relayfile mount <ws> <dir> --background.AR-30/31/32, the project) still never appear locally;relayfile statuskeeps showinglinear … lagging … last event 13h ago.Why it matters: the local mirror silently diverges from cloud truth. Agents/humans reading the mirror see a stale world with no error surfaced.
Suspected cause: regular cycles do incremental, event-cursor-based pulls; since Linear's last tracked event is ~13h old, newer records (ingested without a newer cursor event) are never pulled. And
RELAYFILE_FORCE_FULL_RECONCILEdid not rescue it, so the "full reconcile" path also isn't enumerating/pulling these remote files. Possibly related to #2 below (index-driven enumeration).2. (P2, data)
_index.jsonis empty forlinear/projectsandlinear/teamseven in the cloudThe record files exist beside it, but the index aggregation is
[]:Contrast
linear/issues/_index.json(size=496, populated). Same forlinear/teams/_index.json([]) despite a team record +by-id/by-namealiases existing.This matters because the
activity-summaryskill instructs agents to start from indexes/digests before walking provider trees — an empty index hides existing records. May also be the root of #1 if the reconcile enumerates provider dirs via_index.jsonrather than the actual tree.3. (P1, dangerous UX)
relayfile mountwith noLOCAL_DIRmirrors the current directory and persists it aslocalDirRunning
relayfile mount(no dir arg) from the repo root:.nextcaches, the 63 MBworkflow-runs.jsonl, compiled binaries) → wall ofskipping oversized local file …andcontext deadline exceeded;google-mail/,.skills/,digests/this-week.md,.relay/,.relayfile-mount-state.json);localDirin~/.relayfile/workspaces.jsonto point at the repo root.Only the
context deadline exceeded(before any enqueue) prevented pushing repo contents into the workspace.Expected: with no
LOCAL_DIR, fall back to the configuredlocalDir; refuse / loudly warn if CWD is not the known mirror; never silently re-home the mirror.4. (P2, UX)
relayfile startis a foreground alias formount, but help frames it as the daemon partner ofstop/restartHelp text: "start — Alias for mount; pairs naturally with stop and restart." This implies
startlaunches a managed background daemon. It does not — it runs in the foreground; you must pass--background. Result:relayfile startleaves a foreground process thatrelayfile stopcannot find (no running mount found).5. (P2, UX)
relayfile statusreportsdaemon: not runningwhile a foreground mount is actively runningA live foreground
relayfile mount/startprocess (confirmed viaps, burning CPU) shows asdaemon: not runningbecause status only tracks--backgrounddaemons. Misleading during diagnosis.6. (P3, UX)
relayfile tree linear/projects→ confusing403 workspace mismatchrelayfile tree [WORKSPACE] [PATH]parsedlinear/projectsas the workspace positional, yieldingerror: http 403 forbidden: workspace mismatchinstead of treating it as a path or reporting "unknown workspace." A path-looking first arg should be detectable, or the error should name the bad workspace.7. (P3, UX) "skipping oversized local file" log is unbounded and repeats every cycle
When pointed at a tree with large artifacts, the same full list of skipped files is re-emitted every sync cycle with no dedup/summary, burying the actual error (
context deadline exceeded). Suggest logging once, or a per-cycle summary count.Suggested priorities