# Production MVP Guide

This guide defines the minimum production baseline for running Logos ADK safely in internal services.

Stable Production additions for `0.2.x`:

- semver-governed public surface defined in [`logos_adk.version`](../logos_adk/version.py)
- per-run telemetry with framework/config metadata
- idempotent task queues with dead-letter and replay support
- audit retention/redaction controls
- production-oriented examples in [`examples.md`](examples.md) and deployment guidance in [`reference-architectures.md`](reference-architectures.md)

Public Framework additions for `0.3.x`:

- upgrade workflow commands in the CLI
- public/private module discipline and compatibility tests
- enterprise guidance for RBAC, tenancy, compliance, and secret rotation
- benchmark suite and reference architectures

## Supported Matrix

- Python: `3.11`, `3.12`
- Install extras:
  - API service: `logos-adk[serve]`
  - PostgreSQL-backed persistence: `logos-adk[postgresql]`
  - CI gates: `logos-adk[dev]`

Recommended install:

```bash
pip install -e ".[dev,serve,postgresql]"
```

## Docker-First Deployment

Build:

```bash
docker build -t logos-adk:latest .
```

Run:

```bash
docker run --rm -p 8000:8000 \
  -e AGENT_CONFIG=/app/agent.yaml \
  -e LOGOS_ADK_API_KEYS_JSON='{"prod-key":{"name":"ops","scopes":["agent:run","state:read","state:write","knowledge:write","quality:read","quality:run"],"workspaces":["acme"]}}' \
  -e LOGOS_ADK_REQUIRE_WORKSPACE=true \
  -e LOGOS_ADK_DATABASE_URL='postgresql://user:pass@db/logos' \
  logos-adk:latest
```

## Persistence and Migrations

Every persistent backend now records a schema version in the database.

Supported targets:

- `state`
- `memory`
- `cache`
- `quality`

Check whether a target needs migration:

```bash
logos-adk storage upgrade-check --kind state --backend sqlite --path .logos_adk/state.db
logos-adk storage upgrade-check --kind quality --backend postgresql --dsn "$LOGOS_ADK_DATABASE_URL"
```

Apply built-in migrations / initialize schema metadata:

```bash
logos-adk storage migrate --kind state --backend sqlite --path .logos_adk/state.db
logos-adk storage migrate --kind memory --backend postgresql --dsn "$LOGOS_ADK_DATABASE_URL"
```

### PostgreSQL-First Operator Persistence

For production, prefer PostgreSQL for operator and self-learning persistence instead of local SQLite files.

Recommended environment layout:

```bash
export LOGOS_ADK_LEARNING_BACKEND=postgresql
export LOGOS_ADK_LEARNING_DSN='postgresql://user:pass@db/learning'
export LOGOS_ADK_RETRIEVAL_DSN='postgresql://user:pass@db/retrieval'
export LOGOS_ADK_TOOL_WORKFLOW_DSN='postgresql://user:pass@db/tool_workflow'
export LOGOS_ADK_MODEL_ROUTING_DSN='postgresql://user:pass@db/model_routing'
export LOGOS_ADK_REFLECTION_DSN='postgresql://user:pass@db/reflection'
export LOGOS_ADK_PROMPT_REGISTRY_DSN='postgresql://user:pass@db/prompts'
export LOGOS_ADK_CONTINUOUS_EVAL_DSN='postgresql://user:pass@db/continuous_eval'
export LOGOS_ADK_QUALITY_DSN='postgresql://user:pass@db/quality'
```

These stores initialize their schemas on first use. Unlike `state` / `memory` / `cache` / `quality` upgrade flows above, most learning/operator stores do not require a separate `storage migrate` command before first access.

Operational guidance:

- keep one DSN per subsystem when you want independent retention, scaling, or incident domains
- use one shared PostgreSQL cluster only if schema ownership, backup, and alerting are already in place
- do not mix `--db-path` and `--dsn` for the same command invocation unless you intentionally want different backends per component

Examples:

```bash
logos-adk evaluation scorecard \
  --dsn "$LOGOS_ADK_LEARNING_DSN" \
  --workspace-id acme

logos-adk evaluation run-regression-job agent.yaml \
  --dsn "$LOGOS_ADK_LEARNING_DSN" \
  --quality-dsn "$LOGOS_ADK_QUALITY_DSN" \
  --continuous-eval-dsn "$LOGOS_ADK_CONTINUOUS_EVAL_DSN" \
  --prompt-registry-dsn "$LOGOS_ADK_PROMPT_REGISTRY_DSN" \
  --workspace-id acme

logos-adk improvement policy \
  --dsn "$LOGOS_ADK_LEARNING_DSN" \
  --retrieval-dsn "$LOGOS_ADK_RETRIEVAL_DSN" \
  --tool-workflow-dsn "$LOGOS_ADK_TOOL_WORKFLOW_DSN" \
  --model-routing-dsn "$LOGOS_ADK_MODEL_ROUTING_DSN" \
  --workspace-id acme
```

## API Auth and Workspace Isolation

Use `LOGOS_ADK_API_KEYS_JSON` to define principals, scopes, and workspace access.

Example:

```json
{
  "prod-key": {
    "name": "ops",
    "scopes": ["agent:run", "state:read", "state:write", "knowledge:write"],
    "workspaces": ["acme", "beta"]
  }
}
```

Pass the token:

```http
Authorization: Bearer prod-key
X-Workspace-Id: acme
```

Scope boundaries:

- `agent:run`
- `state:read`
- `state:write`
- `knowledge:write`
- `quality:read`
- `quality:run`
- `observability:read`

## Health and Readiness Contract

- `/health/live`
  - process is running
- `/health/ready`
  - providers and core runtime dependencies are ready
- `/health`
  - full health payload for operators

If your load balancer supports separate liveness/readiness probes:

- use `/health/live` for liveness
- use `/health/ready` for readiness

## Secret Management

Do not commit secrets into YAML config files.

Use environment variables for:

- `LOGOS_ADK_API_KEYS_JSON`
- `LOGOS_ADK_DATABASE_URL`
- `LOGOS_ADK_LEARNING_DSN`
- `LOGOS_ADK_RETRIEVAL_DSN`
- `LOGOS_ADK_TOOL_WORKFLOW_DSN`
- `LOGOS_ADK_MODEL_ROUTING_DSN`
- `LOGOS_ADK_REFLECTION_DSN`
- `LOGOS_ADK_PROMPT_REGISTRY_DSN`
- `LOGOS_ADK_CONTINUOUS_EVAL_DSN`
- `LOGOS_ADK_QUALITY_DSN`
- provider keys such as `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`

For production:

- inject secrets via container runtime / orchestrator secret store
- rotate API keys independently from deploys
- avoid passing secrets through CLI flags unless debugging locally

## CI Release Gates

The MVP release gate is:

```bash
ruff check .
python -m mypy
pytest -q
```

CI runs on Python `3.11` and `3.12`.
