---
name: lifecycle-activate-node
risk_class: config_mutation
inputs: [node_name]
verification: "homelab service <name> health (if it hosts a service); homelab doctor (if it's a client)"
docs_update_checklist: [doc_page_complete]
transition: "provisioning -> active"
---

# Lifecycle: activate a node

Per [seeds/ontology.yaml](../../../seeds/ontology.yaml). Requires: age key
enrolled if it needs secrets, mesh joined if it needs off-LAN reach,
ingress live if public, health check answering, doc page complete,
ledger entry.

1. If the node is a `homelab` client: finish enrollment per
   [client-enrollment.md](../client-enrollment/SKILL.md) (`--finalize-pubkey`,
   mesh join, `homelab doctor` green).
2. If it hosts a public service: add the `services:` entry in
   `inventory.yaml` (backend, url, doc_page, config_repo, risk_notes —
   see the Week-1 service contract fields) and wire the Caddy route in
   `dtoro/caddy-conf`.
3. Confirm the health check answers: `homelab service <name> health` or
   a direct `curl`.
4. Flip `state: provisioning` → `state: active` (or delete the `state:`
   field — `active` is the default) in `inventory.yaml`.
5. Complete the doc page (stub → full narrative: role, specs, how it's
   configured, dependencies).
6. Record the activation: `oikos/ledger.py append host:<name> activate
   config_mutation --result ok` (or let the CLI wrapper do this once
   Week 3's runbook automation lands).

Regenerate derived data: `python3 mcp/build_host_files.py && python3
inventory.yaml` so `inventory.yaml`, the topology diagram, and
the context card all reflect the new state.
