Skip to content

1.0.8 — an uninstall that actually leaves, and a task-core per chat

Choose a tag to compare

@ReidenXerx ReidenXerx released this 08 Aug 15:50

Fixed — uninstall did not leave the repo as it found it

A shakedown of install / update / uninstall across every runtime and module combination. The
install and update paths held up — idempotent over repeated runs, recorded choices preserved,
feature downgrade removing what it should. Uninstall was the weak one, and every defect below needs
a SECOND install to appear, which is why a suite that installs once never saw them.

  • The Node floor stayed in the user's package.json forever. Install adds
    engines.node >= 22.9.0 because bearing's own scripts need it; uninstall never took it back. Left
    behind it is enforced by npm under engine-strict, by Yarn always, and by CI — so a project on
    Node 20 fails to install because of a tool it removed. Now recorded at install and removed at
    uninstall, and a floor the user set themselves is never touched in either direction.
  • Uninstall restored bearing's own Cursor config. A backup answers "was there a file of the
    user's here before bearing?", and only a first install can observe that — by the second run
    .cursor/hooks.json exists because we wrote it. So update backed up our own file and uninstall
    faithfully restored it, leaving Cursor registering hooks whose scripts the same uninstall had just
    deleted: a failed spawn on every session start, prompt and tool call, in a repo the user believes
    is clean. The earlier install's answer now wins, per adapter so a runtime added later still backs
    up a genuinely user-owned file. Uninstall also strips a leftover registration written by an older
    version, and only when the entry is the one we write — a user's own gitnexus MCP server survives.
  • Empty .zed/ and .cursor/ shells were left behind. Install creates these in repos that
    never had them; uninstall wrote back {"context_servers":{},"agent":{"profiles":{}}} and stopped.
    Both are now removed once nothing of the user's is left in them — and a settings file holding
    their theme, keymap or own servers is left exactly as it is.
  • An intel-only contract pointed at a section that isn't there. The north-stars text
    distinguished itself from "the graph-first North star above", which in a repo without the GitNexus
    module is a pointer to a section the filter had just removed (NS-13). Contract tags now apply to a
    paragraph as well as a section.
  • A bad target printed a stack trace. "Not a git repository" is a fact the user needs, not a
    crash to read; the stack is one BEARING_DEBUG=1 away.

Known and accepted: installing rewrites package.json as 2-space JSON, so a repo that minified or
tab-indented it sees a whitespace-only diff that uninstall cannot undo.

Fixed — the task-core was one file per REPO, not per chat

.bearing/.task-core.md was a single path. The moment two agent sessions ran in the same
repository — a second editor window is enough, and three is routine — they overwrote each other's
save-state. The failure is worse than losing the file: on recovery a session reads whatever the
last writer left, so it reconstructs from another chat's task with full confidence. That is
precisely the drift a task-core exists to prevent, manufactured by the task-core itself.

  • One file per chat, at .bearing/task-cores/<chat-id>.md. The key comes from the transcript
    path every hook already receives; its basename is the session id and it stays stable across
    compaction, which is exactly when the core must be found again.
  • The path is now unguessable, so the session brief states it — on a fresh start as well as on
    recovery. Before, the agent could name the one documented file from memory; without this it
    could not write a core proactively at a milestone and would only learn its path once compaction
    hit, which is too late.
  • A pre-existing single-file core is still read, so upgrading mid-task loses nothing.
  • Old chats' cores are pruned after 30 days, never the current chat's however old it looks.
  • .bearing/task-cores/ is gitignored and covered by the post-install check — the previous rule
    matched a file, not a folder, so every chat's save-state would have been committed. Uninstall
    removes the empty directory but keeps any core still in it, the same way it keeps north-stars.

Fixed — the contract promised commands the install did not have

Found by dogfooding: bearing's own repo runs an intel-only install, and npm run bearing:northstars
— the command its own CLAUDE.md advertises — does not exist there.

Every npm script is owned by the GitNexus module, so an intel-only install has none of them. The
north-stars section was advertising a command you only get by installing a different module, in
the one file every agent reads as authoritative (NS-13, NS-20). The contract now points at the
skill and the file path, both of which are always installed.

  • The generated-file note shipped into user repos said "edit there, run npm run gen:contract" — a
    path and a command that exist only in bearing's own repo. It now tells the user what they actually
    need to know: edits to that block are replaced on the next update.
  • The post-install check that catches dangling commands scanned only executable files, on the
    reasoning that docs mention commands illustratively. True in general, but the contract is an
    instruction, so those three files are now held to what is installed — including when
    package.json has no scripts at all, which the original scan skipped as uninteresting and was in
    fact the broken case.
  • README lists those commands under "With the GitNexus module".

Added — bearing update tells you what changed

Nobody visits a changelog; everybody reads the terminal they just typed into. An update is the one
moment you are asking "what did this just do to my repo?", and bearing already records the version
you were on, so it can answer:

  What's new since 1.0.4
    1.0.5 — the compound-command notice was silent on the shape it exists for
    1.0.6 — one MCP server for the whole machine, instead of one per client
    1.0.7 — a domain expert on every review, and an installer that checks its own claims
    Full notes: https://github.com/ReidenXerx/bearing/releases

Titles only — 1.0.7's section alone is 13k characters, and burying the next steps under it would
make the useful part unreadable. It stays silent rather than guess: a fresh install, an unknown
previous version, no packaged changelog, or nothing new all print nothing, and an update never
fails because release notes could not be read.

CHANGELOG.md now ships in the npm package, so this works from an install as well as a checkout.

Added — every release is on GitHub

The repo had zero tags and zero releases, so the changelog was visible only to someone who thought
to open the file. All eight — v1.0.0 through v1.0.7 — are now published, each tagged at the
commit that actually shipped it, with its changelog section as the body. npm run release:notes -- --list shows what is releasable; it refuses Unreleased and the pre-rename 1.2.0.

The README's changelog link is now absolute, since npm does not reliably rewrite relative paths
(NS-17), and points at the releases page too.