# AGENTS.md — orientation for any agent on a homelab client You are running on a machine that is part of the **hubris** homelab. The full context is in this checkout at `/opt/homelab-context/`. This file is the entry point. Read it once at start, then keep working. - **New client?** Read [CLIENTS.md](CLIENTS.md) first. - **Developing on this repo?** Also read [.agents/dev/CONTRIBUTING.md](.agents/dev/CONTRIBUTING.md). The operating model — OODA loop, risk classes, approval rules, the ontology, and node lifecycle — is defined in [OIKOS.md](.agents/OIKOS.md). Before any mutation, classify the action against `seeds/policy.yaml`; when the class requires approval, stop and ask the operator. Agent-facing instruction lives under `.agents/`: `.agents/shared/` holds the conventions every agent applies ([writing-style](.agents/shared/writing-style.md), [caveman](.agents/shared/caveman.md), [page-templates](.agents/shared/page-templates.md), [llm-wiki](.agents/shared/llm-wiki.md)), and `.agents/domains/` holds the per-domain schemas ([knowledge](.agents/domains/knowledge/schema.md), [operations](.agents/domains/operations/schema.md)). **Source of truth:** The Postgres database is the single source of truth for all structured data and knowledge. It is bootstrapped from `seeds/` at deploy time: `seeds/ontology.yaml` (entity types, relationships, lifecycles), `seeds/inventory.yaml` (hosts, services, entities), `seeds/policy.yaml` (risk classes, approval rules), and `seeds/knowledge.yaml` (documents, investigations, runbooks). The old narrative wiki is archived at `archive/knowledge/` for historical reference. ## 1. Who you are Run `hostname` (Linux) or `scutil --get LocalHostName` (macOS), then read: /opt/homelab-context/inventory.yaml That file tells you your role, your peers, what's mounted, and what services you host. If it does not exist, this client was not enrolled — stop and tell the operator to run `homelab client add ` from an existing client. ## 2. The topology - `/opt/homelab-context/inventory.yaml` — every host, LXC, VM, and workstation with their mesh addresses, roles, and service mappings. This is the seed file; at runtime the DB is authoritative (query via MCP `get_entity` or the REST API). - `/opt/homelab-context/seeds/knowledge.yaml` — full narrative knowledge: 36 documents, 6 investigations, 12 runbooks. Ingested into the DB on deploy. - `/opt/homelab-context/.agents/operations/commands.md` — the operator's cheatsheet for pct, caddy, DNS, and the Oikos command surface. ## 3. The MCP server The homelab exposes a Model Context Protocol server with structured tools. Endpoint: `https://mcp.hubris.network/mcp`. Available tools (21 total): Context — observe + orient: get_entity(slug), list_entities(type, limit, cursor), get_relations(entity), get_blast_radius(entity), search_knowledge(query) — ILIKE search over documents, investigations, runbooks in the knowledge_entities table get_patterns(status, entity_type, action) — learned action patterns get_skills(status) — available automation skills Management — live state: get_service_status(service_slug) — systemctl is-active on target host tail_log(service_slug, lines=200) — journalctl list_lxcs() — all LXC containers with ID, host, IP, health get_lxc_state(lxc_slug) — pct status from Proxmox host ping_service(service_slug) — HTTP reachability from entity_status Oikos — decisions: explain(service_slug) — compact context card (type, state, health, relations) preflight(service_slug, action) — risk class + approval requirement whoami(hostname) — entity record, peers, health for a client get_change_history(entity_slug, limit=20) — last audit-log entries per entity get_state_snapshot() — fleet health, disk, drift count Operations — observe + act: get_health_summary() — fleet health counts (healthy/degraded/down/unknown) get_signal_history(entity_slug, state, limit) — open + recent signals get_audit_trail(entity_id) — audit log filter + browse get_agent_activity(limit) — agent self-inspection query_metrics(hours=24) — time-series metric bucketed averages get_trend(entity_id, days=7) — metric slope over time get_event_timeline(severity, entity_slug, limit) — recent events Execution — the single mutation path: request_execution(target, action, params) — policy-gated. reversible_low (restart, reload, pct_exec, apt audit) runs immediately; config_mutation (systemctl enable/disable, apt upgrade) queues for operator approval via Matrix, then executes on ✅. get_execution_status(execution_id) — poll progress **When to prefer MCP over grepping the clone:** always for knowledge queries. `search_knowledge("jellyfin hardware acceleration")` returns ranked results from the DB with entity links. `get_entity_knowledge("lxc:jellyfin")` returns documents, runbooks, and investigations in one call. Grep the clone only when MCP is unreachable. ## 4. Knowledge conventions All narrative knowledge (documents, investigations, runbooks) lives in the DB (`knowledge_entities` table) and is seeded from `seeds/knowledge.yaml`. Agents can register new knowledge via the API: ``` POST /api/v1/knowledge/{entity_slug} {"title": "...", "content": "...", "tags": ["..."]} ``` The DB is the truth. The old wiki files are in `knowledge/wiki/` pending archive per the DB-as-source-of-truth plan. - **Runbook procedures** live as `runbook` entities in the DB and as SKILL.md files under `.agents/skills//`. They carry `risk_class`, `procedure` (JSON-schema-validated), and are linked to entity types via `applies_to_type`. - **Investigations** are `investigation` entities linked to affected entities via `about` edges. - **Documents** are `document` entities linked to entities via `documents` edges. They carry `at_glance` (structured attributes) and `changelog` (parsed entries). - **Live state precedence.** If you observe a discrepancy between the docs and running state, update the DB *in the same session* via the API. The `oikos export` command regenerates `seeds/knowledge.yaml` for version control. ## 5. Acting on the homelab - **Read state**: use MCP tools. Nomos (the AI agent) is the primary operator interface — it has 21 MCP tools for observe/orient/decide/act. - **Actions** (restart, logs, apt, pct exec): Nomos calls `request_execution` via MCP. `reversible_low` actions execute immediately; `config_mutation` and `destructive` actions are queued for operator approval via Matrix. - **Secrets**: managed by Infisical (`oikos secret` subcommand for migration). Never hardcode secrets — use env vars from `.env`. - **Mutations** (restart, edit configs, etc.): classified against `seeds/policy.yaml`. `reversible_low` actions auto-execute; `config_mutation`/`destructive` actions require approval. a valid `--approval-id` from `homelab approval request` — see OIKOS.md. ## 6. Communication mode Read and apply `/opt/homelab-context/.agents/shared/caveman.md` (if present). It defines the lab's terse-communication standard — drop filler, keep substance, use fragments. ## 7. Auto-setup mechanism The homelab-context repo ships tooling that gets automatically installed on every client after `git pull`. This is handled by `tools/post-pull.sh` (replaces the raw git pull in the sync timer) which runs any script matching `tools/*.setup.sh` after pull. Currently auto-setup: - **Caveman + templates** (`tools/setup-caveman.sh`): Installs Caveman npm package, wrapper scripts, and compact output templates for token-efficient CLI output. Wrapper at `~/bin/caveman_wrapper.sh`. - **Nomos agent persona** (`tools/setup-nomos-soul.sh`): Provisions `~/.nomos/SOUL.md` from `NOMOS.md` on Nomos agents. This ensures every Nomos agent follows the canonical homelab persona (token efficiency, source of truth hierarchy). No-op on non-Nomos agents. To add a new auto-setup, create `tools/.setup.sh` in the repo, commit and push. All enrolled clients pick it up within 5 minutes. To trigger sync manually: `sudo homelab sync` or wait for the 5-min timer. ## 8. When in doubt Use MCP tools: `search_knowledge ` for narrative context, `get_entity ` for structured data, `get_entity_knowledge ` for everything linked to an entity. The clone is the fallback; MCP is the index.