|
19 | 19 | # - git |
20 | 20 | # - network reachability to https://github.com |
21 | 21 | # |
22 | | -# The pinned commit is declared here rather than resolved dynamically so |
23 | | -# upgrades are explicit and reviewable. Update PINNED_COMMIT when gstack |
24 | | -# verifies compatibility with a new gbrain release. |
| 22 | +# gbrain installs at the latest default-branch HEAD by default — the hard pin |
| 23 | +# was removed in #1744 (it had drifted ~23 versions behind). Pass |
| 24 | +# --pinned-commit <sha> to install a specific commit for reproducibility. A |
| 25 | +# minimum-version floor (MIN_GBRAIN_VERSION) hard-fails the install when the |
| 26 | +# resulting gbrain is too old for gstack's sync integration, and a fast |
| 27 | +# `gbrain doctor` self-test hard-fails a broken install when gbrain is already |
| 28 | +# configured. This keeps the version gate that the pin used to provide without |
| 29 | +# freezing users 23 releases behind. |
25 | 30 | # |
26 | 31 | # Env: |
27 | 32 | # GBRAIN_INSTALL_DIR — override default install path (~/gbrain) |
|
33 | 38 | set -euo pipefail |
34 | 39 |
|
35 | 40 | # --- defaults --- |
36 | | -PINNED_COMMIT="08b3698e90532b7b66c445e6b1d8cdfe71822802" # gbrain v0.18.2 |
37 | | -PINNED_TAG="v0.18.2" |
| 41 | +# No version pin by default — install the latest default-branch HEAD (#1744). |
| 42 | +# --pinned-commit <sha> overrides for reproducibility. |
| 43 | +PINNED_COMMIT="" |
| 44 | +PINNED_TAG="" |
| 45 | +# Minimum gbrain version gstack's integration is known to work with. The |
| 46 | +# `sources list --json` wrapped-object shape + federated sources landed by 0.20; |
| 47 | +# older predates the surface gstack drives. Hard-fail below this floor (#1744). |
| 48 | +MIN_GBRAIN_VERSION="0.20.0" |
38 | 49 | GBRAIN_REPO_URL="https://github.com/garrytan/gbrain.git" |
39 | 50 | DEFAULT_INSTALL_DIR="${GBRAIN_INSTALL_DIR:-$HOME/gbrain}" |
40 | 51 | INSTALL_DIR="$DEFAULT_INSTALL_DIR" |
@@ -113,16 +124,20 @@ elif [ -n "$DETECTED_CLONE" ]; then |
113 | 124 | else |
114 | 125 | # Fresh clone path. |
115 | 126 | if $DRY_RUN; then |
116 | | - log "DRY RUN: would clone $GBRAIN_REPO_URL @ $PINNED_COMMIT → $INSTALL_DIR" |
| 127 | + log "DRY RUN: would clone $GBRAIN_REPO_URL ${PINNED_COMMIT:+@ $PINNED_COMMIT }→ $INSTALL_DIR (latest HEAD unless --pinned-commit)" |
117 | 128 | exit 0 |
118 | 129 | fi |
119 | 130 | if [ -d "$INSTALL_DIR" ]; then |
120 | 131 | fail "install dir $INSTALL_DIR exists but is not a valid gbrain clone. Remove it or pass --install-dir <other>." |
121 | 132 | fi |
122 | 133 | log "cloning $GBRAIN_REPO_URL → $INSTALL_DIR" |
123 | 134 | git clone --quiet "$GBRAIN_REPO_URL" "$INSTALL_DIR" |
124 | | - ( cd "$INSTALL_DIR" && git checkout --quiet "$PINNED_COMMIT" ) |
125 | | - log "pinned to $PINNED_COMMIT${PINNED_TAG:+ ($PINNED_TAG)}" |
| 135 | + if [ -n "$PINNED_COMMIT" ]; then |
| 136 | + ( cd "$INSTALL_DIR" && git checkout --quiet "$PINNED_COMMIT" ) |
| 137 | + log "checked out pinned commit $PINNED_COMMIT${PINNED_TAG:+ ($PINNED_TAG)}" |
| 138 | + else |
| 139 | + log "installed latest gbrain (default-branch HEAD)" |
| 140 | + fi |
126 | 141 | fi |
127 | 142 |
|
128 | 143 | if $DRY_RUN; then |
|
195 | 210 |
|
196 | 211 | log "installed gbrain $actual_version from $INSTALL_DIR" |
197 | 212 |
|
| 213 | +# --- minimum-version floor (#1744) --- |
| 214 | +# Unpinning means new installs track gbrain HEAD. Hard-fail if the resulting |
| 215 | +# version is below the floor gstack's sync integration needs — same exit-3 posture |
| 216 | +# as the PATH-shadow / version-mismatch failures above. A warning here is exactly |
| 217 | +# how the data-loss class slipped through, so this gate fails closed. |
| 218 | +version_lt() { |
| 219 | + # 0 (true) when $1 < $2 by version sort; equal versions are NOT less-than. |
| 220 | + [ "$1" = "$2" ] && return 1 |
| 221 | + [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -1)" = "$1" ] |
| 222 | +} |
| 223 | +if version_lt "$actual_norm" "$MIN_GBRAIN_VERSION"; then |
| 224 | + echo "" >&2 |
| 225 | + echo "gstack-gbrain-install: gbrain $actual_version is below the minimum gstack-tested version ($MIN_GBRAIN_VERSION)." >&2 |
| 226 | + echo " gstack's sync integration needs the v0.20+ source/list surface." >&2 |
| 227 | + echo " Fix: update the gbrain clone at $INSTALL_DIR to a newer release (git pull), then" >&2 |
| 228 | + echo " re-run /setup-gbrain. Or pass --pinned-commit <sha> to install a specific newer commit." >&2 |
| 229 | + echo "" >&2 |
| 230 | + exit 3 |
| 231 | +fi |
| 232 | + |
| 233 | +# --- functional self-test when gbrain is already configured (#1744) --- |
| 234 | +# When a brain config exists (re-install / detected clone), run a fast doctor as |
| 235 | +# a hard gate so a broken gbrain is caught at setup, not at data-loss time. |
| 236 | +# Pre-init installs skip this (config not written yet); the full |
| 237 | +# `/sync-gbrain --dry-run` self-test runs from /setup-gbrain after `gbrain init`. |
| 238 | +_GBRAIN_HOME_CHECK="${GBRAIN_HOME:-$HOME/.gbrain}" |
| 239 | +if [ -f "$_GBRAIN_HOME_CHECK/config.json" ]; then |
| 240 | + if ! gbrain doctor --fast >/dev/null 2>&1; then |
| 241 | + echo "" >&2 |
| 242 | + echo "gstack-gbrain-install: gbrain $actual_version installed but 'gbrain doctor --fast' failed." >&2 |
| 243 | + echo " Refusing to leave a broken gbrain in place. Run 'gbrain doctor' to see what's wrong," >&2 |
| 244 | + echo " fix it, then re-run /setup-gbrain." >&2 |
| 245 | + echo "" >&2 |
| 246 | + exit 3 |
| 247 | + fi |
| 248 | + log "gbrain doctor --fast passed" |
| 249 | +fi |
| 250 | + |
198 | 251 | # v1.40.0.0 post-install validation (T6 / codex review #19): --ignore-scripts |
199 | 252 | # may skip artifacts gbrain needs at runtime, especially on Windows |
200 | 253 | # MSYS/MINGW where we DID pass --ignore-scripts. `gbrain --version` above |
|
0 commit comments