Skip to content

fix: persistent overlay homes for pi/omp/hermes launchers (session history loss) - #230

Merged
ranxianglei merged 5 commits into
masterfrom
2026-08-25_persistent-overlay-home
Aug 25, 2026
Merged

ranxianglei merged 5 commits into
masterfrom
2026-08-25_persistent-overlay-home

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

Fixes #12 (omp session history invisible via bili omp) plus the same bug class in the pi and hermes launchers.

Root cause

bili omp pointed PI_CODING_AGENT_DIR at a mkdtemp temp home (entries symlinked to ~/.omp/agent, rewritten models.yml) and rm -rf'd it in a finally when the client exited. Two loss modes:

  1. Dangling resume pointers — omp persists absolute session paths derived from the temp home into shared state. Found on the reporting machine: ~/.omp/agent/terminal-sessions/pts-1 contained /tmp/bili-omp-*/sessions/.../*.jsonl — dangling after cleanup, so resume-last-session could not find the session.
  2. Files destroyed with the temp home — anything the client created directly inside the temp home (agent.db, models.db, ...) ceased to exist on exit.

Also: killed processes skipped the finally, leaking /tmp/bili-omp-* dirs (3 found; plus 4 bili-pi-*, 2 bili-hermes-*).

pi (PI_CODING_AGENT_DIR) and hermes (HERMES_HOME, terminal-sessions/<id> last-session pointers) have the identical bug class. opencode/claude/codex launchers are env/temp-file only — unaffected.

Fix

Replace temp homes with stable persistent overlays next to the real home: ~/.omp/agent-bili, ~/.pi/agent-bili, ~/.hermes-bili. Every launch:

  • refreshes entry symlinks (drops dead ones; merges overlay-created entries that shadow real-home entries back into the real home, so no data is ever lost)
  • rewrites the generated config (models.yml / models.json / config.yaml) atomically
  • never deletes the overlay — all paths the client persisted stay resolvable across runs

The real home's config files remain untouched.

Test plan

  • npm run typecheck ✓
  • npm test — 567/567 ✓ (new launcher tests: overlay path is <home>-bili and stable across launches; symlink refresh picks up new real-home entries; bili-created state inside the overlay survives; dead symlinks dropped; shadowed dirs merged into the real home)
  • npm run build ✓

…story loss)

The pi/omp/hermes launchers built their /bili/-rewritten config inside a
mkdtemp temp home (PI_CODING_AGENT_DIR / HERMES_HOME) and rm -rf'd it when
the client exited. Clients persist absolute session paths derived from that
temp home into shared state (e.g. omp ~/.omp/agent/terminal-sessions/pts-*
resume pointers), and any file the client created directly inside the temp
home (agent.db, models.db, ...) was destroyed on exit — making omp session
history invisible and leaking temp dirs when the process was killed.

Replace temp homes with stable persistent overlays next to the real home
(~/.omp/agent-bili, ~/.pi/agent-bili, ~/.hermes-bili): every launch
refreshes entry symlinks (dropping dead ones, merging overlay-created
entries that shadow real-home entries back into the real home) and rewrites
the generated config atomically. The overlay is never deleted, so paths
stayed resolvable across runs.

opencode/claude/codex launchers are unaffected (env/temp-file only).
@github-actions

github-actions Bot commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-08-25_persistent-overlay-home (cd8bd8a)

Option A — Install from npm PR tag (recommended)

npm install -g billion-context@pr-230

Each push to this PR publishes a new version under the pr-230 npm tag.

Option B — Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr230.tgz
npm install -g package

This comment is automatically updated on each push.

Review of the first overlay commit found three paths where overlay-created
data could be silently destroyed instead of merged back into the real home:

- a regular FILE shadowing a real-home entry was rm'd without merging
  (client atomic-write-over-symlink lost its newer content)
- the dir merge was shallow: new files under subdirs that exist on both
  sides were skipped and then deleted
- a type clash (real-home file vs overlay dir, or vice versa) aborted the
  merge silently while the caller still rm'd the shadow subtree

mergeOverlayDir is replaced by a recursive mergeOverlayEntry that preserves
both sides (mtime-newer-wins for files, losers kept as
<name>.bili-conflict) and reports failure; the caller now removes the
shadow only when the merge fully succeeded, otherwise it is kept in place
with a warning. Also add a .bili-launch.pid marker that warns when two bili
launches share one overlay (each launch rewrites the generated config with
its own proxy origin).

Regression tests for all three loss paths plus the pid marker.
…nt-overlay-home

# Conflicts:
#	src/launcher.ts
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.

refactor: reapOrphanBlocks should live in acp-kernel, not the proxy

1 participant