# Correx live-QA environment — bring-up runbook

The plans in `docs/qa/QA-*.md` cite **observable signals** (events, logs, files, TUI
renders). This runbook stands up the stack that produces them. Run it on a capable box
(JDK 21, Go ≥ 1.24, Docker, a GPU + GGUF model for any model-dependent plan).

Helper scripts live in `scripts/qa/` (see `scripts/qa/README.md`).

> **Low-RAM note:** a machine-local `~/.gradle/gradle.properties` on the dev box caps the
> Gradle/Kotlin heap (`-Xmx768m`, `parallel=false`) for a 1.9 GB machine. It is **not
> committed**. On a QA box with real RAM, delete it (or ignore it) so builds aren't throttled.

---

## Prerequisites

- **JDK 21** (`java -version` → 21).
- **Go ≥ 1.24** — the TUI builds via `GOTOOLCHAIN=auto` (go.mod pins `go 1.24.2`); the
  toolchain auto-downloads if your `go` is older.
- **Docker** — only for SearXNG (research-workflow QA).
- **llama-server** binary + at least one **GGUF model** — for any model-dependent plan.
- (optional) an **embedder** model/endpoint — required for the architect-contradiction plan
  and any L3-retrieval-dependent behavior (`[router.embedder] backend = "llamacpp"`).

---

## 1. Config

Correx reads `~/.config/correx/config.toml` plus `workflows/`, `prompts/`, `schemas/`
alongside it. Stale copies cause silent bugs (BACKLOG ops note), so **sync from the repo**:

```bash
scripts/qa/sync-config.sh        # copies examples/workflows + prompts + docs/schemas
                                 # and seeds config.toml from docs/sample-config.toml IF ABSENT
```

Then edit `~/.config/correx/config.toml` for the plan you're running:

- **Model** — pick ONE:
  - *Managed* (`[[models]]` + `[models]`): correx spawns llama-server at `[models].host:port`
    (default `127.0.0.1:10000`) and kills it on shutdown. Simplest.
  - *Static* (`[[providers]]`, type `llamacpp`, `url`): you run llama-server yourself. **Use
    this for the llama-health plan** so you can stop the server independently of correx.
- **`[project] enabled = true`** — required for project memory + the **architect-contradiction**
  plan (it queries the `project:<repoRoot>` L3 namespace written at session end).
- **`[router.embedder] backend = "llamacpp"`** (not `noop`) — required wherever embeddings
  matter (architect contradiction, L3 retrieval). `noop` makes every distance meaningless.
- **`[tools.research] enabled = true` + `searxng_url`** — for the research/egress plan.
- **`[health] enabled = true`** — for the llama-health plan; note `interval_ms` (probe cadence).

A `[[artifacts]]` entry must exist for every LLM-emitted artifact kind a workflow `produces`
(schemas under `~/.config/correx/schemas/`). `sync-config.sh` copies the schemas; confirm the
`[[artifacts]]` table in `config.toml` references the kinds your workflow uses.

## 2. llama-server

- **Managed:** nothing to start — correx launches it. The health probe pings
  `http://<[models].host>:<[models].port>/health`.
- **External/static:** start your llama-server on the `url` host:port; its `/health` must 2xx.
  ```bash
  llama-server -m ~/models/<model>.gguf --host 127.0.0.1 --port 10000
  ```

## 3. SearXNG (research-workflow QA only)

```bash
scripts/qa/searxng-up.sh         # http://localhost:8888, JSON format enabled
# ... run research QA ...
scripts/qa/searxng-down.sh
```

> **Gotcha:** SearXNG ships with only the `html` output format; the research `web_search`
> needs the **JSON API**. `searxng-up.sh` writes a `settings.yml` enabling `formats: [html, json]`
> and mounts it. Without that, `web_search` returns nothing and the workflow stalls.

## 4. Start the server

```bash
./gradlew :apps:server:run        # mainClass com.correx.apps.server.MainKt, listens on :8080
# or build a runnable dist once and reuse it:
./gradlew :apps:server:installDist
apps/server/build/install/server/bin/server
```

> **Gotcha:** do **not** rebuild jars while the server JVM is running — lazy classloading
> breaks (`NoClassDefFoundError`). Stop the server first, rebuild, restart.

## 5. Start the TUI

```bash
cd apps/tui-go
GOTOOLCHAIN=auto go build -o correx-tui .
./correx-tui -host localhost -port 8080      # flags default to localhost:8080
```

## 6. Evidence tools (what the plans cite)

| Source | Command / where |
|--------|-----------------|
| Event log (the truth) | `./gradlew :apps:cli:run --args="events <sessionId>"` or `GET /sessions/{id}/events` |
| Deterministic replay | `./gradlew :apps:cli:run --args="replay <sessionId>"` |
| System health | `./gradlew :apps:cli:run --args="health"` |
| Server logs | stdout of `:apps:server:run` — MDC carries `sessionId` |
| Files on disk | e.g. `<workspaceRoot>/.correx/project.toml` (idea-promotion plan) |
| TUI render | the running `correx-tui` |

(Once `:apps:cli:installDist` is built, `apps/cli/build/install/cli/bin/cli events <id>` works too.)

## Teardown

1. Stop the server (Ctrl-C) — a managed `[[models]]` llama-server is killed by the shutdown hook.
2. `scripts/qa/searxng-down.sh` if you started it.
3. External llama-server: stop it yourself.

---

## Per-plan env matrix

| QA plan | model | embedder=llamacpp | SearXNG | `project.enabled` | workspace `.correx/` |
|---------|:-----:|:-----------------:|:-------:|:-----------------:|:--------------------:|
| `QA-research-egress` | yes (tool-calling) | no | **yes** | no | no |
| `QA-architect-contradiction` | yes | **yes** | no | **yes** | repo root, 2 sessions same process |
| `QA-llama-health-probe` | yes (static path to kill) | no | no | no | no |
| `QA-idea-promotion` | router only (or seed event) | no | no | no | **yes** (bound workspace) |
| `QA-reviewer-static-first` | yes | no | no | no | seed `StaticFindingsRecordedEvent` |
| `QA-brief-echo-gate` | yes (the prod candidate) | no | no | no | analyst brief with criteria |
