Who this is for: a junior engineer joining a crew that already uses Team Brain.
Time: about 10 minutes.
You do not need: your own Supabase account, a service_role key, or Docker.
You do need from your admin: invite code, Jira key, and the crew’s Supabase project URL + anon key (placeholders ship in the repo — not a live project).
Workshop demo scripts:
docs/workshop-brainstack-day0.md(local workshop copy — not in the public repo) documentsteam-brain-admin-setup.sh/team-brain-member-setup.shwith demo epicKAN-4. Everything below usesYOU_JIRA_TICKET_HERE(replace with your ticket key).
You and your teammates work on the same Jira ticket (for example YOU_JIRA_TICKET_HERE).
Without Team Brain, each person’s AI starts cold and re-researches the same things.
With Team Brain, the intended loop is:
start <JIRA-KEY> (enter sync mode)remembers findingswake to resumebreakdown turns shared memory into story draftsYour personal career notes (BRAIN.md / engineer-brain) stay private. Team Brain only shares work on the initiative.
| Moment | What should happen |
|---|---|
| You start team work on a ticket | You run start once → memory loads + sync mode on |
| You (or AI) learn something durable | AI saves immediately (remember + source_ref) |
| Same topic, updated finding | Updates that memory (no duplicate / no clobber of other refs) |
| You correct bad research | AI corrects the same source_ref (+ optional learning) |
| Teammate saved something | Background sync merges into your cache/ |
| You step away ~1h | Sync sleeps — AI should ask you to wake |
Enforced strongest in Cursor (team-brain.mdc + skill + optional MCP).
Ask a teammate (crew admin) for secrets (Slack/chat is fine). The Jira key may already be in a committed pin:
| Ask for | Example | Notes |
|---|---|---|
| Invite code | 16 hex chars | From admin’s register / rotate-invite — never in git |
| Supabase URL + anon key | https://….supabase.co + anon JWT |
Crew’s project — local env / project.public.env only |
| Jira key (if no pin) | YOU_JIRA_TICKET_HERE |
Or pull .team-brain/project.json from the product repo (#39) |
| Role (required) | member (read+write+delete) or viewer (read-only) |
Admin tells you which; pass --role on onboard |
Also make sure you have:
brainstack) and/or the product repo with .team-brain/project.jsonengineer-brain sync (setup)curl and jq installed (brew install jq if needed)supabase/project.public.env.example → supabase/project.public.env (or use bootstrap --write-env) with the crew’s URL + anonYou do not need your own Supabase account or the dashboard.
Many crews commit only .team-brain/project.json (Jira key + team name — no anon/api_key/invite):
# In the product workspace (example shape):
cat .team-brain/project.json
# { "default_jira_key": "YOU_JIRA_TICKET_HERE", "team_name": "Spike Crew", … }
Example fixture: examples/team-spike-crew/project.json.
Admin creates/updates the pin with: bash core/scripts/team-brain-api.sh pin set --jira YOU_JIRA_TICKET_HERE --team-name "Spike Crew".
cd /path/to/brainstack
Use the real path on your machine (where you cloned the repo). Work with TEAM_BRAIN_DIR pointing at the product workspace .team-brain/ when the pin lives there.
Edit supabase/project.public.env (or export env / fill .team-brain/team.yaml) with the URL + anon key your admin shared. Leave placeholders → onboard will fail with a clear error. Never put these into project.json.
# Contributor (read + write + delete) — Jira from pin when omitted:
bash core/scripts/team-brain-api.sh onboard INVITE_CODE "Your Name" --role member
# Or explicit Jira + contributor role:
bash core/scripts/team-brain-api.sh onboard INVITE_CODE "Your Name" YOU_JIRA_TICKET_HERE --role member
# Read-only viewer:
bash core/scripts/team-brain-api.sh onboard INVITE_CODE "Your Name" --role viewer
Real example:
bash core/scripts/team-brain-api.sh onboard 9F7AC910 "Ada Junior" YOU_JIRA_TICKET_HERE --role member
Tips:
"Ada Junior"recall / breakdown but not remember / attach / delete (ask admin for set-role … member)bash core/scripts/team-brain-api.sh whoami
bash core/scripts/team-brain-api.sh pin show
You should see JSON with your display_name, team_name, and role (member, viewer, or admin).
Then:
bash core/scripts/team-brain-api.sh status
You should see something like:
TEAM_DIR=.../.team-brainCREDENTIALS=... OKAPI_KEY=setTeam Brain created a folder next to your work (often the parent workspace), for example:
.team-brain/
├── project.json ← commit-safe pin (Jira key / team name) — OK to commit
├── credentials.json ← YOUR secret — never commit or paste in Slack
├── team.yaml ← often has URL+anon locally — do not commit anon
├── cache/
│ └── YOU_JIRA_TICKET_HERE.json ← what agents should read
└── initiatives/
└── YOU_JIRA_TICKET_HERE.md ← optional human-readable export
Safety rule: never commit credentials.json. Never share your api_key. Sharing the invite code with a new teammate is OK.
Use the same Jira key your crew is on.
bash core/scripts/team-brain-api.sh start YOU_JIRA_TICKET_HERE
This:
.team-brain/cache/YOU_JIRA_TICKET_HERE.jsontouch/remember/recall stay activeCheck:
bash core/scripts/team-brain-api.sh sync-status YOU_JIRA_TICKET_HERE
Optional topic search anytime:
bash core/scripts/team-brain-api.sh recall YOU_JIRA_TICKET_HERE "scaffold"
Keep it short and professional (a teammate’s AI will see this). Prefer a stable --source-ref:
bash core/scripts/team-brain-api.sh remember YOU_JIRA_TICKET_HERE research --source-ref "YOU_JIRA_TICKET_HERE#cli-entrypoint" "Found CLI entrypoint in pkg/scaffold — start there for EE schema."
| Kind | When to use |
|---|---|
research |
What you discovered in the code/docs |
decision |
What the team agreed |
note |
Small reminder / link / open question |
Merge rules:
deduped)source_ref, new text → update that memory (updated)source_ref → insertbash core/scripts/team-brain-api.sh breakdown YOU_JIRA_TICKET_HERE
bash core/scripts/team-brain-api.sh stop YOU_JIRA_TICKET_HERE
If sync slept: wake YOU_JIRA_TICKET_HERE (or start again).
watch on long spikesSync mode already pulls while active, but during a long research session you can keep the cache warmer without waiting for idle sleep or the next start:
bash core/scripts/team-brain-api.sh watch YOU_JIRA_TICKET_HERE &
# or with Realtime push (full content, encrypted; falls back to signal+pull without `cryptography`): watch YOU_JIRA_TICKET_HERE --push &
Run it once when the spike gets long — not every command. Cursor agents also refresh via periodic recall (see the team-brain skill); watch is the human/CLI companion. If sync slept, use wake (or start) — watch does not replace sleep/wake.
Only one person does this for a new crew. You need a Supabase account (free tier is fine). Joiners do not.
Fill everything in one place, then run one command:
cd /path/to/brainstack
bash core/scripts/team-brain-admin-setup.sh --init
# edit supabase/admin.setup.env (admin name, crew, Jira epic, Supabase URL + anon)
bash core/scripts/team-brain-admin-setup.sh
supabase/admin.setup.env is gitignored. The script writes runtime files (project.public.env, credentials.json, share bundle, pin).
If migrations cannot auto-apply (no psql), bootstrap stops with SQL Editor instructions — set TEAM_BRAIN_SKIP_MIGRATIONS=true in the same file and re-run after pasting supabase/.bootstrap-migrations.combined.sql.
macOS / no
psql? Use Step 2A (SQL Editor) below — you do not needpsql, Supabase CLI, or--db-url.
https://YOUR_REF.supabase.co)--db-url / psql).| Path | Needs | Best for |
|---|---|---|
| A. SQL Editor | Dashboard only | Default — no local installs |
B. --db-url |
psql (brew install libpq) |
Scripted / CI |
| C. Supabase CLI | supabase link + db push |
Teams already on CLI |
cd /path/to/brainstack
bash core/scripts/team-brain-api.sh bootstrap \
--team "Team Name" --admin "Your Name" \
--url "https://YOUR_REF.supabase.co" \
--anon "eyJ..." \
--jira YOU_JIRA_TICKET_HERE \
--write-env
supabase/.bootstrap-migrations.combined.sql
(all files in supabase/migrations/ in timestamp order — includes delete permissions #66 and pending review #67)
--skip-migrations.psql + --db-url (optional)brew install libpq && brew link --force libpq # once
bash core/scripts/team-brain-api.sh bootstrap \
--team "Team Name" --admin "Your Name" \
--url "https://YOUR_REF.supabase.co" \
--anon "eyJ..." \
--db-url "postgresql://postgres:YOUR_DB_PASSWORD@db.YOUR_REF.supabase.co:5432/postgres" \
--jira YOU_JIRA_TICKET_HERE \
--write-env
One command if psql is on PATH — migrations + register + share bundle.
If you used Step 2A, migrations are already applied — register only:
bash core/scripts/team-brain-api.sh bootstrap \
--team "Team Name" --admin "Your Name" \
--url "https://YOUR_REF.supabase.co" \
--anon "eyJ..." \
--jira YOU_JIRA_TICKET_HERE \
--write-env \
--skip-migrations
Bootstrap prints the share bundle (invite + URL + anon + Jira key). Copy to Slack for joiners (Path A).
Do not commit live URL/anon/DB password.
When members hit overlapping research, they can remember … --queue. You approve or reject from the CLI (dashboard UI: #69):
# Audit crew roles
bash core/scripts/team-brain-api.sh list-members
# Review pending overrides for an initiative
bash core/scripts/team-brain-api.sh pending list YOU_JIRA_TICKET_HERE
# Keep the improved finding (promotes to live memory)
bash core/scripts/team-brain-api.sh pending approve <pending-id> --note "Supersedes prior auth note"
# Discard a duplicate proposal
bash core/scripts/team-brain-api.sh pending reject <pending-id> --note "Use existing source_ref"
Verify migrations: bash core/scripts/team-brain-api.sh doctor should report pending review queue RPC present.
psql) — see supabase/README.md.supabase/project.public.env. Set TEAM_BRAIN_JIRA_SITE.bash core/scripts/team-brain-api.sh register "Team Name" "Your Name"
bash core/scripts/team-brain-api.sh attach YOU_JIRA_TICKET_HERE "Short title" "active" "https://your-org.atlassian.net/browse/YOU_JIRA_TICKET_HERE"
Note: New teams get 16-character invite codes. Only admins see the invite via
register/whoami/ bootstrap share bundle — joiners’credentials.jsondoes not store it.
Goal: one trigger → live merge-safe shared AI context for the ticket → sleep when idle.
| Behavior | Status |
|---|---|
start — one manual entry; load memory + background pull |
✅ |
Merge-safe writes — dedupe identical; update same source_ref |
✅ (apply sync-mode migration) |
| Cache merge — no blind wipe of other memories on pull | ✅ |
Idle sleep + warn — default 1h; wake to resume |
✅ |
| Agent prompts on sleep | ✅ Cursor rule/skill |
| Long-session refresh nudge | ✅ Skill/rule: periodic recall / optional watch (#37); not every turn |
Peer push while sync/watch active |
✅ Signal Broadcast (#31) + poll fallback; needs start or watch once |
Push into open chat with zero start |
❌ Still needs you (or the agent) to enter sync mode once |
Cursor: say “I’m starting on YOU_JIRA_TICKET_HERE — start Team Brain sync.”
The always-on rule expects start → summarize cache → work → remember / touch.
| When | What happens |
|---|---|
| Starting work on the ticket | start JIRA-KEY (once) |
| You / AI learned something durable | remember with source_ref |
| AI got research wrong — you correct it | correct (or re-remember same source_ref) |
| Overlapping research blocked | remember returns redundant_candidate — reuse source_ref or --queue |
| Admin keeps improved finding | pending list → pending approve <pending-id> |
| Keep sync awake | automatic via recall/remember; or touch |
| Long spike / peer freshness | Optional once: watch JIRA-KEY & · agent: periodic recall (not every turn) |
| Sync slept | Prompt → wake JIRA-KEY (not watch) |
| Done for the day | stop JIRA-KEY |
| Planning stories / spikes | breakdown JIRA-KEY |
| “Am I connected?” | whoami / sync-status |
Agents can be wrong. When you paste a correction, the AI should update the matching memory (same source_ref) — not leave a stale row and not invent a second topic slug.
bash core/scripts/team-brain-api.sh correct YOU_JIRA_TICKET_HERE --source-ref "YOU_JIRA_TICKET_HERE#cli-schema" \
--was "Claimed schema lived in tox-ansible" \
"EE schema path lives in packages/ansible-language-server."
Optional --learning "Was wrong: … Prefer: …" writes a learning row at source_ref/learning.
Memory bodies should be natural prefer/avoid guidance — not TODO/NO-TODO lists.
Each source_ref update archives the prior body. Inspect or soft-rollback:
bash core/scripts/team-brain-api.sh history YOU_JIRA_TICKET_HERE --source-ref "YOU_JIRA_TICKET_HERE#cli-schema"
bash core/scripts/team-brain-api.sh restore YOU_JIRA_TICKET_HERE --source-ref "YOU_JIRA_TICKET_HERE#cli-schema" --revision 1
restore keeps the audit trail (current body is archived before rollback).
In Cursor you can say:
Correct Team Brain for YOU_JIRA_TICKET_HERE#cli-schema — the schema is in packages/ansible-language-server, not tox-ansible.
Show Team Brain history for YOU_JIRA_TICKET_HERE#cli-schema and restore revision 1 if needed.
Apply once on the crew Supabase project:
20260802000001_team_brain_learning_kind.sql — learning kind20260803000001_team_brain_memory_history.sql — revisions + history/restoreInstall into your workspace once:
bash install.sh cursor /path/to/your/workspace
That installs:
team-brain.mdc — always-on: recall before research, remember after findings, soft compliance gateteam-brain skill — chat commands (+ compliance / MCP prepare_research)Paste into Cursor chat / Composer (pick one):
I'm starting on YOU_JIRA_TICKET_HERE — start Team Brain sync.
I'm starting on YOU_JIRA_TICKET_HERE — start Team Brain sync, summarize crew memory, then help me.
/team-brain start YOU_JIRA_TICKET_HERE
Other useful lines:
| When | Say this |
|---|---|
| Keep working after a break | Wake Team Brain sync for YOU_JIRA_TICKET_HERE and continue. |
| Done for the day | Stop Team Brain sync for YOU_JIRA_TICKET_HERE. |
| Check state | What's my Team Brain sync-status for YOU_JIRA_TICKET_HERE? |
| Compliance | What's Team Brain compliance for YOU_JIRA_TICKET_HERE? |
| Plan stories | Breakdown YOU_JIRA_TICKET_HERE from Team Brain memory. |
| Fix bad research | Correct Team Brain for YOU_JIRA_TICKET_HERE#<slug> — … |
Then work. After findings the AI should remember (and touch) without you asking.
If compliance.agent_action is set, the agent should follow it before deep research.
If you correct it, it should correct / re-remember the same source_ref.
If sync sleeps, it should ask before continuing.
Personal BRAIN.md stays private — never upload it to Team Brain.
If your team wired the team-brain MCP server, your agent can call attach / remember / recall / breakdown as tools.
Setup: mcp/team-brain/README.md.
Juniors can ignore MCP and use the bash commands or Cursor skill.
| Problem | What to try |
|---|---|
missing dependency: jq |
brew install jq (macOS) |
missing dependency: psql on bootstrap |
Expected on macOS without Postgres. Do not use --db-url. Run bootstrap once (no --db-url) → paste supabase/.bootstrap-migrations.combined.sql in Supabase SQL Editor → re-run with --skip-migrations. Or: brew install libpq && brew link --force libpq. |
function digest(…) does not exist / SQLSTATE 42883 on register/join/onboard |
Admin: apply 20260809000001_fix_tb_anon_fingerprint_digest.sql (or full combined SQL / db push), then retry. Confirm with bash core/scripts/team-brain-api.sh doctor. |
Could not find the function public.register_team / join_team (PGRST202) |
Admin: migrations not applied (or wrong Supabase project). Apply all supabase/migrations/*.sql in order. Also check project.public.env URL matches .team-brain/team.yaml. |
cannot change name of input parameter "p_team_name" (SQL 42P13) on combined SQL |
Migration stopped before 60806 renamed register_team. In SQL Editor run DROP FUNCTION IF EXISTS public.register_team(text, text); then re-run from 20260806000001_team_brain_rate_limits.sql onward (or the full combined file on a fresh project). |
unauthorized / RPC failed |
Re-run whoami. If still broken, ask admin for a fresh invite and onboard again with a new display name |
member already exists |
Pick a different "Your Name" (must be unique on the team) |
initiative not found — attach first |
attach JIRA-KEY or include the key in onboard … KEY |
TEAM_DIR points somewhere weird |
export TEAM_BRAIN_DIR="$PWD/.team-brain" from your workspace, then retry |
Nothing in recall |
Nobody has remember’d yet — add the first finding yourself |
| Afraid you committed secrets | Check git status — credentials.json must stay untracked. If it was committed, tell a senior immediately |
api_key or credentials.json into Slack, PRs, or screenshotscache/ are; md is a convenience exportrecall / breakdown first# Join (admin assigns role)
bash core/scripts/team-brain-api.sh onboard <INVITE> "Your Name" <JIRA-KEY> --role member
# or: ... --role viewer
# Admin: review queued overrides (#67)
bash core/scripts/team-brain-api.sh pending list <JIRA-KEY>
bash core/scripts/team-brain-api.sh pending approve <pending-id>
# Check
bash core/scripts/team-brain-api.sh whoami
bash core/scripts/team-brain-api.sh status
# Work session (CLI)
bash core/scripts/team-brain-api.sh start <JIRA-KEY>
bash core/scripts/team-brain-api.sh sync-status <JIRA-KEY>
bash core/scripts/team-brain-api.sh remember <JIRA-KEY> research --source-ref "<KEY>#slug" "Finding…"
bash core/scripts/team-brain-api.sh breakdown <JIRA-KEY>
bash core/scripts/team-brain-api.sh stop <JIRA-KEY>
# Sleep / wake / long-session freshness
bash core/scripts/team-brain-api.sh wake <JIRA-KEY>
bash core/scripts/team-brain-api.sh touch <JIRA-KEY>
bash core/scripts/team-brain-api.sh watch <JIRA-KEY> & # optional; once per long spike
bash core/scripts/team-brain-api.sh metrics <JIRA-KEY>
bash core/scripts/team-brain-api.sh metrics --team # crew coverage + reuse (#35)
# Or in Cursor chat:
# I'm starting on YOU_JIRA_TICKET_HERE — start Team Brain sync.
# Wake Team Brain sync for YOU_JIRA_TICKET_HERE and continue.
# Stop Team Brain sync for YOU_JIRA_TICKET_HERE.