Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions specs/GH374/product.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Product specification: option alias pairing convention

## Summary

Define one contributor convention for representing equivalent option spellings in hand-written command specs. Equivalent short, long, and alternate long spellings belong in one `name` array; genuinely different options remain separate entries. Document the convention in the repository's contributor-facing documentation without requiring a corpus-wide migration.

## Problem

The schema accepts an option `name` as either one string or an array of strings, but the repository does not explain when contributors should use each form. Both patterns are common in `command-signatures/json/`: 14,269 option entries use an array and 38,457 use a string. As a result, contributors and reviewers must infer whether a newly added long form should be grouped with an existing short form.

The same ambiguity affects `exclusiveOn`. Existing specs variously reference one alias or every alias of a conflicting option. Although `exclusiveOn` is not enforced by the runtime today, inconsistent references make specs harder to review and would make future enforcement ambiguous.

## Desired behavior

### Representing option aliases

An option entry represents one semantic option. Its `name` field follows these rules:

1. Use a string when the target command and platform expose only one documented spelling.
2. Use one array for every documented spelling that is fully equivalent: the spellings have the same meaning, argument shape, repeatability, and other option metadata. Put short aliases first, followed by long aliases in the command's documented order.
3. Include multiple long synonyms in that same array when they are equivalent. For example, `["-q", "--quiet", "--silent"]` is one option.
4. Use separate option entries when spellings differ in semantics, accepted arguments, applicability, or metadata. Similar descriptions or names alone do not make options aliases.
5. Do not invent aliases. In particular, a BSD/macOS-oriented spec may legitimately retain a short-only string when the targeted command does not provide a GNU long form. A long form should be paired only after its support and intended platform coverage have been verified.

Equivalent aliases must not be duplicated as separate entries merely to give each spelling its own `name` string.

### Referencing aliases from `exclusiveOn`

`exclusiveOn` contains literal option spellings, not logical option identifiers. Each entry must therefore list every alias a user could type for each conflicting semantic option.

For two mutually exclusive paired options, the convention is:

```json
[
{
"name": ["-L", "--files-without-match"],
"exclusiveOn": ["-l", "--files-with-matches"]
},
{
"name": ["-l", "--files-with-matches"],
"exclusiveOn": ["-L", "--files-without-match"]
}
]
```

When adding a verified long form to an existing short-only option:

1. Replace the option's scalar `name` with an array containing the existing short form and the new long form.
2. Search the same command or subcommand for every `exclusiveOn` that references the existing short form and add the new long form beside it.
3. Review the changed option's own `exclusiveOn` list and ensure it includes every alias of each conflicting option.
4. Keep mutual relationships symmetric when the command describes the options as mutually exclusive.

These updates are local to the option and its relationships. Contributors are not required to normalize unrelated options or files.

### Documentation location

The canonical convention will live in `README.md`, under the existing "JSON Command Signatures" section. This is the public, human-facing entry point that already explains where hand-written specs live, whereas `AGENTS.md` is architecture-oriented and `.agents/skills/add-command-spec/SKILL.md` is an execution workflow consumed primarily by agents.

The implementation should add a short pointer from the option-authoring portion of `.agents/skills/add-command-spec/SKILL.md` to the canonical README section. This keeps agents on the same workflow without duplicating the rule. No new contributor file is warranted for one focused convention, and `AGENTS.md` should continue to point agents to the repository skills rather than duplicate authoring details.

## User-visible impact

This is contributor documentation. It makes new and edited specs more predictable to author and review, but it does not change completion rendering, parsing, or runtime option exclusivity.

## Acceptance criteria

- `README.md` states when to use a scalar `name`, when to use one alias array, and when similar spellings require separate entries.
- The documentation covers equivalent short/long aliases and multiple long synonyms, with concrete JSON examples.
- The documentation states that `exclusiveOn` must contain every literal alias of each conflicting option.
- The documentation gives the required update sequence for adding a long form to a short-only option, including affected peer `exclusiveOn` lists.
- The documentation explicitly says not to invent GNU long forms for BSD/macOS-oriented specs or other command variants that do not support them.
- Migration of existing specs is explicitly opportunistic; landing the convention does not require a corpus-wide rewrite.
- `.agents/skills/add-command-spec/SKILL.md` points to the canonical README convention without maintaining a second copy.
- The documentation notes that `exclusiveOn` is currently parsed but not enforced and does not promise runtime behavior.
- The implementation changes contributor documentation only; it does not modify command JSON, Rust source, generators, or generated specs.

## Out of scope

- Rewriting existing specs to conform to the convention.
- Adding missing aliases to any command, including the `du` change discussed in #372.
- Changing the JSON schema or runtime `Opt` representation.
- Implementing, validating, or otherwise changing runtime handling of `exclusiveOn`.
- Adding automated lint or formatting enforcement for the convention.

