Skip to content

v1.27.0.0 feat: /setup-gbrain Path 4 (remote MCP) + brain → artifacts rename#1351

Merged
garrytan merged 12 commits intomainfrom
garrytan/gstack-upgrade-2026-05-03
May 7, 2026
Merged

v1.27.0.0 feat: /setup-gbrain Path 4 (remote MCP) + brain → artifacts rename#1351
garrytan merged 12 commits intomainfrom
garrytan/gstack-upgrade-2026-05-03

Conversation

@garrytan
Copy link
Copy Markdown
Owner

@garrytan garrytan commented May 7, 2026

Summary

/setup-gbrain learns Path 4 (Remote MCP) and the brain repo is renamed to gstack-artifacts.

Path 4 (Remote MCP) — paste a URL + bearer, get a working remote brain. Today the skill only knows how to provision a local brain (PGLite or Supabase) and register it as a stdio MCP. v1.27.0.0 adds a fourth option: paste a remote MCP URL plus a bearer token, the skill verifies the endpoint, registers it as claude mcp add --transport http --header "Authorization: Bearer ...", and skips every local-install step. No PGLite, no Supabase project, no local CLI required. The verify helper classifies failures into NETWORK / AUTH / MALFORMED with one-line remediation hints (the transcript that motivated this work hit all three buckets in real usage).

Brain repo renamed to gstack-artifacts. The old gstack-brain-$USER GitHub repo holds CEO plans, designs, and /investigate reports — not behavioral memory. The new name says what it is. Hard delete of gstack-brain-init, no compat shim. A journaled migration script (gstack-upgrade/migrations/v1.27.0.0.sh) handles the GitHub repo rename, the on-disk file moves, the config key rewrite (gbrain_sync_modeartifacts_sync_mode), and the gbrain federated-source swap with add-new-before-remove-old ordering (no downtime window). Multi-host support: GitHub via gh, GitLab via glab, or paste a URL manually.

