Skip to content

Global layer (`~/.beetl`)

Source: packages/core/src/global/global.ts, packages/cli/src/commands/global.ts, doctor hook in packages/core/src/store/doctor.ts · Spec: §11, §3.4

~/.beetl/
├── config.json # user identity (M0)
├── registry.json # projects, lastSyncAt, terminal-session hashes
└── mirror/<slug>/sessions.json # lightweight session summaries

Opt-in per project via global.enabled (interactive init preselects yes; non-interactive defaults off — nothing leaves a repo boundary without a human choice). enable syncs immediately. disable purges this project’s mirror and registry entry by default (--keep-data is the explicit exception; no prompt — identical semantics under --yes and automation, ADR-0005). beetl global purge is the standalone idempotent purge; beetl global status shows enabled/slug/mirror state and the last sync error. Project slug = directory name + short path hash.

beetl global sync refreshes this project’s mirror + registry entry; every mutating command (new, file-complete, update, move, resolve, diagnose, privacy redact) also syncs implicitly when enabled. Implicit sync failures are never swallowed: a non-fatal stderr warning (human) or warnings[] entry (JSON), plus a persisted lastSyncError surfaced by doctor and global status. Mirrors hold summaries only — id, title, type, status, category, surface, rootCause, refixOf, reporting Actor, attribution authors — never raw error output or private artifacts, so the layer is safe under private-split.

  • beetl global report — pattern engine across the mirror: recurring categories/types/surfaces across every repo, refix count, per-project rollup. JSON is snapshot-tested.
  • beetl blame --global — per-author/per-agent analysis over mirrored summaries, same local-only output rules as project blame (§8.1): attribution is never recorded into shared artifacts. Mirror identities are namespaced <projectSlug>/<sessionId> so same-day ID collisions across projects cannot merge author buckets or invent refix chains (M-11).

loadRegistry() surfaces corruption (GLOBAL_REGISTRY_CORRUPT) and leaves the file untouched — never silently replaced by a blank registry. beetl global repair is the explicit recovery: atomic timestamped backup, then rebuild from readable mirrors. Corrupt mirrors are preserved on disk and reported as warnings in report output and by doctor (GLOBAL_MIRROR_CORRUPT).

registry.json stores a sha256 of every terminal session file at last sync. beetl doctor compares current content against those hashes and flags TERMINAL_EDITED (error) on mismatch — unless the session’s events show a redaction at/after lastSyncAt, the sanctioned exception (§7); privacy redact re-syncs so its hash stays current.