## Open questions

1. Should the runtime eventually carry `exclusiveOn` into `Opt` and enforce it? Recommendation: track this as a separate behavior change because it needs runtime semantics, compatibility analysis, and tests.
2. Should a future presubmit check enforce alias grouping and complete `exclusiveOn` references? Recommendation: first apply the written convention opportunistically and evaluate false positives across platform-specific and imported specs before adding automation.
57 changes: 57 additions & 0 deletions specs/GH374/tech.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Technical specification: option alias pairing convention

## Current implementation

`CommandOption.name` accepts one string or many and deserializes both forms into `Vec<String>` in `completion-metadata/src/fig_types.rs:167`. `CommandOption.exclusive_on` is independently deserialized as `Vec<String>` in `completion-metadata/src/fig_types.rs:190`.

When a `CommandOption` becomes a runtime `Opt`, every value in `name` is copied to `Opt.exact_string`, but `exclusive_on` is not copied (`completion-metadata/src/fig_types.rs:485`). Runtime short- and long-hand collections then classify each value in `Opt.exact_string` with `is_short_hand_flag` and `is_long_hand_flag` (`completion-metadata/src/signature.rs:94` and `completion-metadata/src/signature.rs:101`).

The repository demonstrates both intended alias grouping and the undocumented inconsistency:

- `command-signatures/json/head.json:10` groups equivalent short and long spellings; `command-signatures/json/head.json:30` includes the multi-long `-q`/`--quiet`/`--silent` option.
- `command-signatures/json/grep.json:101` references both aliases of a paired conflicting option in `exclusiveOn`.
- `command-signatures/json/du.json:89` defines `-d` as a short-only option and peer relationships refer only to `-d`.
- `command-signatures/json/df.json:12` combines aliases in one option while its exclusivity relationships use literal individual spellings.
- `README.md`, `AGENTS.md`, and `.agents/skills/add-command-spec/SKILL.md` do not currently define an alias-pairing convention.

No runtime code reads `exclusive_on` after deserialization. The only Rust construction outside the type itself initializes it as empty in `command-signatures/src/powershell_autogenerator/to_fig_types.rs:141`.

## Documentation changes

Implementation is limited to two documentation edits:

1. Add an "Option aliases and exclusivity" subsection to `README.md` beneath "JSON Command Signatures". It will be the canonical source and include:
- the scalar-versus-array decision rules;
- short/long and multi-long examples;
- the criteria for separate entries;
- the complete-alias rule for `exclusiveOn`;
- the steps for adding a long form to a short-only option;
- the platform-support caveat and opportunistic-migration policy;
- a note that `exclusiveOn` is currently unenforced.
2. Add a concise link in Step 2 of `.agents/skills/add-command-spec/SKILL.md` directing option authors to the README subsection before creating or editing options.

`AGENTS.md` remains unchanged because it already directs agents editing command signatures to repository skills. A new contributor document would add another discovery path and split a convention that fits the README's existing hand-written-spec overview.

## Data and API impact

There are no schema, serialization, API, or runtime data changes. The documented array form is already accepted, and the convention does not alter how `Opt.exact_string` is populated or how flags are classified.

## Edge cases

- **Multiple aliases of one kind:** Multiple short aliases or multiple long aliases can share an array when all option behavior and metadata are identical.
- **Similar but non-equivalent options:** Keep them separate if any argument, semantic, availability, or metadata distinction exists.
- **Platform-specific commands:** Document only aliases verified for the spec's intended command variant. The convention does not make GNU aliases mandatory for BSD/macOS targets.
- **Mixed-platform specs:** If an alias is not valid across the spec's intended coverage, contributors must first make an explicit scope decision rather than infer an alias from another implementation.
- **Existing inconsistency:** Do not touch unrelated entries. Normalize an existing entry only when it is already being changed and the command's behavior is verified.
- **Mutual exclusion:** List all aliases on both sides when exclusivity is bidirectional; do not infer symmetry when the command's behavior is directional.
- **Currently unenforced metadata:** Treat complete `exclusiveOn` lists as authored metadata and future-compatible documentation, not as evidence that Warp currently suppresses or rejects conflicting options.

## Validation strategy

Because implementation is documentation-only:

1. Review every JSON example for valid syntax and consistency with the stated rules.
2. Confirm README anchors and the skill's relative link resolve in the repository.
3. Run `git diff --check` to catch whitespace errors.
4. Confirm the implementation diff contains only `README.md` and `.agents/skills/add-command-spec/SKILL.md`.
5. No Rust build, command-spec formatting, generator verification, or UI test is required unless implementation expands beyond the approved documentation scope.
Loading