v1.12.0.0 feat: /setup-gbrain — coding-agent onboarding for gbrain#1183
Merged
v1.12.0.0 feat: /setup-gbrain — coding-agent onboarding for gbrain#1183
Conversation
Per-remote trust-tier store for the forthcoming /setup-gbrain skill. Tiers are the D3 triad (read-write / read-only / deny), keyed by a normalized remote URL so ssh-shorthand and https variants collapse to the same entry. The file carries _schema_version: 2 (D2-eng); legacy `allow` values from pre-D3 experiments auto-migrate to `read-write` on first read, idempotent, with a one-shot log line. Pure bash + jq to match the existing gstack-brain-* family. Atomic writes via tmpfile + rename. Policy file mode 0600. Corrupt files quarantine to .corrupt-<ts> and start fresh. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 tests covering normalize (ssh/https/shorthand/uppercase collapse to one key), set/get round-trip, all three D3 tiers accepted, invalid tiers rejected, file mode 0600, _schema_version field written on fresh files, legacy allow migration (including idempotence and preservation of non-allow entries), corrupt-JSON quarantine + fresh-file recovery, list output sorting, and get-without-arg auto-detect against a git repo with no origin. All tests green against a per-test tmpdir GSTACK_HOME so nothing leaks into the real ~/.gstack. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pure-introspection JSON emitter for the /setup-gbrain skill's start-up branching. Reports: gbrain presence + version on PATH, ~/.gbrain/config.json existence + engine, `gbrain doctor --json` health (wrapped in timeout 5s to match the /health D6 pattern), gstack-brain-sync mode via gstack-config, and ~/.gstack/.git presence for the memory-sync feature. Never modifies state. Always emits valid JSON even when every check is false. Handles malformed ~/.gbrain/config.json without crashing — gbrain_engine is null in that case, not an error. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…D19 PATH-shadow guard Clones gbrain at a pinned commit (v0.18.2) and registers it via `bun link`. Before any clone: D5 detect-first — probes ~/git/gbrain, ~/gbrain, and the install target for a valid pre-existing clone (package.json with name "gbrain" and bin.gbrain set). If one is found, `bun link` runs there instead of cloning a second copy. Prevents the day-one duplicate-install footgun on the skill author's own machine. After install: D19 PATH-shadow guard — reads the install-dir's package.json version, compares to `gbrain --version` on PATH. On mismatch: exits 3, prints every gbrain binary on PATH via `type -a`, and gives a remediation menu. Setup skills refuse broken environments instead of warning and continuing. Prereq checks (bun, git, https://github.com reachability) fail fast with install hints. --dry-run and --validate-only flags let the skill probe the plan without touching state; tests use them to cover D5 and D19 without exercising real bun link. Pin is a load-bearing version: setup-gbrain v1 verified against gbrain v0.18.2. Updating requires re-running Pre-Impl Gate 1 to verify gbrain's CLI + config shapes haven't drifted. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
15 tests covering: detect emits valid JSON when nothing configured, reports gstack_brain_git on GSTACK_HOME/.git presence, reads ~/.gbrain/config.json engine, tolerates malformed config, detects a mocked gbrain binary on PATH with version parsing. For install: D5 detect-first uses ~/git/gbrain fixtures under a sandboxed HOME, verifies fall-through to fresh clone when no valid clone exists, rejects invalid package.json shapes. D19 PATH-shadow validation uses a fake gbrain on a minimal SAFE_PATH to simulate version mismatch, same-version-pass, v-prefix tolerance, missing binary on PATH, and missing version field in package.json. --validate-only mode in the install bin makes the D19 check unit- testable without running real bun link (which touches ~/.bun/bin). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…(D3-eng) Shared secret-read helper for PAT (D11) and pooler URL paste (D16). One implementation of the hardest-to-get-right pattern: stty -echo + SIGINT/TERM/EXIT trap that restores terminal mode, read into a named env var, optional redacted preview. Validates the target var name against [A-Z_][A-Z0-9_]* to prevent bash name-injection via `read -r "$varname"`. When stdin is not a TTY (CI, piped tests) the stty branches skip cleanly — piped input doesn't echo anyway. Exports the var after read so subprocesses inherit it; callers own the `unset` at handoff time. Sourced, not executed — no +x bit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…check
Zero-network validator for Supabase Session Pooler URLs before handing
them to `gbrain init`. Canonical shape verified per gbrain init.ts:266:
postgresql://postgres.<ref>:<password>@aws-0-<region>.pooler.supabase.com:6543/postgres
Rejects direct-connection URLs (db.*.supabase.co:5432) with a distinct
exit code 3 and clear IPv6-failure remediation — that's the most common
paste mistake users make, so it earns its own UX path rather than a
generic "bad URL" error.
Never echoes the URL (contains a password) in error messages; tests
verify a distinct seed password never appears in stderr on any reject
path. Accepts URL from argv[1] or stdin ("-" or no arg).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lper 22 tests. verify: accepts canonical pooler URL (argv + stdin modes), rejects direct-connection URL with exit 3, rejects wrong scheme, wrong port, empty password, missing userinfo, plain 'postgres' user (catches direct-URL paste errors), wrong host, empty URL. Case-insensitive host match. Explicit negative: error messages never echo the URL password. lib.sh read_secret_to_env: reads piped stdin into the named env var, exports to subprocesses, redacted-preview emits masked form on stderr with the seed password absent, rejects invalid var names (lowercase, leading digit, hyphens), rejects missing/unknown flags, secret value never appears on stdout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…PI wrapper
Four subcommands: list-orgs, create, wait, pooler-url. Built against
the verified Supabase Management API shape (Pre-Impl Gate 1):
- POST /v1/projects with {name, db_pass, organization_slug, region}
— not the original plan's /v1/organizations/{ref}/projects
- No `plan` field; subscription tier is org-level per the OpenAPI
description ("Subscription Plan is now set on organization level
and is ignored in this request")
- GET /v1/projects/{ref}/config/database/pooler for pooler config
— not /config/database
Secrets discipline: SUPABASE_ACCESS_TOKEN (PAT) and DB_PASS read from
env only, never from argv (D8 grep test enforces this). `set +x` at
the top as a defensive default so debug tracing never leaks secrets.
Management API hostname hardcoded to SUPABASE_API_BASE env override —
no user-controlled URL portion (SSRF guard).
HTTP error paths: 401/403 → exit 3 (auth), 402 → 4 (quota), 409 → 5
(conflict), 429 + 5xx → exponential-backoff retry up to 3 attempts,
then exit 8. Wait subcommand polls every 5s until ACTIVE_HEALTHY
with a configurable timeout; terminal states (INIT_FAILED, REMOVED,
etc.) exit 7 immediately with a clear message. Timeout emits the
--resume-provision hint so the skill can recover.
Pooler-url constructs the URL locally from db_user/host/port/name +
DB_PASS rather than trusting the API response's connection_string
field, which is templated with [PASSWORD] rather than the real value.
Handles both object and array response shapes, preferring session
pool_mode when Supabase returns multiple pooler configs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ia mock API 22 tests covering D21 HTTP error suite (401/403/402/409/429/5xx) and happy paths for all four subcommands. Every test spins up a Bun.serve mock server bound to SUPABASE_API_BASE so nothing hits the real API. Uses Bun.spawn (async) rather than spawnSync because spawnSync blocks the Bun event loop, which prevents Bun.serve mocks from responding — calls would hit curl's own timeout instead of round-tripping. Verifies: POST body contains organization_slug (not organization_id) and no `plan` field, bearer-token auth header, retry-on-429 with eventual success, exit-8 on persistent 5xx after max retries, wait succeeds on ACTIVE_HEALTHY, exits 7 on INIT_FAILED, exits 6 with --resume-provision hint on timeout, pooler-url builds URL locally from db_user/host/port/name + DB_PASS (not response connection_string template), handles array pooler responses. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Stitches together every slice built so far (repo-policy, detect, install, lib.sh secret helper, supabase-verify, supabase-provision) into a single interactive flow. Paths: Supabase existing-URL, Supabase auto-provision (D7), Supabase manual, PGLite local, switch (PGLite ↔ Supabase via gbrain migrate wrapped in timeout 180s per D9). Secrets discipline per D8/D10/D11: PAT + DB_PASS + pooler URL all read via read_secret_to_env from lib.sh and handed to gbrain via GBRAIN_DATABASE_URL env, never argv. PAT carries the full D11 scope disclosure before collection and an explicit revocation reminder after success. D12 SIGINT recovery prints the in-flight ref + resume command. D18 MCP registration is scoped honestly to Claude Code — skips with a manual-register hint when `claude` is not on PATH. D6 per-remote trust-triad question (read-write/read-only/deny/skip-for-now) gates repo import; the triad values compose with the D2-eng schema-version policy file so future migrations stay deterministic. Skill runs concurrent-run-locked via mkdir ~/.gstack/.setup-gbrain.lock.d (atomic, same pattern as gstack-brain-sync). Telemetry (D4) payload carries enumerated categorical values only — never URL, PAT, or any postgresql:// substring. --repo, --switch, --resume-provision, --cleanup-orphans shortcut modes documented inline; the skill parses its own invocation args. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a GBrain row to the /health dashboard rubric with weight 10%. Three sub-signals rolled into one 0-10 score: doctor status (0.5), sync queue depth (0.3), last-push age (0.2). Redistributes when gbrain_sync_mode is off so the dimension stays fair. Weights rebalance: typecheck 25→22, lint 20→18, test 30→28, deadcode 15→13, shell 10→9, gbrain +10 — sums to 100. gbrain doctor --json wrapped in timeout 5s so a hung gbrain never stalls the /health dashboard. Dimension is omitted (not red) when gbrain is not installed — running /health on a non-gbrain machine shouldn't penalize that choice. History-JSONL adds a `gbrain` field. Pre-D6 entries read as null for trend comparison; new tracking starts from first post-D6 run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…D21 #5) Runs a subprocess with a seeded secret, captures every channel the subprocess could leak through, and asserts the seed never appears. Built per the D1-eng tightened contract: per-run tmp $HOME, four seed match rules (exact + URL-decoded + first-12-char prefix + base64), fd-level stdout/stderr capture via Bun.spawn, post-mortem walk of every file written under $HOME, separate buckets for telemetry JSONL. Reusable: any future skill that handles secrets can import runWithSecretSink and run positive/negative controls against its own bins. The harness itself is ~180 lines of TS with no external deps beyond Bun + node:fs. Out of scope for v1 (documented as follow-ups): subprocess env dump (portable /proc reading), the user's real shell history (bins don't modify it). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
11 tests. Positive controls deliberately leak a seed in every covered
channel (stdout, stderr, a file under $HOME, the telemetry JSONL path,
base64-encoded, first-12-char prefix) and assert the harness catches
each one. Without these, a harness that silently under-reports would
look identical to a harness that works.
Negative controls run real setup-gbrain bins with distinctive seeds:
- supabase-verify rejects a mysql:// URL and a direct-connection URL,
password never appears in any captured channel
- lib.sh read_secret_to_env reads piped stdin, emits only the length,
seed value stays invisible
- supabase-provision on an auth-failure path fails fast without
leaking the PAT to any channel
Covers D21 #5 leak harness + uses it to validate D3-eng, D10, D11
discipline end-to-end on the already-shipped bins.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Powers /setup-gbrain --cleanup-orphans. list-orphans filters the
authenticated user's Supabase projects by name prefix (default
"gbrain") and excludes the project the local ~/.gbrain/config.json
currently points at, so only unclaimed gbrain-shaped projects come
back. Active-ref detection parses the pooler URL's user portion
(postgres.<ref>:<pw>@...).
delete-project is a thin DELETE /v1/projects/{ref} wrapper with no
confirmation of its own — the skill's UI layer owns the per-project
confirm AskUserQuestion loop. Keeps responsibilities clean: the bin
manages HTTP; the skill manages user intent.
Both subcommands reuse the existing api_call retry+backoff and the
same PAT discipline (env only, never argv).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t 404
6 new tests bringing the supabase-provision suite to 28:
list-orphans:
- Filters to gbrain-prefixed projects, excludes the active-ref derived
from ~/.gbrain/config.json's pooler URL
- Treats all gbrain-prefixed projects as orphans when no config exists
(first run on a new machine)
- Respects custom --name-prefix for users who named their brain
something else
delete-project:
- Happy path sends DELETE /v1/projects/<ref> and returns {deleted_ref}
- 404 surfaces cleanly (exit 2, "404" in stderr)
- Missing <ref> positional rejected with exit 2
Uses per-test tmpdir HOME with a stubbed ~/.gbrain/config.json so
active-ref extraction runs against deterministic fixtures.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ships /setup-gbrain and its supporting infrastructure end-to-end: per-remote trust policy, installer with PATH-shadow guard, shared secret-read helper, structural URL verifier, Supabase Management API wrapper, /health GBrain dimension, secret-sink test harness. 100 new tests across 5 suites, all green. Three pre-existing test failures noted as P0 in TODOS.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
E2E Evals: ❌ FAIL63/64 tests passed | $8.45 total cost | 12 parallel runners
12x ubicloud-standard-2 (Docker: pre-baked toolchain + deps) | wall clock ≈ slowest suite Failures
|
README changes: - Rewrote the "Cross-machine memory with GBrain sync" section into "GBrain — persistent knowledge for your coding agent." Covers the three /setup-gbrain paths (Supabase existing URL, auto-provision, PGLite local), MCP registration, per-remote trust triad, and the (still-separate) memory sync feature. - Added /setup-gbrain row to the skills table pointing at the full guide. - Added /setup-gbrain to both skill-list install snippets. - Added USING_GBRAIN_WITH_GSTACK.md to the Docs table. New doc (USING_GBRAIN_WITH_GSTACK.md): - All three setup paths with trust-surface caveats - MCP registration details (and honest Claude-Code-v1 scoping) - Per-remote trust triad semantics + how to change a policy - Switching engines (PGLite ↔ Supabase) via --switch - GStack memory sync + its relationship to the gbrain knowledge base - /setup-gbrain --cleanup-orphans for orphan Supabase projects - Full command + flag reference, every bin helper, every env var - Security model: what's enforced in code, what's enforced by the leak harness, and the honest limits of v1 - Troubleshooting: PATH shadowing, direct-connection URL reject, auto-provision timeout, stale lock, policy file hand-edits, migrate hang - Why-this-design section explaining the non-obvious choices Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ns in JSON
The bearer-token-json regex value charset was [A-Za-z0-9_./+=-]{16,},
which does NOT permit spaces. Real HTTP auth headers embed the scheme
name with a literal space — "Bearer <token>" — so the value portion
actually starts with "Bearer " and the existing regex couldn't match.
Result: any JSON blob containing "authorization":"Bearer ..." would
slip past the scanner and sync to the user's private brain repo with
the bearer token inline.
Added optional (Bearer |Basic |Token )? prefix in front of the value
charset. Now matches the common auth-scheme forms without broadening
the matcher to tolerate arbitrary whitespace (which would false-positive
on lots of benign JSON).
Verified against 5 positive cases (bearer-in-json, clean bearer, apikey
no-prefix, token with Bearer, password no-prefix) + 3 negative cases
(too-short tokens, non-secret field names like username, random JSON).
This closes the P0 security regression first noticed during v1.12.0.0
/ship. brain-sync.test.ts now passes all 7 secret-scan fixtures.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8 tests covering the gh-repo-create happy path that had zero coverage
before. Existing brain-sync.test.ts always passes --remote <bare-url>
to bypass gh entirely, so the interactive default ("press Enter, we'll
run gh repo create for you") was shipping on trust.
Test strategy: write a bash stub for gh that records every call into
a file, then run gstack-brain-init with that stub on PATH. Assertions
verify: gh auth status is checked, gh repo create fires with the
computed gstack-brain-<user> default name + --private + --source
flags, fall-through to gh repo view when create reports already-exists,
user-provided URL bypasses gh entirely, gh-not-on-path and gh-not-authed
branches both prompt for URL, --remote flag short-circuits all gh
calls, conflicting-remote re-runs exit 1 with a clear message.
No real GitHub, no live auth. Gate tier — runs on every commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… tier)
Two periodic-tier E2E tests exercising the preamble's privacy gate
end-to-end via the Agent SDK + canUseTool. Previously uncovered:
- Positive: stages a fake gbrain on PATH + gbrain_sync_mode_prompted=false
in config, runs a real skill, intercepts tool-use. Asserts the
preamble fires a 3-option AskUserQuestion matching the canonical
prose ("publish session memory" / "artifact" / "decline") and does
NOT fire a second time in the same run (idempotency within session).
- Negative: same staging but prompted=true. Asserts the gate stays
silent even with gbrain detected on the host.
Registered in test/helpers/touchfiles.ts as `brain-privacy-gate`
(periodic) with dependency tracking on generate-brain-sync-block.ts,
the three gstack-brain-* bins, gstack-config, and the Agent SDK runner.
Diff-based selection re-runs the E2E when any of those change.
Cost: ~$0.30-$0.50 per run. Only fires under EVALS=1 EVALS_TIER=periodic;
gate tier stays free.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Moves the bearer-json secret-scan regression from the P0 "pre-existing failures" block into the Completed section with full context on the fix, the mock-gh tests, the E2E privacy-gate tests, and the touchfile registration. Remaining P0s are the GSTACK_HOME config-isolation bug and the stale Opus 4.7 overlay pacing assertion, both unrelated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two fixes to get the E2E actually running end-to-end (first attempt failed at the SDK auth step, second at the assertion step): 1. Don't pass an explicit `env:` object to runAgentSdkTest. The SDK's auth pipeline misses ANTHROPIC_API_KEY when env is supplied as an object (verified against the plan-mode-no-op test, which passes no env and auths cleanly). Mutate process.env before the call instead, and restore the originals in finally so other tests don't inherit the ambient mutation. 2. The "Run /learn with no arguments" user prompt was too narrow — the model reduced it to a direct action and skipped the preamble privacy-gate directives entirely, so zero AskUserQuestions fired. Mirror the plan-mode-no-op pattern: point the model at the skill file on disk and ask it to follow every preamble directive. Bumped maxTurns from 6 to 10 to give the preamble room to execute. Verified both tests pass under `EVALS=1 EVALS_TIER=periodic bun test test/skill-e2e-brain-privacy-gate.test.ts` against a real ANTHROPIC_API_KEY. Cost per run: ~$0.30-$0.50 per test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…evals Conductor workspaces don't inherit the interactive shell env, so both API keys are absent from the default process env even though they're set in ~/.zshrc. Documents the source-from-zshrc pattern (grep + eval, never echo the value) plus the Agent SDK gotcha: do NOT pass env as an object to runAgentSdkTest — mutate process.env ambiently and restore in finally. Discovered this during the brain-privacy-gate E2E. First run failed at SDK auth with 401; second failed because explicit env handoff bypassed the SDK's own auth routing. Fix pattern now codified so the next paid-eval session in a Conductor workspace doesn't hit the same two dead ends. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New
/setup-gbrainskill + 6 new bins + /health integration + reusable leak-test harness. Closes the gbrain onboarding gap: fresh Claude Code users go from zero to "gbrain is running, and my agent can call it" in under five minutes, with three paths (Supabase existing URL, Supabase auto-provision via Management API, PGLite local), MCP registration for Claude Code, and a per-remote trust triad so multi-client consultants don't mingle brains.Key decisions:
/plan-ceo-review. 5 scope expansions accepted (trust-triad, telemetry, detect-existing-clone, /health integration, Supabase auto-provision via Management API). 21 D-decisions total across CEO + Codex outside-voice + Eng review.POST /v1/projectsnot/v1/organizations/{ref}/projects;/config/database/poolernot/config/database). Codex found these; Pre-Impl Gate closed them before code.Test Coverage
100 new tests across 5 suites, 100% green:
gbrain-repo-policy.test.tsallow→read-writemigration,_schema_version: 2, corrupt-file quarantinegbrain-detect-install.test.tsgbrain-lib-verify.test.tsread_secret_to_envstdin + env handoff + redacted preview;supabase-verifyrejects direct-connection URLs w/ exit 3gbrain-supabase-provision.test.tsplan); pooler URL construction; list-orphans active-ref filtering; delete-projectsecret-sink-harness.test.tsCoverage on new code: ~95% per the Step 7 diagram. E2E periodic tier (claude -p flows) is follow-up scope.
Pre-Landing Review
CEO + Codex outside-voice + Eng reviews all ran in plan mode before any code. Findings → fixes:
read -s+ redacted preview.us-east-1.08b3698e(v0.18.2)._schema_version: 2added.bin/gstack-gbrain-lib.sh.No remaining critical gaps. Review log at
~/.gstack/projects/garrytan-gstack/garrytan-create-gbrain-skill-reviews.jsonl.Plan Completion
All 21 D-decisions implemented. Plan file at
~/.claude/plans/system-instruction-you-are-working-ethereal-bubble.mdand CEO plan at~/.gstack/projects/garrytan-gstack/ceo-plans/2026-04-23-setup-gbrain.md.TODOS
Added one P0 entry for three pre-existing test failures surfaced during this ship (pre-existing on bare main, not caused by this branch):
gstack-config gbrain keys > GSTACK_HOME overrides real config dirgstack-brain-sync secret scan > blocks bearer-jsonOpus 4.7 overlay — pacing directive > keeps Fan out nudgesEach deserves individual triage rather than green-washing. Third one is a stale test vs a real scanner regression — worth investigating before any more memory-sync work lands.
Follow-ups (in the plan, not this PR)
claude -p(stub-gbrain harness exists; wiring is its own PR)Test plan
bun test test/gbrain-repo-policy.test.ts— 24 passbun test test/gbrain-detect-install.test.ts— 15 passbun test test/gbrain-lib-verify.test.ts— 22 passbun test test/gbrain-supabase-provision.test.ts— 28 pass (Bun.serve mock server)bun test test/secret-sink-harness.test.ts— 11 pass (6 positive + 4 negative + 1 clean)bun run gen:skill-docs --host all— clean regeneration, no token-ceiling violations on setup-gbrain/setup-gbrainpath 3 (PGLite) on a fresh machine — install + init + MCP register + smoke test/setup-gbrainpath 1 (Supabase existing URL) against a throwaway project — verify redacted preview, env-var handoff/setup-gbrainpath 2a (auto-provision) against a throwaway Supabase account — verify PAT disclosure, cleanup-orphans~/git/gbrain— D5 detect-first reuses instead of duplicatingDocumentation
Updated for v1.12.0.0's /setup-gbrain:
Follow-up commits (after initial ship)
bin/gstack-brain-syncPython scanner's value charset did not permit spaces, so auth headers with the standardBearer <token>form (literal space after the scheme name) slipped past. Added an optional(Bearer |Basic |Token )?prefix. The 7-pattern secret-scan test suite now passes cleanly including bearer-json. This closes a real leak path that was shipping through recent /ship runs via green-wash.gstack-brain-init's auto-create path (test/gstack-brain-init-gh-mock.test.ts, 8 tests, gate tier). Existing tests always bypassed gh via--remote <bare-url>; now a fake gh stub on PATH records every call so we assertgh repo create --private --description ... --source $GSTACK_HOMEfires with the right args. Covers happy path, already-exists fall-through, user-URL bypass, gh-missing + gh-not-authed branches, idempotent re-runs, conflicting-remote rejection.test/skill-e2e-brain-privacy-gate.test.ts, periodic tier). Uses the Agent SDK + canUseTool to drive a real skill with a fake gbrain on PATH + stagedgbrain_sync_mode_prompted=false, intercepts tool-use, asserts the 3-option AskUserQuestion fires with canonical prose and does not fire twice in one session. Negative twin asserts the gate stays silent when prompted=true.brain-privacy-gatein touchfiles.ts with dependency tracking on generate-brain-sync-block.ts, gstack-brain-sync, gstack-brain-init, gstack-config, and the Agent SDK runner. Diff-based test selection re-runs the E2E whenever any of those change.🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com