sources harden --dry-run performs a live git fetch + pull --rebase before any dry-run guard
#3,692 opened on Jul 31, 2026
Repository metrics
- Stars
- (21,368 stars)
- PR merge metrics
- (Avg merge 18d 10h) (162 merged PRs in 30d)
Description
What happens
gbrain sources harden <id> --dry-run is not read-only. hardenBrainRepo runs step 1
unconditionally before any dryRun check, and step 1 is a live network + working-tree operation.
src/core/brain-repo-durability.ts:673-676 calls divergenceSafePull(...) before the
dryRun guards that gate steps 2-7. divergenceSafePull (src/core/git-remote.ts:489-531)
runs git fetch followed by git pull --rebase against the user's brain working tree.
So a user reaching for --dry-run to see what hardening WOULD do gets a real fetch and a real
rebase-pull of their brain repository. On a repo with local commits not yet pushed, that is a
history-touching operation performed by a flag whose entire purpose is to avoid performing
operations.
Expected
--dry-run performs no network calls and no working-tree mutations. Either move the pull inside
the same dryRun guard the other six steps use, or report it as "would pull" in the plan.
Where it is
src/core/brain-repo-durability.ts:668-712-- the orchestrator; step 1 at :673-676 precedes everydryRunchecksrc/core/git-remote.ts:489-531--divergenceSafePull, the fetch +pull --rebase
Notes
Two smaller things found in the same read, mentioned in case they are one fix:
gbrain sources harden --helpandgbrain sources --helpboth print only the genericgbrain sources - run gbrain --help for the full command list.stub, so the command's flags (including--dry-run) are undiscoverable from its own help. This is the same CLI-self-help class as the report filed as #3686.- The credential step stores an https PAT. On a source whose remote is an SSH URL that store is inert, and the harden run still reports the step as done.
Version
gbrain 0.42.67.0. Established by reading the dispatch (src/commands/sources.ts:1365-1367 ->
src/commands/sources-harden.ts:53 runHarden) and the orchestrator source. I did NOT execute
harden --dry-run against a live brain -- precisely because of the behavior reported here.