Absorbing #2031 un-blocked a destructive remove that bypassed the #1734
data-loss guards: ensureSourceRegistered's drift path issued
`gbrain sources remove` directly, without the detectAutopilot +
decideSourceRemove checks every other remove routes through via
safeSourcesRemove. gbrain >= 0.42's own prompt was accidentally blocking
that path; with --confirm-destructive passed it is live again.
- Drift remove now refuses LOUDLY (throws, actionable message) while an
autopilot is active or when decideSourceRemove disallows; a silent
changed=false would hide the drifted registration.
- decideSourceRemove's extraArgs (--keep-storage when supported) propagate
to the remove call, matching safeSourcesRemove.
- Drift is realpath-normalized before being declared: a symlink alias of the
same directory (macOS /tmp -> /private/tmp) is a match, not drift — the
probable cause of #1985's reporter hitting the remove on an unmoved repo.
- Drift fires a loud stderr line (old -> new path); perpetual drift in logs
is the trigger for promoting #1985's reindex-in-place design.
Tests: autopilot-active refusal (no remove in call log), fail-closed refusal
on unreadable sources list, --keep-storage propagation, symlink-alias
no-drift; existing drift tests pin the guard probes so a live autopilot on
the dev machine can't flip them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ensureSourceRegistered() handles match-but-different-path by removing the
old source then re-adding it at the new path. The remove was issued as
`gbrain sources remove <id> --yes`, but gbrain >= 0.42 gates `sources
remove` behind `--confirm-destructive` (`--yes` alone no longer suppresses
the data-loss prompt). The remove therefore fails with "To proceed, pass
--confirm-destructive", which ensureSourceRegistered surfaces as "source
registration failed" — aborting the entire /sync-gbrain code stage for any
already-registered source whose path has drifted. The memory and brain-sync
stages still pass, so the code index silently stops refreshing.
The orchestrator's own safeSourcesRemove() already passes
--confirm-destructive; this brings the lib helper in line with that
convention. Keeps --yes for older gbrain.
Tests: extend the fake gbrain shim in gbrain-sources.test.ts to simulate
the gbrain >= 0.42 guard (remove without --confirm-destructive exits 1),
update the drift re-register assertion, and add a regression test that
proves the drift path no longer throws. Both fail on main with the exact
"To proceed, pass --confirm-destructive" error and pass with the fix.
Fixes#1985
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: native gbrain code-surface orchestrator + ensureSourceRegistered helper
Replaces gbrain import (markdown only) with gbrain sources add + sync
--strategy code (or reindex-code on --full). Adds lib/gbrain-sources.ts
exporting ensureSourceRegistered/probeSource/sourcePageCount, plus lock
file + tmp-rename atomicity + dry-run write skip in the orchestrator.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: setup-gbrain Step 8 writes ## GBrain Search Guidance after smoke test
Extends Step 8 to write a machine-agnostic guidance block that teaches
the agent when to prefer gbrain CLI (search/query/code-def/code-refs/
code-callers/code-callees) over Grep. Gated on smoke test pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: /sync-gbrain skill — keep gbrain current and refresh agent guidance
New top-level skill that wraps gstack-gbrain-sync with state probing,
capability check (write+search round-trip, not gbrain doctor), CLAUDE.md
guidance lifecycle (write iff healthy, remove iff broken), and a
per-source verdict block. Re-runnable, idempotent.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: preamble emits gbrain-availability block when capability ok
Extends generate-brain-sync-block.ts to emit Variant A (steady-state, 4
lines) when cwd page_count > 0 or Variant B (empty-corpus emergency, 3
lines) when 0; empty string otherwise. Reads cached page_count from
.gbrain-sync-state.json (handles pretty + compact JSON). Refreshes ship
golden fixtures and bumps the plan-review preamble byte budget to 35K
to absorb the new block.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: register /sync-gbrain in AGENTS.md and docs/skills.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: regenerate SKILL.md across all hosts (gen:skill-docs)
Mechanical regeneration after preamble + setup-gbrain template + new
sync-gbrain skill. Run via: bun run gen:skill-docs --host all.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: bump version and changelog (v1.26.3.0)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: add /sync-gbrain to README skills table and gbrain section
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>