# Oikos — client guide

If you are a homelab machine, this is what Oikos is and what it gives you.
If you are an AI agent running on this machine, also read [AGENTS.md](AGENTS.md).

## What is Oikos?

Oikos is the agentic operating system for the **hubris** Proxmox homelab. It
observes state, classifies actions against policy, executes approved
procedures, learns from outcomes, and notifies the operator. It runs as a
Docker stack on mac-mini and exposes an MCP server + REST API.

## What Oikos provides

| Capability | How you access it |
|------------|-------------------|
| Entity query (topology, blast radius) | MCP `get_entity`, `get_blast_radius` |
| Full-text knowledge search | MCP `search_knowledge` |
| Service status + logs | MCP `get_service_status`, `tail_log` |
| LXC inventory + state | MCP `list_lxcs`, `get_lxc_state` |
| Context cards | MCP `explain` |
| Pre-flight risk classification | MCP `preflight` |
| Change history | MCP `get_change_history` |
| State snapshot (health, disk, drift) | MCP `get_state_snapshot` |
| Secrets (Infisical) | REST API + `oikos secret` CLI |
| Approve/deny pending executions | MCP `list_approvals`, `decide_approval` (chat-native, works on any platform) |
| Run a command on a host/LXC (policy-gated) | MCP `run` |
| Record a discovered fact/relationship | MCP `update_entity_attributes`, `create_relationship`, `upsert_knowledge` |

Most MCP tools are read-only; a few mutate the knowledge graph (recording
what you learned) or the live infrastructure (`run`),
gated by risk classification and — for `config_mutation`/`destructive`
actions — operator approval. See [AGENTS.md](AGENTS.md#3-the-mcp-server) for
the full tool catalog.

## Authentication

Every API/MCP call needs `Authorization: Bearer <token>` — there is no
unauthenticated path except `POST /api/v1/clients/enroll` and `/healthz`.
Enrollment (below) does not currently hand out a per-client bearer token;
get the shared `OIKOS_MCP_BEARER_TOKEN` from the operator until per-client
token issuance exists.

## Enrollment

Thin client model — no git clone, no sync timer. `bootstrap.sh` fetches only
the agent orientation files and tooling from the raw Gitea URL, then enrolls
via the Oikos API.

To enroll:
```bash
# Run from any machine with mesh connectivity
curl -fsSL https://git.hubris.network/dtoro/oikos/raw/main/bootstrap.sh | sudo bash

# Or with optional tooling:
curl ... | sudo bash -s -- --with-mcp      # wire Claude's MCP config
```

This calls `POST /api/v1/clients/enroll` on the Oikos API, which:
1. Validates the entity exists in DB (planned or provisioning state)
2. Validates mesh IP against expected subnets
3. Generates an age keypair and delivers it to the client
4. Creates an Infisical machine identity
5. Transitions the entity to provisioning state

## After enrollment

### What changes on your machine

- `/opt/homelab/` — agent orientation files (CLIENTS.md, AGENTS.md, OIKOS.md)
- `/opt/homelab/tools/` — tooling scripts (checks)
- `/etc/age/key.txt` — age private key for SOPS decryption (fallback)
- `/etc/infisical/identity` — Infisical machine identity (primary secrets)
- Context poller — launchd/systemd timer hits `GET /api/v1/clients/{slug}/context` every 5 minutes for agent file updates

### What's NOT on your machine

- No git clone of the full repo
- No `git pull` sync timer
- No `bin/homelab` CLI (replaced by MCP tools + API)
- No `.sops.yaml` or SOPS-encrypted backups (served via API context endpoint on demand)

### Thin client vs control plane

| | Thin client (workstation) | Control plane (mac-mini) |
|---|---|---|
| Disk footprint | ~100KB (orientation files + tools) | Full repo clone (~50MB) |
| Update mechanism | `GET /context?since=` poll | Git pull + post-pull.sh |
| Source of truth | DB via MCP | DB + local seeds + archive |
| Secrets access | Infisical (primary), age/SOPS served via API (fallback) | Infisical + local SOPS files |

### Your identity

Your identity in the homelab is defined in `inventory.yaml`. Run `hostname`
(Linux) or `scutil --get LocalHostName` (macOS), then look up your entry.
It tells you your role, what services you host, what's mounted, and your
mesh address.

### Source of truth hierarchy

1. **Postgres database** (runtime) — authoritative for entities, knowledge,
   signals, ledger. Query via MCP or REST API.
2. **Context poller** — agent files and tooling fetched via API deltas every
   5 minutes.
3. **Never guess.** If data is missing, query MCP. If MCP is down, grep the
   local `/opt/homelab/` files.

## The context poller

Every 5 minutes, launchd (macOS) or systemd (Linux) hits:

```
GET /api/v1/clients/ws:{hostname}/context?since={last_timestamp}
```

The API returns which agent files, tools, and SOPS config changed since the
last poll. Only changed files are downloaded. This replaces the old
`git pull` with a lightweight HTTP delta.

To trigger manually: run `/opt/homelab/tools/context-poller.sh`.

## Making changes

- **Read state**: use MCP tools or the API
- **Mutate state** (restart, edit config, deploy): classify the action against
  policy (query `preflight` MCP tool):
  - `read_only` / `reversible_low` — execute directly
  - `config_mutation` / `destructive` — request operator approval via
    `POST /api/v1/entities/{slug}/activate` (or equivalent lifecycle endpoint)
- **Secrets**: use Infisical (primary) or SOPS (fallback). Never hardcode.
- **Knowledge**: if you observe a discrepancy between docs and live state,
  update the DB via the API in the same session.

## MCP endpoint

```
https://mcp.hubris.network/mcp
```

Available tools are listed in [AGENTS.md](AGENTS.md#3-the-mcp-server).

## Communication mode

Apply [.agents/shared/caveman.md](.agents/shared/caveman.md) — terse,
fragment-heavy communication. Drop filler, keep substance.

## Related

- [AGENTS.md](AGENTS.md) — full agent orientation (read this first)
- [OIKOS.md](.agents/OIKOS.md) — operating model, OODA loop, risk classes
- [CONTRIBUTING.md](CONTRIBUTING.md) — developer guide for the Oikos codebase