Files
oikos/plans/2026-07-08-plan-implementation-audit.md
dtoro efa66c7321 close client lifecycle plan — API was already fully implemented
Plan #3 at 95%. Initial audit was incorrect — the entire API surface was
already implemented and tested:

- POST /clients/enroll — age key pair generation, mesh IP validation,
  attrs update, state → provisioning (impl.go:1091)
- GET /clients/{slug}/context — context_version delta with file/tool/sops
  change tracking (impl.go:1195)
- GET /clients/{slug}/secrets — scoped secret key listing (impl.go:1245)
- POST /entities/provision — constraint validation, provisioning_steps
  tracking, relationship edges, audit trail (impl.go:1271)
- GET /entities/{slug}/provision/status — step-by-step progress (impl.go:1380)
- PATCH /entities/{id} — lifecycle validation against lifecycle_defs,
  409 on illegal transitions (impl.go:933)
- client_lifecycle_test.go: 324 lines, full e2e:
  planned→enroll→provisioning→active→migrating→deprecated→failed
  + provision + relations + blast radius + rejection tests

Remaining (follow-up): bootstrap.sh + context-poller.sh thin-client scripts.
2026-07-08 11:12:45 +02:00

13 KiB

2026-07-08 — Plan vs implementation cross-reference

Status: Planned

Goal

Snapshot each active plan against the actual codebase on disk. No action taken — this is the map from which the next round of work is drawn.


1. Consolidate Oikos on mac-mini (2026-07-06)

Plan status: In Progress (Phases 1-6 implemented, pending cutover)

Reality check:

Claim Reality
Single binary, role subcommands True — cmd/oikos/main.go handles api|scheduler|notifier|all|migrate|seed|export|secret|version
OpenAPI-first True — 1,884-line api/openapi.yaml, oapi-codegen + chi, generated server stubs
DB as source of truth True — seeds → DB → API round-trip works, 13 forward-only migrations
MCP server (official SDK) True — modelcontextprotocol/go-sdk, Streamable HTTP, 21 tools registered
Docker stack on mac-mini True — docker-compose.yml with 9 services across 3 profiles, distroless images
Go domain layer + sentinel errors True — internal/domain/ with entity/signal/execution/pattern/skill/approval/check types
SQLC + repositories True — 4 query files in internal/db/queries/, generated into sqlcgen/
SSE event stream True — internal/httpapi/sse.go
Matrix approval webhook loop DONE. Migration 013 added matrix_event_id + alert_sent_at. Notifier polls reactions via /relations/{id}/m.annotation. / reactions trigger DecideApproval API call. Token verification in DecideApproval endpoint.
Phase 6 deploy + cutover complete Partially. 5 items still pending: Infisical bootstrap, watchdog test, rollback drill, rollback verify, apps/105 cleanup

Score: 85%

Blockers:

  • 5 cutover cleanup items outstanding
  • Infisical bootstrap never executed (SOPS still primary)
  • Rollback drill never rehearsed
  • Watchdog end-to-end test never run
  • apps/105 webhooks not removed, LXC not archived

2. Oikos Prometheus LXC (2026-07-05)

Plan status: Planned

Reality check:

Claim Reality
No LXC exists True
"Extend oikos/scheduler.py" probes Stale. oikos/scheduler.py was deleted. Plan references dead Python.
"bin/homelab" CLI for provisioning Stale. bin/homelab directory deleted. Go binary handles operations.
Undocumented LXC 131 Unchanged. Never investigated.

Score: 0%

Blockers:

  • Plan needs rewrite to reference Go scheduler (internal/scheduler/) and check_defs table
  • LXC 131 mystery unresolved — may collide with Prometheus VMID

3. Client Lifecycle in Go (2026-07-07)

Plan status: Done (2026-07-08)

Initial audit was incorrect — the API was already fully implemented. Discovery:

Phase Status
Phase 1: enrollment API (POST /api/v1/clients/enroll) DONE. impl.go:1091. Generates age keypair, stores pubkey in attrs, sets state→provisioning.
Phase 1: GET /api/v1/clients/{slug}/secrets DONE. impl.go:1245. Lists secrets scoped to client prefix from secretsManager.
Phase 1: GET /api/v1/clients/{slug}/context DONE. impl.go:1195. Returns context_version + changed file/tool/sops deltas.
Phase 2: POST /api/v1/entities/provision DONE. impl.go:1271. Creates entity in planned, validates slug uniqueness, inserts provisioning_steps, creates hosts relationship, emits audit+events.
Phase 2: GET /api/v1/entities/{slug}/provision/status DONE. impl.go:1380. Polls provisioning_steps table for step-by-step progress.
Phase 2: lifecycle transitions (activate/deprecate/destroy/fail) DONE. impl.go:933. PATCH /entities/{id} validates transitions against lifecycle_defs, rejects illegal transitions with 409.
Phase 3: MCP tools (whoami, explain, preflight, etc.) DONE. All 6 in mcp/server.go.
Tests DONE. client_lifecycle_test.go: 324 lines, full e2e: planned→enroll→provisioning→active→migrating→deprecated→failed. Provision rejection, relationship edges, blast radius verified.

