Skip to content

fix(graph): self-heal tree-sitter deps on existing installs from session start#326

Merged
efenocchi merged 2 commits into
mainfrom
fix/graph-deps-selfheal
Jul 21, 2026
Merged

fix(graph): self-heal tree-sitter deps on existing installs from session start#326
efenocchi merged 2 commits into
mainfrom
fix/graph-deps-selfheal

Conversation

@efenocchi

@efenocchi efenocchi commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Problem

#323 provisions tree-sitter into the shared ~/.hivemind/embed-deps, but ensureGraphDeps only runs from hivemind graph init and hivemind embeddings install. Installs that predate #323 never run either, so the graph-on-stop auto-build stays dead forever. Verified on a real machine running deployed 0.7.138: 0 tree-sitter packages in embed-deps and every real session end logging build threw: Cannot find package 'tree-sitter'.

Fix

Commit 1 — harden ensureGraphDeps for unattended use:

  • Ownership-safe install lock (owner token; release only removes our own lock; 30-min stale reclaim that re-acquires instead of clobbering; mtime refreshed before npm and before the heal so long installs aren't reclaimed mid-flight).
  • Ready marker deleted BEFORE any repair mutation and re-stamped only after npm install AND the native heal both succeed; keyed by spec set + platform + arch + Node ABI.
  • Strict heal: a missing ensure-tree-sitter script is a failure, and it runs with HIVEMIND_STRICT_POSTINSTALL=1 so a failed bindings load can't stamp a broken install as ready.
  • Offline backoff: failed attempts recorded and retried at most every 6h — no npm storm on network-less machines. The satisfied fast path spawns no subprocess at all.

Commit 2 — self-heal wiring:

  • New detached graph-deps-worker (claude-code + codex bundles) spawned from session-start-setup BEFORE the credentials gate (provisioning is local). The hook returns immediately — the 120s async allowance never bounds the npm install; the lock serializes concurrent sessions.
  • The codex setup worker now spawns unconditionally; credentialed remote setup stays gated inside the worker.

CLI paths (graph init, installEmbeddings) keep calling ensureGraphDeps inline as before.

Validation (real harness)

Fresh sandbox HOME with empty embed-deps, real interactive claude session with this build via --plugin-dir:

  1. Session start → detached worker provisioned 10 tree-sitter packages + ready marker; attempt file cleared on success.
  2. Next real session end → graph-on-stop built the graph (gate: FIRE, snapshot json written) — on a machine state that pre-fix could never auto-build.
  • tsc clean, npm run build clean (new worker bundled for cc + codex).
  • Full suite: 5664 passed; only the pre-existing cli-bundle-runtime env flake fails (its bare graph exit-code assumption; unrelated).
  • codex review of the diff: initial round's 5 blockers (lock ownership, marker invalidation on repair, heal false-success, 120s hook cap vs sync npm, offline retry storm) all addressed as above.

Session Context

Session transcript

Summary by CodeRabbit

  • New Features

    • Graph dependencies are now provisioned automatically in the background during session startup.
    • Provisioning continues even when users are logged out, without delaying normal setup or hook completion.
    • Native parser setup now detects incomplete or outdated installations and repairs them safely.
  • Bug Fixes

    • Added retry backoff and failure handling to prevent repeated installation attempts.
    • Improved validation to avoid marking broken native bindings as ready.

Prepares ensureGraphDeps to run unattended from session hooks:

- Ownership-safe install lock: mkdir lockdir with an owner token; release
  only removes our own lock, stale reclaim (30 min) re-acquires instead of
  clobbering a live owner, and the lock mtime is refreshed before npm and
  before the heal so a long install is not reclaimed mid-flight.
- The ready marker is deleted BEFORE any repair mutation and re-stamped
  only after BOTH npm install and the native heal succeed, keyed by spec
  set + platform + arch + Node ABI - a crash mid-repair leaves no marker.
- Heal is strict: a missing ensure-tree-sitter script is a failure, and
  the script runs with HIVEMIND_STRICT_POSTINSTALL=1 so a failed bindings
  load exits non-zero instead of stamping a broken install as ready.
- Offline backoff: a failed attempt is recorded (.graph-deps.attempt) and
  retried at most every 6h, so network-less machines do not spawn an npm
  install on every session; the satisfied fast path never touches it and
  spawns no subprocess at all.
The graph auto-build hook resolves tree-sitter from the shared
~/.hivemind/embed-deps, but ensureGraphDeps only ran from 'graph init'
and 'embeddings install' - installs that predate #323 never run either,
so their graph-on-stop hook degrades to a skip forever (verified on a
real machine: 0 tree-sitter packages, every session end logging
"build threw: Cannot find package 'tree-sitter'").

Spawn a detached graph-deps worker from the claude-code and codex
session-start-setup paths, before the credentials gate (provisioning is
local): the hook returns immediately (the 120s async allowance never
bounds the npm install), the install lock serializes concurrent
sessions, and the codex setup worker now spawns unconditionally with
credentialed remote setup still gated inside the worker.
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 87ddb906-83d1-4f73-9479-6117de013349

📥 Commits

Reviewing files that changed from the base of the PR and between 87c285d and 58efef0.

📒 Files selected for processing (12)
  • esbuild.config.mjs
  • src/cli/graph-deps.ts
  • src/hooks/codex/session-start-setup.ts
  • src/hooks/codex/session-start.ts
  • src/hooks/graph-deps-worker.ts
  • src/hooks/session-start-setup.ts
  • tests/claude-code/session-start-setup-branches.test.ts
  • tests/claude-code/session-start-setup-hook.test.ts
  • tests/codex/codex-integration.test.ts
  • tests/codex/codex-session-start-hook.test.ts
  • tests/codex/codex-session-start-setup-hook.test.ts
  • tests/shared/graph-deps.test.ts

📝 Walkthrough

Walkthrough

Graph-dependency provisioning now uses readiness markers, locking, retry backoff, and strict native healing. Claude Code and Codex session hooks launch a bundled detached worker before credential-gated setup, with tests covering provisioning and spawn behavior.

Changes

Graph dependency provisioning

Layer / File(s) Summary
Provisioning state machine
src/cli/graph-deps.ts, tests/shared/graph-deps.test.ts
Provisioning now validates keyed readiness markers and parser directories, coordinates installs with an atomic lock, records failures for backoff, runs npm before native healing, and writes readiness only after successful validation.
Detached worker entrypoint and bundles
src/hooks/graph-deps-worker.ts, esbuild.config.mjs
A detached worker invokes ensureGraphDeps, catches failures, exits successfully, and is bundled for Claude Code and Codex.
Session hook integration
src/hooks/..., tests/claude-code/..., tests/codex/...
Session setup launches graph-deps provisioning before credential checks, and Codex session-start launches setup even without credentials; tests mock and verify detached spawning and ordering.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: kaghni, khustup2

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description has a solid Summary/Fix/Validation, but it omits the template's Version Bump section and the required Test plan checklist. Add a Version Bump section and a Test plan checklist covering local tests, new tests, and whether package.json was bumped.
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.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately captures the main change: session-start self-healing of tree-sitter graph deps on existing installs.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/graph-deps-selfheal

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.

@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Scope: files changed in this PR. Enforced threshold: 90% per metric (per file via vitest.config.ts).

Status Category Percentage Covered / Total
🟢 Lines 95.57% (🎯 90%) 194 / 203
🟢 Statements 94.47% (🎯 90%) 222 / 235
🟢 Functions 96.77% (🎯 90%) 30 / 31
🔴 Branches 88.28% (🎯 90%) 113 / 128
File Coverage — 5 files changed
File Stmts Branches Functions Lines
src/cli/graph-deps.ts 🟢 93.4% 🟢 90.7% 🟢 100.0% 🟢 95.7%
src/hooks/codex/session-start-setup.ts 🟢 100.0% 🔴 79.2% 🟢 100.0% 🟢 100.0%
src/hooks/codex/session-start.ts 🟢 100.0% 🟢 96.2% 🟢 100.0% 🟢 100.0%
src/hooks/graph-deps-worker.ts 🔴 0.0% 🔴 0.0% 🔴 0.0% 🔴 0.0%
src/hooks/session-start-setup.ts 🟢 100.0% 🟢 90.9% 🟢 100.0% 🟢 100.0%

Generated for commit e27118f.

@efenocchi
efenocchi merged commit 3acb388 into main Jul 21, 2026
11 checks passed
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