Files
PiCloud/docs/design
MechaCat02 22d6c33d0b feat(hierarchies): per-env approval-policy gating (M5)
A project's root manifest can mark environments confirm-required; applying to
one needs an explicit `pic apply --dir --env <e> --approve <e>` (a blanket
`--yes` does NOT cover it), the act is admin-gated and audited, and the policy
folds into the bound-plan token. The last unbuilt piece of the project-tool
track (§4.2/§6).

- manifest: `[project]` block → `ManifestProject { environments[{name,confirm}] }`,
  valid only on the tree's ROOT manifest (rejected elsewhere by build_tree).
- discover: build_tree emits `project` into the bundle from the root manifest.
- apply_service: `TreeBundle.project` + `ProjectPolicy`; policy folds into the
  state_token (a policy edit between plan and apply trips StateMoved); plan
  surfaces `approvals_required`; new `ApplyError::ApprovalRequired` → 409.
- apply_api: `enforce_env_approval` (after authz_tree) — refuses a gated env
  not in `approved_envs`, and on approval requires admin (AppAdmin/GroupAdmin)
  on every declared node + audits. The server re-derives the policy from the
  bundle (CLI check is convenience; server is authoritative).
- CLI: `--approve <env>` (repeatable); `resolve_approvals` refuses a gated env
  non-interactively, prompts on a TTY (retype the env name); plan renders gated
  envs. Single-node `apply --file --env <e>` REFUSES a confirm-required env
  (can't carry the admin-gated approval) and directs to `--dir` — closing the
  bypass found in review rather than silently skipping the gate.
- approval journey + manifest/ProjectPolicy unit tests. No migration (policy
  lives in the manifest, like takeover/blast-radius).
- doc §11 Phase 5 + §12: approval gating shipped; gate is a `--dir` feature.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 19:06:27 +02:00
..