Files
gstack/docs/gbrain-sync-errors.md
T
Garry Tan 9dbaf906cf feat(v1.9.0.0): gbrain-sync — cross-machine gstack memory (#1151)
* feat(gbrain-sync): queue primitives + writer shims

Adds bin/gstack-brain-enqueue (atomic append to sync queue) and
bin/gstack-jsonl-merge (git merge driver, ts-sort with SHA-256 fallback).
Wires one backgrounded enqueue call into learnings-log, timeline-log,
review-log, and developer-profile --migrate. question-log and
question-preferences stay local per Codex v2 decision.

gstack-config gains gbrain_sync_mode (off/artifacts-only/full) and
gbrain_sync_mode_prompted keys, plus GSTACK_HOME env alignment so
tests don't leak into real ~/.gstack/config.yaml.

* feat(gbrain-sync): --once drain + secret scan + push

bin/gstack-brain-sync is the core sync binary. Subcommands: --once
(drain queue, allowlist-filter, privacy-class-filter, secret-scan
staged diff, commit with template, push with fetch+merge retry),
--status, --skip-file <path>, --drop-queue --yes, --discover-new
(cursor-based detection of artifact writes that skip the shim).

Secret regex families: AWS keys, GitHub tokens (ghp_/gho_/ghu_/ghs_/
ghr_/github_pat_), OpenAI sk-, PEM blocks, JWTs, bearer-token-in-JSON.
On hit: unstage, preserve queue, print remediation hint (--skip-file
or edit), exit clean. No daemon — invoked by preamble at skill
boundaries.

* feat(gbrain-sync): init, restore, uninstall, consumer registry

bin/gstack-brain-init: idempotent first-run. git init ~/.gstack/,
.gitignore=*, canonical .brain-allowlist + .brain-privacy-map.json,
pre-commit secret-scan hook (defense-in-depth), merge driver registration
via git config, gh repo create --private OR arbitrary --remote <url>,
initial push, ~/.gstack-brain-remote.txt for new-machine discovery,
GBrain consumer registration via HTTP POST.

bin/gstack-brain-restore: safe new-machine bootstrap. Refuses clobber
of existing allowlisted files, clones to staging, rsync-copies tracked
files, re-registers merge drivers (required — not cloned from remote),
rehydrates consumers.json, prompts for per-consumer tokens.

bin/gstack-brain-uninstall: clean off-ramp. Removes .git + .brain-*
files + consumers.json + config keys. Preserves user data (learnings,
plans, retros, profile). Optional --delete-remote for GitHub repos.

bin/gstack-brain-consumer + bin/gstack-brain-reader (symlink alias):
registry management. Internal 'consumer' term; user-facing 'reader'
per DX review decision.

* feat(gbrain-sync): preamble block — privacy gate + boundary sync

scripts/resolvers/preamble/generate-brain-sync-block.ts emits bash that
runs at every skill invocation:
- Detects ~/.gstack-brain-remote.txt on machines without local .git
  and surfaces a restore-available hint (does NOT auto-run restore).
- Runs gstack-brain-sync --once at skill start to drain any pending
  writes (and at skill end via prose instruction).
- Once-per-day auto-pull (cached via .brain-last-pull) for append-only
  JSONL files.
- Emits BRAIN_SYNC: status line every skill run.

Also emits prose for the host LLM to fire the one-time privacy
stop-gate (full / artifacts-only / off) when gbrain is detected and
gbrain_sync_mode_prompted is false. Wired into preamble.ts composition.

* test(gbrain-sync): 27-test consolidated suite

test/brain-sync.test.ts covers:
- Config: validation, defaults, GSTACK_HOME env isolation
- Enqueue: no-op gates, skip list, concurrent atomicity, JSON escape
- JSONL merge driver: 3-way + ts-sort + SHA-256 fallback
- Init + sync: canonical file creation, merge driver registration,
  push-reject + fetch+merge retry path
- Init refuses different remote (idempotency)
- Cross-machine restore round-trip (machine A write → machine B sees)
- Secret scan across all 6 regex families (AWS, GH, OpenAI, PEM, JWT,
  bearer-JSON). --skip-file unblock remediation
- Uninstall removes sync config, preserves user data
- --discover-new idempotence via mtime+size cursor

Behaviors verified via integration smokes during implementation. Known
follow-up: bun-test 5s default timeout needs 30s wrapper for
spawnSync-heavy tests.

* docs(gbrain-sync): user guide + error lookup + README section

docs/gbrain-sync.md: setup walkthrough, privacy modes, cross-machine
workflow, secret protection, two-machine conflict handling, uninstall,
troubleshooting reference.

docs/gbrain-sync-errors.md: problem/cause/fix index for every
user-visible error. Patterned on Rust's error docs + Stripe's API
error reference.

README.md: 'Cross-machine memory with GBrain sync' section near the
top (discovery moment), plus docs-table entry.

* chore: bump version and changelog (v1.7.0.0)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore: regenerate SKILL.md files for gbrain-sync preamble block

Re-runs bun run gen:skill-docs after adding generateBrainSyncBlock
to scripts/resolvers/preamble.ts in a2aa8a07. CI check-freshness
caught the drift. All 36 SKILL.md files regenerated with the new
skill-start bash block + privacy-gate prose + skill-end sync
instructions baked in.

* fix(test): session-awareness reads AskUserQuestion Format from a Tier 2+ SKILL.md

The test was reading ROOT/SKILL.md (browse skill, Tier 1) which never
contained '## AskUserQuestion Format' — that section is only emitted
for Tier 2+ skills by scripts/resolvers/preamble.ts. As a result the
agent was prompted with an empty format guide and only emitted
'RECOMMENDATION' intermittently, making the test flaky.

Pre-existing on main (same ROOT/SKILL.md shape there) — surfaced now
because the agent run didn't hit the RECOMMENDATION/recommend/option a
fallback strings in this particular attempt.

Fix: read from office-hours/SKILL.md (Tier 3, always has the section)
with a fallback that scans for the first top-level skill dir whose
SKILL.md contains the header. Future template moves won't break this
test again.

* chore: bump to v1.9.0.0 for gbrain-sync landing

Changes just the VERSION + package.json + CHANGELOG header (1.7.0.0 → 1.9.0.0
and date 2026-04-22 → 2026-04-23). No code changes. User call: land gbrain-sync
as a bigger-signal release above main's 1.6.4.0, skipping 1.8.0.0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 17:54:54 -07:00

6.2 KiB

gbrain-sync error lookup

Every error message gstack-brain-* can print, with problem, cause, and fix.

Search this file by the prefix after BRAIN_SYNC: or by the binary name in the command output.


BRAIN_SYNC: brain repo detected: <url>

Problem. You're on a machine that has ~/.gstack-brain-remote.txt (copied from another machine) but no local git repo at ~/.gstack/.git.

Cause. You've set up GBrain sync elsewhere and your gstack hasn't been restored on this machine yet.

Fix.

gstack-brain-restore

This pulls the repo into ~/.gstack/ and re-registers merge drivers.

If you don't want to restore here, dismiss the hint with:

gstack-config set gbrain_sync_mode_prompted true

BRAIN_SYNC: blocked: <pattern-family>:<snippet>

Problem. Sync stopped because the secret scanner detected credential-shaped content in a staged file. The queue is preserved; nothing was pushed.

Cause. One of the pre-commit secret patterns matched the file contents — likely an AWS key, GitHub token, OpenAI key, PEM block, JWT, or bearer token embedded in JSON.

Fix (three options).

  1. If it's a real secret: edit the offending file to remove the secret, then re-run any skill to retry sync.

  2. If the pattern is a false positive (e.g., your learning contains a GitHub token pattern in an example string that you want to publish):

    gstack-brain-sync --skip-file <path>
    

    This permanently excludes the path from future syncs.

  3. If you want to abandon this sync batch entirely (start fresh):

    gstack-brain-sync --drop-queue --yes
    

    This clears the queue without committing. Future writes will re-populate it normally.


BRAIN_SYNC: push failed: auth.

Problem. Git push was rejected because your auth with the remote expired or is missing.

Cause. The remote is unreachable with current credentials.

Fix. Refresh auth based on your remote:

  • GitHub: gh auth status (then gh auth refresh if needed)
  • GitLab: glab auth status
  • Other: git remote -v + check SSH keys or credential helper

After fixing auth, run any skill to retry sync automatically.


BRAIN_SYNC: push failed: <first-line-of-error>

Problem. Push failed for a reason other than auth. The first line of git's error appears after the colon.

Cause. Could be network issue, rejected push (remote ahead), server 500, or repo access revoked.

Fix. Look at ~/.gstack/.brain-sync-status.json for more detail, or run:

cd ~/.gstack && git status && git push origin HEAD

to see git's full error. The queue is cleared after any push attempt, but your local commit still exists — the next skill run will retry the push.


gstack-brain-init: ~/.gstack/.git is already a git repo pointing at <url>

Problem. You tried to init with a remote URL that doesn't match the existing one.

Cause. You already ran gstack-brain-init with a different remote.

Fix. Either:

  • Use the existing remote: run gstack-brain-init without --remote, or with the matching URL.
  • Switch remotes: gstack-brain-uninstall first, then re-init with the new URL. This does not delete your data.

Remote not reachable: <url>

Problem. Init couldn't reach the git remote to verify connectivity.

Cause. Wrong URL, missing auth, network issue.

Fix. Test manually:

git ls-remote <url>

If that fails, check:

  • URL spelling
  • GitHub: gh auth status
  • GitLab: glab auth status
  • Private network / VPN / DNS

gstack-brain-init: failed to create or find '<name>'

Problem. Auto-repo-creation via gh repo create failed and the repo isn't discoverable via gh repo view either.

Cause. gh is unauthenticated, a repo with that name already exists owned by someone else, or your GitHub account hit a quota.

Fix.

gh auth status

If unauth'd, run gh auth login. If the repo name collides, pass a different name:

gstack-brain-init --remote git@github.com:YOURUSER/custom-name.git

gstack-brain-restore: ~/.gstack/.git already points at <url>

Problem. You tried to restore from a URL that doesn't match the existing git config.

Cause. Stale .git from a previous init with a different remote.

Fix. gstack-brain-uninstall, then re-run gstack-brain-restore <url>.


gstack-brain-restore: ~/.gstack/ has existing allowlisted files that would be clobbered

Problem. You're trying to restore, but ~/.gstack/ already contains learnings or plans that would be overwritten.

Cause. Either (a) this machine has accumulated state from a pre-sync gstack session, or (b) a previous failed restore left partial state.

Fix (three options).

  1. If this machine's state should become the new truth: run gstack-brain-init instead of restore — this creates a brand-new brain repo from this machine's state.

  2. If you want to adopt the remote and discard this machine's state: back up ~/.gstack/projects/ first, then remove the offending files and re-run restore.

  3. If you want to merge: there's no automatic merge for this. Manually copy learnings from ~/.gstack/ into your running gstack on a machine with sync already on, then restore here.


gstack-brain-restore: <url> does not look like a gstack-brain repo

Problem. The clone succeeded but the repo is missing .brain-allowlist and .gitattributes.

Cause. You pointed restore at a random git repo, or someone deleted the canonical config files from the brain repo.

Fix. Verify the URL. If it's correct, run gstack-brain-init --remote <url> to re-seed the canonical config.


Nothing is syncing but I expect it to

Not an error, but a common gotcha. Check in order:

  1. gstack-brain-sync --status — is mode off?
  2. ~/.gstack/.git exists?
  3. gstack-config get gbrain_sync_mode — should be full or artifacts-only.
  4. The file you expect to sync — is it in the allowlist? cat ~/.gstack/.brain-allowlist
  5. Privacy class filter — if mode is artifacts-only, behavioral files (timelines, developer-profile) are intentionally skipped.

If all those look right, run:

gstack-brain-sync --discover-new
gstack-brain-sync --once

to force a drain.