Fixed with: #1053
Surface: min init · Severity: High · Class: data loss
Source: lib.rs:2514-2538 (run_init_flow), lib.rs:879 (confirm)
Re-running min init in a project that already has a minimal.toml silently replaces it.
No warning, no backup, no diff. The banner says “Will create” when the file already exists;
the result says “Created” when it replaced.
Reproduce
min -C proj init -y # packages = ["base","vim"]
min -C proj add --session ripgrep # packages = ["base","vim","ripgrep"]
min -C proj init -y # "Created /.../minimal.toml"
grep packages proj/minimal.toml # packages = ["base","vim"] <- edits gone
--no-input does not stop it
Documented behaviour of --no-input: “Skip interactive prompts that need a terminal… When a
choice is ambiguous, the command errors with a list of candidates instead of opening a
picker.” Observed:
min --no-input -C proj init
Will create /.../minimal.toml:
Continue? [Y/n] Created /.../minimal.toml
exit 0 # wrote anyway
Plain min init with a non-TTY stdin behaves the same.
Cause
--no-input is not merely weakened on this path — it is never read. Neither cmd_init nor
run_init_flow looks at global.no_input at all. The auto-accept comes from confirm()
(lib.rs:879), which reads stdin and returns the default — true — on the empty string
EOF hands it.
Re-run on main: packages = ["base","vim","ripgrep"] -> ["base","vim"], exit 0, no backup
written.
Fix
Refuse when the file exists unless --force; make --no-input/non-TTY a hard error on the
overwrite path rather than an implicit yes.
Shared failure mode
One of four high-severity findings with the same shape: a command performs a consequential action while its stated safeguard does not fire, or reports success for a condition it never checked. The others are min init overwriting an existing config, bare min creating a session under --no-input before failing, and min completions install reporting success for shells that will never load the file.
The reference implementation already ships in this binary: min session destroy --all refuses non-interactively and names the flag that would proceed (error: refusing to destroy all sessions without confirmation; pass --force, exit 1). That message is the convention the other three should copy.
QA sweep of the published min help tree against a live local-minvmd daemon (min 0.5.0-rc3.dev.31.gc1375225, HEAD c137522); every finding re-executed against main at df22d71 and read back to source. Ledger finding F2 (confirmed on main).
Surface:
min init· Severity: High · Class: data lossSource:
lib.rs:2514-2538(run_init_flow),lib.rs:879(confirm)Re-running
min initin a project that already has aminimal.tomlsilently replaces it.No warning, no backup, no diff. The banner says “Will create” when the file already exists;
the result says “Created” when it replaced.
Reproduce
--no-inputdoes not stop itDocumented behaviour of
--no-input: “Skip interactive prompts that need a terminal… When achoice is ambiguous, the command errors with a list of candidates instead of opening a
picker.” Observed:
Plain
min initwith a non-TTY stdin behaves the same.Cause
--no-inputis not merely weakened on this path — it is never read. Neithercmd_initnorrun_init_flowlooks atglobal.no_inputat all. The auto-accept comes fromconfirm()(
lib.rs:879), which reads stdin and returns the default —true— on the empty stringEOF hands it.
Re-run on
main:packages = ["base","vim","ripgrep"]->["base","vim"], exit 0, no backupwritten.
Fix
Refuse when the file exists unless
--force; make--no-input/non-TTY a hard error on theoverwrite path rather than an implicit yes.
Shared failure mode
One of four high-severity findings with the same shape: a command performs a consequential action while its stated safeguard does not fire, or reports success for a condition it never checked. The others are
min initoverwriting an existing config, baremincreating a session under--no-inputbefore failing, andmin completions installreporting success for shells that will never load the file.The reference implementation already ships in this binary:
min session destroy --allrefuses non-interactively and names the flag that would proceed (error: refusing to destroy all sessions without confirmation; pass --force, exit 1). That message is the convention the other three should copy.QA sweep of the published
minhelp tree against a live local-minvmd daemon (min 0.5.0-rc3.dev.31.gc1375225, HEAD c137522); every finding re-executed againstmainat df22d71 and read back to source. Ledger finding F2 (confirmed on main).