# Backend bootstrap — initializing a suitable graph backend

The praxis skills run **without any backend**: filesystem-fallback is a designed, first-class
mode. Initialize a backend only if you want the graph-backed features — coverage grids, active
swarm state, bridge consultation, and cross-session audit persistence.

Throughout the skill bodies, `<praxis-backend>` names the root of whatever backend you
initialize. If none exists locally, bootstrap one as follows.

## 1. Choose and initialize the root

```
mkdir praxis-backend && cd praxis-backend
py -m venv .venv          # Windows (never bare `python` — Store-stub trap)
python3 -m venv .venv     # macOS / Linux
```

Convention the skills assume (so their auto-start and probe steps work unchanged):
- server entrypoint at `<praxis-backend>/server.py`
- dedicated interpreter at `<praxis-backend>/.venv/Scripts/python.exe` (Windows) or
  `<praxis-backend>/.venv/bin/python` (macOS/Linux) — launch is
  `.venv/Scripts/python.exe server.py` / `.venv/bin/python server.py` respectively
- HTTP on `http://localhost:8080`

**Port note:** the skills probe `:8080` by default. If 8080 is already occupied on your
machine, run the backend on another port and adjust the port in the skills' health-probe and
auto-start lines to match. The collision failure mode is loud (a bind error at startup),
never silent — but there is no environment-variable override today; the port lives in the
skill text.

## 2. The contract a "suitable" backend satisfies

Any server that answers these routes with these minimal shapes qualifies. Field-level
graceful degradation is built into the skills: empty-but-schema-valid responses render as
honest empty states, never as errors.

| Route | Method | Minimal conforming response |
|---|---|---|
| `/api/health` | GET | `{"status": "healthy"}` |
| `/api/search?q=&scope=nodes&limit=` | GET | `[]` or `{"nodes": []}` — rows are `{id, graph_id, name}` |
| `/api/megapraxis/mgs_coverage?cwd=` | GET | `{"version":"1","layers":{"meta":[],"genesis":[],"shadow":[],"mgs":[]},"totals":{"total":0,"per_layer":{"meta":0,"genesis":0,"shadow":0,"mgs":0},"unclassified":0,"dark":0},"tarski_unclassified":[]}` |
| `/api/megapraxis/agents_coverage?cwd=` | GET | same shape, agent rows |
| `/api/megapraxis/verify_completeness?cwd=` | GET | `{"converge":{"verdict":"incomplete","decidable_gaps":0,"tarski_acknowledged":true}}` (honest verdict while empty) |
| `/api/megapraxis/swarms_active?cwd=` | GET | `{"active":[],"methodology_active":[],"recommended":[],"total_scanned":0}` |
| `/api/nodes/<id>` | GET | node row JSON, or a JSON 404 |
| node create/update | POST/PUT | persist name + position; audit records are **name-encoded** (`SwarmInvocation::…`, `Contribution::…`, `Bridge::…` — encodings documented in the skill bodies) |

Optional richest tier: a stdio MCP server exposing `megapraxis_boot`, the coverage tools, and
node CRUD. Without MCP the skills fall back to HTTP; without HTTP, to filesystem. Every tier
is a designed mode, not an error.

## 3. Escalation path

- **Tier 0 — no backend.** Skills fully usable: deterministic disk scans, briefing contract intact.
  Coverage grids and swarm state are omitted with an explicit one-line footer.
- **Tier 1 — minimal stub.** A ~100-line HTTP server returning the shapes above. The skills'
  health and auto-start probes succeed, and HTTP consumers (exporters, ops) work against it.
  Note honestly: the skills' own graph-backed rendering is gated on the optional MCP layer,
  not on HTTP — with a stub but no MCP server, the briefing stays in filesystem mode by design.
  A stub that persists name-encoded nodes to SQLite already supports the audit trail and
  bridge manifest for HTTP consumers.
- **Tier 2 — full knowledge-graph server.** Real search, node CRUD, layer classification, and the
  megapraxis routes computing live coverage. This is what the origin system (intrikata-topology, a
  self-evolving knowledge-graph platform) provides; any equivalent works — the routes above are
  the entire coupling surface.

## 4. Optional assistant-op contract

A full backend may provide peer assistant ops behind the same `OP_CONTEXT` envelope:
`ClaudeCode_v1`, `CodexCode_v1`, and `GrokBuild_v1`. This is an optional Tier-2 capability,
not a prerequisite for the praxis skills.

The Codex boundary is deliberate:

- `codex exec` uses the Codex installation's existing subscription authentication.
- If Codex is unavailable at launch, `CodexCode_v1` may fall back to the official OpenAI CLI
  Responses API. That fallback prefers `CODEXCODE_OPENAI_API_KEY` and exposes it only to the
  fallback child process; legacy `OPENAI_API_KEY` remains supported.
- A missing fallback key returns `https://platform.openai.com/api-keys` and may open that page
  in the default browser. It does not reconfigure the Codex desktop app.
- The API fallback is response-only: it receives the enriched prompt but cannot inspect or edit
  local files like `codex exec` can.
- No API key belongs in this package, a graph node, an audit certificate, or a repository.

## 5. Verify your bootstrap

```
curl -s http://localhost:8080/api/health
```

must return `{"status": "healthy", ...}`. Then invoke `/megapraxis`. The briefing footer flips
from `_via: filesystem_` to `_via: graph_` (or a hybrid) only once an MCP server exposing
`megapraxis_boot` is registered (Tier 2 with MCP); with an HTTP-only backend the footer honestly
stays `_via: filesystem_` while health/auto-start and HTTP consumers use your server.
