fix(cli): make the per-env approval gate fail closed
Review #2 (MEDIUM). The M3 `[project.environments]` approval gate silently failed open in three shapes: - `EnvPolicy.confirm` was `#[serde(default)]`, so `production = {}` parsed as un-gated. `confirm` is now a REQUIRED field — an env listed with an empty policy is a load error (`missing field 'confirm'`), not a silent no-gate. - `pic apply --file <leaf>` where the leaf carried no `[project]` skipped the gate even when the repo root gated the env. `run` now discovers the governing `[project]` by walking up from the manifest to the nearest ancestor `picloud.toml` that declares one (`find_governing_project`, loaded without the env overlay — only the block matters). - A `[project].environments` in a non-root manifest under `--dir` was dropped with a generic "ignored" note; `build_tree` now warns explicitly that its approval gating is not enforced. Pinned by `tests/env_approval.rs` (empty-policy load error; leaf `--file` apply honoring the root gate). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -296,8 +296,11 @@ pub struct ManifestProject {
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct EnvPolicy {
|
||||
/// Require an explicit `--approve <env>` to apply to this env.
|
||||
#[serde(default)]
|
||||
/// Require an explicit `--approve <env>` to apply to this env. NOT
|
||||
/// `#[serde(default)]`: an env listed with an empty policy (`prod = {}`)
|
||||
/// must fail to load (`missing field 'confirm'`) rather than silently
|
||||
/// parse as un-gated — listing an env to protect it, then having the gate
|
||||
/// quietly absent, is the failure mode to avoid.
|
||||
pub confirm: bool,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user