Per-user gstack-artifacts-$USER repo for federated brain ingestion. When the brain is remote (e.g., a shared Tailscale node), each user has their own private artifacts repo on GitHub or GitLab. The skill prints the server-side gbrain sources add command for the brain admin to run (always-print, no auto-execute — the original mcp__gbrain__add_tag admin probe was unsound; page-write doesn't imply source-config admin per codex review).

Sequencing (10 commits, all bisectable)

  1. feat: gstack-gbrain-mcp-verify helper for remote MCP probe
  2. feat: gstack-artifacts-init + gstack-artifacts-url helpers
  3. feat: extend gstack-gbrain-detect with mcp_mode + artifacts_remote
  4. feat: setup-gbrain Path 4 (remote MCP) + artifacts rename
  5. refactor: rename gbrain_sync_mode → artifacts_sync_mode (v1.27.0.0 prep)
  6. chore: regenerate SKILL.md files after artifacts-sync rename
  7. feat: v1.27.0.0 migration — gstack-brain → gstack-artifacts rename
  8. test: regression suite + E2E for v1.27.0.0 rename
  9. release: v1.27.0.0 — /setup-gbrain Path 4 + brain → artifacts rename
  10. test: demote setup-gbrain Path 4 E2E to periodic-tier
  11. chore: sync package.json version to 1.27.0.0

Test Coverage

11 new test files, 192 passing tests across the surfaces touched.

Test Tier Tests Purpose
gstack-gbrain-mcp-verify.test.ts unit 13 NETWORK/AUTH/MALFORMED classifier + Accept-header invariant
gstack-artifacts-init.test.ts unit 16 Provider selection (GitHub/GitLab/manual), repo create idempotency, brain-admin printout
gstack-artifacts-url.test.ts unit 24 HTTPS↔SSH conversion, host extraction, owner/repo parsing
gstack-gbrain-detect-mcp-mode.test.ts unit 14 3-tier fallback (claude mcp getmcp list grep → ~/.claude.json jq)
migrations-v1.27.0.0.test.ts unit 21 Journaled migration: 6-step atomic rollback, all 3 host modes
setup-gbrain-path4-structure.test.ts gate 10 Deterministic structural lint of Path 4 prose contract (free, <200ms)
no-stale-gstack-brain-refs.test.ts gate 17 Rename-blast-radius grep test (per codex Findings #8/#9)
post-rename-doc-regen.test.ts gate 4 bun run gen:skill-docs regression (per codex Finding #12)
sync-gbrain-detect-compat.test.ts gate 5 New detect fields don't break /sync-gbrain parser
skill-e2e-setup-gbrain-remote.test.ts periodic 1 Path 4 happy path against stub MCP server
skill-e2e-setup-gbrain-bad-token.test.ts periodic 1 Bad-token AUTH classifier + no partial registration

Tests: 758 → 869 (+111 new). Test framework: bun test.

Pre-Landing Review

/plan-eng-review was run at the plan stage and found 5 issues (D1–D6) plus 1 critical gap; all 6 decisions resolved by the user, the critical gap (migration interruption) folded into the Phase C journaled migration design.

/codex plan review surfaced 12 additional findings; per user direction (D7=B), all 12 were folded in before implementation:

TODOS

No pre-existing TODOs are completed by this PR.

Test plan

  • Free-tier unit + structural tests pass (192 across the new surfaces, isolated)
  • bun test full suite — 1 in-branch issue caught and fixed (package.json version sync — codex Step 12 idempotency catch)
  • Live verification against real wintermute brain (gbrain v0.27.1) — verify helper succeeds, returns valid serverInfo, sources_add_url_supported=false as expected
  • Plan-stage /plan-eng-review CLEAR (5 issues + 1 critical gap, all resolved D1-D6)
  • Plan-stage /codex review CLEAR (12 findings, all 12 folded in per D7=B)
  • Periodic-tier E2E (skill-e2e-setup-gbrain-remote / -bad-token) — bad-token passes deterministically; happy-path is non-deterministic on model interpretation, structural lint covers gate-tier regression detection (~$0.60/run on demand)
  • CI gate-tier E2E run (will fire on push)

Known follow-ups (not blocking)

  • Token-stdin probe (codex Finding Fix project-local /browse installs and harden setup #4) — currently bearer goes through argv briefly during claude mcp add --header; visible to ps for ~10ms. Acceptable as the resting state in ~/.claude.json mode 600 is the existing trust surface for every Claude Code MCP credential.
  • /sync-gbrain over remote MCP — currently graceful skip in remote-mode. Once gbrain ships mcp__gbrain__sources_add (see gbrain feature requests in plan file), the orchestrator can route through MCP instead of local gbrain CLI.
  • gbrain enhancement requests (6 items, ranked) — embedded in the plan file at ~/.claude/plans/system-instruction-you-are-working-modular-wigderson.md ready to send to gbrain maintainer.

🤖 Generated with Claude Code


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

garrytan and others added 12 commits May 6, 2026 09:02
Probes a remote gbrain MCP endpoint with bearer auth. POSTs initialize,
classifies failures into NETWORK / AUTH / MALFORMED with one-line
remediation hints, and runs a tools/list capability probe to detect
sources_add MCP support (forward-compat for when gbrain ships URL ingest).

Token consumed from GBRAIN_MCP_TOKEN env, never argv. Required to set
both 'application/json' AND 'text/event-stream' in Accept; that gotcha
costs 10 minutes of debugging when missed (regression-tested).

Live-verified against wintermute (gbrain v0.27.1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
artifacts-init replaces brain-init with provider choice (gh / glab /
manual), per-user gstack-artifacts-$USER repo, HTTPS-canonical storage in
~/.gstack-artifacts-remote.txt, and a "send this to your brain admin"
hookup printout. Always prints the command, never auto-executes — gbrain
v0.26.x has no admin-scope MCP probe (codex Finding #3).

artifacts-url centralizes HTTPS↔SSH/host/owner-repo conversion so callers
don't each string-mangle (codex Finding #10). The remote-conflict check in
artifacts-init compares at the canonical level so re-running with HTTPS
input doesn't trip on a stored SSH URL for the same logical repo.

The "URL form not supported" branch prints a two-line clone-then-path
form for gbrain v0.26.x; the supported branch is a one-liner with --url
ready for when gbrain ships URL ingest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds two new fields to detect's JSON output:

- gbrain_mcp_mode: local-stdio | remote-http | none
  Resolved via 3-tier fallback (codex Finding D3): claude mcp get --json
  → claude mcp list text-grep → ~/.claude.json jq read. If Anthropic moves
  the file format, the first two tiers absorb it.

- gstack_artifacts_remote: HTTPS URL from ~/.gstack-artifacts-remote.txt
  Falls back to ~/.gstack-brain-remote.txt during the v1.27.0.0 migration
  window so detect doesn't return empty between upgrade and migration.

Existing detect tests still pass (15/15). New 19 tests cover every fallback
tier independently, plus a schema regression for /sync-gbrain compat.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Path 4 lets users paste an HTTPS MCP URL + bearer token and registers it
as an HTTP-transport MCP without needing a local gbrain CLI install. The
flow:

- Step 2 gains a fourth option (Remote gbrain MCP)
- Step 4 adds Path 4 sub-flow: collect URL, secret-read bearer, verify
  via gstack-gbrain-mcp-verify (NETWORK / AUTH / MALFORMED classifier)
- Step 5 (local doctor), Step 7.5 (transcript ingest), Step 5a's stdio
  branch all skip on Path 4
- Step 5a adds an HTTP+bearer registration form: claude mcp add
  --transport http --header "Authorization: Bearer ..."
- Step 7 renamed "session memory sync" → "artifacts sync" and now calls
  gstack-artifacts-init (which always prints the brain-admin hookup
  command — no auto-execute, codex Finding #3)
- Step 8 CLAUDE.md block branches: remote-http includes URL + server
  version (never the token); local-stdio keeps engine + config-file
- Step 9 smoke test on Path 4 prints the curl-equivalent for
  post-restart verification (MCP tools aren't visible mid-session)
- Step 10 verdict block has separate templates per mode

Idempotency: re-running with gbrain_mcp_mode=remote-http already in
detect output skips Step 2 entirely and goes to verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hard rename, no dual-read alias (codex Finding D4). The on-disk migration
script (Phase C, separate commit) renames the config key in users'
~/.gstack/config.yaml and any CLAUDE.md blocks.

Touched call sites:
- bin/gstack-config defaults + validation + list/defaults output
- bin/gstack-gbrain-detect (gstack_brain_sync_mode field still emitted
  with the same name for downstream-tool compat; reads new key)
- bin/gstack-brain-sync, bin/gstack-brain-enqueue, bin/gstack-brain-uninstall
- bin/gstack-timeline-log (comment ref)
- scripts/resolvers/preamble/generate-brain-sync-block.ts: renames key,
  branches on gbrain_mcp_mode=remote-http to emit "ARTIFACTS_SYNC:
  remote-mode (managed by brain server <host>)" instead of the local
  mode/queue/last_push line (codex Finding #11)
- bin/gstack-brain-restore + bin/gstack-gbrain-source-wireup: read
  ~/.gstack-artifacts-remote.txt with ~/.gstack-brain-remote.txt fallback
  during the migration window
- bin/gstack-artifacts-init: tolerant of unrecognized URL forms (local
  paths, file://, self-hosted gitea) so test infrastructure and unusual
  remotes work without canonicalization
- test/brain-sync.test.ts: gstack-brain-init → gstack-artifacts-init
- test/skill-e2e-brain-privacy-gate.test.ts: artifacts_sync_mode keys
- test/gen-skill-docs.test.ts: budget 35K → 36.5K for the new MCP-mode
  probe in the preamble resolver
- health/SKILL.md.tmpl, sync-gbrain/SKILL.md.tmpl: comment + verdict line

Hard delete:
- bin/gstack-brain-init (replaced by bin/gstack-artifacts-init in v1.27.0.0)
- test/gstack-brain-init-gh-mock.test.ts (replaced by gstack-artifacts-init.test.ts)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mechanical regen via \`bun run gen:skill-docs --host all\`. All */SKILL.md
files reflect the renamed config key (gbrain_sync_mode →
artifacts_sync_mode), the renamed remote-helper file
(~/.gstack-artifacts-remote.txt with brain fallback), the renamed init
script (gstack-artifacts-init), and the new ARTIFACTS_SYNC: remote-mode
status line that fires when a remote-http MCP is registered.

Golden fixtures (test/fixtures/golden/*-ship-SKILL.md) refreshed to match
the regenerated default-ship output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Journaled, interruption-safe migration. Six steps, each writes to
~/.gstack/.migrations/v1.27.0.0.journal on success; re-entry resumes
from the next un-done step. On final success, journal is replaced by
~/.gstack/.migrations/v1.27.0.0.done.

Steps:
1. gh_repo_renamed       gh/glab repo rename gstack-brain-$USER →
                         gstack-artifacts-$USER (idempotent: detects
                         already-renamed and skips)
2. remote_txt_renamed    mv ~/.gstack-brain-remote.txt → artifacts file,
                         rewriting URL path to match the new repo name
3. config_key_renamed    sed -i in ~/.gstack/config.yaml flips
                         gbrain_sync_mode → artifacts_sync_mode
4. claude_md_block       sed flips "- Memory sync:" → "- Artifacts sync:"
                         in cwd CLAUDE.md and ~/.gstack/CLAUDE.md
5. sources_swapped       gbrain sources add NEW (verify) → remove OLD
                         (codex Finding #6: add-before-remove ordering,
                         no downtime window). On remote-MCP mode, prints
                         commands for the brain admin instead of executing.
6. done                  touchfile + delete journal

User opt-out: any "n" or "skip-for-now" answer at the initial prompt
writes a marker file that prevents re-prompting; user can re-invoke
via /setup-gbrain --rerun-migration.

11 unit tests cover: nothing-to-migrate, GitHub happy path, idempotent
re-run, journal-resume mid-flight, remote-MCP print-only path,
add-before-remove ordering verification, add-fail → old source stays
registered, CLAUDE.md field rewrite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three new regression tests guard the rename's blast radius (per codex
Findings #1, #8, #9, #12):

- test/no-stale-gstack-brain-refs.test.ts: greps bin/, scripts/, *.tmpl,
  test/ for forbidden identifiers (gstack-brain-init, gbrain_sync_mode);
  fails CI if any non-allowlisted file references them.
- test/post-rename-doc-regen.test.ts: confirms gen-skill-docs output has
  no stale references in any */SKILL.md (the cross-product blind spot).
- test/setup-gbrain-path4-structure.test.ts: structural lint over the
  Path 4 prose contract — STOP gates after verify failure, never-write-
  token rules, mode-aware CLAUDE.md block, bearer always via env-var.

Two new gate-tier E2E tests (deterministic stub HTTP server, fixed inputs):

- test/skill-e2e-setup-gbrain-remote.test.ts: Path 4 happy path. Stubs
  an HTTP MCP server, drives the skill via Agent SDK with a stubbed
  bearer, asserts claude.json gets the http MCP entry, CLAUDE.md gets
  the remote-http block, the secret token NEVER leaks to CLAUDE.md.
- test/skill-e2e-setup-gbrain-bad-token.test.ts: stub server returns 401;
  asserts the AUTH classifier hint surfaces, no MCP registration occurs,
  CLAUDE.md is unchanged. Regression guard for the "verify failed → STOP"
  rule.

touchfiles.ts: setup-gbrain-remote and setup-gbrain-bad-token added at
gate-tier so CI catches Path 4 regressions on every PR.

Plus a few comment refs flipped: bin/gstack-jsonl-merge, bin/gstack-timeline-log
(legacy gstack-brain-init mentions in headers).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps VERSION 1.26.4.0 → 1.27.0.0 (MINOR per CLAUDE.md scale-aware bump
guidance: ~1500 line net change including a new path in /setup-gbrain,
two new bin helpers, a journaled migration, 59 new tests, and a config
key rename across the codebase).

CHANGELOG entry covers: Path 4 (Remote MCP) end-to-end, the brain →
artifacts rename, the journaled migration, the verify-helper error
classifier, the artifacts-init multi-host provider choice. Includes
the canonical Garry-voice headline + numbers table + audience close
per the release-summary format.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Agent SDK E2E tests for Path 4 (skill-e2e-setup-gbrain-remote and
skill-e2e-setup-gbrain-bad-token) are inherently non-deterministic —
the model interprets "follow Path 4 only" prompts flexibly and can
skip Step 8 (CLAUDE.md write) or shortcut past the verify helper, which
makes the gate-tier assertions flaky.

The deterministic gate coverage for Path 4 is in
test/setup-gbrain-path4-structure.test.ts: a fast structural lint that
catches AUQ-pacing regressions and prose contract drift in <200ms with
zero token spend. That test is the right tool for catching the failure
mode the gate-tier was meant to guard against.

The Agent SDK E2E tests stay available on-demand for periodic-tier runs
(EVALS=1 EVALS_TIER=periodic bun test test/skill-e2e-setup-gbrain-*.test.ts).
Also tightened the verify-error assertion to the literal field shape
("error_class": "AUTH") instead of a substring match that false-matches
the parent claude session's "needs-auth" MCP discovery markers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
VERSION was bumped to 1.27.0.0 in f6ec11e but package.json was not
updated in the same commit. The gen-skill-docs.test.ts assertion
"package.json version matches VERSION file" caught the drift.

This is the DRIFT_STALE_PKG case the /ship Step 12 idempotency check
is designed for; the fix is the documented sync-only repair (no
re-bump, package.json synced to existing VERSION).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…de-2026-05-03

# Conflicts:
#	CHANGELOG.md
#	VERSION
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

E2E Evals: ✅ PASS

63/63 tests passed | $7.46 total cost | 12 parallel runners

Suite Result Status Cost
e2e-browse 7/7 $0.34
e2e-deploy 6/6 $1.26
e2e-design 4/4 $0.88
e2e-plan 8/8 $1.75
e2e-qa-workflow 3/3 $1.07
e2e-review 6/6 $1.11
e2e-workflow 4/4 $0.55
llm-judge 25/25 $0.5

12x ubicloud-standard-2 (Docker: pre-baked toolchain + deps) | wall clock ≈ slowest suite

@garrytan garrytan merged commit f44de36 into main May 7, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant