sync AGENTS.md tool list with MCP server (63 tools); fix 7 stale references in .agents/
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled

This commit is contained in:
2026-08-09 00:04:58 +02:00
parent 5e10437fe3
commit ebe1b95acf
7 changed files with 82 additions and 68 deletions

View File

@@ -30,7 +30,7 @@ one pass through **Observe → Orient → Decide → Act**:
- **queue**: informational — console + reports - **queue**: informational — console + reports
The classifier can only *lower* autonomy relative to policy, never raise The classifier can only *lower* autonomy relative to policy, never raise
it. When in doubt, escalate. it. When in doubt, escalate.
4. **Act** — execute through `homelab` commands or runbooks (never ad-hoc 4. **Act** — execute through MCP `run` or runbooks (never ad-hoc
SSH), then **verify** with the action's verification command, write a SSH), then **verify** with the action's verification command, write a
**ledger** entry, resolve the Signal, and update docs in the same session. **ledger** entry, resolve the Signal, and update docs in the same session.
@@ -88,7 +88,7 @@ via the API's `/api/v1/graph` endpoint, and the Mermaid export at
## Conventions carried forward ## Conventions carried forward
- Inventory is the truth; live state wins over narrative docs. - Inventory is the truth; live state wins over narrative docs.
- Prefer `homelab` CLI and MCP over ad-hoc SSH. - Prefer MCP tools over ad-hoc SSH.
- Meaningful changes update docs in the same session. - Meaningful changes update docs in the same session.
- Secrets are decrypted locally via per-client keys; never into docs/comments. - Secrets are decrypted locally via per-client keys; never into docs/comments.
- Tracked configs change by commit + push, not local edits. - Tracked configs change by commit + push, not local edits.
@@ -141,7 +141,7 @@ in the Go binary.
- Standalone Nomos MCP client binary (`cmd/nomos`) with gateway mode - Standalone Nomos MCP client binary (`cmd/nomos`) with gateway mode
(:8092). Structured queries + natural-language routing to the MCP tool (:8092). Structured queries + natural-language routing to the MCP tool
list (see AGENTS.md §3). Agent activity logging on every tool call. No SSH keys. list (see AGENTS.md §3). Agent activity logging on every tool call. No SSH keys.
- `nomos/` directory with config, SOUL.md, homelab-ops skill. - `nomos/` directory with config, SOUL.md, `homelab-ops` skill at `nomos/skills/homelab-ops/`.
- Nomos Docker service in `docker-compose.yml` (profile: full). - Nomos Docker service in `docker-compose.yml` (profile: full).
- Go packages: `cmd/nomos/`, `compose/nomos/`. - Go packages: `cmd/nomos/`, `compose/nomos/`.

View File

@@ -20,6 +20,6 @@ Run from the repo root:
Exit code is non-zero when any violation is found, so it can gate a commit. The banned-vocabulary Exit code is non-zero when any violation is found, so it can gate a commit. The banned-vocabulary
list mirrors `writing-style.md`; update both together if the standard changes. list mirrors `writing-style.md`; update both together if the standard changes.
> **Known baseline.** `archive/knowledge/archive/knowledge/containers/101-jellyfin.md` links into a sibling repo > **Known baseline.** `archive/knowledge/containers/101-jellyfin.md` links into a sibling repo
> (`devops/homelab-authentik-admin`) that this checkout does not contain — expected, not a bug. > (`devops/homelab-authentik-admin`) that this checkout does not contain — expected, not a bug.
> Any other broken link is a real regression; investigate before dismissing it as baseline noise. > Any other broken link is a real regression; investigate before dismissing it as baseline noise.

View File

@@ -36,8 +36,9 @@ ledger entry.
6. Update the entity's `state` to `destroyed` in `seeds/inventory.yaml` 6. Update the entity's `state` to `destroyed` in `seeds/inventory.yaml`
(or move it to an `archaeology:`-style section if the schema still has (or move it to an `archaeology:`-style section if the schema still has
one) — `pve_id`, `destroyed` date, `reason` — then `oikos seed` to one) — `pve_id`, `destroyed` date, `reason` — then `oikos seed` to
ingest. Add a row to `containers/index.md` "Recently destroyed" table ingest. Add a row to the legacy `archive/knowledge/containers/index.md`
(kept for human-readable browsing alongside the structured data). "Recently destroyed" table (kept for human-readable browsing
alongside the structured data in the DB).
7. No manual ledger step — mutations through the API are recorded 7. No manual ledger step — mutations through the API are recorded
automatically in the `audit_log` table (MCP `get_audit_trail`, automatically in the `audit_log` table (MCP `get_audit_trail`,
`get_change_history`). The old `oikos/ledger.py append` was retired `get_change_history`). The old `oikos/ledger.py append` was retired

View File

@@ -27,9 +27,10 @@ chosen, doc page stub.
will self-enroll as a client afterward (see will self-enroll as a client afterward (see
[CLIENTS.md](../../../CLIENTS.md#enrollment)), the entity must exist in [CLIENTS.md](../../../CLIENTS.md#enrollment)), the entity must exist in
`planned`/`provisioning` state before `bootstrap.sh` runs there. `planned`/`provisioning` state before `bootstrap.sh` runs there.
3. Stub the doc page (`containers/<pve_id>-<name>.md` or 3. Stub a document entity via MCP `upsert_knowledge` with
`vms/<pve_id>-<name>.md`) — even a one-line "provisioning, see plan X" `kind: document` and about set to the new entity slug — even a
is enough to satisfy the transition requirement. one-line "provisioning, see plan X" is enough to satisfy the
transition requirement.
4. Reserve the IP in DNS/DHCP notes if it's a fixed LAN address. 4. Reserve the IP in DNS/DHCP notes if it's a fixed LAN address.
Next: [lifecycle-activate-node.md](../lifecycle-activate-node/SKILL.md). Next: [lifecycle-activate-node.md](../lifecycle-activate-node/SKILL.md).

View File

@@ -78,5 +78,5 @@ Session: {id[:8]} — "{title[:60]}"
- `internal/mcp/server.go` — all tool implementations (`run`, `list_lxcs`, …) - `internal/mcp/server.go` — all tool implementations (`run`, `list_lxcs`, …)
- `web/src/lib/components/ToolCallGroup.svelte` — tool result display - `web/src/lib/components/ToolCallGroup.svelte` — tool result display
- `nomos/SOUL.md` — agent persona and tool selection rules - `nomos/SOUL.md` — agent persona and tool selection rules
- `plans/2026-07-09-chat-sessions-improvements.md` — prior session findings - `plans/done/2026-07-09-chat-sessions-improvements.md` — prior session findings
- `plans/2026-07-09-session-execution-and-ux-fixes.md` — latest plan - `plans/done/2026-07-09-session-execution-and-ux-fixes.md` — latest plan

120
AGENTS.md
View File

@@ -56,67 +56,79 @@ Endpoint: `https://mcp.hubris.network/mcp`. Every call needs
enrollment and `/healthz` (see "Authentication" below for where the token enrollment and `/healthz` (see "Authentication" below for where the token
comes from). comes from).
Available tools (the authoritative list — count them below if a number is Available tools (63 total — the authoritative list; do not hardcode the count
needed; do not hardcode the count elsewhere): elsewhere; regenerate from `internal/mcp/` when tools change):
Context — observe + orient: Entity Tools — knowledge graph, discovery, and lifecycle:
get_entity(slug), list_entities(type, limit, cursor), ping — lightweight connectivity check
get_relations(entity), get_blast_radius(entity), get_entity(slug_or_id) — get an entity by slug or UUID
search_knowledge(query) — ILIKE search over documents, investigations, list_entities(type, state, q, limit) — entities filtered by type, state, or search
runbooks in the knowledge_entities table get_relations(entity_id, types) — list inbound/outbound edges for one entity
get_entity_knowledge(entity_slug) — every document, investigation, and get_blast_radius(entity_id, depth=3) — entities affected if this one goes down
runbook linked to one entity, in one call create_entity(type, name, slug, attributes, state) — create a new entity in the graph
get_patterns(status, entity_type, action) — learned action patterns update_entity_attributes(slug, attributes) — merge discovered facts into an entity
get_skills(status) — available automation skills set_entity_state(slug, state) — transition entity to a new lifecycle state
http_get(url) — fetch a public page/raw file (e.g. researching how to create_relationship(source, target, type) — record a discovered edge
deploy something before provisioning it); HTTP/HTTPS only, ~16KB cap end_relationship(source, target, type) — soft-delete an active edge
whoami(hostname) — entity record, peers, and health for a host
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
list_my_secrets(caller_pubkey) — secrets accessible to this client by
age public key
Oikos — decisions:
explain(service_slug) — compact context card (type, state, health, relations) explain(service_slug) — compact context card (type, state, health, relations)
preflight(service_slug, action) — risk class + approval requirement 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_change_history(entity_slug, limit=20) — last audit-log entries per entity
get_state_snapshot() — fleet health, disk, drift count get_state_snapshot() — last scheduler Observe-pass: fleet health, disk, drift
audit_knowledge_graph() — read-only drift report over the graph and checks
discover_infra_drift() — running guests vs DB: missing/ghost entities
find_entities_by(key, value, limit=25) — search entities by attribute values
Operations — observe + act: Ops Tools — live state, signals, checks, and execution:
get_health_summary() — fleet health counts (healthy/degraded/down/unknown) run(target, command, purpose, declared_risk) — general execution primitive; read-only auto-acts, mutations queue for approval, destructive always needs explicit confirmation
get_signal_history(entity_slug, state, limit) — open + recent signals inspect_path(path, targets) — bulk mount/df/ls/stat across multiple hosts/LXCs
get_audit_trail(entity_id) — audit log filter + browse get_execution_status(execution_id) — poll execution progress
get_agent_activity(limit) — agent self-inspection tail_log(service_slug, lines=50) — journalctl for a service
query_metrics(hours=24) — time-series metric bucketed averages get_service_status(service_slug) — systemctl is-active/is-enabled
get_trend(entity_id, days=7) — metric slope over time get_lxc_state(lxc_slug) — pct status from Proxmox host
get_event_timeline(severity, entity_slug, limit) — recent events ping_service(service_slug) — HTTP reachability + scheduler health state
list_lxcs(state) — all LXC containers with ID, host, IP, last-audited hint
ack_signal(signal_id) — acknowledge an open signal
resolve_signal(signal_id, resolution) — resolve a signal with optional note
mute_signal(signal_id, duration_s=3600) — temporarily mute a signal
cancel_execution(execution_id, reason) — cancel a queued/running execution
update_check(check_id, enabled) — enable or disable a health check
list_checks(entity_slug, enabled) — list health checks with verdict, probe kind
list_executions(entity_slug, status, limit=25) — cursor-paginated execution history
list_entity_sessions(entity_slug) — active Nomos sessions linked to an entity
get_dashboard_summary() — fleet overview: counts, health, signals, approvals
get_secret(key, path, environment) — retrieve a secret from the Infisical vault
list_secrets(path_prefix) — list secret keys in the Infisical vault
set_secret(key, value, path, environment) — store/update a secret (requires approval)
Knowledge — keep the graph current (none require approval; this updates Knowledge Tools — search, read, and maintain the knowledge base:
the knowledge graph, not live infrastructure): search_knowledge(query) — full-text search across docs (snippets, not full body)
upsert_knowledge(title, content) — record what you learned after solving get_entity_knowledge(entity_slug) — all docs/investigations/runbooks linked to a slug
a non-obvious problem; the only way anything persists past a session get_knowledge_content(slug) — full markdown body of one knowledge entry
update_entity_attributes(slug, attributes) — merge a discovered fact upsert_knowledge(title, content, about, tags, kind) — write what you learned
(IP, version, port, ...) into an entity so a future task doesn't delete_knowledge(knowledge_slug) — soft-delete a knowledge entry
rediscover it from scratch restore_knowledge(knowledge_slug) — restore a soft-deleted entry
create_relationship(source, target, type) — record a discovered edge merge_knowledge(target_slug, source_slugs) — fold entries into a target
(depends-on, hosts, routes-to, ...) between two entities rename_knowledge_tag(from, to) — bulk-rename tags across all entries
get_knowledge_revisions(knowledge_slug) — version history for a knowledge entry
get_knowledge_duplicates(threshold=0.6) — near-duplicate detection via trigram similarity
get_knowledge_orphans(stale_days=90) — unlinked, untagged, or stale entries
list_knowledge_tags() — all tags with usage counts and casing variants
list_my_secrets(caller_pubkey) — secrets accessible to a client by age public key
Execution — mutating the live infrastructure: Analysis Tools — fleet health, metrics, and introspection:
run(target, command) — the general execution primitive. Run any shell get_health_summary(health) — fleet health per entity, optionally filtered
command against a host or LXC; every command is auto-classified — get_audit_trail(entity_id) — query the audit log
read-only inspection runs immediately, anything state-changing needs query_metrics(hours=24) — time-series with bucketed avg/min/max
operator approval, and destructive patterns (rm -rf, dd, mkfs, get_signal_history(entity_slug, state, limit=50) — open and recent signals
pct/qm destroy, DROP TABLE, reboot, curl-pipe-to-shell, ...) always get_patterns(status, entity_type, action) — learned action patterns
need approval regardless of what you declare. This is the ONLY get_skills(status) — available automation skills
mutation tool — `request_execution` was retired 2026-07-14; the get_trend(entity_id, days=7) — metric slope, variance, and averages
former enum actions (restart, systemctl, pct_exec, apt_upgrade, get_event_timeline(severity, entity_slug, limit=50) — recent events
pct_create) are all expressed as `run(target, command)` now. get_agent_activity(limit=50) — agent self-inspection log
get_execution_status(execution_id) — poll progress classify_command(command, declared_risk) — pre-flight risk classification before `run`
get_ontology() — entity types, relationship types, and lifecycle definitions
http_get(url) — fetch a public web page/raw file; ~16KB cap
**When to prefer MCP over grepping the clone:** always for knowledge queries. **When to prefer MCP over grepping the clone:** always for knowledge queries.
`search_knowledge("jellyfin hardware acceleration")` returns ranked results from `search_knowledge("jellyfin hardware acceleration")` returns ranked results from

View File

@@ -1 +1 @@
0.30.0 0.30.1