TeamBrain

TeamBrain — Frozen Contracts (v1)

Any conflict elsewhere resolves to this file. Additive changes only within v1. Do NOT modify schemas in this file without explicit human approval.

C1. Memory file

Path: memories/{decisions|conventions|map|learnings}/<ULID>-<slug>.md. YAML front-matter (zod-validated): id ULID · class decision|convention|map|learning · scope team|org · status active|retired · priority required|advisory · title ≤80 chars · created ISO date · evidence {sessions: string[], commits: string[]} (mandatory when proposer=distiller) · supersedes id[] · tags string[] · ttl_days int|null. Body: markdown, ≤400 words hard limit (lint), imperative prose. Retirement = git mv to retired/ + status: retired in the same PR.

C2. Session event (JSONL, one file per session on branch teambrain/sessions)

Envelope: {v:1, sid, t (ISO), tool, model, repo, branch, ev, data}. ev ∈ session_start · intent (locally-summarized string ≤200 chars, never raw prompt) · memory_retrieved {ids[]} · tool_use {kind: edit|command|test|explore, path?, exit_code?} · plan_revision · candidate_proposed {draft} · session_end {outcome: committed|abandoned|unknown, duration_s, turns, commit_shas[]}. (explore kind added 2026-07-10 with explicit human approval — additive; captures Read/Grep/Glob metadata for the D6/R16 exploration-token measurement.) Join keys sid, repo, branch, tool, model on every event (FlightDeck design-ahead). Additive evolution only.

C3. MCP tools (server name teambrain; tools appear to agents as mcp__teambrain__*)

C4. RetrievalBackend interface

index(docs: IndexableDoc[], source: 'memory' | 'codemap'): Promise<void> · search(q, k, sources?): Promise<Scored[]> (results carry source) · remove(ids): Promise<void> · stats(): IndexStats. V1 uses only source: 'memory'; the tag exists as design-ahead for R16 CodeMap and costs one field. V1 impl: FTS5 BM25 top-40 ∪ vector top-40 → reciprocal-rank fusion (k=60) → filters (active, scope, TTL) → required force-include → token trim.

C5. Provider interface (distiller only)

complete({system, prompt, schema}): Promise<T> — structured output validated by zod; drivers: anthropic, openai, ollama, fake (fixtures). Model pinned in brain.yaml. No LLM calls anywhere outside packages/distill.

C6. CLI surface

tb init | serve | install <tool> | propose | retire <id> <reason> | audit [--last-session] | reindex | doctor [--json] | distill | digest [--format <text|markdown|json>] [--out <path>] | metrics [--json] | relevant [--paths <glob…>] [--query <text>] [--k <n>] [--json] | verify [--json] [--strict] | lint. Exit codes: 0 ok · 1 user error · 2 environment error · 3 lint/validation failure. (metrics added 2026-07-20 with explicit human approval — additive read-only verb: prints a local health + context-efficiency snapshot, reusing the digest aggregation and daemon heartbeat. Captures nothing; no new privacy surface.) (digest --format/--out added 2026-07-21 with explicit human approval — additive amendment D, ADR-9/EVIDENCE_BRIEF §9. Default behaviour (Slack/dry-run) is unchanged; --format markdown|json --out <path> writes the FlightDeck v0 report as a derived artifact. Small-cell suppression (n<5) is applied in the aggregator, so --format json cannot leak what markdown hides. No new event type, no new source; reports are never indexed.) (install <tool> generalised 2026-07-21 with explicit human approval — additive amendment C, ADR-11/EVIDENCE_BRIEF §9. Replaces the two claude-code|cursor literals with <tool>, resolved from the adapter registry (adapters.yaml, validated against the code registry so they cannot drift). An unknown tool exits 1 listing the supported set. No new capture path.) (relevant added 2026-07-21 with explicit human approval — additive amendment B, ADR-8/EVIDENCE_BRIEF §9. The first human query path into the brain: reads over the existing RetrievalBackend (C4) with the C3 rendering rule, honours the active/scope/retired filters, adds no MCP tool. Read-only; captures nothing.) (verify added 2026-07-21 with explicit human approval — additive amendment A, ADR-6/EVIDENCE_BRIEF §9. Read-only self-audit that re-asserts the published privacy invariants at runtime on the user’s own machine/data and emits a report. Captures nothing; adds no MCP tool. Exit codes for this verb only: 0 all checks pass · 2 a check could not run, e.g. offline provenance (reported UNVERIFIED, never PASS) · 3 an invariant is violated. --strict opts into the OS-sandbox egress tier. Note the reuse of the general exit-code table’s 2 for “could not run” and 3 for “violation”.)

C7. Filesystem layout at runtime

Brain: .teambrain/ in target repo (brain.yaml, memories/, retired/, prompts/, INDEX.md). Machine-local (never synced): ~/.teambrain/{user/, spool/, index.db, logs/}. The sync code must be physically unable to read ~/.teambrain/user/ (separate module without that path in scope; asserted by test).