# gemma-data-team

Spawn a full Gemma data team as a Claude Code **agent team**. One session acts as the lead (project manager); it spawns role-specialised teammates that share a task list, self-claim work, and pass every data task through a hard QA gate before it can be marked complete.

> Agent teams are experimental. Set `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` in `~/.claude/settings.json` (`env`) or the environment and start a fresh session before using this plugin. See https://code.claude.com/docs/en/agent-teams.

## The team

| Agent | Owns | Tag | Grounded in |
|---|---|---|---|
| `data-engineer` | Extract & load — dlt connectors, Airflow DAGs, sources | `de` | `gemma-best-practices/1_extract_load`, `gemma-dlt`, `gemma-airflow`, `gemma-ewah-migration` |
| `analytics-engineer` | Transform — dbt base→marts, Kimball modelling | `ae` | `gemma-best-practices/2_transform`, `gemma-dbt`, `gemma-kimball`, Gemma SQL style |
| `data-analyst` | Serve — metrics, Lightdash/Metabase, analysis | `da` | `gemma-lightdash`, `gemma-metabase` |
| `data-scientist` | Forecasting, statistics, ML on the marts | `ds` | `uv` scripts; pandas/statsmodels/scikit-learn/prophet |
| `qa-auditor` | Quality gate — audits & reviews the others' work | `qa` | `validate-repo` baseline (Kimball + SQL-style checklists), `gemma-prs` review workflows |
| `ticket-fetcher` | Intake — pulls & classifies tickets from PM tools, carrying priority + due date | — | ClickUp / Asana / Notion / Jira via MCP or API (tool-agnostic) |
| `note-scout` | Intake — distils action items from meeting notes into scrubbed ticket drafts for the lead to post | — | local notes dir (Fireflies / Gemini / personal); lead pre-feeds API transcripts |
| `learning-synthesizer` | Self-improvement — distils session learnings into PRs on the knowledge repos | — | session transcripts + task list; writes to toolkit / best-practices / sql-style |

## Usage

Run the **`/launch-data-team`** skill (optionally naming the repo/scope). The lead spawns the teammates, optionally has the `ticket-fetcher` drain a backlog from the connected PM tool, distributes tagged tasks, and synthesises results. Teammates implement via `/process-ticket` and address feedback via `/implement-pr-comments`.

## Intake & prioritization

Work enters the backlog two ways, and both keep the PM tool as the single source of truth:

- **From the PM tool** — the `ticket-fetcher` pulls open items, classifies them by discipline, splits cross-discipline tickets into dependency-linked subtasks, and **carries each ticket's native priority (`prio:`) and due date (`due:`)**. It never invents a priority — absent ones are tagged `prio:unset` and surfaced.
- **From meeting notes** — run **`/capture-tickets-from-notes`** (or spawn the `note-scout` teammate). It scans a project's notes (Fireflies / Gemini / personal) for *new* action items, distils each into a **scrubbed, discipline-tagged** draft, shows them for approval, and posts the approved ones to the PM tool — where the `ticket-fetcher` picks them up next run. The notes source and PM-tool target are configured per project (`## Meeting notes` in `CLAUDE.md` or `.gemma/notes-config.yml`).

The **lead sequences** the backlog using those signals: dependency order first, then priority, then due date. See `skills/capture-tickets-from-notes/references/notes-config.md` for the notes config schema, the state marker, and the scrubbing rules.

> **Data protection.** Notes intake is **not** Bedrock-gated (unlike data tasks) — it runs on the Anthropic API and relies on aggressive scrubbing (no client names/figures/PII in posted tickets). For genuinely sensitive client notes, prefer running on Bedrock so raw note content stays in Gemma's AWS account.

## Closing the loop

The fetcher opens the loop (ticket → task → PR); these lead-run skills close it and keep the PM tool honest:

