mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-08 06:26:45 +02:00
feat: helper locks GBRAIN_DATABASE_URL at startup, defends against config rewrites
The wireup helper previously read ~/.gbrain/config.json on every gbrain subprocess invocation. On Garry's Mac, multiple concurrent test runs and agent integrations were rewriting that file mid-sync, redirecting the wireup at the wrong brain partway through a 4-min initial import. This commit adds a `--database-url <url>` flag to the helper and locks the URL at startup. Precedence: 1. --database-url flag (explicit caller intent) 2. GBRAIN_DATABASE_URL / DATABASE_URL env (CI / manual override) 3. read once from ~/.gbrain/config.json (default) Whichever wins gets exported as GBRAIN_DATABASE_URL for every child `gbrain` invocation. Per gbrain's loadConfig at src/core/config.ts:53, env-var URLs override the file URL — so a process that flips config.json between two of our gbrain calls can't redirect us. Defense-in-depth: once the URL is locked, the wireup completes against the original brain even under hostile filesystem conditions. setup-gbrain/SKILL.md.tmpl Step 7 now reads the URL out of config.json once (via python3 inline) and passes it explicitly with --database-url, so even the very first wireup call is decoupled from config.json mutability. Three new test cases cover the lock behavior: - --database-url flag is exported to child gbrain calls - falls back to ~/.gbrain/config.json when no flag and no env - flag overrides env GBRAIN_DATABASE_URL and config.json values The fake gbrain in the test suite now records GBRAIN_DATABASE_URL alongside each call so tests can assert the helper exported the locked URL. Total test count: 13 → 16 passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+15
-1
@@ -1370,8 +1370,22 @@ federated source on the user's gbrain (Supabase or PGLite), and runs an
|
||||
initial `gbrain sync`. Local-Mac only. No cloud agent required. Subsequent
|
||||
skill runs trigger incremental sync via the existing skill-end push hook.
|
||||
|
||||
Capture the database URL out of `~/.gbrain/config.json` first and pass it
|
||||
explicitly so the wireup is robust against any other process rewriting
|
||||
`~/.gbrain/config.json` mid-sync (e.g., concurrent `gbrain init` runs
|
||||
elsewhere on the machine):
|
||||
|
||||
```bash
|
||||
~/.claude/skills/gstack/bin/gstack-gbrain-source-wireup --strict
|
||||
GBRAIN_URL=$(python3 -c "
|
||||
import json, os, sys
|
||||
try:
|
||||
c = json.load(open(os.path.expanduser('~/.gbrain/config.json')))
|
||||
print(c.get('database_url', ''))
|
||||
except Exception:
|
||||
pass
|
||||
")
|
||||
~/.claude/skills/gstack/bin/gstack-gbrain-source-wireup --strict \
|
||||
${GBRAIN_URL:+--database-url "$GBRAIN_URL"}
|
||||
```
|
||||
|
||||
`--strict` exits non-zero on missing prereqs (gbrain not installed, < 0.18.0,
|
||||
|
||||
@@ -372,8 +372,22 @@ federated source on the user's gbrain (Supabase or PGLite), and runs an
|
||||
initial `gbrain sync`. Local-Mac only. No cloud agent required. Subsequent
|
||||
skill runs trigger incremental sync via the existing skill-end push hook.
|
||||
|
||||
Capture the database URL out of `~/.gbrain/config.json` first and pass it
|
||||
explicitly so the wireup is robust against any other process rewriting
|
||||
`~/.gbrain/config.json` mid-sync (e.g., concurrent `gbrain init` runs
|
||||
elsewhere on the machine):
|
||||
|
||||
```bash
|
||||
~/.claude/skills/gstack/bin/gstack-gbrain-source-wireup --strict
|
||||
GBRAIN_URL=$(python3 -c "
|
||||
import json, os, sys
|
||||
try:
|
||||
c = json.load(open(os.path.expanduser('~/.gbrain/config.json')))
|
||||
print(c.get('database_url', ''))
|
||||
except Exception:
|
||||
pass
|
||||
")
|
||||
~/.claude/skills/gstack/bin/gstack-gbrain-source-wireup --strict \
|
||||
${GBRAIN_URL:+--database-url "$GBRAIN_URL"}
|
||||
```
|
||||
|
||||
`--strict` exits non-zero on missing prereqs (gbrain not installed, < 0.18.0,
|
||||
|
||||
Reference in New Issue
Block a user