feat: chat + optmz control panel
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
# CASAN local full stack (macOS)
|
||||
|
||||
This guide runs the entire currently implemented CASAN stack on one Mac. It is
|
||||
a local production-like lab, not a production compliance claim. The Linux
|
||||
server is deliberately not used in this phase.
|
||||
|
||||
## What runs locally
|
||||
|
||||
| Component | Address | Role |
|
||||
|---|---|---|
|
||||
| Vault dev / Transit | `http://127.0.0.1:18200` | KMS signing and rotation exercises |
|
||||
| Mock OIDC / JWKS | `http://127.0.0.1:18081` | Approval JWT validation |
|
||||
| MinIO S3 API | `http://127.0.0.1:19090` | S3-compatible object storage |
|
||||
| MinIO Console | `http://127.0.0.1:19091` | S3 administration UI |
|
||||
| MinIO WORM bucket | `casan-worm` | Object Lock / 1-day compliance retention |
|
||||
| Alert mock | `http://127.0.0.1:19092` | Alert webhook target |
|
||||
| Billing mock | `http://127.0.0.1:19093/usage` | Provider-usage import target |
|
||||
| AgentOps dashboard | `http://127.0.0.1:18080` | Dashboard behind nginx basic auth |
|
||||
| CASAN Control Panel | `https://localhost:18443` | TLS + mock OIDC + oauth2-proxy + nginx + NestJS + React |
|
||||
| OmniRoute | `http://127.0.0.1:20128/v1` | Existing local OpenAI-compatible model gateway |
|
||||
|
||||
The Control Panel uses a different mock IdP port (`18082`) so it can run at the
|
||||
same time as the approval IdP (`18081`).
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
- Docker Desktop running, with at least 6 GB RAM allocated.
|
||||
- Node.js 20+ and npm (needed only for host-side development and CASAN pipeline
|
||||
execution; the local services run in Docker).
|
||||
- OmniRoute already reachable at `http://127.0.0.1:20128/v1` when model mode is
|
||||
required.
|
||||
|
||||
Confirm Docker first:
|
||||
|
||||
```bash
|
||||
docker version
|
||||
docker compose version
|
||||
```
|
||||
|
||||
## 2. Start every local service
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
bash packages/casan-harness/scripts/bash/local-full.sh start
|
||||
```
|
||||
|
||||
The first run builds the mock services and Control Panel images. Open:
|
||||
|
||||
- Dashboard: `http://127.0.0.1:18080` — credentials `casan` / `casan`.
|
||||
- MinIO Console: `http://127.0.0.1:19091` — credentials `casanadmin` /
|
||||
`casanadmin123`.
|
||||
- Control Panel: `https://localhost:18443` — accept the local self-signed
|
||||
certificate. The mock OIDC flow signs in automatically as `oidc-ops` with
|
||||
`org-admin` for local testing only.
|
||||
|
||||
Check running services at any time:
|
||||
|
||||
```bash
|
||||
bash packages/casan-harness/scripts/bash/local-full.sh status
|
||||
```
|
||||
|
||||
## 3. Verify infrastructure controls
|
||||
|
||||
```bash
|
||||
bash packages/casan-harness/scripts/bash/local-full.sh verify
|
||||
```
|
||||
|
||||
This performs live Vault Transit sign/verify, gets an RS256 JWT from the mock
|
||||
OIDC IdP and validates it via JWKS, writes a retained object to MinIO, sends an
|
||||
alert, imports billing telemetry, and accesses the authenticated dashboard.
|
||||
|
||||
For the stricter TLS/OIDC Control Panel browser smoke:
|
||||
|
||||
```bash
|
||||
bash packages/casan-harness/scripts/bash/local-full.sh smoke
|
||||
```
|
||||
|
||||
`smoke` is intentionally isolated and stops its temporary Control Panel stack
|
||||
when complete. Run `start` again if you want the UI to remain up afterwards.
|
||||
|
||||
## 4. Connect CASAN to OmniRoute
|
||||
|
||||
CASAN now supports an explicit OpenAI-compatible gateway model syntax. It does
|
||||
not relax the public OpenAI endpoint hardening: the custom URL is required and,
|
||||
by default, may only be localhost. Keep secrets out of shell history and Git.
|
||||
|
||||
First load your key into the current shell using the mechanism you normally use
|
||||
(for example a password manager or a non-tracked `.env.local`). Then list model
|
||||
IDs that OmniRoute exposes:
|
||||
|
||||
```bash
|
||||
curl -fsS http://127.0.0.1:20128/v1/models | python3 -m json.tool
|
||||
```
|
||||
|
||||
Configure a returned model ID. `CASAN_OPENAI_COMPATIBLE_API_KEY` may be a
|
||||
dedicated OmniRoute key; if omitted, the router falls back to `OPENAI_API_KEY`.
|
||||
|
||||
```bash
|
||||
export CASAN_OPENAI_COMPATIBLE_BASE_URL=http://127.0.0.1:20128/v1
|
||||
export CASAN_OPENAI_COMPATIBLE_API_KEY="$OPENAI_API_KEY"
|
||||
export CASAN_MODEL_PRIMARY='openai-compatible:auto/best-coding'
|
||||
export CASAN_CHAT_MODEL_MODE=model
|
||||
export CASAN_CHAT_MODEL_PROVIDER=omniroute
|
||||
export CASAN_PREFLIGHT=1
|
||||
```
|
||||
|
||||
For the Dockerized Control Panel, copy the provided template and replace only
|
||||
the key locally. Docker uses `host.docker.internal` so the Linux container can
|
||||
reach OmniRoute on the Mac host.
|
||||
|
||||
```bash
|
||||
cp infra/local-prod/casan.local.env.example infra/local-prod/casan.local.env
|
||||
# Edit casan.local.env in your editor and replace the placeholder key.
|
||||
bash packages/casan-harness/scripts/bash/local-full.sh start
|
||||
```
|
||||
|
||||
Do not set a bare `localhost` URL in this file: inside the Control Panel
|
||||
container, `localhost` means the container itself, not your Mac.
|
||||
|
||||
Run a non-destructive router smoke. A successful response records real token
|
||||
usage in `.specify/logs/level5/provider-usage.jsonl`.
|
||||
|
||||
```bash
|
||||
printf 'Return exactly: CASAN_OK\n' >/tmp/casan-prompt.txt
|
||||
bash packages/casan-harness/scripts/bash/model-router.sh \
|
||||
/tmp/casan-prompt.txt /tmp/casan-model-result.json --role generate \
|
||||
--model "$CASAN_MODEL_PRIMARY"
|
||||
python3 -m json.tool /tmp/casan-model-result.json
|
||||
```
|
||||
|
||||
The configured `omniroute` chat provider is classified as a gateway and always
|
||||
forces CASAN's preflight data-governance check before prompt content is sent.
|
||||
This is intentional: OmniRoute could route a request to a cloud model even when
|
||||
the first selected model is local.
|
||||
|
||||
To use a gateway on a private-LAN host later, explicitly name it; never use an
|
||||
open allowlist:
|
||||
|
||||
```bash
|
||||
export CASAN_OPENAI_COMPATIBLE_BASE_URL=http://192.168.1.5:20128/v1
|
||||
export CASAN_OPENAI_COMPATIBLE_ALLOWED_HOSTS=192.168.1.5
|
||||
```
|
||||
|
||||
Use HTTPS and a real certificate before moving this beyond a trusted LAN.
|
||||
|
||||
### Local Ornith default for the Control Panel
|
||||
|
||||
The local Docker Control Panel now defaults to the existing host Ollama model
|
||||
`ornith:9b`. It reaches Docker Desktop's host bridge at
|
||||
`host.docker.internal:11434`; CASAN permits only that exact bridge when the
|
||||
local compose profile explicitly enables it. If Ollama is unavailable, chat
|
||||
returns its deterministic evidence answer instead of fabricating a model result.
|
||||
|
||||
Use OmniRoute/OpenAI only when you deliberately want the gateway route. Create
|
||||
`casan.local.env` as described above and set:
|
||||
|
||||
```bash
|
||||
CASAN_CHAT_MODEL_PROVIDER=omniroute
|
||||
CASAN_OPENAI_COMPATIBLE_BASE_URL=http://host.docker.internal:20128/v1
|
||||
CASAN_OPENAI_COMPATIBLE_API_KEY=your-key
|
||||
```
|
||||
|
||||
## 5. Run CASAN with local models
|
||||
|
||||
For model-backed source generation, use the same environment and enable it only
|
||||
for the invocation:
|
||||
|
||||
```bash
|
||||
CASAN_GEN_MODE=model CASAN_PREFLIGHT=1 \
|
||||
node scripts/casan-step.mjs 01-srs 1
|
||||
```
|
||||
|
||||
CASAN continues to fall back safely to deterministic templates if the gateway
|
||||
is unavailable or the output is rejected by a harness gate. For governed chat,
|
||||
start the Control Panel and select the `omniroute` provider through the existing
|
||||
model configuration; the default remains deterministic/offline.
|
||||
|
||||
## 6. Stop and reset
|
||||
|
||||
Stop all containers while preserving MinIO data:
|
||||
|
||||
```bash
|
||||
bash packages/casan-harness/scripts/bash/local-full.sh stop
|
||||
```
|
||||
|
||||
To remove only the lab's persisted object-store data, first stop the lab, then:
|
||||
|
||||
```bash
|
||||
docker volume rm casan-local-prod_minio-data
|
||||
```
|
||||
|
||||
This is destructive and cannot be undone. Do not use it if the MinIO bucket has
|
||||
evidence you need to retain.
|
||||
|
||||
## Current scope and next phase
|
||||
|
||||
This local environment includes every currently implemented CASAN component.
|
||||
It intentionally uses Vault dev mode, self-signed TLS, mock IdPs, local MinIO,
|
||||
and mock alert/billing endpoints. Production promotion to the Linux server
|
||||
should replace those with managed Vault/KMS or HSM, real S3 Object Lock, real
|
||||
OIDC, HTTPS certificates, a secret manager, backup/restore tests, and firewall
|
||||
rules; it is a separate deployment exercise.
|
||||
Reference in New Issue
Block a user