v0.18.0: MCP entity-graph CRUD, lifecycle validation, curl -o /dev/null fix
- create_entity, set_entity_state, end_relationship MCP tools - update_entity_attributes now triggers check derivation via EnsureEntityChecks - shared db.EnsureEntityChecks + db.ValidateTransition hooks (HTTP + MCP parity) - curl -o /dev/null now classified read_only (was config_mutation) - db.ErrTransitionInvalid sentinel for HTTP error-type accuracy - SOUL.md: capability escalation, self-grounding, exploration budget rules - Runbook: oikos check lifecycle for agent self-knowledge
This commit is contained in:
104
archive/knowledge/infrastructure/oikos-check-lifecycle.md
Normal file
104
archive/knowledge/infrastructure/oikos-check-lifecycle.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Oikos check lifecycle — how monitoring works
|
||||
|
||||
This runbook covers how Oikos health checks are derived, created, and wired so
|
||||
an agent (Nomos) doesn't reverse-engineer source when asked to add monitoring to
|
||||
an entity — the problem that stranded session `23da10db` (2026-08-03).
|
||||
|
||||
## Concepts
|
||||
|
||||
- **`check_defs`** (scheduler config, table `check_defs`): the row the scheduler
|
||||
reads to know *what* to probe and *when*. One per check instance.
|
||||
- **`check` entity** (type `check`, slug `check:<kind>:<target>:<n>`): the
|
||||
knowledge-graph entity for that check. It carries attributes
|
||||
(`check_type`, `target`, `port`, …) and `checks` edges to the probed target.
|
||||
- **`monitoring` spec** on an entity type (`entity_types.monitoring_spec`): the
|
||||
default list of check kinds (e.g. `[http, process]` for `service`).
|
||||
- Per-entity override: set `monitoring` in the entity's attributes —
|
||||
`"none"` for zero checks, `["http"]` to replace the type defaults.
|
||||
- **`checkdefaults.Ensure`** (`internal/checkdefaults/defaults.go`): the
|
||||
function that reads the monitoring spec, resolves host/port/URL from
|
||||
attributes + relationships, and writes `check_defs` rows. Idempotent.
|
||||
|
||||
## When checks are derived
|
||||
|
||||
`checkdefaults.Ensure` runs in three situations (as of v0.17.1+):
|
||||
|
||||
1. **Seed/deploy ingest** — `internal/db/seed.go:231`. Every entity gets its
|
||||
default checks once on initial ingest.
|
||||
2. **HTTP `POST /api/v1/entities` (create)** — `ensureDefaultChecks` at
|
||||
`internal/httpapi/impl.go:1012`. Creating an entity via the REST API derives
|
||||
its checks in the same transaction.
|
||||
3. **HTTP `PATCH /api/v1/entities` (patch)** — `ensureDefaultChecks` at
|
||||
`internal/httpapi/impl.go:1280`. Changing an entity's attributes (especially
|
||||
`monitoring`) via the REST API regenerates its checks.
|
||||
4. **MCP `create_entity`** — SAME hook. Creating an entity via the MCP tool
|
||||
derives checks. (Added 2026-08-03; previously MCP had no create.)
|
||||
5. **MCP `update_entity_attributes`** — SAME hook. Changing an entity's
|
||||
`monitoring` attribute via MCP now regenerates checks. (Added 2026-08-03;
|
||||
previously MCP updates silently skipped check derivation — the exact bug
|
||||
that stranded the haos session.)
|
||||
|
||||
## Check slug grammar
|
||||
|
||||
```
|
||||
check:<kind>:<target-type>:<target-name>:<n>
|
||||
```
|
||||
|
||||
Examples: `check:http:service:jellyfin:0`, `check:vm-status:vm:haos:0`,
|
||||
`check:cert-expiry:cert:house.hubris.network:0`.
|
||||
|
||||
## Adding monitoring to an entity
|
||||
|
||||
**If the entity already exists:**
|
||||
|
||||
```
|
||||
update_entity_attributes(slug="service:haos", attributes={"monitoring":["http"]})
|
||||
```
|
||||
|
||||
This regenerates checks via `checkdefaults.Ensure`. The result message tells you
|
||||
how many checks were derived and whether any kinds were skipped (and why).
|
||||
|
||||
**If the entity does not exist yet (a new check, ingress, cert, etc.):**
|
||||
|
||||
```
|
||||
create_entity(type="check", name="HAOS http check",
|
||||
slug="check:http:service:haos:0",
|
||||
attributes={"check_type":"http:service","target":"service:haos","port":"8123"})
|
||||
```
|
||||
|
||||
This creates the entity AND derives its `check_defs`. Same for a new `ingress`
|
||||
(`type=ingress`, monitoring `[http]`) or `cert` (`type=cert`,
|
||||
monitoring `[cert-expiry]`).
|
||||
|
||||
**To remove monitoring:** set `monitoring:["none"]` or transition the entity
|
||||
to a terminal lifecycle state (`set_entity_state` → `deprecated`/`destroyed`).
|
||||
|
||||
## Caveats
|
||||
|
||||
- **A service without a `url` attribute AND without a `probe_unit` gets no
|
||||
process check** (the http check covers liveness; the process check would
|
||||
be redundant without an opt-in `probe_unit`). The skip is logged.
|
||||
- **A service whose address comes from a `hosts` edge** may produce no checks on
|
||||
initial create because the edge doesn't exist yet — the next inventory ingest
|
||||
(or a later `update_entity_attributes` after the edge is created) fills it in.
|
||||
- **A `not found` error from `update_entity_attributes`** means the entity
|
||||
doesn't exist — use `create_entity` instead.
|
||||
- **`check_defs` has target columns** (`target_id`, `target_type`). A check
|
||||
entity needs a `checks` relationship (`create_relationship(source=check:…,
|
||||
target=service:…, type="checks")`) so the scheduler can resolve what to
|
||||
probe. `create_entity` derives the check_def; `create_relationship` links
|
||||
the check entity to its target in the graph.
|
||||
|
||||
## Related files
|
||||
|
||||
- `internal/checkdefaults/defaults.go` — `Ensure`, `Target`, `LogResult`
|
||||
- `internal/httpapi/default_checks.go` — `ensureDefaultChecks` (HTTP hook)
|
||||
- `internal/db/checks.go` — `db.EnsureEntityChecks` (shared hook)
|
||||
- `internal/db/seed.go` — seed-time check derivation
|
||||
- `internal/mcp/tools.go` — `create_entity`, `update_entity_attributes`
|
||||
|
||||
## Revision history
|
||||
|
||||
- **2026-08-03:** Created after session `23da10db` stranded for lack of entity-
|
||||
creation tool and unawareness of check-derivation triggers. Covers the MCP
|
||||
create_entity + update_entity_attributes regen paths added same day.
|
||||
Reference in New Issue
Block a user