fix(project-tool): address review findings on the apply foundation
Remediation of the single-app reconcile foundation after two independent review passes. No new feature surface — closes correctness, parity, and safety gaps in pull/plan/apply/prune. apply engine (manager-core): - validate_bundle reached parity with the interactive trigger API: reject an empty kv/docs/files collection_glob and a malformed pubsub topic_pattern (previously written and silently never matched), and lift the queue visibility floor to MIN_QUEUE_VISIBILITY_TIMEOUT_SECS (30) — apply had accepted a [5,29] value the dashboard refuses. Per-kind checks extracted into a pure, unit-tested validate_trigger_shape. - An omitted script `description` now means "leave as-is" (matching the other optional fields and the function's own documented contract) instead of clearing the stored value. - Doc fixes: drop stale "next milestone" notes; record the one deliberate plan/apply divergence (set-but-empty secret); document delete_route_tx as intentionally idempotent for reconcile. CLI: - Gate destructive `apply --prune` behind confirmation: interactive y/N, or `--yes` for CI; a non-interactive prune without `--yes` refuses rather than silently deleting. Journey tests pass `--yes`; a new test proves the gate refuses and deletes nothing. - Harden pull's filename safety: reject all control characters and the Unicode bidi-override / zero-width chars used for terminal/filename spoofing, and cap length at 200 bytes (NAME_MAX headroom). Tested: manager-core lib (incl. queue-floor + sparse-description parity) + CLI bins + 9 project-tool journeys green; clippy -D warnings clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -159,7 +159,8 @@ enum Cmd {
|
||||
},
|
||||
|
||||
/// Reconcile the live app to a `picloud.toml` manifest in one
|
||||
/// transaction (additive: creates + updates).
|
||||
/// transaction (creates + updates; `--prune` also deletes resources
|
||||
/// absent from the manifest).
|
||||
Apply(ApplyArgs),
|
||||
|
||||
/// Diff a `picloud.toml` manifest against the live app and print the
|
||||
@@ -181,6 +182,10 @@ struct ApplyArgs {
|
||||
/// Secrets are never pruned.
|
||||
#[arg(long)]
|
||||
prune: bool,
|
||||
/// Skip the `--prune` confirmation prompt. Required to prune
|
||||
/// non-interactively (CI).
|
||||
#[arg(long)]
|
||||
yes: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
@@ -1086,7 +1091,7 @@ async fn main() -> ExitCode {
|
||||
}
|
||||
Cmd::Logout => cmds::logout::run().await,
|
||||
Cmd::Whoami => cmds::whoami::run(mode).await,
|
||||
Cmd::Apply(args) => cmds::apply::run(&args.file, args.prune, mode).await,
|
||||
Cmd::Apply(args) => cmds::apply::run(&args.file, args.prune, args.yes, mode).await,
|
||||
Cmd::Plan(args) => cmds::plan::run(&args.file, mode).await,
|
||||
Cmd::Pull(args) => cmds::pull::run(&args.app, &args.dir, mode).await,
|
||||
Cmd::Apps { cmd: AppsCmd::Ls } => cmds::apps::ls(mode).await,
|
||||
|
||||
Reference in New Issue
Block a user