Components¶
This section covers the seven independent GitHub repositories that make up the running platform and its deploy/observability tooling. Each ships its own Helm chart (or deploy mechanism), CI pipeline, and independent release lifecycle. There is no umbrella helmfile and no monorepo. Components compose into the platform at runtime but version, build, and deploy in isolation.
Two further repos support the platform without being runtime components and are documented outside this section: tatara-agent-skills (the source of the wrapper agent skills) and tatara-documentation (this site).
Component table¶
| Component | Role | Language | Deploy unit | Build phase |
|---|---|---|---|---|
tatara-operator | CRD controller, webhook receiver, agent orchestrator, per-project memory stack provisioner | Go | Helm chart (tatara-operator) -> K8s Deployment | 6 |
tatara-memory | OIDC-gated REST memory service over LightRAG + Neo4j + Postgres | Go | Helm chart (tatara-memory) with CNPG, Neo4j, LightRAG subcharts -> K8s Deployment | 1 |
tatara-cli | OIDC device-flow auth, REST passthrough to any tatara backend, stdio MCP server for agent sessions | Go | Homebrew tap (szymonrychu/tap) + binary pre-installed in wrapper container image | 2 |
tatara-claude-code-wrapper | Single-session Claude Code supervisor over PTY; submits turns, captures results via Stop hook | Go + Claude Code | K8s Pod - ephemeral, one per Task, spawned by operator | 4 |
tatara-memory-repo-ingester | Stateless batch ingester: language-aware static analysis, code graph + semantic chunk push to memory | Go | K8s Job - ephemeral, spawned per ingest cycle by operator | 3 |
tatara-helmfile | GitOps helmfile: owns all platform Helm releases and enrollment CRs; deploys on merge via in-cluster ARC runner | Helmfile + YAML | GitHub Actions + in-cluster ARC runner | - |
tatara-observability | Observability-as-code: Grafana alert rules applied by Terraform on merge to main | Terraform + YAML | GitHub Actions | - |
Build phases
Phase numbers reflect the order the platform was originally designed and built. tatara-helmfile and tatara-observability are operational repos (no runtime service, no container image) and carry no phase number.
Plane model¶
The seven components fall into three functional layers.
Control plane¶
The control plane holds the decisions and the desired-state declarations. Nothing in the data plane runs without the control plane authorizing it.
| Component | Responsibility |
|---|---|
tatara-operator | Single source of truth for task state. Reconciles six CRDs (Project / Repository / Task / QueuedEvent / Issue / MergeRequest); Subtask is deleted and WorkItem was never a CRD. Decides what runs, when, and with what context. Receives SCM and Grafana webhooks, enforces the maxConcurrentAgents pod-admission gate, drives the agent turn loop, walks the merge and deploy sequence itself, writes results back to the SCM as PRs, comments, and (once) a review verdict. |
tatara-helmfile | Single source of truth for deployment state. Every Helm release version and every enrollment CR is pinned here. No component is deployed outside this repo's apply pipeline. |
Data plane¶
The data plane does the work: storing knowledge, executing agent sessions, and keeping the knowledge graph current.
| Component | Responsibility |
|---|---|
tatara-memory | Permanent knowledge store. Agents read and write through it across all sessions. Persists entity graphs, code structure, and semantic chunks. One instance per Project CR, provisioned by the operator. |
tatara-cli | Tool surface inside every agent session. Translates MCP tool calls (from Claude Code) into REST calls against tatara-memory and the operator. Agents never hold raw service credentials. |
tatara-claude-code-wrapper | Agent execution boundary. Owns one interactive claude process per pod over a PTY (not -p/print mode - the full interactive harness). Submits turns, captures results via the cc-stop-hook, delivers callbacks to the operator. Optionally restores S3-backed conversation transcripts across pod restarts. |
tatara-memory-repo-ingester | Knowledge pipeline. Runs as an ephemeral K8s Job on each repository at enrollment and on each push event. Produces the code-entity graph and semantic chunks that tatara-memory serves to agents. |
Supporting infrastructure¶
Supporting components provide CI/CD and observability. They do not participate in the core agent turn loop.
| Component | Responsibility |
|---|---|
tatara-observability | Platform alerting. Defines Grafana alert rules as declarative YAML; on firing, alerts labelled system=tatara route to the operator's Grafana webhook endpoint, which opens an incident Task. |
Per-component summaries¶
-
tatara-operator
The orchestration brain. Reconciles six CRDs with a controller-runtime manager:
Project,Repository,Task,QueuedEvent,Issue, andMergeRequest(Subtaskis deleted;WorkItemwas never a CRD). Provisions per-project memory stacks (CNPG Postgres, Neo4j, LightRAG, tatara-memory), ingests repos, receives HMAC-verified GitHub/GitLab and bearer-verified Grafana webhooks, admits agent pods against themaxConcurrentAgentsgate, spawnstatara-claude-code-wrapperpods, drives the 8-state Task machine end to end, walks the merge sequence and the semver push-CD cascade itself, and writes results back as PRs, issue comments, and its own posted review. -
tatara-memory
An OIDC-gated REST service fronting LightRAG (entity/relation graph + semantic retrieval), Neo4j (graph storage), and CNPG Postgres (relational state + ingest job tracking). Every client authenticates with a Keycloak bearer token carrying
aud: tatara-memory. The operator provisions one stack perProjectCR; instances are not shared across projects. -
tatara-cli
A Go CLI distributed via Homebrew tap (
szymonrychu/tap) and pre-installed in the wrapper container image. Subcommands:login(OIDC device flow),status,raw(REST passthrough to memory or the operator),mcp(starts the stdio MCP server Claude Code connects to), andmcp-config(writes.mcp.json). Inside every agent pod it is the sole MCP server - all tool calls flow through it. -
tatara-claude-code-wrapper
A Go supervisor that allocates a PTY, spawns an interactive
claudeprocess, submits turns via bracketed-paste input, and captures results from a custom cc-stop-hook. Exposes a turn-lifecycle HTTP API (POST /v1/messages,GET /v1/messages/{turnId},GET /v1/session, etc.) that the operator drives. One pod is one bounded run, capped byagentPodTTLSeconds; there is no session-resume mode. The operator renders an identical context bundle at every pod's turn 0, and continuity across pods comes fromTask.status.notes, an append-only journal the wrapper's stop sequence guarantees is written before a TTL-expired pod is torn down. -
tatara-memory-repo-ingester
A stateless Go batch tool (
tatara-ingest). Walks a repository with language-aware static analysis (Go, Python, JavaScript, Terraform, Helm, Markdown), produces a deterministic entity-and-edge code graph, and pushes it to tatara-memory via its REST API. Alternatively accepts a pre-generated SCIP index for languages with existing indexers. Runs as an ephemeral K8s Job; incremental ingest tracks the last-ingested commit to push only changed files. -
tatara-helmfile
The single source of truth for what is running. A Helmfile repo with releases including
tatara-operator,project-tatara, andproject-infrastructure. PRs post a stickyhelmfile diffcomment; merge to main triggershelmfile applyon the in-cluster ARC runner (arc-runner-tatara-helmfile), using that runner pod's in-cluster ServiceAccount. Both the Helm chart version (bare semverX.Y.Z) and the image tag (vX.Y.Z) pin live here, auto-bumped by the push-CD pipeline. -
tatara-observability
Grafana alert rules as declarative YAML files under
alerts/tatara-<component>.yaml. Each file is one Grafana rule group rendered by a Terraform module into the GrafanaTatarafolder. A PR posts a stickyterraform plan; merge runsterraform apply. Alerts labelledsystem=tatararoute (via the infra notification policy) to the operator's Grafana webhook endpoint, which opens anincidentTask.
How they compose at runtime¶
At runtime the components form two concurrent flows: the agent execution loop and the CI/CD supply chain.
Agent execution loop¶
A developer (or the operator's periodic brainstorm scan) labels a GitHub or GitLab issue. The operator picks it up and drives the following sequence:
sequenceDiagram
actor SCM as GitHub / GitLab
participant Op as tatara-operator
participant Mem as tatara-memory
participant Ing as repo-ingester Job
participant Wrap as claude-code-wrapper Pod
participant Cli as tatara-cli (MCP stdio)
SCM->>Op: HMAC-verified webhook (comment / push)
Op->>Mem: provision memory stack (if new Project)
Op->>Ing: spawn ingest Job for changed repo
Ing->>Mem: POST entities + edges (code graph, semantic chunks)
Op->>Wrap: spawn agent Pod (Task context injected as env)
Note over Wrap: clone repo, configure MCP,<br/>render fresh context bundle
loop each turn, bounded by agentPodTTLSeconds
Op->>Wrap: POST /v1/messages (turn prompt)
Wrap->>Cli: MCP tool calls (memory query, task_note, submit_outcome)
Cli->>Mem: REST (query memories, entities, code graph)
Cli->>Op: REST (task_note, submit_outcome, report_internal_issue)
Wrap-->>Op: callback POST (turn result)
end
Op->>SCM: PR opened + issue comment (one PR per changed repo) CI/CD supply chain¶
Component images and charts move from source repo to the cluster through the CI/CD supply chain, never by hand. tatara-argo-workflows was decommissioned (2026-07-05); it was homelab GitLab CI, never part of the tatara platform runtime. The in-cluster argo-workflows Helm release remains as separate, unrelated homelab infrastructure.
graph LR
subgraph "Component repos"
R1[tatara-operator]
R2[tatara-memory]
R3[tatara-cli]
R4[tatara-claude-code-wrapper]
end
subgraph "Component repo CI"
CI[build + test + lint\nimage + chart publish]
end
subgraph "Artifact registry"
H[Harbor OCI\nimages + charts]
end
subgraph "GitOps deploy"
HF[tatara-helmfile PR\nimage tag + chart version bump]
ARC[in-cluster ARC runner\nhelmfile apply]
K8s[Kubernetes cluster]
end
R1 & R2 & R3 & R4 -->|push / tag event| CI
CI -->|docker push + helm push| H
H -->|version pin bump PR| HF
HF -->|merge to main| ARC
ARC -->|helmfile apply| K8s Component interaction map¶
The diagram below shows the full platform topology grouped by plane, matching the control / data / supporting classification above:
graph TB
subgraph CP["Control plane"]
Op[tatara-operator\nCRDs + reconcilers]
HF[tatara-helmfile\nGitOps releases]
end
subgraph DP["Data plane"]
Mem[tatara-memory\nLightRAG + Neo4j + Postgres]
Cli[tatara-cli\nMCP stdio server]
Wrap[tatara-claude-code-wrapper\nephemeral Pod per Task]
Ing[tatara-memory-repo-ingester\nephemeral Job per ingest]
end
subgraph Sup["Supporting"]
Obs[tatara-observability\nGrafana alerts via Terraform]
end
HF -->|helm apply| Op
HF -->|helm apply| Mem
Op -->|spawns| Wrap
Op -->|spawns| Ing
Op -->|provisions per-project| Mem
Wrap -.-|MCP stdio| Cli
Cli -->|REST| Mem
Cli -->|REST| Op
Ing -->|REST| Mem
Obs -->|Grafana alert webhook| Op Release model¶
Since the semver push-CD migration (2026-07-05), every component that ships a container image publishes at a bare-semver image tag (vX.Y.Z) and its chart at the matching bare semver (X.Y.Z). The release pipeline cuts the tag from a semver:* label on the merged PR, auto-propagates the version pins into a tatara-helmfile PR, coalesces sibling components into a deploy train, and lets the operator close the originating issue on apply. tatara-helmfile pins the chart version and the image tag independently - an image-only update does not require a chart version bump, and vice versa.
The legacy 0.0.0-g<sha> pre-release scheme (the g prefix avoids an all-digit leading segment failing helm package semver validation) is still packaged on every push to main, but the deployed pins are the bare-semver releases, not the per-commit charts.
No hand deploys
Every release flows through tatara-helmfile. Direct kubectl set-image, kubectl patch, or helm upgrade invocations are prohibited except for incident response (unblocking a downed service), and any such live patch must be immediately re-asserted via a tatara-helmfile PR so live state matches the repo. See Deployment & GitOps.