Skip to content

fix(onboard): reuse an existing global store instead of stranding history - #26

Merged
mikehasa merged 1 commit into
mainfrom
fix/onboard-existing-global-store
Jul 29, 2026
Merged

fix(onboard): reuse an existing global store instead of stranding history#26
mikehasa merged 1 commit into
mainfrom
fix/onboard-existing-global-store

Conversation

@mikehasa

Copy link
Copy Markdown
Owner

The bug

Global onboard always targeted the new canonical (XDG) store. Re-running it on a machine that already had a populated global store — e.g. the pre-rename ~/.agent-sentinel-global — silently repointed Claude Code and Codex at a new, empty store. The user's recorded history looked gone, and their clients ended up split across two ledgers.

Upgrading users hit this on exactly the step the 0.5.0 release notes tell them to run. Found by dogfooding: my own machine ended up with 7258 events in the old store and 1116 in the new one, with OpenCode and the Claude hook still writing to the old one while MCP wrote to the new one.

The fix

  • onboard_global_store_dir() returns the recognized global store that already holds records, and only falls back to the canonical XDG store on a fresh machine. Global onboard uses it, and prints when it's reusing an existing store.
  • Warn about the two surfaces onboard does not rewrite when they point elsewhere: an OpenCode registration (agentacct never writes OpenCode config) and a hook command running a wrapper from outside ~/.claude/hooks/. Either one silently splits recording between two stores — which reads as "attribution mysteriously got worse".

No data migration machinery: reuse-in-place plus a loud warning and a copy-paste recovery command.

Why it slipped through

Every install test — unit and cleanroom — only covered a fresh machine. There was no upgrade scenario anywhere.

  • 5 new onboard tests: reuse a populated legacy store, canonical on fresh, ignore an empty legacy dir, and both mismatch warnings. Verified non-vacuous (revert the fix → the reuse test fails).
  • Cleanroom gained UPGRADE=1 mode + INV6: the install must adopt the existing ledger.

Validation

  • Full suite: 2894 passed, 1 skipped.
  • Cleanroom INSTALL_METHOD=onboard UPGRADE=1: INV1–INV6 all pass. Fresh mode still all pass.

…tory

Global onboard always targeted the new canonical (XDG) store, so re-running it
on a machine that already had a populated global store (e.g. the pre-rename
~/.agent-sentinel-global) silently repointed Claude Code and Codex at a new,
EMPTY store: the user's recorded history looked gone, and clients ended up split
across two ledgers. Upgrading users hit this on exactly the step the 0.5.0
release notes tell them to run.

- `onboard_global_store_dir()` returns the recognized global store that already
  holds records, and only falls back to the canonical XDG store on a fresh
  machine. Global onboard uses it and says when it is reusing an existing store.
- Warn about the two surfaces onboard does NOT rewrite when they point somewhere
  else: an OpenCode registration (agentacct never writes OpenCode config) and a
  hook command running a wrapper from outside ~/.claude/hooks/. Either one
  silently splits recording between two stores.
- Cover the upgrade path that was never tested: 5 onboard tests (reuse a
  populated legacy store, canonical on fresh, ignore an empty legacy dir, both
  mismatch warnings) plus a cleanroom UPGRADE=1 mode with INV6.
@mikehasa
mikehasa merged commit f5d5565 into main Jul 29, 2026
3 checks passed
@mikehasa
mikehasa deleted the fix/onboard-existing-global-store branch July 29, 2026 21:57
@mikehasa mikehasa mentioned this pull request Jul 30, 2026
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