Skip to content

fix(ruvnet-brain): drift in the release-tag namespace so it converges - #24

Merged
pacphi merged 1 commit into
mainfrom
fix/ruvnet-brain-release-drift
Jul 16, 2026
Merged

pacphi merged 1 commit into
mainfrom
fix/ruvnet-brain-release-drift

Conversation

@pacphi

@pacphi pacphi commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Problem

ak status reported a ruvnet-brain version that could never converge:

⚠ ruvnet-brain 0.5.0-dev installed, 3.0.1 available → sync re-runs the installer

It compared the plugin semver (plugin.json → 0.5.0-dev) against the GitHub release tag (3.0.1). Grounding in the installed installer source (~/.claude/plugins/marketplaces/ruvnet-brain/bin/install.mjs) showed ruvnet-brain actually has three unrelated version tracks:

Track Where Example
Plugin semver plugin.json / package.json 0.5.0-dev
KB bundle version KB manifest.json brainVersion v0.3.0-dev
Release tag (what the installer downloads by) GitHub releases/latest v3.0.1

None is stamped on disk in the release namespace, so the old check nagged forever and re-running the installer couldn't clear it (the plugin's own version stays 0.5.0-dev). ak setup correctly did nothing because it only installs when absent — the download at the end of the user's ak setup --force was unrelated tooling output, not ak refreshing the brain.

Fix

Compute drift in the release-tag namespace, using a stamp ak controls:

  • recordInstalledRelease() writes the release tag ak just pulled into kit.json (versionCheck.ruvnetBrain.installedRelease) after a successful heal.installRuvnetBrain().
  • classifyDrift() (pure) compares that stamp vs releases/latest — same namespace → converges after a refresh.
  • A present-but-unstamped install (manual / pre-existing, like the reporter's) surfaces as outdated once so ak sync pulls it onto the managed track, then converges.
  • latest unknown (offline / rate-limited) is never falsely "outdated".

New row behavior:

State Row
Present, ak never stamped ⚠ ruvnet-brain present (unversioned install), release v3.0.1 available → sync refreshes the KB
Present, stamped older ⚠ ruvnet-brain release v3.0.0, release v3.0.1 available → sync refreshes the KB
Present, stamped == latest ✓ ruvnet-brain release v3.0.1 (latest)
Not installed ⚠ RuvNet Brain not installed → setup installs it

Verification

npm run check passes clean (exit 0): typecheck, eslint, markdownlint, build, 74 kit + 20 statusline tests. New classifyDrift unit tests cover converged / older / unversioned / offline. Verified live: the row now reads present (unversioned install), release v3.0.1 available → sync refreshes the KB on the reporter's machine state. (The convergence-after-refresh path is proven by unit tests rather than triggering the real ~512 MB KB download.)

MAINTAINER.md documents the three-namespace gotcha to prevent regression.

🤖 Generated with Claude Code

The ruvnet-brain status row reported a version that could never converge:
it compared the plugin semver (plugin.json, e.g. 0.5.0-dev) against the
GitHub *release* tag (e.g. 3.0.1). Those are unrelated version tracks —
ruvnet-brain has THREE (plugin semver, KB bundle brainVersion, and the
release tags the installer downloads by), and none is stamped on disk in
the release namespace. So the row nagged "3.0.1 available" forever and no
reinstall could clear it (the plugin's own version stays 0.5.0-dev).

Fix: compute drift against ak's OWN record of the release it last pulled
(kit.json versionCheck.ruvnetBrain.installedRelease, written by
recordInstalledRelease() after a successful install) vs GitHub
releases/latest — same namespace, so it converges. A present-but-unstamped
install (manual / pre-existing) surfaces as outdated once so `ak sync`
pulls it onto the managed track, then converges.

- ruvnet-brain.mjs: classifyDrift() (pure), recordInstalledRelease(),
  drift() reworked to the release-tag namespace + cache preserves the stamp.
- heal.installRuvnetBrain(): stamp the pulled release; drop the misleading
  plugin-semver diff from its detail.
- status/setup: release-tag phrasing; setup no longer prints the plugin semver.
- tests: classifyDrift cases (converged / older / unversioned / offline).
- MAINTAINER: document the three-namespace gotcha.
@pacphi
pacphi merged commit c4bd58d into main Jul 16, 2026
11 checks passed
@pacphi
pacphi deleted the fix/ruvnet-brain-release-drift branch July 16, 2026 06:17
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