8000 `min completions install` reports success for shells that will never load the file · Issue #1027 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

min completions install reports success for shells that will never load the file #1027

Closed

Description

@norrietaylor

Fixed with: #1082

Surface: min completions install · Severity: Medium · Class: silent no-op
Source: completions.rs:116-158 (install_one)

install_one probes the target directory for writability, writes, and returns the path. There
is no loader check of any kind, for any shell. Its help names one failure mode only:
“A shell that cannot be installed for (an unwritable shared directory, say) is a warning on
stderr, not a failure.”
Writing a file nothing will ever read is not covered.

bash — the documented path is not a bash mechanism

bash has no completion search path; complete is a builtin that registers into the running
shell. The documented path is read only by the separate bash-completion project, whose
_completion_loader (hooked via complete -D) searches
$BASH_COMPLETION_USER_DIR/completions/<cmd>, defaulting to
${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion — correct given bash-completion ≥2.0
installed and sourced
. Measured on the validation host:

/bin/bash                                       -> 3.2.57  (bash-completion 2.x needs >=4.1)
/opt/homebrew/bin/bash                          -> 5.3.9
/opt/homebrew/share/bash-completion             -> missing
/opt/homebrew/etc/profile.d/bash_completion.sh  -> missing
~/.bashrc, ~/.bash_profile                      -> absent entirely

/opt/homebrew/etc/bash_completion.d/ exists (legacy v1 drop-in dir used by other formulae)
but the main bash_completion script that would load it does not. The written file is inert;
exit 0.

zsh — no XDG convention exists

~/.local/share/zsh/completions is meaningful only if something adds it to fpath. It happens
to reach fpath on the validation host from somewhere in the startup chain, and end-to-end
completion works there:

COMPLETE=zsh _CLAP_COMPLETE_INDEX=1 min -- min ses
  -> session:Session management subcommands

That is the finding restated, not weakened: whether the installed file is ever read is a
property of the host, and install never checks it.

fish

$XDG_CONFIG_HOME/fish/completions is native. Unconditionally correct.

Fix

Skip bash with a warning when no bash_completion script is found; for zsh, test fpath and
print the fpath+=(~/.local/share/zsh/completions) line the user needs when it is absent.

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 F22 (confirmed on main, one attribution corrected).

Activity

  1. gominimal-aw-bot commented on Jul 29, 2026

    @gominimal-aw-bot
    Contributor

    Routing triage — #1027

    Kind: bug · Route: patch · Confidence: 0.92 · Target: gominimal/minimal

    install_one in crates/minimal/src/completions.rs writes the completion file and exits 0 without verifying the shell will ever load it. Fix is localised to that file.

    Evidence

    • Code search: install_one confirmed at crates/minimal/src/completions.rs:116-158 in gominimal/minimal (direct match to the source cited in the issue). This is the strongest routing signal available.
    • Distillery (informed by minimal#711, minimal#714): Prior work on the installer's completions path (feat(installer): setup PATH and shell completions, fix(installer): better handle case where shell dir is not writeable) confirms this is an active area of the minimal CLI codebase; no prior fix for the loader-check gap was found.
    • Similar issues: No prior issue in gominimal/minimal or gominimal/inbox tracking this exact defect. Sibling issues from the same QA sweep — inbox#379 (min session policy silent false negative), inbox#380 (min init silent overwrite), inbox#382 (bare min orphaned session) — are distinct findings; none is a duplicate.
    • Routing precedents: No routing-outcome entry specifically about completions or shell loader checks. General precedents confirm gominimal/minimal as the target for CLI subcommand bugs (informed by routing-outcome entries from inbox-route-retro).
    • Manifest: gominimal/minimal is route: allow; CLI subcommand bugs are its stated domain.

    Patch scope

    Expected change: 1 file — crates/minimal/src/completions.rs. Add a bash-completion loader probe and a zsh fpath membership check to install_one, emitting a warning or skipping when the file would be ignored.

    Similar issues

    • inbox#379, inbox#380, inbox#382 — related QA sweep findings (distinct issues, same batch)
    • minimal#711 — prior completions install feature (merged)
    • minimal#714 — prior fix for unwriteable shell dir (merged)
    • No duplicates found (searched open and closed in inbox and minimal)

    [inbox-route:decision]

    {"schema":"inbox-route/v1","issue":386,"issue_node_id":"I_kwDOSUhdos8AAAABKmglFQ","dry_run":false,"kind":"bug","route":"patch","confidence":0.92,"targets":[{"repo":"gominimal/minimal","reason":"install_one confirmed at crates/minimal/src/completions.rs; fix localised to that file"}],"labels":["kind:bug","priority:should-have"],"patch":{"target_ref":"main","brief":"install_one in completions.rs writes the completion file and returns success without verifying the shell will load it. For bash, the documented path only works with bash-completion >=2.0 installed and sourced — both are absent on the validation host. For zsh, the target directory reaches fpath only if something in the host startup chain adds it. Evidence suggests install_one should check for the bash-completion loader script before writing for bash, and test fpath membership for zsh, warning the user when the file would be silently ignored.","files":["crates/minimal/src/completions.rs"]},"work_issue":{"title":"bug: completions install exits 0 for bash and zsh without verifying the shell will load the file","body":"## Summary\n\n`min completions install` writes the completion file and exits 0 for bash and zsh even when nothing will ever load that file. Fish is unaffected (native XDG path).\n\n## Details\n\nSource: `crates/minimal/src/completions.rs:116-158` (`install_one`). The function probes directory writability, writes, and returns — no loader check exists for any shell.\n\n**bash**: the target path is only scanned by the separate `bash-completion` project. On the validation host, `bash-completion` was missing entirely, so the written file is inert. The function exits 0 regardless.\n\n**zsh**: `~/.local/share/zsh/completions` is only meaningful if something adds it to `fpath`. Whether it does is a property of the host startup chain; `install_one` never checks.\n\nExpected: warn (or skip with a clear message) when the file will not be loaded. The binary already ships the convention: `min session destroy --all` refuses without `--force` and names the flag.\n\n## Suggested next step\n\nIn `install_one` (or a helper), for bash: probe for the `bash_completion` init script before writing; warn or skip if absent. For zsh: query `$fpath` and emit the `fpath+=(...)` line the user needs when the directory is not already present."},"related":[{"repo":"gominimal/inbox","number":379,"relation":"related"},{"repo":"gominimal/inbox","number":380,"relation":"related"},{"repo":"gominimal/inbox","number":382,"relation":"related"},{"repo":"gominimal/minimal","number":711,"relation":"related"},{"repo":"gominimal/minimal","number":714,"relation":"related"}],"rationale":"install_one in crates/minimal/src/completions.rs (confirmed via code search: exact file and function match) writes the completion file and exits 0 with no shell-loader check for bash or zsh. The fix is isolated to that file and involves adding probes for bash-completion presence and fpath membership before writing. The issue provides exact line references, a concrete fix description, and live validation evidence. No prior tracking of this exact defect found in minimal or the inbox. Target is gominimal/minimal with high confidence because the source file is directly named and confirmed in that repo. Sibling issues from the same QA sweep (inbox#379, gominimal/inbox#380, gominimal/inbox#382) are distinct findings routed separately."}

    Generated by inbox-route for issue #1027 · ◷

  2. added
    kind:bugSomething is not working. Applied by the inbox-route classifier.
    on Jul 29, 2026
  3. gominimal-aw-bot commented on Jul 29, 2026

    @gominimal-aw-bot
    Contributor

    [inbox-route:ledger]
    Routed from gominimal/inbox#386 by inbox-route (https://github.com/gominimal/inbox/actions/runs/30430277093)
    Routing-Key: inbox-route/I_kwDOSUhdos8AAAABKmglFQ
    Route: patch
    Patch-Dispatched: https://github.com/gominimal/inbox/actions/runs/30430277093

  4. transferred this issue fromon Jul 29, 2026
  5. gominimal-aw-bot commented on Jul 29, 2026

    @gominimal-aw-bot
    Contributor

    [inbox-patch:handoff]
    inbox-patch did not produce a verified fix PR for this issue — the agent run failed (agent result: failure).

    Run: https://github.com/gominimal/inbox/actions/runs/30430804439

    Manual retry:

    gh workflow run inbox-patch.yml -R gominimal/inbox -f "target-repo=gominimal/minimal" -f "target-ref=main" -f "issue=1027" -f "language=rust" -f "distillery-project=minimal" -f "decision-url=https://github.com/gominimal/inbox/issues/386#issuecomment-5114358830"
    
  6. added
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Jul 29, 2026
  7. removed
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Jul 29, 2026
  8. gominimal-aw-bot commented on Jul 29, 2026

    @gominimal-aw-bot
    Contributor

    [inbox-patch:handoff]
    inbox-patch did not produce a verified fix PR for this issue — the agent run failed (agent result: failure).

    Run: https://github.com/gominimal/inbox/actions/runs/30483084925

    Manual retry:

    gh workflow run inbox-patch.yml -R gominimal/inbox -f "target-repo=gominimal/minimal" -f "target-ref=main" -f "issue=1027" -f "language=rust" -f "distillery-project=minimal" -f "decision-url=https://github.com/gominimal/inbox/issues/386#issuecomment-5114358830"
    
  9. added
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Jul 29, 2026
  10. removed
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:bugSomething is not working. Applied by the inbox-route classifier.priority:should-haveShould be done. Applied by the inbox-route classifier or a human.routed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0