Skip to content

vex product_undetected never names an unusable .csproj or .gemspec because the CLI keeps its own copy of the probe table #816

Description

[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: register comment.

Kind: bug (duplication). Source: review 6.4 / 6.5 ("the product-manifest probe table is copied three times and has drifted"); register E38.

Problem

Product auto-detection's probe list exists three times (main @ 045d7ec):

  1. Core, the real probe: vex/product.rs#L79-L86 has six fixed names, and #L105-L124 adds the single-root *.csproj and *.gemspec probes. It already collects every manifest it saw in present (#L87, #L129-L140), but only uses it for the multi-manifest warning and doesn't return it.
  2. CLI, for the error message: commands/vex.rs#L1106-L1124 re-stats PRODUCT_MANIFESTS, a hand copy of the six fixed names. It lacks the csproj and gemspec probes added later.
  3. The --product help text: commands/vex.rs#L52-L63, which is up to date today.

Proved by execution (a temporary vex_terminal_output test, run twice on main; a one-patch manifest plus one root file, vex --no-verify):

  • package.json = {"name":"app"} → Could not auto-detect a top-level product PURL in … (package.json was found but has no usable name and version).
  • Tool.csproj with <PackageId>$(Company).Tool</PackageId> (rejected by parse_csproj because of the $) → Could not auto-detect a top-level product PURL in …. It doesn't say which file was found and why it was unusable.

The same happens for a .gemspec whose spec.name is computed to something with a space or slash. Both exit 2 with product_undetected, so only the message is affected.

Symptoms

None filed. This is the drift the review predicted; the next probe added to core will repeat it.

Impact

Low: a less helpful error for .NET and Ruby projects. The structural cost is that every new probe has to be added in two places, and the CLI stats the cwd a second time.

Proposed change

  • Add pub present: Vec<String> (or a found_unusable list) to ProductDetection in vex/product.rs, filled by the existing loops.
  • resolve_product_id passes detect.present to format_product_undetected.
  • Delete PRODUCT_MANIFESTS and the second stat loop in commands/vex.rs.
  • Optional: a unit test that asserts the --product help text lists every probe name, so the third copy can't drift silently.

Size and scope

Two files, about −20/+10 production lines, plus tests. Out of scope: the probe parsers that don't reuse the format parsers (Cargo #693, go.mod #781, pom #715), and #642 (PDM 0.x names).

Acceptance criteria

  • PRODUCT_MANIFESTS is gone; the CLI builds its message from ProductDetection.
  • A new test in vex_terminal_output.rs: a lone Tool.csproj with <PackageId>$(Company).Tool</PackageId> → stderr contains (Tool.csproj was found but has no usable name and version). Add the same for a .gemspec whose computed name has a space.
  • product_undetected_names_the_unusable_manifest and the vex::product unit tests stay green.

Dependencies

None.


Backlog review — 2026-10-08

Closed as not planned following backlog review.

Product detection fails safely and --product remains available. This issue only asks the error to name an unusable .csproj/.gemspec; its own impact section calls this low severity.

Priority: P1 → P3. Cosmetic, maintenance-only, or subsumed scope; retain at P3 if not closed.

Activity

  1. added
    bugSomething isn't working
    arch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)
    on Oct 5, 2026
  2. added a commit that references this issue on Oct 5, 2026
  3. mikolalysenko commented on Oct 5, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Triaged: priority:p1. The issue touches .gemspec (RubyGems) as well as .csproj, and the highest applicable tier wins. Not a duplicate. Confirmed on main: commands/vex.rs:1117 still defines its own PRODUCT_MANIFESTS with only the six fixed names, and ProductDetection in core does not expose the manifests it found. No open PR addresses this.


    Generated by Claude Code

  4. mikolalysenko commented on Oct 8, 2026

    @mikolalysenko
    CollaboratorAuthor

    [agent] Re-checked on main @ e61a845 (architecture audit, ecosystems and formats): the finding still stands, and the code has moved.

    • The CLI still re-stats a hand copy of the six fixed names when it builds the product_undetected message: commands/vex.rs#L1397-L1416. The copy still lacks the *.csproj and *.gemspec probes.
    • The core probe still collects every manifest it sees in present without returning it: vex/product.rs#L87-L115.
    • The --product help text (vex.rs#L61-L62) is still up to date.

    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