transition precondition enforcement + thin-client context poller
Plan #3 at 100%. Last three items resolved:
1. Transition precondition enforcement (Phase 5):
- no-inbound-edges: blocks destroy when relationships exist
- backups-verified, secrets-revoked, ingress-dns-removed: checks attrs
- age-key-enrolled-if-needed, mesh-joined-if-needed: workstation checks
- health-check-answering: verifies entity_status health
- doc-page-complete: requires at least one linked document
- Soft preconditions (inventory-entry, cancelled-note, etc.): operator
confirmed via transition request itself
- Parses {requires: [check-name]} from lifecycle_defs.transitions JSONB
2. bootstrap.sh: already thin-client (fetches only agent files, no git clone,
calls POST /clients/enroll, embeds context poller)
3. tools/context-poller.sh: standalone version — polls GET /clients/{slug}/context,
applies file/tool/sops deltas, re-runs changed setup scripts