# Team Brain — beginner onboarding

**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) documents **`team-brain-admin-setup.sh`** / **`team-brain-member-setup.sh`** with demo epic **`KAN-4`**. Everything below uses **`YOU_JIRA_TICKET_HERE`** (replace with your ticket key).

---

## What is Team Brain? (30 seconds)

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:

1. **You trigger once** — `start <JIRA-KEY>` (enter **sync mode**)  
2. **Crew memory loads** — cache fills; your AI summarizes, *then* digs into code  
3. **While sync is active** — background pull stays merge-safe; AI `remember`s findings  
4. **Idle ~1h** — sync goes to **sleep** (you’ll be prompted); `wake` to resume  
5. **Planning** — `breakdown` turns shared memory into story drafts  

Your personal career notes (`BRAIN.md` / engineer-brain) stay **private**. Team Brain only shares work on the initiative.

### Context-first (what you should feel)

| 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 **`correct`s** 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).

---

## Before you start — checklist

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:

- [ ] This repo cloned (`brainstack`) **and/or** the product repo with `.team-brain/project.json`
- [ ] **Atlassian MCP** for Jira — required if you use `engineer-brain sync` ([setup](engineer-brain-onboarding.md#step-3--atlassian-mcp-jira--required))
- [ ] A terminal (macOS Terminal, iTerm, VS Code/Cursor terminal)
- [ ] `curl` and `jq` installed (`brew install jq` if needed)
- [ ] Copy `supabase/project.public.env.example` → `supabase/project.public.env` (or use `bootstrap --write-env`) with the crew’s URL + anon

You do **not** need your own Supabase account or the dashboard.

---

## Path A — Join an existing team (most juniors)

### Step 0 — Pull the commit-safe pin (when the product repo has one)

Many crews commit **only** `.team-brain/project.json` (Jira key + team name — **no** anon/api_key/invite):

```bash
# 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](../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"`.

### Step 1 — Open a terminal in the right place

```bash
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.

### Step 1b — Point at the crew’s Supabase project (secrets — not in the pin)

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`.

### Step 2 — Run one onboard command

```bash
# 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
bash core/scripts/team-brain-api.sh onboard 9F7AC910 "Ada Junior" YOU_JIRA_TICKET_HERE --role member
```

Tips:

- Keep your name in quotes if it has a space: `"Ada Junior"`
- Jira key can be upper or lower case; the tool normalizes it
- Use a **display name that nobody else on the team already used** (duplicates are rejected)
- Viewers can `recall` / `breakdown` but not `remember` / `attach` / `delete` (ask admin for `set-role … member`)

### Step 3 — Check that it worked

```bash
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
bash core/scripts/team-brain-api.sh status
```

You should see something like:

- `TEAM_DIR=.../.team-brain`
- `CREDENTIALS=... OK`
- `API_KEY=set`

### Step 4 — Find your local files

Team Brain created a folder next to your work (often the parent workspace), for example:

```text
.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.

---

## Your first day — sync mode

Use the **same Jira key** your crew is on.

### 1) Start sync (the only manual step before work)

```bash
bash core/scripts/team-brain-api.sh start YOU_JIRA_TICKET_HERE
```

This:

- Loads crew memories into `.team-brain/cache/YOU_JIRA_TICKET_HERE.json`
- Starts **background sync** (merge-safe pull)
- Stays awake while you/`touch`/`remember`/`recall` stay active
- **Sleeps after 1 hour** of no local activity (warning ~5 min before)

Check:

```bash
bash core/scripts/team-brain-api.sh sync-status YOU_JIRA_TICKET_HERE
```

Optional topic search anytime:

```bash
bash core/scripts/team-brain-api.sh recall YOU_JIRA_TICKET_HERE "scaffold"
```

### 2) Save something useful you learned

Keep it short and professional (a teammate’s AI will see this). Prefer a stable `--source-ref`:

```bash
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:

- Same text again → no-op (`deduped`)
- Same `source_ref`, **new** text → **update** that memory (`updated`)
- New `source_ref` → insert

### 3) Draft stories / stop when done

```bash
bash 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).

### Optional — background `watch` on long spikes

Sync 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
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.

---

## Path B — You are creating the team (admin, once)

Only one person does this for a new crew. **You need a Supabase account** (free tier is fine). Joiners do not.

### Quick path — one config file (recommended)

Fill **everything** in one place, then run one command:

```bash
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** need `psql`, Supabase CLI, or `--db-url`.

### Step 1 — Create a Supabase project

1. [supabase.com](https://supabase.com) → New project  
2. From **Project Settings → API**, copy:
   - **Project URL** (`https://YOUR_REF.supabase.co`)
   - **anon** public key  
3. From **Database → Connection string**, note the **DB password** (only needed if you use `--db-url` / `psql`).

### Step 2 — Apply migrations (pick **one** path)

| 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 |

#### Step 2A — SQL Editor (recommended)

1. Bootstrap once **without** migrations — it writes the combined SQL file and stops with instructions:

```bash
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
```

2. Open **Supabase Dashboard → SQL Editor** for that project.  
3. Paste and run:

`supabase/.bootstrap-migrations.combined.sql`

(all files in `supabase/migrations/` in timestamp order — includes delete permissions #66 and pending review #67)

4. Continue at **Step 3** with `--skip-migrations`.

#### Step 2B — `psql` + `--db-url` (optional)

```bash
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.

### Step 3 — Register (after SQL Editor migrations)

If you used **Step 2A**, migrations are already applied — register only:

```bash
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.

### Step 4 — Admin: review queue (#67)

When members hit overlapping research, they can **`remember … --queue`**. You approve or reject from the CLI (dashboard UI: [#69](https://github.com/Hrithik-Gavankar/brainstack/issues/69)):

```bash
# 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`.

### Manual path (same outcome, no bootstrap)

1. Create a project at [supabase.com](https://supabase.com).
2. Apply migrations (SQL Editor or `psql`) — see [supabase/README.md](../supabase/README.md).
3. Copy **Project URL** + **anon** into local `supabase/project.public.env`. Set `TEAM_BRAIN_JIRA_SITE`.
4. Register and share:

```bash
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.json` does not store it.

---

## How sync actually works (read this)

**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`.

## Daily habits (keep it simple)

| 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` |

### Correcting bad research (important)

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
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
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:

```text
Correct Team Brain for YOU_JIRA_TICKET_HERE#cli-schema — the schema is in packages/ansible-language-server, not tox-ansible.
```

```text
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` kind  
- `20260803000001_team_brain_memory_history.sql` — revisions + history/restore

---

## Using Cursor (recommended for the context-first loop)

Install into your workspace once:

```bash
bash install.sh cursor /path/to/your/workspace
```

That installs:

- `team-brain.mdc` — always-on: **recall before research**, **remember after findings**, soft `compliance` gate
- `team-brain` skill — chat commands (+ `compliance` / MCP `prepare_research`)

### Start-of-ticket (do this every time)

Paste into Cursor chat / Composer (pick one):

```text
I'm starting on YOU_JIRA_TICKET_HERE — start Team Brain sync.
```

```text
I'm starting on YOU_JIRA_TICKET_HERE — start Team Brain sync, summarize crew memory, then help me.
```

```text
/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.

### MCP tools (advanced)

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](../mcp/team-brain/README.md).  
Juniors can ignore MCP and use the bash commands or Cursor skill.

---

## Troubleshooting

| 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`](../supabase/migrations/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 |

---

## What not to do

- Do not paste your `api_key` or `credentials.json` into Slack, PRs, or screenshots
- Do not put personal career / performance notes into Team Brain
- Do not treat the markdown file as the source of truth — **Supabase + `cache/`** are; md is a convenience export
- Do not invent an epic breakdown without running `recall` / `breakdown` first

---

## Quick command cheat sheet

```bash
# 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.
```

---

## Next reading (when you are ready)

- [team-brain-tutorial.md](team-brain-tutorial.md) — hands-on walkthrough with verification checklist  
- [team-brain-demo.md](team-brain-demo.md) — demo script and Office Hours one-pager  
- [team-brain.md](team-brain.md) — how sync layers fit together  
- [team-brain-memory.md](team-brain-memory.md) — full product plan  
- [supabase/README.md](../supabase/README.md) — admin / new project setup  
