Skip to content

fix: reject unknown --flag in positional args#366

Merged
danieljohnmorris merged 7 commits into
mainfrom
fix/cli-unknown-flag-guard
May 17, 2026
Merged

fix: reject unknown --flag in positional args#366
danieljohnmorris merged 7 commits into
mainfrom
fix/cli-unknown-flag-guard

Conversation

@danieljohnmorris
Copy link
Copy Markdown
Collaborator

@danieljohnmorris danieljohnmorris commented May 17, 2026

Summary

Six rerun8 personas (ab-tester, routing-tsp, content-mod, qa-tester, interactive-cli, security-researcher) independently burned minutes on the same trap: ilo main.ilo --engine tree silently consumed --engine as a positional arg (because Cli::args and RunArgs::rest use trailing_var_arg = true, allow_hyphen_values = true), then surfaced misleading ILO-R012 no functions defined or ILO-R004 main: expected N args, got N+1 further down the line.

This guard rejects any clean long-flag shape (--word or --word-with-dashes) in the positional tail with a clear, actionable error and exit code 1. The -- separator escapes through hyphen-prefixed literal args.

Repro

Before:

$ ilo main.ilo --engine tree
^"ILO-R004: main: expected 0 args, got 2"
exit 1

After:

$ ilo main.ilo --engine tree
error: unrecognised flag '--engine'. Use 'ilo --help' for valid flags. To pass it as a literal arg, separate with '--' first.
exit 1

$ ilo main.ilo -- --engine
{ runs main with "--engine" as a literal arg, exit 0 }

What's in the diff

  • src/cli/args.rsreject_unknown_flags + reject_unknown_flags_with_allowlist helpers, with 10 unit tests covering every accept/reject path (clean flags, hyphenated, -- separator, --key=val, trailing/doubled dashes, negative numbers).
  • src/main.rs — guard at top of dispatch_run (catches Cmd::Run(r).rest and the bare-args path's final rest); guard at top of dispatch_bare_args source-slot detection (catches ilo --engine tree main.ilo style mis-placements); first -- separator stripped from r.rest so it doesn't reach the program as a positional arg.
  • tests/regression_unknown_flag_guard.rs — 19 cross-engine integration tests covering bare path, run subcommand path, -- escape, recognised flags still working, all four engines respecting the guard, negative-number and --key=val data shapes not flagged.
  • examples/unknown-flag-guard.ilo — minimal example exercised by the engine harness.
  • SPEC.md, ai.txt, skills/ilo/SKILL.md — CLI section gains the unknown-flag-guard rule + -- escape doc.
  • site/src/content/docs/docs/reference/cli.md (separate repo, already pushed) — mirrored.

Test plan

  • Manual repro confirms before/after behaviour across default, --run-tree, --run-vm, --run-cranelift.
  • All recognised flags (--run-vm, --run-tree, --bench, --dense, etc.) still parse cleanly.
  • -- separator correctly strips and passes literal --foo through as a program arg.
  • Negative numbers (-1, -3.14) and --key=val shapes still pass through as data.
  • CI green (in progress).

Follow-ups

None — single-purpose fix.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

…nknown-flag-guard

# Conflicts:
#	ai.txt
#	skills/ilo/SKILL.md
The rerun8 personas typed `--engine tree` expecting it to be a flag
(it had been clap-known but undocumented), then hit silent-consume
traps when the value was misinterpreted. The canonical surface is the
`--run-*` convenience flags; `--engine` should fall through to the
unknown-flag guard. Replace #[arg(long, ...)] with #[arg(skip)] so the
field still exists for internal construction sites but is no longer
exposed on the CLI.
@danieljohnmorris danieljohnmorris merged commit 382c383 into main May 17, 2026
5 checks passed
@danieljohnmorris danieljohnmorris deleted the fix/cli-unknown-flag-guard branch May 17, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant