Skip to content

--ecosystems rejects NPM and npm, pypi, which socket.yml patches.ecosystems accepts: the ecosystem name parser is written three times #773

Description

[agent] Filed by the scheduled architecture audit routine (CLI and core). Register: discussion #560 register.

Kind: bug. Source: new finding; register C44.

Problem

Verified on main @ 045d7ec. The same ecosystem scope filter accepts different spellings depending on where it is set:

  • Flag/env: --ecosystems / SOCKET_ECOSYSTEMS goes through parse_supported_ecosystem, which requires an exact, case-sensitive match on cli_name() with no trim (args.rs#L33-L44).
  • Config: socket.yml patches.ecosystems trims, lowercases and offers a "did you mean" hint (socket_yml.rs#L602-L631).`` The test every_key_parses pins `ecosystems: [NPM, pypi]` as valid.
  • Third copy: vendor::ecosystem_in_scope does its own exact cli_name() == eco lookup (vendor.rs#L343-L352).

The sibling filter shows the intended shape: --min-severity and socket.yml minSeverity share one parser (policy::parse_min_severity → socket_yml::parse_severity_name, which trims and ignores case), so --min-severity High and minSeverity: High agree.

Proof by execution (debug CLI built from 045d7ec, run twice):

$ socket-patch list --json --ecosystems NPM
error: invalid value 'NPM' for '--ecosystems <ECOSYSTEMS>': unsupported ecosystem `NPM` (supported: npm, pypi, …)   # exit 2
$ socket-patch list --json --ecosystems "npm, pypi"
error: invalid value ' pypi' for '--ecosystems <ECOSYSTEMS>': unsupported ecosystem ` pypi` …                      # exit 2
$ SOCKET_ECOSYSTEMS=PyPI socket-patch list --json                                                                     # exit 2
$ cargo test -p socket-patch-core --lib policy::socket_yml::tests::every_key_parses                                  # ok: [NPM, pypi] → ["npm","pypi"]

--min-severity High and --min-severity " high" both parse.

Symptoms

None filed. Impact: a user who copies ecosystems: [NPM, PyPI] from socket.yml into SOCKET_ECOSYSTEMS, or writes -e "npm, pypi", gets a usage error (exit 2) from the flag while the file form works. That is an inconsistent CLI surface with a small blast radius (p3).

Proposed change

  • Add Ecosystem::from_cli_name(&str) -> Option<Ecosystem> in crawlers/types.rs (trim + ASCII-lowercase) and one shared rejection message with the "did you mean" hint.
  • Use it in parse_supported_ecosystem (which stores the canonical cli_name()), in socket_yml ecosystems, and in vendor::ecosystem_in_scope.
  • Delete: the exact-match lookup in args.rs, the inline known/to_lowercase loop in socket_yml.rs and the lookup in vendor.rs.
  • Contract: accepting more spellings is additive, and the value_delimiter = ',' behavior pinned in CLI_CONTRACT stays. Add one sentence to the --ecosystems row ("case-insensitive; surrounding spaces ignored").

Size and scope

crawlers/types.rs, cli/src/args.rs, policy/socket_yml.rs, commands/vendor.rs and CLI_CONTRACT.md. About 60 production lines. Out of scope: other enum flags.

Acceptance criteria

  • --ecosystems NPM, -e "npm, pypi" and SOCKET_ECOSYSTEMS=PyPI parse to ["npm"], ["npm","pypi"] and ["pypi"] (args unit test).
  • --ecosystems bogus and the empty-token message stay as they are; socket.yml [npn] keeps its "did you mean npm" hint, and the flag gains the same hint.
  • every_key_parses, ecosystems_flag_splits_and_validates and the socket.yml error-path table (patches.ecosystems[0]) stay green.
  • grep -rn "cli_name() ==" crates/*/src has no production matches outside from_cli_name.

Dependencies

None. Touches commands/vendor.rs lightly; no conflict with the arch-refactor PRs.

Activity

added
bugSomething isn't working
arch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)
on Oct 4, 2026
added a commit that references this issue on Oct 4, 2026

mikolalysenko commented on Oct 4, 2026

@mikolalysenko
CollaboratorAuthor

[agent] Triage: priority p3 (general CLI). No duplicate and no open PR. Confirmed on main 045d7ec: parse_supported_ecosystem in args.rs and vendor::ecosystem_in_scope do an exact cli_name() match, while socket_yml trims and lowercases.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)bugSomething isn't workingpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions