# Citadel Integration Plan

rdev integrates with a **partner-hosted Citadel** instance at `citadel-staging.orchard9.ai` for centralized log aggregation, querying, and alerting across both the platform and generated projects.

## Environment Architecture

```
Organization: orchard9 (on citadel-staging.orchard9.ai)
│
├── Environment: "rdev-platform"
│   ├── rdev-api logs (stdout via agent)
│   ├── rdev-worker logs (stdout via agent)
│   ├── claudebox logs (stdout via agent)
│   └── audit events (shipped from AuditLogger)
│
├── Environment: "<project-slug>"       (auto-created per project)
│   └── Project pod logs (stdout via agent, routed by k8s labels)
│
├── Tenant Group: "platform"            → rdev-platform
└── Tenant Group: "projects"            → all project-* environments
```

Each project gets its own Citadel environment, matching rdev's isolation model (each project gets its own DB, Redis, DNS, registry namespace).

## Integration Points

### 1. Agent DaemonSet (Log Collection)

**What:** A `citadel-agent` DaemonSet on every k3s node collects container stdout/stderr and ships to Citadel via HTTPS.

**Why:** rdev already outputs structured JSON slog to stdout. Zero code changes needed.

**Routing:** Agent reads k8s labels to route logs to the correct Citadel environment:
- `citadel.io/environment` label → determines target environment
- `citadel.io/service` label → tags the service name in Citadel

**Manifests:** `deployments/k8s/base/citadel-agent/`

### 2. Citadel Client Adapter (API Integration)

**What:** Go HTTP client for Citadel's API, following rdev's hexagonal architecture (port interface + adapter).

**Why:** Needed for auto-provisioning environments and shipping audit logs.

**Files:**
- `internal/port/citadel.go` — Port interface
- `internal/adapter/citadel/client.go` — HTTP client implementation
- `internal/adapter/citadel/audit_shipper.go` — Audit log shipping

### 3. Project Provisioning Step

**What:** When `ProjectInfraService.CreateProject()` runs, a new step creates a Citadel environment for the project.

**Why:** Each project needs its own isolated log environment. Auto-provisioning eliminates manual setup.

**Where in the flow:**
```
CreateProject()
  1. Generate slug
  2. Create project in DB
  3. Create git repo
  4. Create DNS
  5. Activate CI
  6. Seed template
  7. Provision DB + cache
  8. *** Create Citadel environment ***  ← NEW
  9. Create initial deployment
  10. Trigger CI build
```

**Rollback:** On project deletion, the Citadel environment is deleted too.

### 4. Skeleton Template Labels

**What:** Add `citadel.io/*` labels to the skeleton's k8s deployment templates.

**Why:** The agent uses these labels to route project logs to the correct Citadel environment.

**Template vars:** `{{CITADEL_TENANT_ID}}` injected during provisioning.

### 5. Audit Log Shipping

**What:** Hook into rdev's existing `AuditLogger` to also ship audit events to Citadel.

**Why:** Unified search across application logs and security events.

**Pattern:** Wrap the existing PostgreSQL `AuditLogger` with a multi-writer that sends to both PostgreSQL and Citadel.

## Configuration

### Environment Variables (rdev-api)

| Variable | Description | Example |
|----------|-------------|---------|
| `CITADEL_URL` | Partner Citadel instance URL | `https://citadel-staging.orchard9.ai` |
| `CITADEL_API_KEY` | API key for environment management | `ck_live_...` |
| `CITADEL_TENANT_ID` | Platform environment tenant ID | `uuid` |
| `CITADEL_ENABLED` | Enable/disable Citadel integration | `true` |

### Secrets (k8s)

```yaml
# deployments/k8s/base/citadel-agent/secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: citadel-agent
  namespace: observability
type: Opaque
stringData:
  api-key: "ck_live_..."
  tenant-id: "..."
```

## Queries (What You Get)

### Platform Operations

```bash
# All errors across platform
citadel query "level:error" --tenant rdev-platform --last 1h

# Track a project lifecycle
citadel query "project_id:my-project" --tenant rdev-platform --last 24h

# Build failures
citadel query "component:build level:error" --tenant rdev-platform

# Saga failures
citadel query "component:saga result:failure" --tenant rdev-platform

# Slow API requests
citadel query "duration_ms:>5000 component:http" --tenant rdev-platform

# Audit trail
citadel query "action:project.create" --tenant rdev-platform --last 7d
```

### Generated Projects

```bash
# Query a specific project's logs
citadel query "level:error" --tenant <project-slug> --last 1h

# All project errors at once
citadel query "level:error" --group projects --last 1h

# Correlate platform + project
citadel query "project_id:my-project" --last 24h  # org-wide
```

## Implementation Order

| Phase | Task | Effort |
|-------|------|--------|
| 1 | Write Citadel client adapter (`internal/adapter/citadel/`) | 2h |
| 1 | Write port interface (`internal/port/citadel.go`) | 30m |
| 2 | Deploy agent DaemonSet (`deployments/k8s/base/citadel-agent/`) | 1h |
| 2 | Add citadel labels to existing rdev-api/worker manifests | 15m |
| 3 | Add Citadel env creation to `ProjectInfraService.CreateProject()` | 2h |
| 3 | Add Citadel env deletion to `ProjectInfraService.DeleteProject()` | 30m |
| 3 | Add migration for `citadel_tenant_id` column on projects table | 15m |
| 4 | Add `citadel.io/*` labels to skeleton k8s templates | 30m |
| 4 | Add `CITADEL_TENANT_ID` to template variables | 15m |
| 5 | Implement audit log shipper | 2h |
| 5 | Wire into main.go startup | 30m |

## Files Created/Modified

### New Files
- `internal/port/citadel.go`
- `internal/adapter/citadel/client.go`
- `internal/adapter/citadel/audit_shipper.go`
- `deployments/k8s/base/citadel-agent/kustomization.yaml`
- `deployments/k8s/base/citadel-agent/daemonset.yaml`
- `deployments/k8s/base/citadel-agent/serviceaccount.yaml`
- `deployments/k8s/base/citadel-agent/configmap.yaml`
- `internal/db/migrations/024_citadel_tenant_id.sql`

### Modified Files
- `deployments/k8s/base/kustomization.yaml` — include citadel-agent
- `deployments/k8s/base/rdev-api.yaml` — add citadel labels + env vars
- `internal/service/project_infra.go` — add CitadelClient field
- `internal/service/project_infra_crud.go` — add provisioning + cleanup steps
- `internal/adapter/templates/templates/skeleton/` — k8s template labels
- `cmd/rdev-api/main.go` — wire Citadel adapter
