diff --git a/docs/configuration/gga.md b/docs/configuration/gga.md index 5f2c3940..72395135 100644 --- a/docs/configuration/gga.md +++ b/docs/configuration/gga.md @@ -15,6 +15,18 @@ Every gga review, in every repository, runs on the OpenAI Codex provider with | `~/.config/environment.d/50-gga-pin.conf` | Same provider and `PATH` for desktop-launched programs (IDE git hooks). | | Fish, Zsh, Bash startup | Export `GGA_PROVIDER=codex` and put the shim dir first on `PATH` when it exists. | +## When Codex is unavailable + +The review is a safety net, not a wall. The block sets `STRICT_MODE="false"` in the global +config, so a provider failure (for example `usage_limit_exceeded` when the Codex quota is used +up) lets the commit through with gga's error on screen instead of blocking it, while a real +`STATUS: FAILED` from the reviewer still blocks. gga never reports `PASSED` for a review that +did not run. The quota is shared across models, so falling back to another model would not help. + +A repository whose own `.gga` sets `STRICT_MODE="true"` overrides the global value (project +config is loaded after the global one) and keeps blocking during an outage: set it to `false` +there, or commit with `git commit --no-verify` until the quota resets. + ## Why a shim gga runs `codex exec ""` without model options, so it would use the model diff --git a/scripts/install-gga-pin.sh b/scripts/install-gga-pin.sh index 468c42e8..42de6cc1 100755 --- a/scripts/install-gga-pin.sh +++ b/scripts/install-gga-pin.sh @@ -5,7 +5,7 @@ # is kept outside it where possible and re-applied here idempotently: # 1. /bin/codex shim that injects the model for gga's `codex exec` # 2. /pin.env model and effort (created once, never overwritten) -# 3. /config marked block at the end: PROVIDER/GGA_PROVIDER=codex +# 3. /config marked block at the end: PROVIDER/GGA_PROVIDER=codex, STRICT_MODE=false # and the shim dir first on PATH # 4. environment.d/50-gga-pin.conf the same for desktop-launched programs # One line is printed per changed file; nothing when everything is current. @@ -96,6 +96,8 @@ ${BLOCK_BEGIN} # gentle-ai rewrites this file; re-run the installer or \`dreamcoder repair\` after it. PROVIDER="codex" GGA_PROVIDER="codex" +# A real STATUS: FAILED still blocks; an unavailable provider (usage limit, network) does not. +STRICT_MODE="false" case ":\${PATH}:" in *":${shim_dir}:"*) ;; *) export PATH="${shim_dir}:\${PATH}" ;; esac ${BLOCK_END} EOF diff --git a/tests/shell/test_gga_pin.bats b/tests/shell/test_gga_pin.bats index 0d173aec..041b1db3 100644 --- a/tests/shell/test_gga_pin.bats +++ b/tests/shell/test_gga_pin.bats @@ -88,6 +88,19 @@ shim() { PATH="${SHIM_DIR}:${REAL_BIN}:${PATH}" "$@"; } [ "$output" = "codex codex ${SHIM_DIR}" ] } +# A review tool is a safety net, not a wall: a real `STATUS: FAILED` still blocks, but an +# unavailable provider (usage limit, network) must not brick every commit. gentle-ai writes +# STRICT_MODE="true" into the generated part of the file, so the block has to override it. +@test "the block makes gga non-blocking when the provider is unavailable" { + gga_setup + gentle_ai_config + printf 'STRICT_MODE="true"\n' >>"${CONFIG}" + run installer + [ "$status" -eq 0 ] + run env -u GGA_PROVIDER bash -c 'source "$1"; printf "%s" "$STRICT_MODE"' _ "${CONFIG}" + [ "$output" = "false" ] +} + @test "sourcing the block twice does not duplicate the shim dir on PATH" { gga_setup installer >/dev/null