Skip to content

feat(derive): check what a parse cannot decide on its own - #817

Merged
jdx merged 2 commits into
mainfrom
agent/derive-post-binding
Aug 11, 2026
Merged

jdx merged 2 commits into
mainfrom
agent/derive-post-binding

Conversation

@jdx

@jdx jdx commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Second of the stack (#816 merged while this was in flight, so it targets main). The parser binds tokens and stops there, which left required-ness, choices, variadic bounds, and env fallback unimplemented — the 18 corpus vectors the harness reports as post-binding, and the reason a subcommand field had to be Option<T>.

Order matters, so it is stated

  1. The environment fills what argv left out.
  2. Required-ness — which the type declares: a String has nowhere to put "absent". After the environment, so a flag with env set is not reported missing.
  3. choices and bounds, which judge a value however it arrived, including from the environment or a default.

Only the command that actually ran is judged. A flag that install requires says nothing about an invocation of run — which is why the check hangs off the CommandArgs trait and the enum forwards it to the selected variant only. A bare subcommand field now means one is required and says so when absent, removing #816's stated limit.

Two decisions worth arguing with

A field remembers whether a token supplied it, rather than inferring that from an empty value. --out= is a value somebody typed, and treating "" as unset would make it unsayable — the same distinction #810 fixed in the parser, carried through to the checks.

Bounds constrain the values a field was given. An unused optional flag is absent, not a violation. Otherwise var_min = 1 becomes a second spelling of required-ness, and there is no way left to say "at least two, if you use it at all". My own test caught this: I put var_min = 1 on an optional flag and every unrelated test in the file started failing with VarTooFew.

Contradictions are compile errors

error: a `bool` or counting field has no value to check against `choices`
error: `var_min = 3` is more than `var_max = 2`, so nothing could satisfy both
error: `var_min` and `var_max` count values, so the field has to be a `Vec`
error: the default `z` is not one of this field's choices, so it could never be valid

Consistent with the rest of this crate: the derive's job is refusing what cannot round-trip or cannot mean anything.

The declarations reach the spec

A test pins that, because a choice list the parser enforces but the spec omits would be invisible to docs and completions — exactly the kind of half-implemented feature this project keeps turning up.

10 tests: each check, the empty-value case, per-command judging, and a required subcommand.

Still missing, and now stated in the crate docs

overrides and required_unless (both need the order flags arrived in, which nothing records yet), nesting past one level, and typed values.

AI-assisted — Tool: Claude Code; model: anthropic/claude-fable-5; version: unavailable.


Note

Medium Risk
Touches public Error and trait APIs and adds substantial generated validation/env logic that changes how CLIs accept or reject input. Well-tested, but incorrect checks would mis-parse real command lines.

Overview
Implements the post-binding layer the parser deliberately left out: after tokens are bound, generated code now checks required-ness, choices, var_min/var_max, and fills from env when argv left a field unset.

Validation order is fixed: env fallback → required checks → choices/bounds. Only the selected subcommand is judged. A bare subcommand: T field is now allowed and reports MissingSubcommand when absent (previously had to be Option<T>).

Extends Error with MissingRequired, InvalidChoice, VarTooFew, VarTooMany, and MissingSubcommand, and marks it non_exhaustive. Adds check to CommandArgs/Subcommands. Declarations also flow into the emitted spec so docs and completions see the same constraints.

Contradictions (choices on bool, var_min > var_max, default outside choices) are compile errors. New conformance tests cover each check, empty values counting as given, and env precedence.

Reviewed by Cursor Bugbot for commit 5bc52c7. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added post-parse validation for required values, allowed choices, variable-length arguments, and required subcommands.
    • Added environment-value fallback and clear precedence when command-line values are provided.
    • Added support for validating only the selected subcommand.
    • Expanded generated command specifications with choices and argument bounds.
  • Bug Fixes

    • Improved handling of boolean environment values and invalid defaults.
  • Documentation

    • Documented validation order, scope, supported constraints, and current limitations.

The parser binds tokens and stops there, which left required-ness, choices,
variadic bounds, and `env` fallback unimplemented — the 18 corpus vectors the
harness reports as post-binding, and the reason a subcommand field had to be
`Option<T>`.

Generated code now checks them after the last token, in an order that matters:
the environment fills what argv left out, then required-ness (so a flag with
`env` set is not missing), then choices and bounds, which judge a value however
it arrived. Only the command that actually ran is judged — a flag that
`install` requires says nothing about an invocation of `run` — which is why the
check hangs off the `CommandArgs` trait rather than running for every variant.

A bare `subcommand` field now means one is required, and says so when it is
absent.

Two decisions worth recording. A field remembers whether a token supplied it,
rather than inferring that from an empty value: `--out=` is a value somebody
typed, and treating "" as unset would make it unsayable. And bounds constrain
the values a field was *given*, so an unused optional flag is absent rather
than a violation — otherwise `var_min` would be a second spelling of
required-ness, with no way left to say "at least two, if you use it at all".

Contradictions are refused at compile time: `choices` on a `bool`, `var_min`
above `var_max`, a bound on something that is not a `Vec`, a default outside
its own choices.

The declarations reach the spec too, which a test now pins — a choice list that
the parser enforces but the spec omits would be invisible to docs and
completions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The parser now performs post-binding validation for required values, choices, variadic bounds, environment fallback, and required subcommands. Public traits expose validation hooks, derive metadata records constraints, generated code validates selected commands, and conformance tests cover the behavior.

Changes

Post-Binding Validation

Layer / File(s) Summary
Public validation contracts
argv/src/lib.rs, argv/src/spec.rs
Error includes deferred validation variants. CommandArgs::check and Subcommands::check expose post-binding validation.
Validation metadata and subcommand model
derive/src/model.rs, derive/src/lib.rs
Field metadata stores choices and variadic bounds. The derive model validates declarations and supports required or optional subcommands. Documentation describes validation order and limitations.
Generated post-binding flow
derive/src/codegen.rs
Generated parsers track supplied fields, apply environment fallback, validate constraints, dispatch checks to the selected subcommand, and build parsed values.
Conformance validation coverage
conformance/src/argv.rs, conformance/tests/post_binding.rs
Tests cover required values, choices, variadic bounds, environment precedence, boolean parsing, subcommand validation scope, and generated specifications.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant GeneratedParser
  participant Environment
  participant SelectedCommand
  participant ParsedValue
  CLI->>GeneratedParser: supply arguments
  GeneratedParser->>Environment: resolve unset fields
  GeneratedParser->>SelectedCommand: validate selected command
  SelectedCommand-->>GeneratedParser: return success or Error
  GeneratedParser-->>ParsedValue: build validated value
Loading

Possibly related PRs

  • jdx/usage#797: Adds the conformance harness and validation behavior extended by this change.
  • jdx/usage#798: Provides the parser infrastructure extended with post-binding validation.
  • jdx/usage#816: Adds subcommand parsing integrated with the new validation flow.

Poem

A rabbit checks each flag in line,
With choices neat and bounds that shine.
Env values hop where fields are bare,
The chosen command gets its share.
“No missing carrots!” says the hare.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding derive-time post-parse checks for conditions the parser cannot decide during binding.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jdx
jdx force-pushed the agent/derive-post-binding branch from 6872b35 to d642010 Compare August 11, 2026 22:34
@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds derive-generated post-binding validation after argv parsing.

  • Applies environment fallback before required-value checks.
  • Validates choices and variadic bounds for supplied values.
  • Supports required subcommands and checks only the selected command.
  • Exposes post-binding failures through new argv error variants and generated spec metadata.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
derive/src/codegen.rs Generates environment fallback, required-value, choice, variadic-bound, and selected-subcommand checks; the previously reported count-environment defect is corrected.
derive/src/model.rs Parses and validates choices and variadic bounds while adding required-subcommand modeling.
argv/src/spec.rs Adds post-binding check hooks to the command and subcommand traits.
argv/src/lib.rs Adds non-exhaustive post-binding error variants.
conformance/tests/post_binding.rs Covers required values, choices, bounds, selected-command validation, required subcommands, and emitted metadata.
conformance/tests/post_binding_env.rs Covers environment fallback, argv precedence, boolean values, and count parsing.

Reviews (2): Last reviewed commit: "fix(derive): stop claiming a count came ..." | Re-trigger Greptile

Comment thread derive/src/codegen.rs Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d642010. Configure here.

Comment thread derive/src/codegen.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
conformance/tests/post_binding.rs (2)

74-98: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No test exercises VarTooFew.

include declares var_min = 1, but the minimum can never be violated on this fixture. bound_checks runs only when __given_include is true, and every --include occurrence pushes exactly one value. The count is therefore at least 1 whenever the check runs.

The min branch of bound_checks in derive/src/codegen.rs is currently untested. Add a field with var_min = 2 and give it one value.

💚 Proposed test addition
/// Files to pair
#[usage(long, var = true, var_min = 2)]
pair: Vec<String>,
#[test]
fn too_few_values_is_refused() {
    let a = argv(["--pair", "a", "x"]);
    assert!(matches!(
        Ex::parse_from(&a),
        Err(Error::VarTooFew {
            name: "pair",
            min: 2,
            got: 1
        })
    ));
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@conformance/tests/post_binding.rs` around lines 74 - 98, Extend the test
fixture with a repeatable pair field configured with var_min = 2, then add a
too_few_values_is_refused test passing one value and asserting Error::VarTooFew
with name "pair", min 2, and got 1. Keep the existing include tests unchanged.

162-205: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a case for an optional subcommand field.

These tests cover the required subcommand path only. derive/src/codegen.rs at lines 126-139 branches on optional, and the Option<T> branch has no test here. That branch must produce None when no command is given, and it must still run check on a command that was given.

💚 Proposed test addition
/// A CLI whose subcommand may be left out
#[derive(Cli)]
#[usage(bin = "opt")]
struct Opt {
    /// What to do, if anything
    #[usage(subcommand)]
    command: Option<Commands>,
}

#[test]
fn an_optional_subcommand_may_be_left_out() {
    let a = argv([]);
    assert!(Opt::parse_from(&a).expect("should parse").command.is_none());

    // A command that was given is still judged.
    let a = argv(["install"]);
    assert!(matches!(
        Opt::parse_from(&a),
        Err(Error::MissingRequired { name: "tool" })
    ));
}

Commands wraps Install and Noop, and the model rejects two variants sharing one struct. Reuse Commands rather than declaring a second enum over the same structs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@conformance/tests/post_binding.rs` around lines 162 - 205, Add a test near
the existing subcommand tests defining an optional-subcommand CLI type, such as
Opt with command: Option<Commands>. Verify parsing no arguments succeeds with
command set to None, and parsing ["install"] still returns
Error::MissingRequired for tool, confirming validation runs for provided
commands while omission is allowed. Reuse the existing Commands enum.
derive/src/codegen.rs (2)

1000-1009: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

A count field with env set is marked as given without receiving a value.

For Shape::Count the assignment is let _ = value;, but the surrounding block still runs partial.#given = true;. The field keeps its zero value while __given_* claims a value arrived.

Nothing reads that marker for a count field today: required_checks only covers Shape::Required, and the model rejects choices and bounds on counting fields. The state is still contradictory, and a later check that consults __given_* would read it wrong.

Consider skipping the field entirely instead of emitting a no-op assignment.

♻️ Proposed change
             // A count from the environment would be a number, not an occurrence
             // count; nothing needs it yet.
-            Shape::Count => quote!(let _ = value;),
+            Shape::Count => return None,
         };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@derive/src/codegen.rs` around lines 1000 - 1009, Update the
environment-variable assignment logic in the Shape::Count branch so count fields
are skipped entirely when env is configured, rather than executing the shared
partial.#given update. Preserve the existing behavior for other shapes, and
ensure count fields do not emit a no-op assignment or mark their given-state
flag.

769-780: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding unused_lifetimes to the generated module's allow list.

check declares 't and 'v, but the body uses neither, and only 't appears in the return type. The generated module inherits the deriving crate's lint configuration. A crate with #![deny(unused_lifetimes)] would then fail to compile on a derive it did not write.

The other generated-module allow lists in this file already cover non_snake_case and unused_imports for the same reason.

♻️ Proposed change
         #[allow(
             non_upper_case_globals,
             non_snake_case,
             unused_imports,
+            unused_lifetimes,
             // Fires when a metadata struct happens to be fully specified. `..EMPTY`
             // is kept on purpose: it is what lets usage-argv gain a metadata field
             // without breaking every crate that derives.
             clippy::needless_update
         )]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@derive/src/codegen.rs` around lines 769 - 780, Add unused_lifetimes to the
generated module’s lint allow list so the generated check method’s unused
generic lifetimes do not fail downstream crates configured with
deny(unused_lifetimes). Update the existing generated-module allow attributes
near the check method generation, preserving the current non_snake_case and
unused_imports allowances.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@argv/src/lib.rs`:
- Around line 288-319: Preserve 5.x compatibility across
argv/src/lib.rs:288-319, argv/src/spec.rs:775-781, and argv/src/spec.rs:804-808,
or explicitly release these changes as 6.0.0. For compatibility, avoid adding
breaking Error variants such as MissingRequired, InvalidChoice, VarTooFew,
VarTooMany, and MissingSubcommand, and give CommandArgs::check and
Subcommands::check default Ok(()) implementations so existing manual
implementations remain valid; generated implementations should continue
providing both checks.

In `@conformance/tests/post_binding.rs`:
- Around line 100-125: Move the_environment_fills_what_argv_left_out into a
separate integration test file containing no other tests that parse a struct
with env bindings, so its set_var/remove_var calls cannot race with sibling
tests. Keep the existing environment assertions and cleanup intact, and add the
required // SAFETY: comments for each unsafe environment mutation.

---

Nitpick comments:
In `@conformance/tests/post_binding.rs`:
- Around line 74-98: Extend the test fixture with a repeatable pair field
configured with var_min = 2, then add a too_few_values_is_refused test passing
one value and asserting Error::VarTooFew with name "pair", min 2, and got 1.
Keep the existing include tests unchanged.
- Around line 162-205: Add a test near the existing subcommand tests defining an
optional-subcommand CLI type, such as Opt with command: Option<Commands>. Verify
parsing no arguments succeeds with command set to None, and parsing ["install"]
still returns Error::MissingRequired for tool, confirming validation runs for
provided commands while omission is allowed. Reuse the existing Commands enum.

In `@derive/src/codegen.rs`:
- Around line 1000-1009: Update the environment-variable assignment logic in the
Shape::Count branch so count fields are skipped entirely when env is configured,
rather than executing the shared partial.#given update. Preserve the existing
behavior for other shapes, and ensure count fields do not emit a no-op
assignment or mark their given-state flag.
- Around line 769-780: Add unused_lifetimes to the generated module’s lint allow
list so the generated check method’s unused generic lifetimes do not fail
downstream crates configured with deny(unused_lifetimes). Update the existing
generated-module allow attributes near the check method generation, preserving
the current non_snake_case and unused_imports allowances.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 75aabba8-962e-4526-a20d-b5b70ad4f1e6

📥 Commits

Reviewing files that changed from the base of the PR and between ac75068 and d642010.

📒 Files selected for processing (7)
  • argv/src/lib.rs
  • argv/src/spec.rs
  • conformance/src/argv.rs
  • conformance/tests/post_binding.rs
  • derive/src/codegen.rs
  • derive/src/lib.rs
  • derive/src/model.rs

Comment thread argv/src/lib.rs
Comment on lines +288 to +319
// The rest are raised *after* the parse, by whoever owns the target type: they
// need to know a value's declared type, which the parser deliberately does not.
// They share this enum so that a caller has one error to handle rather than two.
/// Something the command requires was never given.
MissingRequired {
/// The flag or argument's name, as the spec calls it.
name: &'t str,
},
/// A value was given that is not among the declared choices.
///
/// Carries the choices rather than the offending value: rendering the value means
/// owning it, and an error that allocates on a path this crate promises not to
/// allocate on would be a poor trade for a better message. Diagnostics are a
/// separate layer.
InvalidChoice {
name: &'t str,
choices: &'t [&'t str],
},
/// Fewer values than `var_min`.
VarTooFew {
name: &'t str,
min: usize,
got: usize,
},
/// More values than `var_max`.
VarTooMany {
name: &'t str,
max: usize,
got: usize,
},
/// A subcommand was required, and none was given.
MissingSubcommand,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect declared package versions and local manual trait implementations.
fd -a 'Cargo.toml' -x sh -c '
  printf "\n== %s ==\n" "$1"
  rg -n "^(name|version)\\s*=" "$1"
' sh {}

ast-grep outline . --items all --type impl --match 'CommandArgs|Subcommands'

rg -n -C 3 --glob '*.rs' \
  '\bimpl(?:<[^>]*>)?\s+(?:[^ \t]+::)?(?:CommandArgs|Subcommands)\b' .

Repository: jdx/usage

Length of output: 803


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== workspace and package metadata =='
sed -n '1,120p' Cargo.toml
sed -n '1,100p' argv/Cargo.toml

printf '%s\n' '== relevant trait definitions and implementations =='
rg -n -C 12 \
  'trait (CommandArgs|Subcommands)|impl[^\\n]*(CommandArgs|Subcommands)|fn check<' \
  argv/src '*.rs' 2>/dev/null || true

printf '%s\n' '== public Error definition =='
rg -n -C 8 'pub enum Error|MissingRequired|InvalidChoice|VarTooFew|VarTooMany|MissingSubcommand' argv/src

printf '%s\n' '== repository-wide manual implementations =='
rg -n -C 8 --glob '*.rs' \
  'impl(?:<[^>]*>)?\\s+(?:[^\\s]+::)?(?:CommandArgs|Subcommands)\\b' . || true

printf '%s\n' '== API and compatibility documentation =='
rg -n -C 3 --glob '*.md' --glob '*.toml' \
  'breaking|major release|semver|compatib|CommandArgs|Subcommands' . || true

Repository: jdx/usage

Length of output: 25343


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== spec module boundaries and check call sites =='
sed -n '1,80p' argv/src/spec.rs
rg -n -C 10 '::check\\(|\\.check\\(|CommandArgs::check|Subcommands::check|check\\(' \
  argv/src derive/src lib/src cli/src 2>/dev/null || true

printf '%s\n' '== derive implementation generation =='
fd -a -e rs . derive -x sh -c '
  if rg -q "CommandArgs|Subcommands|fn check|MissingRequired|InvalidChoice|VarTooFew|VarTooMany|MissingSubcommand" "$1"; then
    printf "\n== %s ==\n" "$1"
    rg -n -C 10 "CommandArgs|Subcommands|fn check|MissingRequired|InvalidChoice|VarTooFew|VarTooMany|MissingSubcommand" "$1"
  fi
' sh {}

printf '%s\n' '== read-only source invariant verifier =='
python3 - <<'PY'
from pathlib import Path
import re

lib = Path("argv/src/lib.rs").read_text()
spec = Path("argv/src/spec.rs").read_text()
derive = "\n".join(p.read_text() for p in Path("derive/src").rglob("*.rs"))

error = re.search(r"pub enum Error<'t, 'v>\s*\{(.*?)\n\}", lib, re.S)
assert error, "public Error enum not found"
body = error.group(1)
print("Error enum is public:", True)
print("Error enum is non_exhaustive:", bool(re.search(r"#\[non_exhaustive\]", lib[:error.start()])))
for variant in ("MissingRequired", "InvalidChoice", "VarTooFew", "VarTooMany", "MissingSubcommand"):
    print(f"Error::{variant} present:", bool(re.search(rf"\b{variant}\b", body)))

for trait_name, method in (("CommandArgs", "check"), ("Subcommands", "check")):
    m = re.search(rf"pub trait {trait_name}\s*:\s*Sized\s*\{{(.*?)\n\}}", spec, re.S)
    assert m, f"{trait_name} trait not found"
    trait_body = m.group(1)
    method_match = re.search(rf"\bfn {method}\b[^;{{]*(;|\{{)", trait_body)
    assert method_match, f"{trait_name}::{method} not found"
    print(f"{trait_name}::{method} has default body:",
          method_match.group(1) == "{")

print("derive source contains CommandArgs implementation:", "CommandArgs" in derive)
print("derive source contains Subcommands implementation:", "Subcommands" in derive)
PY

Repository: jdx/usage

Length of output: 28079


Preserve 5.x compatibility or release these APIs as 6.0.0.

  • New Error variants break exhaustive downstream matches.
  • Required CommandArgs::check and Subcommands::check methods break manual implementations. Add default Ok(()) bodies if 5.x compatibility is required.
  • Generated implementations already provide both checks.
📍 Affects 2 files
  • argv/src/lib.rs#L288-L319 (this comment)
  • argv/src/spec.rs#L775-L781
  • argv/src/spec.rs#L804-L808
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@argv/src/lib.rs` around lines 288 - 319, Preserve 5.x compatibility across
argv/src/lib.rs:288-319, argv/src/spec.rs:775-781, and argv/src/spec.rs:804-808,
or explicitly release these changes as 6.0.0. For compatibility, avoid adding
breaking Error variants such as MissingRequired, InvalidChoice, VarTooFew,
VarTooMany, and MissingSubcommand, and give CommandArgs::check and
Subcommands::check default Ok(()) implementations so existing manual
implementations remain valid; generated implementations should continue
providing both checks.

Comment thread conformance/tests/post_binding.rs Outdated
@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Instruction counts

benchmark trend instructions Δ wall (min) Δ
markdown ▁▁▁▁▁▁▁▁████████ 148,143,213 → 148,149,874 +0.00% 14.03 → 13.45ms -4.14%
startup ▄▄▄▄▄▄▄▄█████▁▁▁ 1,199,527 → 1,199,593 +0.01% 0.96 → 0.95ms -1.03%

No instruction-count regression above 1%.

Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run.

Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.

5bc52c746c9f vs ac75068b9a59 · measured on the runner, not pushed to the history.

Four review findings.

A counting field with `env` discarded the value and marked the field filled
anyway. It now reads a number — `EX_VERBOSE=3` is how you say `-vvv`, since the
environment cannot repeat a flag — and something unparseable leaves the field
alone rather than counting as given.

A required *flag* said so at run time but not in the spec, so docs and
completions described a different CLI from the one that runs. The same rule an
argument already followed.

Two about not breaking things. `Error` is `non_exhaustive`, because an error
enum grows and recognizing a new failure should never be a breaking change —
which is the last time adding a variant breaks anyone. Both `check` methods now
default to `Ok(())`, so a hand-written implementation with nothing to check is
not forced to say so.

And the environment tests move to their own test binary. Environment variables
are process-wide, so setting one races every test in the same binary that reads
it — including one that only reads it implicitly, by parsing a CLI with an `env`
field. Consolidating the cases into a single `#[test]` fixed the race between
those cases and not the race with their neighbours; a separate file is a
separate process, which does.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jdx
jdx force-pushed the agent/derive-post-binding branch from 4dcf923 to 5bc52c7 Compare August 11, 2026 22:42

jdx commented Aug 11, 2026

Copy link
Copy Markdown
Owner Author

Four findings fixed, and two of them are about not breaking people.

A counting field with env discarded the value and marked the field filled anyway. It now reads a number — EX_VERBOSE=3 is how you say -vvv, since the environment cannot repeat a flag — and something unparseable leaves the field alone rather than counting as given. Both cases are pinned.

A required flag said so at run time but not in the spec, so docs and completions described a different CLI from the one that runs. Same rule an argument already followed. That is the second time this PR has caught a declaration enforced in one place and missing from the other, which is why the test asserting "the declarations reach the spec" earns its keep.

On semver, you were right to raise it. Error is now non_exhaustive — an error enum grows, and recognizing a new failure should never be a breaking change. This is the last time adding a variant breaks anyone, and it immediately proved itself by breaking the conformance harness's exhaustive match, which now has a wildcard. Both check methods default to Ok(()), so a hand-written implementation with nothing to check is not forced to say so.

The environment test race is the most interesting one. My comment claimed consolidating the cases into one #[test] handled it, and that was wrong in a way worth spelling out: it removed the race between those cases and not the race with their neighbours — including tests that read the environment only implicitly, by parsing a CLI that has an env field. Those tests would have been flaky depending on scheduling.

The fix is a separate test binary, since each integration test file is its own process. The file says so at the top, because the next person will be tempted to merge it back.

AI-assisted — Tool: Claude Code; model: anthropic/claude-fable-5; version: unavailable.

@jdx
jdx merged commit 7047ae1 into main Aug 11, 2026
9 checks passed
@jdx
jdx deleted the agent/derive-post-binding branch August 11, 2026 23:22
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Aug 24, 2026
⚠️ **CAUTION: this is a major update, indicating a breaking change!** ⚠️

This MR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [usage](https://github.com/jdx/usage) | tools | major | `5.1.0` → `6.2.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>jdx/usage (usage)</summary>

### [`v6.2.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#620---2026-08-24)

[Compare Source](jdx/usage@v6.1.1...v6.2.0)

##### 🚀 Features

- **(argv)** add embedded parse outcomes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1250](jdx/usage#1250)
- **(cli)** render inline formatting in help text by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1245](jdx/usage#1245)
- **(cli)** split grouped help template sections by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1251](jdx/usage#1251)
- **(complete)** add presentation labels to candidates by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1239](jdx/usage#1239)
- **(complete)** expose structured completion traces by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1241](jdx/usage#1241)
- **(complete)** add semantic candidate kinds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1242](jdx/usage#1242)
- **(complete)** add Elvish runtime completions by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1243](jdx/usage#1243)
- **(derive)** let argument groups carry values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1253](jdx/usage#1253)
- **(derive)** add typed command finalization by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1254](jdx/usage#1254)
- **(derive)** add runtime-computed defaults by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1256](jdx/usage#1256)
- **(derive)** dispatch embedded control requests by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1270](jdx/usage#1270)
- **(derive)** emit embedded\_outcome\_into for converted CLIs by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1281](jdx/usage#1281)
- **(docs)** allow overriding markdown templates by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1267](jdx/usage#1267)
- **(docs)** default to compact markdown references by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1272](jdx/usage#1272)
- **(docs)** polish compact markdown references by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1280](jdx/usage#1280)
- **(help)** expose addressable help topics by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1257](jdx/usage#1257)
- **(help)** list commands by name in one aligned column by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1284](jdx/usage#1284)
- **(help)** wrap the short help page by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1287](jdx/usage#1287)
- **(parse)** add structured diagnostic reports by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1255](jdx/usage#1255)
- **(parse)** add opt-in response files by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1259](jdx/usage#1259)
- **(parse)** preserve ordered argument groups by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1271](jdx/usage#1271)
- **(spec)** declare command outputs and exit codes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1249](jdx/usage#1249)
- **(spec)** add surface availability metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1258](jdx/usage#1258)
- **(spec)** add semantic note and warning blocks by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1273](jdx/usage#1273)
- **(spec)** add output media types by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1274](jdx/usage#1274)
- **(spec)** add help prose to heading sections by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1282](jdx/usage#1282)
- add dynamic command catalogs by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1275](jdx/usage#1275)

##### 🐛 Bug Fixes

- **(completion)** handle attached values and emit built-ins by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1277](jdx/usage#1277)
- **(derive)** preserve flattened command metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1268](jdx/usage#1268)
- **(derive)** skip choice checks for typed defaults by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1269](jdx/usage#1269)
- **(derive)** suppress generated partial field lint by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1278](jdx/usage#1278)
- **(derive)** keep an invalid choice after an override displaces the flag by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1286](jdx/usage#1286)
- **(spec)** make the two KDL writers agree on three more nodes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1289](jdx/usage#1289)

##### 🚜 Refactor

- **(deps)** replace versions with semver by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1285](jdx/usage#1285)

##### ⚡ Performance

- **(argv)** reduce sort code size by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1264](jdx/usage#1264)
- **(markdown)** skip empty admonition context by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1279](jdx/usage#1279)
- document usage-rs parser tradeoffs by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1265](jdx/usage#1265)

##### 🛡️ Security

- **(complete)** filter path candidates by extension by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1240](jdx/usage#1240)

##### 🔍 Other Changes

- update usage of deprecated `str downcase` thingy in nushell by [@&#8203;TheBearodactyl](https://github.com/TheBearodactyl) in [#&#8203;1262](jdx/usage#1262)

##### New Contributors

- [@&#8203;TheBearodactyl](https://github.com/TheBearodactyl) made their first contribution in [#&#8203;1262](jdx/usage#1262)

### [`v6.1.1`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#611---2026-08-23)

[Compare Source](jdx/usage@v6.1.0...v6.1.1)

##### 🐛 Bug Fixes

- **(argv)** simplify generated completion headers by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1226](jdx/usage#1226)
- **(argv)** plan for the target platform, not the host by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1233](jdx/usage#1233)
- **(complete)** keep the path separator the caller typed by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1230](jdx/usage#1230)
- **(config)** report config paths without the verbatim prefix by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1232](jdx/usage#1232)
- **(docs)** separate visible flag aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1228](jdx/usage#1228)
- **(test)** compile the platform-conditional fixtures warning-free on windows by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1234](jdx/usage#1234)

##### ⚡ Performance

- **(derive)** outline invalid-value error construction from generated builds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1235](jdx/usage#1235)
- **(derive)** share the repeated-value collection loop across fields by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1236](jdx/usage#1236)

##### 🧪 Testing

- **(windows)** let the suite run where zsh, fish and bash-completion are not by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1229](jdx/usage#1229)

### [`v6.1.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#610---2026-08-22)

[Compare Source](jdx/usage@v6.0.0...v6.1.0)

##### 🚀 Features

- **(cli)** read settings under a prefix mise does not strip by [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562) in [#&#8203;1213](jdx/usage#1213)
- **(derive)** dispatch more of the matches CLIs already write by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1221](jdx/usage#1221)
- **(spec)** apply runtime identity and flatten headings in help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1220](jdx/usage#1220)

##### 🐛 Bug Fixes

- **(derive)** flow long help and emit kdl raw multiline strings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1215](jdx/usage#1215)

##### 📚 Documentation

- **(rust)** drop the restated one-declaration line from the intro by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1211](jdx/usage#1211)
- **(spec)** complete KDL reference by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1214](jdx/usage#1214)

### [`v6.0.0`](https://github.com/jdx/usage/blob/HEAD/CHANGELOG.md#600---2026-08-22)

[Compare Source](jdx/usage@v5.1.0...v6.0.0)

##### 🚀 Features

- **(argv)** add a zero-allocation argv parser by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;798](jdx/usage#798)
- **(argv)** emit a usage spec from static metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;801](jdx/usage#801)
- **(argv)** a bound stops a variadic by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;826](jdx/usage#826)
- **(argv)** route a word that names nothing to the default subcommand by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;848](jdx/usage#848)
- **(argv)** join static tables at compile time by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;851](jdx/usage#851)
- **(argv)** render the usage line, byte-identical to usage-lib's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;854](jdx/usage#854)
- **(argv)** render `-h`, byte-identical to usage-lib's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;860](jdx/usage#860)
- **(argv)** render `--help` too, byte-identical to usage-lib's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;866](jdx/usage#866)
- **(argv)** answer `--help` and `-h` by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;870](jdx/usage#870)
- **(argv)** answer the `help` subcommand by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;872](jdx/usage#872)
- **(argv)** split a command line the way the shell that typed it would by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;874](jdx/usage#874)
- **(argv)** read the cursor's position off a real parse by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;876](jdx/usage#876)
- **(argv)** offer what the reference offers, from compiled tables by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;877](jdx/usage#877)
- **(argv)** generate the shell script each shell wants by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;887](jdx/usage#887)
- **(argv)** let a Rust function answer for a value by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;888](jdx/usage#888)
- **(argv)** write the `run=` a declared completer answers by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;890](jdx/usage#890)
- **(argv)** say what went wrong the way clap says it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;895](jdx/usage#895)
- **(argv)** suggest what was probably meant by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;897](jdx/usage#897)
- **(argv)** answer `--version`, which an adopter loses on the way from clap by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;909](jdx/usage#909)
- **(argv)** a flag whose value may be left off by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;969](jdx/usage#969)
- **(argv)** take flag-like detached values when declared by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1012](jdx/usage#1012)
- **(bench)** count what a parse allocates, and stop allocating for commands nobody ran by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;829](jdx/usage#829)
- **(cli)** hold a spec's declaration order, the way clap-sort holds a clap CLI's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;915](jdx/usage#915)
- **(cli)** parse usage's own command line with the parser usage ships by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;965](jdx/usage#965)
- **(cli)** support long version text by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1120](jdx/usage#1120)
- **(cli)** check that examples still parse, and let the derive declare them by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1168](jdx/usage#1168)
- **(cli)** add usage explain by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1179](jdx/usage#1179)
- **(cli)** add usage diff for spec compatibility checking by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1171](jdx/usage#1171)
- **(complete)** complete config keys and values from the spec by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;840](jdx/usage#840)
- **(complete)** add async runtime overlays by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1060](jdx/usage#1060)
- **(complete)** support command value hints by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1081](jdx/usage#1081)
- **(complete)** add shell quoting filter by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1114](jdx/usage#1114)
- **(complete)** support full value hint vocabulary by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1119](jdx/usage#1119)
- **(complete)** expand partial path segments by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1128](jdx/usage#1128)
- **(complete)** support shell alias registration by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1158](jdx/usage#1158)
- **(complete)** **breaking** remove the vendored bash-completion copy by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1176](jdx/usage#1176)
- **(complete)** install a completion script where its shell looks for it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1188](jdx/usage#1188)
- **(config)** read config files as a layer by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;856](jdx/usage#856)
- **(config)** explain why a setting has the value it has by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;857](jdx/usage#857)
- **(config)** read a resolution as the types a struct holds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;862](jdx/usage#862)
- **(config)** generate the settings registry from the spec by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;864](jdx/usage#864)
- **(config)** generate the settings struct a CLI reads by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;865](jdx/usage#865)
- **(config)** hold a value to the choices its setting declares by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;868](jdx/usage#868)
- **(config)** carry a setting's choices into the generated registry by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;869](jdx/usage#869)
- **(config)** say what sort of thing each warning is by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;873](jdx/usage#873)
- **(config)** carry the flags a setting declares into its registry by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;880](jdx/usage#880)
- **(config)** read the command line as a layer by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;881](jdx/usage#881)
- **(config)** compare the flags a spec declares with the flags a CLI binds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;884](jdx/usage#884)
- **(config)** support optional props and aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1134](jdx/usage#1134)
- **(config)** read YAML config files by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1192](jdx/usage#1192)
- **(config)** ask for provenance by key, like a value by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1195](jdx/usage#1195)
- **(config)** a read that keeps every setting that reads by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1196](jdx/usage#1196)
- **(config)** close Config derive and spec authoring gaps by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1202](jdx/usage#1202)
- **(config)** gate deprecated settings by explicit CLI version by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1201](jdx/usage#1201)
- **(derive)** compile a struct into parse tables and a spec by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;803](jdx/usage#803)
- **(derive)** compile subcommands from an enum by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;816](jdx/usage#816)
- **(derive)** check what a parse cannot decide on its own by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;817](jdx/usage#817)
- **(derive)** nest commands to any depth by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;818](jdx/usage#818)
- **(derive)** declare which flags conflict and which require each other by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;820](jdx/usage#820)
- **(derive)** let a flag displace another, the last one given winning by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;821](jdx/usage#821)
- **(derive)** let a command answer to more than one name by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;827](jdx/usage#827)
- **(derive)** let a variant hold its command in a `Box` by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;828](jdx/usage#828)
- **(derive)** let a field be the type it means by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;833](jdx/usage#833)
- **(derive)** declare the words a value may be by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;838](jdx/usage#838)
- **(derive)** hold the bytes a word arrived as by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;841](jdx/usage#841)
- **(derive)** declare the properties mise patches in by hand by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;842](jdx/usage#842)
- **(derive)** accept a value the OS accepts and UTF-8 does not by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;844](jdx/usage#844)
- **(derive)** share declarations between commands with flatten by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;852](jdx/usage#852)
- **(derive)** say three things about a CLI the spec could and the derive could not by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;853](jdx/usage#853)
- **(derive)** answer a completion request from the binary itself by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;885](jdx/usage#885)
- **(derive)** bind a flag to a setting, from what the parser saw by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;889](jdx/usage#889)
- **(derive)** a setting can be declared wherever a flag is by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;896](jdx/usage#896)
- **(derive)** let a field name the function that completes it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;892](jdx/usage#892)
- **(derive)** say how an argument relates to `--`, all four ways by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;900](jdx/usage#900)
- **(derive)** a default a collecting field can hold by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;902](jdx/usage#902)
- **(derive)** say what a command does to the world by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;905](jdx/usage#905)
- **(derive)** name a value the way clap names it, and say which usage can read the spec by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;907](jdx/usage#907)
- **(derive)** let `parse()` answer a failure the way a program does by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;910](jdx/usage#910)
- **(derive)** read the package's version, and be called what the binary is called by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;917](jdx/usage#917)
- **(derive)** a command that takes nothing can be written that way by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;923](jdx/usage#923)
- **(derive)** say that a command cannot be run alone, which it knew and did not write by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;937](jdx/usage#937)
- **(derive)** keep command aliases on their args by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;946](jdx/usage#946)
- **(derive)** preserve verbatim doc comments by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;949](jdx/usage#949)
- **(derive)** support path value hints by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;951](jdx/usage#951)
- **(derive)** declare a group where the flags are declared by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;934](jdx/usage#934)
- **(derive)** add value-conditional requirements by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1002](jdx/usage#1002)
- **(derive)** add skip for fields that are not arguments by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1009](jdx/usage#1009)
- **(derive)** support inline subcommand fields by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1055](jdx/usage#1055)
- **(derive)** accept runtime metadata expressions by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1056](jdx/usage#1056)
- **(derive)** accept clap value attributes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1057](jdx/usage#1057)
- **(derive)** parse full argv with program name by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1063](jdx/usage#1063)
- **(derive)** support clap no binary name by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1064](jdx/usage#1064)
- **(derive)** support unit command structs by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1071](jdx/usage#1071)
- **(derive)** reuse args across commands by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1076](jdx/usage#1076)
- **(derive)** support runtime program identity by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1078](jdx/usage#1078)
- **(derive)** preserve value enum metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1079](jdx/usage#1079)
- **(derive)** accept clap field spellings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1086](jdx/usage#1086)
- **(derive)** preserve hidden flag aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1087](jdx/usage#1087)
- **(derive)** resolve relationships through flatten by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1088](jdx/usage#1088)
- **(derive)** support flattened overrides by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1089](jdx/usage#1089)
- **(derive)** preserve flattened help headings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1090](jdx/usage#1090)
- **(derive)** support clap casing policies by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1094](jdx/usage#1094)
- **(derive)** bind value enums directly by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1110](jdx/usage#1110)
- **(derive)** accept portable clap field spellings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1135](jdx/usage#1135)
- **(derive)** inherit clap command metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1136](jdx/usage#1136)
- **(derive)** support clap implicit groups by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1137](jdx/usage#1137)
- **(derive)** generate command dispatch by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1182](jdx/usage#1182)
- **(derive)** add usage::Config derive for settings declared in code by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1180](jdx/usage#1180)
- **(derive)** close remaining PLAN gaps for 6.x by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1197](jdx/usage#1197)
- **(docs)** support granular help visibility by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1107](jdx/usage#1107)
- **(docs)** customize subcommand presentation by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1108](jdx/usage#1108)
- **(docs)** color process-facing help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1111](https://github.com/jdx/usage/pull/1111)
- **(docs)** support help width controls by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1113](https://github.com/jdx/usage/pull/1113)
- **(docs)** support next-line help layout by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1117](https://github.com/jdx/usage/pull/1117)
- **(docs)** support flattened subcommand help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1118](https://github.com/jdx/usage/pull/1118)
- **(docs)** support explicit display order by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1121](https://github.com/jdx/usage/pull/1121)
- **(docs)** group subcommands under help headings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1153](https://github.com/jdx/usage/pull/1153)
- **(docs)** add recursive help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1132](https://github.com/jdx/usage/pull/1132)
- **(generate)** add json-schema for a CLI's config file by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;839](https://github.com/jdx/usage/pull/839)
- **(go)** emit Go parse tables from a spec, which is what Go has instead of a derive by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;931](https://github.com/jdx/usage/pull/931)
- **(go)** emit the cold table too, so generated code can apply the rules by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;959](https://github.com/jdx/usage/pull/959)
- **(go)** render the usage line, from a third table that costs nothing unused by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;964](https://github.com/jdx/usage/pull/964)
- **(go)** render a failure as something a person can act on by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;977](https://github.com/jdx/usage/pull/977)
- **(go)** generate a struct per command, and the Parse that fills them by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;990](https://github.com/jdx/usage/pull/990)
- **(go)** answer the completion request a shell sends by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1005](https://github.com/jdx/usage/pull/1005)
- **(go)** enforce value-conditional requirements by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1003](https://github.com/jdx/usage/pull/1003)
- **(help)** line the flag column up, and give the short page a column at all by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;912](https://github.com/jdx/usage/pull/912)
- **(help)** list the flags a command inherits by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;913](https://github.com/jdx/usage/pull/913)
- **(help)** list `--help` and `--version`, which every page answers by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;914](https://github.com/jdx/usage/pull/914)
- **(lib)** add usage-rs facade by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;963](https://github.com/jdx/usage/pull/963)
- **(lib)** ship usage-rs as the one-crate rust default by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1041](https://github.com/jdx/usage/pull/1041)
- **(parse)** support inferred prefixes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1080](https://github.com/jdx/usage/pull/1080)
- **(parse)** support arg required else help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1093](https://github.com/jdx/usage/pull/1093)
- **(parse)** add narrow token boundary controls by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1097](https://github.com/jdx/usage/pull/1097)
- **(parse)** preserve trailing delimiters by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1098](https://github.com/jdx/usage/pull/1098)
- **(parse)** add scalar repeat policy by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1102](https://github.com/jdx/usage/pull/1102)
- **(parse)** add subcommand requirement policy by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1103](https://github.com/jdx/usage/pull/1103)
- **(parse)** add argument subcommand conflicts by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1104](https://github.com/jdx/usage/pull/1104)
- **(parse)** add subcommand value precedence by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1105](https://github.com/jdx/usage/pull/1105)
- **(parse)** support missing optional positionals by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1106](https://github.com/jdx/usage/pull/1106)
- **(parse)** support optional flag values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1109](https://github.com/jdx/usage/pull/1109)
- **(parse)** support custom help and version actions by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1123](https://github.com/jdx/usage/pull/1123)
- **(parse)** accept explicit boolean values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1124](https://github.com/jdx/usage/pull/1124)
- **(parse)** support non-strict choices by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1127](https://github.com/jdx/usage/pull/1127)
- **(parse)** support ordered environment fallbacks by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1130](https://github.com/jdx/usage/pull/1130)
- **(parse)** warn at runtime when a deprecated declaration is used by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1186](https://github.com/jdx/usage/pull/1186)
- **(spec)** support flag relationships by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;793](https://github.com/jdx/usage/pull/793)
- **(spec)** add help\_heading, and render it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;802](https://github.com/jdx/usage/pull/802)
- **(spec)** allow a mount at the top level by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;806](https://github.com/jdx/usage/pull/806)
- **(spec)** make unknown flags configurable, and keep them as values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;810](https://github.com/jdx/usage/pull/810)
- **(spec)** add `conflicts` to flags by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;819](https://github.com/jdx/usage/pull/819)
- **(spec)** say that one flag needs another, which nothing here could by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;925](https://github.com/jdx/usage/pull/925)
- **(spec)** **breaking** a group, for the rule that no single flag can state by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;927](https://github.com/jdx/usage/pull/927)
- **(spec)** a flag that has to be given on its own by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;941](https://github.com/jdx/usage/pull/941)
- **(spec)** split a value the way clap splits one by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;961](https://github.com/jdx/usage/pull/961)
- **(spec)** add value-conditional requirements by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1001](https://github.com/jdx/usage/pull/1001)
- **(spec)** refuse a detached value when require\_equals is set by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1013](https://github.com/jdx/usage/pull/1013)
- **(spec)** bind a value when a flag is given with none by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1015](https://github.com/jdx/usage/pull/1015)
- **(spec)** forward unmatched words as an external subcommand by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1021](https://github.com/jdx/usage/pull/1021)
- **(spec)** bind a default when another flag is given by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1023](https://github.com/jdx/usage/pull/1023)
- **(spec)** add portable expression validation by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1037](https://github.com/jdx/usage/pull/1037)
- **(spec)** add borrowed metadata overlays by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1059](https://github.com/jdx/usage/pull/1059)
- **(spec)** omit versions from metadata views by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1066](https://github.com/jdx/usage/pull/1066)
- **(spec)** support positional conflicts and groups by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1085](https://github.com/jdx/usage/pull/1085)
- **(spec)** add fixed arity value names by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1099](https://github.com/jdx/usage/pull/1099)
- **(spec)** complete relationship families by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1100](https://github.com/jdx/usage/pull/1100)
- **(spec)** expose package metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1116](https://github.com/jdx/usage/pull/1116)
- **(spec)** add deprecation milestones by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1129](https://github.com/jdx/usage/pull/1129)
- **(spec)** add executable views by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1143](https://github.com/jdx/usage/pull/1143)
- **(spec)** add deprecated config environment aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1159](https://github.com/jdx/usage/pull/1159)
- **(spec)** declare source\_code\_link\_template on the derive by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1184](https://github.com/jdx/usage/pull/1184)
- **(spec)** answer **usage\_spec** from a binary's own tables by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1183](https://github.com/jdx/usage/pull/1183)
- **(spec)** reusable flag declarations with flagset and use by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1170](https://github.com/jdx/usage/pull/1170)
- **(spec)** **breaking** lower the derive's flatten into a flagset by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1172](https://github.com/jdx/usage/pull/1172)
- **(test)** a test harness for an adopter's own suite by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1181](https://github.com/jdx/usage/pull/1181)

##### 🐛 Bug Fixes

- **(argv)** stop a repeatable flag from eating a positional by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;799](https://github.com/jdx/usage/pull/799)
- **(argv)** inherit `unknown_flags`, which reached one command out of a tree by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;939](https://github.com/jdx/usage/pull/939)
- **(argv)** reject duplicate flags by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;945](https://github.com/jdx/usage/pull/945)
- **(argv)** show choices when a subcommand is required by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;947](https://github.com/jdx/usage/pull/947)
- **(argv)** a bare `-` binds where it was typed by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;986](https://github.com/jdx/usage/pull/986)
- **(argv)** put zsh's magic comment first, and print fish's candidates as data by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1033](https://github.com/jdx/usage/pull/1033)
- **(ci)** unblock releases by cutting usage-derive's dev-dependency by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;811](https://github.com/jdx/usage/pull/811)
- **(ci)** check the version the crates promise, and promise one that is true by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;918](https://github.com/jdx/usage/pull/918)
- **(clap)** say what clap would do with an unknown flag by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;899](https://github.com/jdx/usage/pull/899)
- **(cli)** recognize about as root command help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;794](https://github.com/jdx/usage/pull/794)
- **(complete)** resolve config keys through aliases and renames by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1169](https://github.com/jdx/usage/pull/1169)
- **(config)** accept case-insensitive boolean words by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1207](https://github.com/jdx/usage/pull/1207)
- **(derive)** let a `--`-only argument follow a variadic by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;823](https://github.com/jdx/usage/pull/823)
- **(derive)** three more descriptions a spec keeps and the derive lost by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;861](https://github.com/jdx/usage/pull/861)
- **(derive)** name the mistake when `settings` has nothing to collect by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;904](https://github.com/jdx/usage/pull/904)
- **(derive)** emit the tables beside the user's types, not in a module above them by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;938](https://github.com/jdx/usage/pull/938)
- **(derive)** a global flag may be given once per command, not once per line by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;991](https://github.com/jdx/usage/pull/991)
- **(derive)** separate value metadata from parsing by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1054](https://github.com/jdx/usage/pull/1054)
- **(derive)** make defaulted fields optional in metadata by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1065](https://github.com/jdx/usage/pull/1065)
- **(derive)** isolate process exit from adopters by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1139](https://github.com/jdx/usage/pull/1139)
- **(derive)** propagate redeclared global values by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1140](https://github.com/jdx/usage/pull/1140)
- **(derive)** preserve set-false actions by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1156](https://github.com/jdx/usage/pull/1156)
- **(derive)** name the count type in standing presence checks by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1205](https://github.com/jdx/usage/pull/1205)
- **(docs)** link multi-word commands to their real source files by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;845](https://github.com/jdx/usage/pull/845)
- **(docs)** link every command to the file that implements it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;846](https://github.com/jdx/usage/pull/846)
- **(docs)** keep hidden entries out of help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;859](https://github.com/jdx/usage/pull/859)
- **(docs)** list visible flag aliases by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1112](https://github.com/jdx/usage/pull/1112)
- **(help)** a command's page should say what that command does by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;911](https://github.com/jdx/usage/pull/911)
- **(help)** a declared name is not a short form, and blank help is no help by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;916](https://github.com/jdx/usage/pull/916)
- **(help)** render the page for the mount the words reached by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;928](https://github.com/jdx/usage/pull/928)
- **(help)** a description ending in a break adds no blank line by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;970](https://github.com/jdx/usage/pull/970)
- **(lib)** validate every variadic fallback by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1049](https://github.com/jdx/usage/pull/1049)
- **(parse)** keep every `--` after the first by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;809](https://github.com/jdx/usage/pull/809)
- **(parse)** stop losing a flag that is missing its value by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;807](https://github.com/jdx/usage/pull/807)
- **(parse)** answer the five vectors the reference implementation was failing by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;930](https://github.com/jdx/usage/pull/930)
- **(parse)** **breaking** a command that needs a subcommand says so by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;992](https://github.com/jdx/usage/pull/992)
- **(parse)** keep optional validation lint-clean by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1141](https://github.com/jdx/usage/pull/1141)
- **(parse)** honor separator after automatic args by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1164](https://github.com/jdx/usage/pull/1164)
- **(parse)** let a bundle contain a supplied short by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1175](https://github.com/jdx/usage/pull/1175)
- **(spec)** make the config block survive being written out by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;832](https://github.com/jdx/usage/pull/832)
- **(spec)** apply default\_subcommand only at the root by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;850](https://github.com/jdx/usage/pull/850)
- **(spec)** split a clap default by the delimiter clap splits it by by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;901](https://github.com/jdx/usage/pull/901)
- **(spec)** rank a subcommand name above another command's alias by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;967](https://github.com/jdx/usage/pull/967)
- **(spec)** preserve clap value count bounds by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1032](https://github.com/jdx/usage/pull/1032)
- **(spec)** deduplicate derived completers by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1072](https://github.com/jdx/usage/pull/1072)
- **(spec)** canonicalize derived kdl by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1095](https://github.com/jdx/usage/pull/1095)

##### 🚜 Refactor

- **(deps)** **breaking** stop shipping features and crates nobody uses by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1185](https://github.com/jdx/usage/pull/1185)
- **(deps)** drop heck from usage-derive by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1187](https://github.com/jdx/usage/pull/1187)
- **(deps)** take expr-lang without the builtins a spec cannot reach by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1191](https://github.com/jdx/usage/pull/1191)

##### 📚 Documentation

- **(plan)** tick landed clap gaps and stop quoting vector counts by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1027](https://github.com/jdx/usage/pull/1027)
- correct current Rust limitations by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1029](https://github.com/jdx/usage/pull/1029)
- audit 6.x release documentation by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1084](https://github.com/jdx/usage/pull/1084)
- add third-party license notices by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1174](https://github.com/jdx/usage/pull/1174)

##### ⚡ Performance

- **(derive)** fill the partial through \&mut instead of returning it by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;980](https://github.com/jdx/usage/pull/980)
- **(derive)** hold one subcommand's partial, not every subcommand's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;981](https://github.com/jdx/usage/pull/981)
- **(derive)** drop proc-macro-crate transitive deps by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1042](https://github.com/jdx/usage/pull/1042)

##### 🧪 Testing

- **(clap)** preserve choices in external adopter probes by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1157](https://github.com/jdx/usage/pull/1157)
- **(corpus)** pin what completes where the cursor is by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;998](https://github.com/jdx/usage/pull/998)
- **(derive)** cover verbatim doc compatibility by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1092](https://github.com/jdx/usage/pull/1092)
- **(docs)** preserve fleet footer spacing by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1142](https://github.com/jdx/usage/pull/1142)
- **(fleet)** refresh typed adopter fixtures by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1115](https://github.com/jdx/usage/pull/1115)
- **(parse)** cover mounted command discovery by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1131](https://github.com/jdx/usage/pull/1131)
- **(parse)** add clap micro-conformance by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1133](https://github.com/jdx/usage/pull/1133)
- **(spec)** import the argv questions clap's suite answers and ours did not by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;926](https://github.com/jdx/usage/pull/926)
- **(spec)** verify portable parser settings by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1053](https://github.com/jdx/usage/pull/1053)

##### 🛡️ Security

- **(config)** resolve settings from layers, with provenance by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;849](https://github.com/jdx/usage/pull/849)
- **(config)** read the environment as a layer by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;867](https://github.com/jdx/usage/pull/867)
- **(config)** give a deprecation notice from anywhere along a rename chain by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;893](https://github.com/jdx/usage/pull/893)
- **(derive)** keep parsed fields live for lints by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1138](https://github.com/jdx/usage/pull/1138)
- **(docs)** render the config block by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;837](https://github.com/jdx/usage/pull/837)
- **(go)** render the page `-h` prints, matching usage-lib on all 211 of mise's by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;974](https://github.com/jdx/usage/pull/974)
- **(go)** render `--help` too, matching usage-lib on all 211 of mise's long pages by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;975](https://github.com/jdx/usage/pull/975)
- **(parse)** require exact command and flag names by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1096](https://github.com/jdx/usage/pull/1096)
- **(spec)** the config vocabulary by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;835](https://github.com/jdx/usage/pull/835)

##### 🔍 Other Changes

- **(docs)** remove stale mise spec fixture by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;1200](https://github.com/jdx/usage/pull/1200)
- **(perf)** say when the clap ratio slides, and record why the derive is stricter by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;996](https://github.com/jdx/usage/pull/996)
- agent/complete files by [@&#8203;jdx](https://github.com/jdx) in [#&#8203;883](https://github.com/jdx/usage/pull/883)

##### 📦️ Dependency Updates

- update rust crate syn to v3 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;808](https://github.com/jdx/usage/pull/808)
- update rust crate toml to v1 by [@&#8203;renovate\[bot\]](https://github.com/renovate\[bot]) in [#&#8203;1016](https://github.com/jdx/usage/pull/1016)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODguMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWFqb3IiXX0=-->
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