Skip to content

fix(bridge): keep pointer and loop files under --data-dir so a second bridge can't clobber the primary - #99

Merged
fkesheh merged 1 commit into
mainfrom
fix/bridge-pointer-datadir
Sep 5, 2026
Merged

fkesheh merged 1 commit into
mainfrom
fix/bridge-pointer-datadir

Conversation

@fkesheh

@fkesheh fkesheh commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Problem

bridge.json, loops.json, loop-runs.json and session-registry.json were written to $HOME/.ftown unconditionally, ignoring --data-dir (which only ever controlled bridge-id, refresh-token, solo/ and the session store). So a Solo test or a second bridge started with its own --data-dir:

  • overwrote the primary bridge's ~/.ftown/bridge.json and deleted it on shutdown, orphaning the harness and CLIs that hardcode that path;
  • merged its scheduled loops into the primary's loops.json.

This bit us in this very session: a Solo verification run deleted the running production bridge's pointer file.

Fix

New resolveFtownHome(dataDir):

  • default data dir (~/.ftown/data) → ~/.ftown, exactly as before, so the harness CLIs keep working with zero change;
  • any other --data-dir → that directory owns its own bridge.json, loops.json, loop-runs.json, session-registry.json.

The pointer is written and unlinked at the same resolved path, so a custom-data-dir bridge can never delete the primary's bridge.json. env.json intentionally stays at ~/.ftown (shared provider tokens). Path setters run at startup before any store is read; paths are computed per call, not cached at import.

Verification

  • With the default data dir, every routed path is byte-identical to the old join(homedir(),'.ftown',<file>) — a test guards this so a revert fails.
  • A scratch --data-dir run wrote the pointer and loops under the scratch dir; the real ~/.ftown was untouched before and after.
  • Independent review confirmed cleanup cannot touch $HOME/.ftown/bridge.json under a custom data dir, and the setter-before-read ordering is correct.
  • 769 bridge tests, tsc and build all pass.

Not in this PR

  • ~/.ftown/workflows/<runId> is not rerouted (run ids are unique, low collision risk).
  • env.json stays global by design.

🤖 Generated with Claude Code

…can't clobber the primary

bridge.json, loops.json, loop-runs.json and session-registry.json were
written to $HOME/.ftown unconditionally, ignoring --data-dir. A Solo test
or a second bridge with its own --data-dir therefore overwrote the
primary bridge's pointer file and deleted it on shutdown, orphaning the
harness, and merged its loops into the primary's loops.json.

New resolveFtownHome(dataDir): the default data dir (~/.ftown/data) still
maps to ~/.ftown so the harness CLIs, which hardcode that path, keep
working unchanged; any other --data-dir owns its own instance files under
that directory. The pointer is written and unlinked at the same resolved
path, so a custom-data-dir bridge can never delete the primary's
bridge.json. env.json stays global (shared provider tokens), by design.

Verified: with the default data dir every path is byte-identical to
before; a scratch --data-dir run wrote the pointer and loops under the
scratch dir and left the real ~/.ftown untouched. 769 bridge tests pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ftown Ready Ready Preview Sep 5, 2026 12:51pm UTC

Request Review

@fkesheh
fkesheh merged commit c99155b into main Sep 5, 2026
6 checks passed
@fkesheh
fkesheh deleted the fix/bridge-pointer-datadir branch September 5, 2026 14:19
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