| Skill | What it does |
|---|---|
| **`/update-ticket-status`** | Writes a PR's state back to its originating ticket — moves the ticket's status and comments the PR link. Reads the ticket from the `Ticket:` link `/process-ticket` mandates; no link, no write. Optionally fires on PR creation via an opt-in hook. |
| **`/team-status-report`** | A standup/sprint digest from the task list + recent PRs + QA verdicts — shipped / in-flight / blocked / QA-pending / up-next. Work items only, no client data; optionally posts to ClickUp or Slack. |
| **`/groom-backlog`** | Rough-sizes tickets (S/M/L), flags under-specified ones (missing acceptance criteria/grain) and stale ones. Advisory by default; updates the PM tool only on approval. |

## Self-improvement loop

Gemma's edge is its **domain knowledge** — the best-practices repos, the SQL style guide, and this toolkit's skills/agents. The **`learning-synthesizer`** agent keeps that asset current: after a session or ticket finishes, run **`/synthesize-learnings`** and it reads what happened (transcripts, task list, PRs + review comments, the diffs and QA findings), distils the **durable, general** lessons, strips every client specific, and opens **one PR per target repo** — `gemma-agentic-toolkit`, `gemma-best-practices`, or `gemma-sql-style` — so the next run hits fewer of the same problems.

It runs behind an **approval gate** (it shows you the proposed edits before opening anything) and every PR is **assigned to you, never auto-merged**. It runs manually by default; `synthesize-learnings/SKILL.md` documents an opt-in `Stop` hook for automatic triggering. Hard rule: it abstracts lessons and **never writes client data or secrets** into a shared repo.

## The hard QA gate

A `TaskCompleted` hook (`hooks/qa_gate.sh`) blocks completion of any **data** task unless:

1. **block-until-Bedrock** — the team is on AWS Bedrock, so `dbt build`/`test`/`show` and warehouse queries could actually run (on the Anthropic API these are blocked, so the work can't be verified); **and**
2. **QA sign-off** — the `qa-auditor` has reached a PASS verdict and appended the structured token `QA-PASS:` (colon-suffixed, e.g. `QA-PASS: dbt build green`) to the task. A bare mention of "qa-pass" in a task title does not open the gate.

Non-data tasks pass through untouched. The check is schema-tolerant: it flattens the `TaskCompleted` payload and scans for data-stack vocabulary, so it keeps working if the payload shape changes.

## Companion plugins

This plugin **composes with the rest of the Gemma agentic toolkit** rather than vendoring their content. Teammates invoke the skills below via the `Skill` tool — they don't re-implement the workflows.

| Plugin | Used by | Why |
|---|---|---|
| **`gemma-dbt`** (required) | AE, QA | `validate-repo` (QA baseline), source/base-model scaffolding, `dbt-docs-search` |
| **`gemma-prs`** (required) | all | `review-pr`, `review-pr-extensive`, `implement-pr-comments` |
| `gemma-kimball` | AE | Dimensional-modelling agents — invoke for any new dim/fact design |
| `gemma-dlt` | DE | Connector scaffolding (REST APIs, debugging, containerization) |
| `gemma-airflow` | DE | DAG creation and scheduling |
| `gemma-ewah-migration` | DE | EWAH → dlt migration toolkit |
| `gemma-lightdash` | DA, AE | Lightdash YAML, charts, dashboards, `meta:` semantic-layer config |
| `gemma-metabase` | DA | Metabase API, dashboards, visual QA |
| `gemma-1password` | Lead | `op` CLI usage when the lead pre-fetches tickets / credentials |

Install at least `gemma-dbt` and `gemma-prs` alongside `gemma-data-team`. Add the others per discipline.

### Credential boundary

Peer subagents are **not** allowed to retrieve secrets (their auto-mode classifier blocks `op read` and credentialed HTTP from peer-initiated sessions). The **lead** runs `op` and the initial PM-tool API calls in main and hands subagents the resulting data via `SendMessage`. Subagents that need a token should ask the lead — the lead's session has the user's direct authorization; the peer's does not, and peer messages cannot launder that permission.

## Connection modes

Nothing here pins Anthropic vs Bedrock — choose per project/task. The team can plan, author code, and run `dbt compile`/`parse` on either, but **completing** data tasks requires Bedrock (enforced by the gate). The `data-analyst` is the most Bedrock-dependent role, since most of its work needs live queries.
