From 477c1403bf7517db948dfb67f00a5de451d08eb4 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 04:17:30 +0000 Subject: [PATCH 01/23] docs(plan): record fleet conversion gaps --- PLAN.md | 91 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 21 deletions(-) diff --git a/PLAN.md b/PLAN.md index 1849ce6b8..5a316aed0 100644 --- a/PLAN.md +++ b/PLAN.md @@ -599,16 +599,25 @@ feature list is not an exhaustive audit. moves the bound fields back into the original enum shape. It accepts both native `usage` field attributes and clap-shaped `arg` attributes in this migration form. +- [x] **Clap-compatible value metadata spelling.** Existing domain enums commonly + use `#[value(name = "...", alias = "...")]`. Requiring those attributes to + be renamed solely to change parsers makes migrations noisier and prevents a + transition where clap and usage derive against the same enum. `ValueEnum` + now accepts both `#[usage(...)]` and `#[value(...)]`, while continuing to + leave `FromStr` ownership with the domain type. - [x] **ValueEnum must coexist with domain parsing and cfg.** aube and fnox enums already implement `FromStr`; deriving usage `ValueEnum` adds a conflicting implementation. fnox also cfg-gates individual variants, while usage's const word list refused holes. ValueEnum now describes choices without taking ownership of domain parsing, and copies variant `cfg`/`cfg_attr` attributes onto the corresponding static-table entries. -- [ ] **Flag aliases in the derive.** aube declares secondary flag spellings. - Static metadata can carry aliases, but a usage field accepts neither - `alias` nor clap's `visible_alias`, so the typed authoring surface cannot - express the spec it is meant to define. +- [ ] **Clap-compatible field spellings and IDs.** Multiple `long` and `short` + entries express flag aliases in usage, but real migrations still have to + rewrite clap's `alias` / `visible_alias`, `id`, `num_args`, `value_parser` + and `rename_all` vocabulary before the derive can explain the semantic + replacement. Accept the lossless spellings directly where practical and + give the rest targeted migration diagnostics rather than a generic unknown + option error. - [ ] **Command-with-arguments completion hints.** fnox uses `ValueHint::CommandWithArguments` for forwarded argv. usage accepts only file, path and directory hints today. Add the command/argv cases or record @@ -618,6 +627,46 @@ feature list is not an exhaustive audit. do not dirty generated docs; hk computes a richer version string. Specify static, expression-backed and omitted versions separately rather than forcing a hard-coded literal into every `Cli` derive. +- [ ] **Unit and tuple Args migration shapes.** fnox's bare command structs and + hk's one-field tuple Args are valid clap derive inputs. usage currently + requires named-field braces, so even a command with no arguments changes + from `Command;` to `Command {}` and a tuple wrapper needs a public shape + change. Support unit structs directly; either support tuple Args or emit a + diagnostic that identifies the named-field rewrite. +- [ ] **Relationships through flatten and positional IDs.** Positional + relationships are already a general gap above. The fleet exposed the + second half: a field cannot name a flag contributed by a flattened Args + type because validation runs against the declaring struct before the + command is assembled. aube lost statically declared relationships and hk + and fnox needed runtime conflict checks. Validate selectors against the + composed command and carry stable IDs for both flags and positionals. +- [ ] **Flattened help topology.** clap's `next_help_heading` and flattened flag + groups preserve meaningful sections in aube's long help. usage flattens the + fields but discards that struct-level heading, so a migration can preserve + parsing while silently degrading help. Define heading inheritance for a + flattened Args type and cover short/long help ordering in conformance. +- [ ] **Facade-owned derive validation.** A direct `usage-derive` adopter can + compile generated code only after separately adding `usage-validation`; + the implementation dependency leaks into every converted manifest. The + supported facade should own or re-export this path so the documented + dependency set is sufficient and generated code does not require users to + discover an internal crate from a compiler error. +- [ ] **Spec mutation without an MSRV jump.** aube and hk parse derived KDL into + usage-lib solely to attach command effects and other generated fragments. + That raises an argv-only adopter from the 1.91 tier to usage-lib's 1.95 + tier (and hk currently declares Rust 1.88). Provide a static metadata hook, + a lightweight spec-editing surface, or an explicit release policy before + claiming these migrations are mergeable. +- [ ] **Runtime program identity.** aube embeds the same CLI under a caller-chosen + binary name. A derived spec can be rewritten after emission, but parser + help and diagnostics still use the static name. Support a runtime identity + source with an explicit portable `name`/`bin` value, analogous to computed + version plus `version_spec`. +- [ ] **Test parsing with argv0.** `parse_from` intentionally takes words after + the binary, while clap tests commonly call `try_parse_from(["tool", ...])`. + Fleet ports needed local wrappers just to preserve their parser tests. + Add an explicit argv0-taking helper rather than making every migration + hand-roll `skip(1)` and accidentally obscure multicall semantics. - [ ] **Generated micro-conformance against clap.** One minimal CLI per matrix row, compared on accepted and rejected argv, typed values, error kind and exit status, stdout versus stderr, short and long help, usage/version output, and @@ -772,7 +821,7 @@ looking at the clap surface, not only at the spec. command) and the same manpage. usage-cli's own `render:usage-cli-completions` already does this for `usage`; the gate now asks it of a clap CLI. -- [~] **Typed rewrites of communique, tak, aube, hk, and fnox, not String +- [x] **Typed rewrites of communique, tak, aube, hk, and fnox, not String shadows.** `gen-shadow` types every field as `String`. The derive already holds `PathBuf`, `OsString`, `ValueEnum`, `FromStr`, `flatten`, `Option`/`Vec`. usage-cli @@ -786,12 +835,14 @@ looking at the clap surface, not only at the spec. 6.x gate, not something to merge before usage 6.x is published. Together they tell us whether the fleet is a rewrite or a set of blocked rewrites. **The experiment PRs now exist and all five modify the real CLI:** - jdx/communique#265 and jdx/tak#47 compile (tak's full suite passes); - jdx/aube#1336, jdx/hk#1211 and jdx/fnox#725 remove the clap dependency and - convert the real derives, but stop on 194, 490 and 326 compiler diagnostics - respectively, including cascades. Their migration-status files group those - failures into the launch-gate rows above. All five pin `jdx/usage` at - `cc60dcb7`. + jdx/communique#265, jdx/tak#47, jdx/aube#1336, jdx/hk#1211 and + jdx/fnox#725 all remove clap, compile against the stacked usage changes and + pass their migrated test suites. The ports preserve their typed domain + values rather than lowering to String, keep intentional forwarding behavior, + and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at + the root because its external-subcommand path is a package-manager forwarder. + All five pin the experiment stack at `7f8aeb47`. The workarounds they still + contain are the unchecked launch-gate rows above, not unfinished conversions. - [x] **The clap-only validation behaviour the fleet actually uses.** Portable `validate` expressions cover numeric ranges in the typed rewrite. Arbitrary clap parser functions remain opaque to `clap_usage`, but they no longer require a @@ -833,16 +884,14 @@ a prerequisite for trying a CLI. `usage-rs`, emits its spec from the same tables, and feeds that spec to the markdown, manpage and completion generators. The remaining items in **Trying the fleet** are about the _other_ CLIs, not this one. -- [~] **communique, tak, aube, hk, and fnox** — five fleet experiment PRs now - exist, each - carried as a ready-for-review experimental PR on a git dependency until - usage 6.x exists. communique and tak parse their real typed commands with - usage and compile; tak's added spec endpoint is experiment-only and outside - its preserved CLI contract. aube, hk and fnox have their real derives and - dependencies converted, not shadows, but do not compile against the current - usage revision. The gaps found are recorded in the general launch gate - above; closing them and finishing those three typed rewrites is required - before 6.x is published. +- [x] **communique, tak, aube, hk, and fnox** — five ready-for-review fleet + experiment PRs parse their real typed commands with usage, remove clap and + pass locally. They deliberately retain a git dependency and are evidence for + the 6.x gate rather than merge candidates before publication. tak's added + spec endpoint is experiment-only and outside its preserved CLI contract. + The gaps found are recorded in the general launch gate above; closing the + merge-blocking rows is required before publishing 6.x and converting these + experiments into release-dependency PRs. - [ ] **mise** — the largest and least forgiving adopter. Likely a router first, then commands lowered a few at a time, with mise's e2e argv corpus replayed against both parsers. Adoption is measured by what it lets mise delete, listed below. From 985dcca23eb449a9625caef3d8d5eb39bf3644d3 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 04:24:20 +0000 Subject: [PATCH 02/23] docs(plan): update stabilized fleet revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index 5a316aed0..030baee45 100644 --- a/PLAN.md +++ b/PLAN.md @@ -841,7 +841,7 @@ looking at the clap surface, not only at the spec. values rather than lowering to String, keep intentional forwarding behavior, and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. - All five pin the experiment stack at `7f8aeb47`. The workarounds they still + All five pin the experiment stack at `88786493`. The workarounds they still contain are the unchecked launch-gate rows above, not unfinished conversions. - [x] **The clap-only validation behaviour the fleet actually uses.** Portable `validate` expressions cover numeric ranges in the typed rewrite. Arbitrary clap From 60c55925e1a57c3ab964e7cf846ed89d4e118d2b Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 04:32:20 +0000 Subject: [PATCH 03/23] docs(plan): format fleet adoption findings --- PLAN.md | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/PLAN.md b/PLAN.md index 030baee45..c37fd1ae9 100644 --- a/PLAN.md +++ b/PLAN.md @@ -822,27 +822,27 @@ looking at the clap surface, not only at the spec. `render:usage-cli-completions` already does this for `usage`; the gate now asks it of a clap CLI. - [x] **Typed rewrites of communique, tak, aube, hk, and fnox, not String - shadows.** `gen-shadow` - types every field as `String`. The derive already holds `PathBuf`, - `OsString`, `ValueEnum`, `FromStr`, `flatten`, `Option`/`Vec`. usage-cli - proves that for usage's own types. These five will prove it across real - clap CLIs rewritten in place: real field types, skip-fields or the split - they force, and binaries that preserve every pre-existing `--help` and - spec-emission entry point. tak's experiment-only spec entry point is tested - as new behavior rather than compared with a nonexistent baseline. Each - experiment is a ready-for-review PR whose `Cargo.toml` - deliberately points at usage's git revision; the PR is evidence for the - 6.x gate, not something to merge before usage 6.x is published. Together - they tell us whether the fleet is a rewrite or a set of blocked rewrites. - **The experiment PRs now exist and all five modify the real CLI:** - jdx/communique#265, jdx/tak#47, jdx/aube#1336, jdx/hk#1211 and - jdx/fnox#725 all remove clap, compile against the stacked usage changes and - pass their migrated test suites. The ports preserve their typed domain - values rather than lowering to String, keep intentional forwarding behavior, - and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at - the root because its external-subcommand path is a package-manager forwarder. - All five pin the experiment stack at `88786493`. The workarounds they still - contain are the unchecked launch-gate rows above, not unfinished conversions. + shadows.** `gen-shadow` + types every field as `String`. The derive already holds `PathBuf`, + `OsString`, `ValueEnum`, `FromStr`, `flatten`, `Option`/`Vec`. usage-cli + proves that for usage's own types. These five will prove it across real + clap CLIs rewritten in place: real field types, skip-fields or the split + they force, and binaries that preserve every pre-existing `--help` and + spec-emission entry point. tak's experiment-only spec entry point is tested + as new behavior rather than compared with a nonexistent baseline. Each + experiment is a ready-for-review PR whose `Cargo.toml` + deliberately points at usage's git revision; the PR is evidence for the + 6.x gate, not something to merge before usage 6.x is published. Together + they tell us whether the fleet is a rewrite or a set of blocked rewrites. + **The experiment PRs now exist and all five modify the real CLI:** + jdx/communique#265, jdx/tak#47, jdx/aube#1336, jdx/hk#1211 and + jdx/fnox#725 all remove clap, compile against the stacked usage changes and + pass their migrated test suites. The ports preserve their typed domain + values rather than lowering to String, keep intentional forwarding behavior, + and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at + the root because its external-subcommand path is a package-manager forwarder. + All five pin the experiment stack at `88786493`. The workarounds they still + contain are the unchecked launch-gate rows above, not unfinished conversions. - [x] **The clap-only validation behaviour the fleet actually uses.** Portable `validate` expressions cover numeric ranges in the typed rewrite. Arbitrary clap parser functions remain opaque to `clap_usage`, but they no longer require a @@ -885,13 +885,13 @@ a prerequisite for trying a CLI. the markdown, manpage and completion generators. The remaining items in **Trying the fleet** are about the _other_ CLIs, not this one. - [x] **communique, tak, aube, hk, and fnox** — five ready-for-review fleet - experiment PRs parse their real typed commands with usage, remove clap and - pass locally. They deliberately retain a git dependency and are evidence for - the 6.x gate rather than merge candidates before publication. tak's added - spec endpoint is experiment-only and outside its preserved CLI contract. - The gaps found are recorded in the general launch gate above; closing the - merge-blocking rows is required before publishing 6.x and converting these - experiments into release-dependency PRs. + experiment PRs parse their real typed commands with usage, remove clap and + pass locally. They deliberately retain a git dependency and are evidence for + the 6.x gate rather than merge candidates before publication. tak's added + spec endpoint is experiment-only and outside its preserved CLI contract. + The gaps found are recorded in the general launch gate above; closing the + merge-blocking rows is required before publishing 6.x and converting these + experiments into release-dependency PRs. - [ ] **mise** — the largest and least forgiving adopter. Likely a router first, then commands lowered a few at a time, with mise's e2e argv corpus replayed against both parsers. Adoption is measured by what it lets mise delete, listed below. From 3fd85a96f6002e4ec15c5593e83f57529335e06c Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 04:39:28 +0000 Subject: [PATCH 04/23] docs(plan): track generated dialect version skew --- PLAN.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/PLAN.md b/PLAN.md index c37fd1ae9..bcff62f43 100644 --- a/PLAN.md +++ b/PLAN.md @@ -657,6 +657,13 @@ feature list is not an exhaustive audit. tier (and hk currently declares Rust 1.88). Provide a static metadata hook, a lightweight spec-editing surface, or an explicit release policy before claiming these migrations are mergeable. +- [ ] **Keep generated-spec producers and consumers on one dialect.** A derive + pinned to the 6.x stack can emit nodes such as `unknown_flags` that the + released 5.x `usage` binary in an adopter's docs task cannot read. The + communique experiment had to build a second git-pinned `usage-cli` just to + render the KDL emitted by its Rust dependency. Define a supported way to + install matching pre-release tooling (and make version diagnostics name the + required dialect) so a migration does not silently combine two revisions. - [ ] **Runtime program identity.** aube embeds the same CLI under a caller-chosen binary name. A derived spec can be rewritten after emission, but parser help and diagnostics still use the static name. Support a runtime identity From b909310fc1acc10315e3b12ce623deda297855d0 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 04:55:10 +0000 Subject: [PATCH 05/23] fix(ci): avoid stalled ubuntu mirror --- .github/workflows/coverage.yml | 1 + .github/workflows/test.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 965abbdf2..d4817bfb0 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -35,6 +35,7 @@ jobs: - name: Install shells for completion integration tests timeout-minutes: 5 run: | + sudo sed -i 's|http://azure.archive.ubuntu.com/ubuntu|https://archive.ubuntu.com/ubuntu|g' /etc/apt/apt-mirrors.txt sudo apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=15 -o Acquire::https::Timeout=15 update sudo apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=15 -o Acquire::https::Timeout=15 install -y zsh fish if ! command -v pwsh >/dev/null 2>&1; then diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 31a19b192..31f6aea3b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,6 +46,7 @@ jobs: - name: Install shells for completion integration tests timeout-minutes: 5 run: | + sudo sed -i 's|http://azure.archive.ubuntu.com/ubuntu|https://archive.ubuntu.com/ubuntu|g' /etc/apt/apt-mirrors.txt sudo apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=15 -o Acquire::https::Timeout=15 update sudo apt-get -o Acquire::Retries=3 -o Acquire::http::Timeout=15 -o Acquire::https::Timeout=15 install -y zsh fish # pwsh is pre-installed on GitHub ubuntu-latest images. Self-heal From c2271a7bb4d7bf58d14ac6d75d7d2ef0d2a44bb4 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 04:58:04 +0000 Subject: [PATCH 06/23] docs(plan): preserve clap alias visibility --- PLAN.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index bcff62f43..689d5470d 100644 --- a/PLAN.md +++ b/PLAN.md @@ -617,7 +617,11 @@ feature list is not an exhaustive audit. and `rename_all` vocabulary before the derive can explain the semantic replacement. Accept the lossless spellings directly where practical and give the rest targeted migration diagnostics rather than a generic unknown - option error. + option error. Preserve the visibility distinction too: clap's `alias` and + `aliases` are hidden while `visible_alias` and `visible_aliases` are + advertised; usage spells those `alias_hidden` and `alias`. The fnox rewrite + initially made `completion`'s hidden aliases and `exec run` visible because + a mechanical rename erased that distinction. - [ ] **Command-with-arguments completion hints.** fnox uses `ValueHint::CommandWithArguments` for forwarded argv. usage accepts only file, path and directory hints today. Add the command/argv cases or record From 92bef14ff326c4eb1b02b4c074f558a1509adee3 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 05:02:43 +0000 Subject: [PATCH 07/23] docs(plan): track require-equals diagnostics --- PLAN.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/PLAN.md b/PLAN.md index 689d5470d..063814096 100644 --- a/PLAN.md +++ b/PLAN.md @@ -681,9 +681,12 @@ feature list is not an exhaustive audit. - [ ] **Generated micro-conformance against clap.** One minimal CLI per matrix row, compared on accepted and rejected argv, typed values, error kind and exit status, stdout versus stderr, short and long help, usage/version output, and - completion candidates. Run the portable cases on Unix and Windows and the - byte-value cases on Unix. The mise fuzzer remains the scale test; this is the - configuration-space test it cannot be. + completion candidates. Include setting-specific diagnostics: for example, + clap explains that `--flag=value` is required when `require_equals` rejects + a detached or missing value, while usage currently reports only a generic + missing value and forced Aube to adapt that error locally. Run the portable + cases on Unix and Windows and the byte-value cases on Unix. The mise fuzzer + remains the scale test; this is the configuration-space test it cannot be. - [ ] **Combination and stateful tests.** Pairwise-cover settings that interact: defaults with env and delimiters, optional values with `require_equals`, globals with overrides, subcommands with required positionals, groups with From 76baa711972de088e9d206ae86abb5660638d580 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 05:31:57 +0000 Subject: [PATCH 08/23] docs: plan public clap api migrations --- PLAN.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/PLAN.md b/PLAN.md index 063814096..0d6cd344d 100644 --- a/PLAN.md +++ b/PLAN.md @@ -520,6 +520,13 @@ Groups are the opposite case: `Command::get_groups`, `ArgGroup::get_args` and deliberate: usage-lib interprets a spec at run time and covers the dynamic case from the other side. Worth writing down as a decision rather than leaving it to be discovered as an absence. +- [ ] **Public `CommandFactory` migration.** A library can expose + `pub fn command() -> clap::Command` as part of its supported API, as aube + does. Replacing its internal parser is not source-compatible for embedders + unless clap remains in the public dependency graph. Specify the supported + transition: a usage metadata return type, a separately named compatibility + entry point, and the semver expectations for adopters that publish the clap + builder itself. **What is _not_ a gap**, checked rather than assumed, because two of these were recorded as gaps here and had quietly been closed: flag aliases (several `long` From 185d39531c0b5333cc3efc17c535f53019a1d221 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 05:41:24 +0000 Subject: [PATCH 09/23] docs: plan static metadata overlays --- PLAN.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/PLAN.md b/PLAN.md index 0d6cd344d..33d44da7d 100644 --- a/PLAN.md +++ b/PLAN.md @@ -662,12 +662,21 @@ feature list is not an exhaustive audit. supported facade should own or re-export this path so the documented dependency set is sufficient and generated code does not require users to discover an internal crate from a compiler error. -- [ ] **Spec mutation without an MSRV jump.** aube and hk parse derived KDL into - usage-lib solely to attach command effects and other generated fragments. - That raises an argv-only adopter from the 1.91 tier to usage-lib's 1.95 - tier (and hk currently declares Rust 1.88). Provide a static metadata hook, - a lightweight spec-editing surface, or an explicit release policy before - claiming these migrations are mergeable. +- [ ] **Central metadata overlays without an MSRV or performance jump.** aube + keeps a centrally audited command-effect table rather than scattering the + policy across command types. Applying that table currently means parsing + derived KDL into usage-lib, which raises an argv-only adopter from the 1.91 + tier to usage-lib's 1.95 tier. hk first did the same and its `usage` + benchmark retired 9x as many instructions; moving every effect into derive + attributes fixed the regression but lost the central declaration. Provide + a static overlay or lightweight spec-editing surface for policies that need + a whole-tree view. +- [ ] **Canonical, duplicate-free derived KDL.** hk's direct `Cli::to_kdl()` + output was semantically accepted but differed substantially from the same + tree after a usage-lib parse/serialize round trip, and repeated identical + `complete "path"` nodes that the round trip collapsed. Make direct emission + canonical and deduplicate composed completers so adopters do not need the + expensive round trip merely for stable generated artifacts. - [ ] **Keep generated-spec producers and consumers on one dialect.** A derive pinned to the 6.x stack can emit nodes such as `unknown_flags` that the released 5.x `usage` binary in an adopter's docs task cannot read. The From 7e85cc8f5fff33cc894596f453cc711d2f4137a0 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 11:09:02 +0000 Subject: [PATCH 10/23] docs: record compiled completion overlay gap --- PLAN.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/PLAN.md b/PLAN.md index 33d44da7d..c3b9c6cfe 100644 --- a/PLAN.md +++ b/PLAN.md @@ -671,6 +671,18 @@ feature list is not an exhaustive audit. attributes fixed the regression but lost the central declaration. Provide a static overlay or lightweight spec-editing surface for policies that need a whole-tree view. +- [ ] **Compiled completions for runtime overlays, multicall projections and async + candidates.** The self-contained completion endpoint can answer only from a + derive-time `usage_argv::spec::Spec`, and custom Rust completers are + synchronous. aube instead appends named completers to KDL at runtime, projects + the `run` and `dlx` subtrees into the `aubr` and `aubx` binaries, and discovers + package candidates asynchronously. Its fleet PR therefore still invokes + `usage g completion`; switching it to `#[usage(completion)]` today would emit a + valid script that silently loses those candidates. Give `usage-rs` a static or + lightweight overlay/projection surface consumable by the compiled completion + walker, define an async completion callback strategy that does not tax normal + parsing, and cover alternate binary identities before calling completions + self-contained for embedders and multicall CLIs. - [ ] **Canonical, duplicate-free derived KDL.** hk's direct `Cli::to_kdl()` output was semantically accepted but differed substantially from the same tree after a usage-lib parse/serialize round trip, and repeated identical @@ -871,8 +883,12 @@ looking at the clap surface, not only at the spec. values rather than lowering to String, keep intentional forwarding behavior, and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. - All five pin the experiment stack at `88786493`. The workarounds they still - contain are the unchecked launch-gate rows above, not unfinished conversions. + All five depend only on the `usage-rs` facade for parsing and derives and pin + the experiment stack at `88786493`. hk and fnox also use its built-in compiled + completion protocol, removing their runtime dependency on an installed `usage` + binary; aube retains the external completion generator for the runtime-overlay + gap above. The workarounds they still contain are the unchecked launch-gate rows + above, not unfinished conversions. - [x] **The clap-only validation behaviour the fleet actually uses.** Portable `validate` expressions cover numeric ranges in the typed rewrite. Arbitrary clap parser functions remain opaque to `clap_usage`, but they no longer require a From 8a5f735804ca42264d5bee110c2dd02b3ce02052 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 11:15:53 +0000 Subject: [PATCH 11/23] docs: include fnox in completion overlay gap --- PLAN.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/PLAN.md b/PLAN.md index c3b9c6cfe..9a3885c18 100644 --- a/PLAN.md +++ b/PLAN.md @@ -682,7 +682,10 @@ feature list is not an exhaustive audit. lightweight overlay/projection surface consumable by the compiled completion walker, define an async completion callback strategy that does not tax normal parsing, and cover alternate binary identities before calling completions - self-contained for embedders and multicall CLIs. + self-contained for embedders and multicall CLIs. fnox exposes the same gap in + a smaller shape: switching it to `Cli::completion_script` dropped the secret, + provider, profile and config-file completers appended from + `fnox-extras.usage.kdl`, so its fleet PR also retains `usage g completion`. - [ ] **Canonical, duplicate-free derived KDL.** hk's direct `Cli::to_kdl()` output was semantically accepted but differed substantially from the same tree after a usage-lib parse/serialize round trip, and repeated identical @@ -884,11 +887,11 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five depend only on the `usage-rs` facade for parsing and derives and pin - the experiment stack at `88786493`. hk and fnox also use its built-in compiled - completion protocol, removing their runtime dependency on an installed `usage` - binary; aube retains the external completion generator for the runtime-overlay - gap above. The workarounds they still contain are the unchecked launch-gate rows - above, not unfinished conversions. + the experiment stack at `88786493`. hk also uses its built-in compiled + completion protocol, removing its runtime dependency on an installed `usage` + binary; aube and fnox retain the external completion generator for the + runtime-overlay gap above. The workarounds they still contain are the unchecked + launch-gate rows above, not unfinished conversions. - [x] **The clap-only validation behaviour the fleet actually uses.** Portable `validate` expressions cover numeric ranges in the typed rewrite. Arbitrary clap parser functions remain opaque to `clap_usage`, but they no longer require a From 681eb8499b302c622ab19318a477c0e805df5ae8 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:17:37 +0000 Subject: [PATCH 12/23] docs: record overlay and clap API decisions --- PLAN.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/PLAN.md b/PLAN.md index 9a3885c18..065312d31 100644 --- a/PLAN.md +++ b/PLAN.md @@ -518,15 +518,16 @@ Groups are the opposite case: `Command::get_groups`, `ArgGroup::get_args` and - [ ] **The builder** — `Command::new`, `augment_args`, `CommandFactory`, `ArgMatches::get_one`, hand-written `FromArgMatches`. Architectural, and deliberate: usage-lib interprets a spec at run time and covers the dynamic - case from the other side. Worth writing down as a decision rather than - leaving it to be discovered as an absence. + case from the other side. This is an explicit non-goal: the usage metadata + API does not need to reproduce clap's `Command` surface or be fully source + compatible with it. - [ ] **Public `CommandFactory` migration.** A library can expose `pub fn command() -> clap::Command` as part of its supported API, as aube - does. Replacing its internal parser is not source-compatible for embedders - unless clap remains in the public dependency graph. Specify the supported - transition: a usage metadata return type, a separately named compatibility - entry point, and the semver expectations for adopters that publish the clap - builder itself. + does. The 6.x transition may intentionally break that API and return a + first-party usage metadata/spec view instead; it does not need to preserve + the complete clap builder contract. Document the semver expectation and any + separately named, opt-in compatibility entry point an adopter chooses to + retain. **What is _not_ a gap**, checked rather than assumed, because two of these were recorded as gaps here and had quietly been closed: flag aliases (several `long` @@ -669,8 +670,11 @@ feature list is not an exhaustive audit. tier to usage-lib's 1.95 tier. hk first did the same and its `usage` benchmark retired 9x as many instructions; moving every effect into derive attributes fixed the regression but lost the central declaration. Provide - a static overlay or lightweight spec-editing surface for policies that need - a whole-tree view. + a typed, borrowed static overlay/spec-view surface for policies that need a + whole-tree view. Overlay resolution belongs only on cold metadata, help and + completion paths: ordinary argv parsing must continue to use the base const + tables directly, without building a command graph, allocating, or consulting + the overlay. - [ ] **Compiled completions for runtime overlays, multicall projections and async candidates.** The self-contained completion endpoint can answer only from a derive-time `usage_argv::spec::Spec`, and custom Rust completers are @@ -680,8 +684,10 @@ feature list is not an exhaustive audit. `usage g completion`; switching it to `#[usage(completion)]` today would emit a valid script that silently loses those candidates. Give `usage-rs` a static or lightweight overlay/projection surface consumable by the compiled completion - walker, define an async completion callback strategy that does not tax normal - parsing, and cover alternate binary identities before calling completions + walker. Async completers should return futures without choosing or bundling + an executor; the embedding CLI runs them on its existing runtime, and neither + async support nor its allocations enter the ordinary parse path. Cover + alternate binary identities before calling completions self-contained for embedders and multicall CLIs. fnox exposes the same gap in a smaller shape: switching it to `Cli::completion_script` dropped the secret, provider, profile and config-file completers appended from From 38351b8de801aa2d8b8a9b860e1d13174274d250 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:45:07 +0000 Subject: [PATCH 13/23] docs(plan): record runtime overlay adoption --- PLAN.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/PLAN.md b/PLAN.md index 065312d31..8d5a7618e 100644 --- a/PLAN.md +++ b/PLAN.md @@ -663,7 +663,7 @@ feature list is not an exhaustive audit. supported facade should own or re-export this path so the documented dependency set is sufficient and generated code does not require users to discover an internal crate from a compiler error. -- [ ] **Central metadata overlays without an MSRV or performance jump.** aube +- [x] **Central metadata overlays without an MSRV or performance jump.** aube keeps a centrally audited command-effect table rather than scattering the policy across command types. Applying that table currently means parsing derived KDL into usage-lib, which raises an argv-only adopter from the 1.91 @@ -674,8 +674,10 @@ feature list is not an exhaustive audit. whole-tree view. Overlay resolution belongs only on cold metadata, help and completion paths: ordinary argv parsing must continue to use the base const tables directly, without building a command graph, allocating, or consulting - the overlay. -- [ ] **Compiled completions for runtime overlays, multicall projections and async + the overlay. `SpecView` and `CommandOverlay` now provide that borrowed cold + path, and aube's fleet PR applies its central effect table through them + without depending on usage-lib. +- [x] **Compiled completions for runtime overlays, multicall projections and async candidates.** The self-contained completion endpoint can answer only from a derive-time `usage_argv::spec::Spec`, and custom Rust completers are synchronous. aube instead appends named completers to KDL at runtime, projects @@ -692,6 +694,12 @@ feature list is not an exhaustive audit. a smaller shape: switching it to `Cli::completion_script` dropped the secret, provider, profile and config-file completers appended from `fnox-extras.usage.kdl`, so its fleet PR also retains `usage g completion`. + `App` now combines a borrowed `SpecView`, sparse sync/async completion + callbacks, runtime identity and command projection. It does not bundle an + executor. aube uses it for all of those cases, including `aubr`/`aubx` and + async registry search; fnox uses it for secret, provider and profile + candidates. Both now generate and answer completions through `usage-rs` + without invoking the `usage` binary. - [ ] **Canonical, duplicate-free derived KDL.** hk's direct `Cli::to_kdl()` output was semantically accepted but differed substantially from the same tree after a usage-lib parse/serialize round trip, and repeated identical @@ -892,12 +900,12 @@ looking at the clap surface, not only at the spec. values rather than lowering to String, keep intentional forwarding behavior, and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. - All five depend only on the `usage-rs` facade for parsing and derives and pin - the experiment stack at `88786493`. hk also uses its built-in compiled - completion protocol, removing its runtime dependency on an installed `usage` - binary; aube and fnox retain the external completion generator for the - runtime-overlay gap above. The workarounds they still contain are the unchecked - launch-gate rows above, not unfinished conversions. + All five use the `usage-rs` facade for parsing and derives and pin the + experiment stack at `44f81ad7`. hk, aube and fnox also use its built-in + compiled completion protocol, removing their runtime dependency on an + installed `usage` binary. aube's remaining direct `usage-validation` + dependency is the facade-validation gap above. The workarounds they still + contain are the unchecked launch-gate rows above, not unfinished conversions. - [x] **The clap-only validation behaviour the fleet actually uses.** Portable `validate` expressions cover numeric ranges in the typed rewrite. Arbitrary clap parser functions remain opaque to `clap_usage`, but they no longer require a From 455bcb7cbd025552615fb64b2c58a259fc1e14f1 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:50:48 +0000 Subject: [PATCH 14/23] docs(plan): refresh stabilized fleet revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index 8d5a7618e..275e82b0f 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `44f81ad7`. hk, aube and fnox also use its built-in + experiment stack at `a86bca29`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From 48d4030605d5a97586c9e9321bcf0cc19b212b26 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:57:22 +0000 Subject: [PATCH 15/23] docs(plan): refresh stabilized fleet revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index 275e82b0f..7557695a0 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `a86bca29`. hk, aube and fnox also use its built-in + experiment stack at `34989d64`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From 0f1bd3feaa4efbd5c00d634c7ec87f39aa9e42b6 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 13:07:13 +0000 Subject: [PATCH 16/23] docs(plan): refresh stabilized fleet revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index 7557695a0..a392e21c9 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `34989d64`. hk, aube and fnox also use its built-in + experiment stack at `f963d01c`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From d550fee343a5edfbd4d72a1be94e3859059d3c4e Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 14:03:23 +0000 Subject: [PATCH 17/23] docs(plan): refresh fleet stack revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index a392e21c9..c5f467e38 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `f963d01c`. hk, aube and fnox also use its built-in + experiment stack at `92201bb7`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From f842f9acbcd01c5ed4919bda94bb8db7d29080b9 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 14:10:36 +0000 Subject: [PATCH 18/23] docs(plan): refresh rebased fleet revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index c5f467e38..63100dd72 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `92201bb7`. hk, aube and fnox also use its built-in + experiment stack at `597f5871`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From 2cd605e52393ddd2a24d6b7d1f3ac44a93d6557b Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 14:52:11 +0000 Subject: [PATCH 19/23] docs(plan): refresh fleet stack revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index 63100dd72..84e5b3b3c 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `597f5871`. hk, aube and fnox also use its built-in + experiment stack at `f8952fa2`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From fe5f60a21075450e5acdff2392c14d9398674573 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 14:57:09 +0000 Subject: [PATCH 20/23] docs(plan): refresh fleet stack revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index 84e5b3b3c..5608257b0 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `f8952fa2`. hk, aube and fnox also use its built-in + experiment stack at `55193c3c`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From 9494f2143d75701ca6ed619568d3d46b1536bcd8 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 15:02:49 +0000 Subject: [PATCH 21/23] docs(plan): refresh fleet stack revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index 5608257b0..d96625ca5 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `55193c3c`. hk, aube and fnox also use its built-in + experiment stack at `1da5eddd`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From 0bc1193a45808e426c8a8863e66f453b4a9ddd60 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 15:18:07 +0000 Subject: [PATCH 22/23] docs(plan): refresh fleet stack revision --- PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLAN.md b/PLAN.md index d96625ca5..3b2d2edec 100644 --- a/PLAN.md +++ b/PLAN.md @@ -901,7 +901,7 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `1da5eddd`. hk, aube and fnox also use its built-in + experiment stack at `f9ea7a76`. hk, aube and fnox also use its built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still From 12349cb387aef8777926525a50de3cad817df686 Mon Sep 17 00:00:00 2001 From: default <216188+jdx@users.noreply.github.com> Date: Wed, 19 Aug 2026 17:09:08 +0000 Subject: [PATCH 23/23] docs(plan): clarify fleet migration gates --- PLAN.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/PLAN.md b/PLAN.md index 3b2d2edec..384ddccab 100644 --- a/PLAN.md +++ b/PLAN.md @@ -695,10 +695,12 @@ feature list is not an exhaustive audit. provider, profile and config-file completers appended from `fnox-extras.usage.kdl`, so its fleet PR also retains `usage g completion`. `App` now combines a borrowed `SpecView`, sparse sync/async completion - callbacks, runtime identity and command projection. It does not bundle an - executor. aube uses it for all of those cases, including `aubr`/`aubx` and - async registry search; fnox uses it for secret, provider and profile - candidates. Both now generate and answer completions through `usage-rs` + callbacks, completion runtime identity and command projection. It does not + bundle an executor or change the parser identity used by help and + diagnostics, so it does not satisfy the separate **Runtime program + identity** gate below. aube uses it for all of those cases, including + `aubr`/`aubx` and async registry search; fnox uses it for secret, provider + and profile candidates. Both now generate and answer completions through `usage-rs` without invoking the `usage` binary. - [ ] **Canonical, duplicate-free derived KDL.** hk's direct `Cli::to_kdl()` output was semantically accepted but differed substantially from the same @@ -706,13 +708,12 @@ feature list is not an exhaustive audit. `complete "path"` nodes that the round trip collapsed. Make direct emission canonical and deduplicate composed completers so adopters do not need the expensive round trip merely for stable generated artifacts. -- [ ] **Keep generated-spec producers and consumers on one dialect.** A derive - pinned to the 6.x stack can emit nodes such as `unknown_flags` that the - released 5.x `usage` binary in an adopter's docs task cannot read. The - communique experiment had to build a second git-pinned `usage-cli` just to - render the KDL emitted by its Rust dependency. Define a supported way to - install matching pre-release tooling (and make version diagnostics name the - required dialect) so a migration does not silently combine two revisions. +- [x] **Keep generated-spec producers and consumers on one dialect.** The 6.x + migration is a coordinated epoch, not a promise that a 5.1 CLI can consume + a 6.x-derived spec. Fleet docs tasks install `usage-cli` from the same git + stack as their `usage-rs` dependency, so nodes such as `unknown_flags` are + produced and consumed by one dialect. All release dependencies move to + 6.x together; cross-major spec consumption is intentionally unsupported. - [ ] **Runtime program identity.** aube embeds the same CLI under a caller-chosen binary name. A derived spec can be rewritten after emission, but parser help and diagnostics still use the static name. Support a runtime identity @@ -901,8 +902,8 @@ looking at the clap surface, not only at the spec. and opt strict CLIs into `unknown_flags="error"`; aube remains permissive at the root because its external-subcommand path is a package-manager forwarder. All five use the `usage-rs` facade for parsing and derives and pin the - experiment stack at `f9ea7a76`. hk, aube and fnox also use its built-in - compiled completion protocol, removing their runtime dependency on an + relevant 6.x experiment-stack revision. hk, aube and fnox also use its + built-in compiled completion protocol, removing their runtime dependency on an installed `usage` binary. aube's remaining direct `usage-validation` dependency is the facade-validation gap above. The workarounds they still contain are the unchecked launch-gate rows above, not unfinished conversions.