{"record":{"id":"d7da0f60882d820f","repo":"Hmbown/CodeWhale","slug":"push-is-never-automatic-re-run-with-dry-run-to","errorCode":null,"errorMessage":"Push is never automatic; re-run with --dry-run to preview, then confirm explicitly","messagePattern":"Push is never automatic; re-run with --dry-run to preview, then confirm explicitly","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"info","filePath":"crates/cli/src/cloud.rs","lineNumber":712,"sourceCode":"            writeln!(out, \"Account settings (pull --dry-run):\")?;\n            writeln!(out, \"Account ID: {}\", printable(&user.id))?;\n            writeln!(out, \"Profile: {}\", printable(profile))?;\n            writeln!(out, \"API: {api_base}\")?;\n            writeln!(\n                out,\n                \"dry-run: remote settings import is not available; local config unchanged\"\n            )?;\n            // Show the invariant: Bearer custody stays in the OS keyring, never in config.toml.\n            writeln!(\n                out,\n                \"Secure custody: Bearer tokens remain in the OS keyring\"\n            )?;\n            Ok(())\n        }\n        CloudCommand::Push(args) => {\n            let user = client.me()?;\n            if !args.dry_run {\n                bail!(\n                    \"Push is never automatic; re-run with --dry-run to preview, then confirm explicitly\"\n                );\n            }\n            writeln!(out, \"Account settings (push --dry-run):\")?;\n            writeln!(out, \"Account ID: {}\", printable(&user.id))?;\n            writeln!(out, \"Profile: {}\", printable(profile))?;\n            writeln!(out, \"API: {api_base}\")?;\n            writeln!(\n                out,\n                \"dry-run: would PATCH /api/me/preferences with If-Match revision check (412 on conflict)\"\n            )?;\n            writeln!(\n                out,\n                \"No credentials, paths, or env are copied; only explicit fields (field-level last-writer-wins)\"\n            )?;\n            Ok(())\n        }\n    }","sourceCodeStart":694,"sourceCodeEnd":730,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/cli/src/cloud.rs#L694-L730","documentation":"`codewhale account push` refuses to run without --dry-run by design: pushing local settings to the account is never automatic and always requires an explicit confirmation step that does not exist yet. The bail fires after client.me() succeeds, so it also proves sign-in works; it is a policy guard, not a failure.","triggerScenarios":"Running `codewhale account push` expecting it to upload settings; scripting config sync via push without flags.","commonSituations":"Users familiar with tools that auto-sync settings assuming push applies immediately; onboarding flows that instruct `account push` before the confirm flow landed.","solutions":["Run `codewhale account push --dry-run` to preview what a future push would PATCH (/api/me/preferences with If-Match revision check).","Wait for the explicit confirm flow; there is currently no way to force a real push.","Remove non-dry-run push from scripts/docs since it always bails."],"exampleFix":"# before\ncodewhale account push\n\n# after\ncodewhale account push --dry-run","handlingStrategy":"validation","validationCode":"let args = PushArgs { dry_run: true }; // preview-only until confirm flow exists","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use `account push --dry-run` for previews.","Do not script non-dry-run push; it is a designed hard stop.","Model future sync flows around explicit confirmation when they land."],"tags":["cloud","cli","explicit-confirmation","config-sync"],"backgroundTag":"destructive-action-requires-confirmation","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}