Score: 95% (API complete; thin-client distribution scripts are follow-up)

Remaining (non-blocking):

  • bootstrap.sh rewrite for thin-client model (fetches AGENTS.md + OIKOS.md instead of git clone)
  • tools/context-poller.sh (polls GET /context every 5min)
  • Transition precondition enforcement (no-inbound-edges before destroy, etc.)

4. Comprehensive Audit & Next Steps (2026-07-07)

Plan status: Done (2026-07-08)

Reality check:

Audit item Status
Remove 9 superseded oikos/*.py files DONE. All deleted. Only gen-topology.py + gen_topology_lib.py remain.
bin/homelab audit/removal DONE. bin/ directory doesn't exist.
oikos/cards/ (45 files) audit/removal DONE. Directory deleted.
.hermes/plans/ (7 files) → archive/hermes-plans/ DONE. All 7 files archived.
TRMNL plan marked done in index DONE. Already in Done table.
Create wiki pages for seanime (133), romm (134) DONE. Both documented in seeds/knowledge.yaml. Wiki is DB-native now.
Update strong.md + hubris.md guest lists ARCHIVED. Host pages are in archive/knowledge/hosts/. DB is source of truth.
Regenerate topology.md ARCHIVED. Topology lives in DB relationships + seeds/inventory.yaml.
Prometheus plan — update Python → Go references DONE. References updated to Go scheduler, check_defs, MCP request_execution.
ADR-0011 (Go rewrite completion) COVERED. ADR-0011 exists (client lifecycle). Consolidation plan (1,540 lines) is the authoritative record.
Traefik reference audit VALID. VPS still runs traefik for public termination. References in seeds are accurate.
Infisical bootstrap PENDING. Cross-plan item, belongs to consolidation plan (#1).
Watchdog tested PENDING. Cross-plan item, belongs to consolidation plan (#1).
Rollback drill PENDING. Cross-plan item, belongs to consolidation plan (#1).
apps/105 cleanup PENDING. Cross-plan item, belongs to consolidation plan (#1).

Score: 100% (audit-specific items complete; remaining items owned by consolidation plan)

4 operator decisions: already resolved — oikos/cards/ deleted, bin/homelab gone. Infisical + apps/105 decisions belong to consolidation plan.


5. DB as Source of Truth (2026-07-07)

Plan status: Done (2026-07-08)

Reality check:

Phase Status
Phase 1: seeds/knowledge.yaml seed format DONE. 24 documents + 6 investigations + 3 runbooks.
Phase 1: content_hash column (migration 010) DONE.
Phase 1: search tsvector column + GIN index (migration 011) DONE.
Phase 1: Knowledge ingestion logic (internal/knowledge/seed.go) DONE.
Phase 2: convert wiki → seeds, archive originals DONE. archive/knowledge/ contains all originals. knowledge/ directory removed.
Phase 3: search_knowledge with PostgreSQL FTS DONE. Both MCP and HTTP use ts_rank + ts_headline + plainto_tsquery.
Phase 3: get_entity_knowledge MCP tool DONE. Walks relationships to return docs/investigations/runbooks linked to entity.
Phase 3: GET /api/v1/knowledge/search (HTTP) DONE. Full FTS with ranked results and snippets.
Phase 3: GET /api/v1/knowledge/{entitySlug} (HTTP) DONE. Aggregates documents, investigations, runbooks via relationship edges.
Phase 4: agent conventions for knowledge cycle DONE. AGENTS.md documents search_knowledge + get_entity_knowledge. Export round-trip via oikos export.

Score: 100%


6. MCP Tool Completion / bin/homelab Migration (2026-07-07)

Plan status: Done (2026-07-08)

Reality check:

Phase Status
tail_log — journalctl via SSH DONE. internal/mcp/server.go:466-488
get_service_status — systemctl is-active/enabled DONE. internal/mcp/server.go:489-509
ping_service — HTTP reachability from entity_status DONE. internal/mcp/server.go:438-465
list_lxcs — all LXCs with ID/host/IP/state DONE. internal/mcp/server.go:425-437
get_lxc_state — pct status from Proxmox DONE. internal/mcp/server.go:511-562
request_execution routing: restart DONE. Immediate execute via SSH.
request_execution routing: systemctl (reload/restart) DONE. Immediate; enable/disable gated as config_mutation.
request_execution routing: pct_exec DONE. Resolves Proxmox host via relationships.
request_execution routing: apt_upgrade (audit/upgrade) DONE. Audit immediate; upgrade gated as config_mutation.
get_execution_status DONE. internal/mcp/server.go:339-365
Matrix approval escalation DONE. Notifier sends Matrix messages with approval tokens. Stores matrix_event_id. Polls for / reactions via /relations/{id}/m.annotation. Calls DecideApproval internally on reaction detection. Token verification in DecideApproval endpoint.
Delete bin/homelab DONE. Directory gone.
Delete bin/oikos DONE. Directory gone.
Update AGENTS.md DONE. Full 21-tool surface documented. Stale homelab CLI references removed.

End-to-end approval flow:

Hermes → request_execution (config_mutation) → creates approval record
Notifier → generates HMAC token → sends Matrix message → stores event_id
Operator → reacts ✅ on Matrix message
Notifier → polls /relations/{eventId}/m.annotation → detects ✅
Notifier → POST /api/v1/approvals/{id}/decision {decision:"approve"}
DecideApproval → verifies token (if provided) → executes gated SSH command

Score: 100%


Summary matrix

Plan Score Key blocker
Consolidation 85% 5 cutover items + Infisical
Prometheus LXC 10% Not provisioned; plan references updated to Go
Client lifecycle 95% DONE — API complete; thin-client scripts are follow-up
Audit & next steps 100% DONE — all cleanup resolved
DB as source of truth 100% DONE — wiki archived, FTS live
MCP tool surface 100% DONE — Matrix approval loop + token verification wired

Drift catalog (index vs reality)

Issue Detail
TRMNL plan still in Active 2026-06-24-trmnl-plugins-lxc.md is in done/ but index.md Active table hasn't been updated
Grimmory plan internal status File in done/ but internal status header says in-progress
.hermes/plans/ directory Missing from disk. 7 executed plans lost. Recoverable from git history.
Prometheus plan stale refs References oikos/scheduler.py (deleted) and bin/homelab (deleted)
Consolidation cutover checklist 5 items open per scripts/cutover-checklist.md
Audit plan decisions 4 operator decisions listed as outstanding (section 7)

Changelog

2026-07-08 — plan 3 completed

Client lifecycle at 95%. Initial audit was wrong — the API was fully implemented with 324-line e2e test covering planned→enroll→provisioning→active→migrating→ deprecated→failed. Provision endpoint with constraints validation, relationship edges, and provisioning_steps tracking. Lifecycle transitions validated against lifecycle_defs with 409 on illegal transitions. Remaining: bootstrap.sh + context-poller.sh (thin-client distribution scripts).

2026-07-08 — plan 4 completed

Audit plan at 100%. All cleanup resolved: hermes plans archived to archive/hermes-plans/, TRMNL in Done, seanime/romm in seeds (no wiki pages needed), Prometheus plan references updated to Go. Remaining items (cutover, Infisical, watchdog, rollback, apps/105) belong to consolidation plan.

2026-07-08 — plan 5 completed

DB as source of truth at 100%. Wiki files already archived to archive/knowledge/. seeds/knowledge.yaml has 24 docs + 6 investigations + 3 runbooks. HTTP knowledge endpoints already used full PostgreSQL FTS. MCP search_knowledge upgraded from ILIKE to ts_rank/ts_headline. MCP get_entity_knowledge tool added, walks relationship edges to return all docs/investigations/runbooks for an entity.

2026-07-08 — plan 6 completed

MCP tool surface at 100%. Matrix approval webhook loop implemented: notifier sends Matrix messages, polls for / reactions via /relations/{id}/m.annotation, calls DecideApproval API internally. Token verification added to DecideApproval. AGENTS.md updated with full 21-tool surface and policy-gated mutation path. Migration 013 added matrix_event_id + alert_sent_at to approvals table.

2026-07-08 — initial audit

Cross-referenced all 6 active plans against codebase on disk. Consolidation infrastructure is solid; client lifecycle and Prometheus are the gap.