VM lifecycle — provisioning architecture & troubleshooting
PRD:
n1-cloud/docs/prd/PRD-350-2026-05-29-pyinfra-osquery-provisioning/PRD-350.mdMilestone M8 · merged vm-lifecycle corpus n1-cloud#1089
Alternatives considered
Section titled “Alternatives considered”- Single monolithic runbook — rejected: operators need a decision tree (state map → invariants → fix recipes) separate from the runtime architecture narrative. Split into six files under
n1-cloud/docs/runbook/vm-lifecycle/INDEX.md. - Keep
provision.ymlas a thin gh dispatch wrapper — rejected: converge now dispatches exclusively vian1-cloud/packages/api-worker/src/pulumi-automation/admin-api routes; a duplicate workflow duplicated failure modes without adding signal (removed fromn1-cloud-pulumi; see sibling README fix). box_<ULID>prefixed scope ids in CLI examples — rejected:n1-cloud/packages/api-worker/src/pulumi-automation/box-desired.lib.tsvalidates bare 26-char Crockford ULIDs only (n1-cloud/docs/agents/PRD-218/issues/0044-converge-rejects-prefixed-box-id-as-not-ulid/0044-converge-rejects-prefixed-box-id-as-not-ulid.md).
Start here — decision tree
Section titled “Start here — decision tree”Read n1-cloud/docs/runbook/vm-lifecycle/INDEX.md once. It routes:
- Architecture —
n1-cloud/docs/runbook/vm-lifecycle/provisioning-architecture.runbook.md: converge →stack.up()→ output-mapper writeback → bootstrap floor; four telemetry sources with authority levels. - Prerequisites —
n1-cloud/docs/runbook/vm-lifecycle/state-map-and-prerequisites.runbook.md: golden image, instance-type catalog ( n1-cloud#1066 ), quotas, stack lock. - Signals —
n1-cloud/docs/runbook/vm-lifecycle/invariants-and-signals.runbook.md: per-stage invariants + the D1 timeline smoking-gun. - Fix recipes —
n1-cloud/docs/runbook/vm-lifecycle/troubleshoot-and-fix.runbook.md: symptom → diagnosis → code-first fix (S1–S7). - Hard-won facts —
n1-cloud/docs/runbook/vm-lifecycle/grounded-intel.runbook.md: noop-not-persisted, drift-not-reroll-only, UTC discipline.
Pyinfra + osquery umbrella
Section titled “Pyinfra + osquery umbrella” n1-cloud/docs/runbook/runbook/pyinfra-osquery-provisioning.runbook.md ties the layers:
| Layer | Workflow | Source |
|---|---|---|
| L1 substrate | converge.yml | n1-cloud-pulumi/.github/workflows/converge.yml |
| Bootstrap floor | pyinfra.yml (deploy_slug=bootstrap) | n1-cloud-pulumi/.github/workflows/pyinfra.yml — auto after box up per n1-cloud/docs/prd/PRD-0-template-project/PRD-0.dos-donts.md:63 |
| Golden bake | golden-bake.yml | n1-cloud-apps/.github/workflows/golden-bake.yml — operator runbook: n1-cloud/docs/runbook/runbook/golden-image-bake.runbook.md |
vm_status remains provisioning until bootstrap pyinfra completes ( n1-cloud/docs/prd/PRD-0-template-project/PRD-0.dos-donts.md:52 ).
Operator CLI entry points
Section titled “Operator CLI entry points”# Soft reroll (idempotent up)bun scripts/reroll.ts --ids 01KPN3W890J2ZZB39XRJF1VT0H --kind box --action up
# Converge dispatch surface (admin)nayaone-admin api adminDeployN1Cloud # deploy web+workers only — not convergeBare ULIDs only — n1-cloud/scripts/reroll.ts:433 rejects box_ / runner_ prefixes at parse time.
Live verification receipts
Section titled “Live verification receipts”- Golden toolchain + M10.8 fresh provision —
n1-cloud/docs/agents/PRD-350/artefacts/dogfood-2026-06-09-golden/README.md(PRD-350 L-82) - Composite health
testsGateremoval —n1-cloud/docs/agents/PRD-346/artefacts/dogfood-2026-06-09-testsgate-drop/README.md