Skip to content

Expose the semantic query surface through the CLI so humans and agents share one tooling surface #429

Description

@e54-bot

Problem

Wright's semantic query surface is reachable only through wright serve. The CLI has no access to it.

crates/wright-cli/src/main.rs contains zero references to Symbols, References, Usage, Cfg, CallGraph, CostEstimate, PersistentObjects, or TargetMetadata. All eight operations exist only on wright-agent/v1.

What a human gets from wright inspect on a two-rule project:

PASS inspect
  2 rule(s), 5 symbol(s)

Program structure
  rule 0: "cake"
  globalVariable 0: cakePos
  ...

What an agent gets on the same project: the full reference list with spans, the CFG, the call graph, exact generated-resource counts, and usage totals.

Humans receive a summary of what agents can query. This contradicts goal.md principle 4 — "Human developers and coding agents share the same core tooling" — and principle 10, since the project now maintains two tiers of surface for one capability.

Numeric addressing is a second defect

The query operations are addressed by integers from two different numbering spaces, and the same rule has two identities. On the fixture above, rule cake is symbol id 3 and rule index 0:

{"op":"references","symbol":3}  -> the cake rule declaration
{"op":"cfg","rule":0}           -> the cake rule CFG
{"op":"cfg","rule":3}           -> {"error":{"code":"invalid-id","message":"unknown rule 3"}}

The response side already speaks names: {"op":"usage","symbol":0} returns {"symbol":"cakePos","reads":16,"writes":1,...}. symbols returns a name for every entry. Only the request side demands integers.

This is why the query surface could not have been a one-shot command: the integers are valid only inside one loaded program, so every query needs the session that produced them. Name addressing removes that coupling.

Session state has no performance justification. Measured with wright 0.2.41: full load-and-check of tests/fixtures/workshop/real-world/overpy-pixelart.ws (195 KB) takes 0.39s, and a 300-rule synthetic project 0.22s — negligible against an agent turn or a human keystroke.

Scope

Resolve project-semantic queries by name and expose them as flat top-level CLI commands. Flat rather than nested under a query subcommand: discovery through wright --help is the shared human/agent affordance, and a nesting level that both audiences must learn adds no information.

New CLI command Existing agent operation
wright symbols [INPUT] [--kind <KIND>] symbols
wright refs <NAME> [INPUT] references + usage
wright cfg <RULE> [INPUT] cfg
wright callgraph [INPUT] callGraph
wright cost [INPUT] costEstimate
  • refs absorbs usage: the counts are the header of the reference list, not a separate command.
  • persistentObjects folds into the analyze report rather than becoming a command. It is a narrow fact list, empty for most programs, and does not earn a top-level entry.
  • Every new command accepts the existing common options (--kind, --locale, --root, --format, --renderer, --color) and returns a wright-result/v1 envelope under --format json, like every other workflow command.
  • references, usage, and cfg accept a name on the agent contract as well. This is an additive wright-agent/v1 change; numeric ids remain accepted.
  • Name resolution that is ambiguous or unmatched is a structured diagnostic, not a guess and not an empty result.
  • wright inspect stays the overview entry point and names the specific command for each detail area it summarizes, so the shared surface performs its own discovery.

Non-goals

  • targetMetadata. It is catalog-scope and project-independent (a 15 KB dump with no relation to the loaded project), so it belongs to a separate catalog surface. Follow-up issue.
  • Removing or deprecating any wright-agent/v1 operation or its numeric addressing.
  • A session reload/incremental-update operation. The measurements above remove its justification.
  • An MCP transport. Revisit only if Establish a product-level coding-agent benchmark for Workshop workflows #414 shows agent failures that are genuinely discovery failures unfixable through help and error text.
  • New semantic analysis. These commands expose what wright-analyzer already computes.

Constraints

  • wright-agent/v1 is a stable versioned contract. Additive optional fields and additive addressing are permitted; changing or removing an operation is not. See docs/agent-contract.md versioning.
  • The CLI stays a presentation layer over wright-driver. Name resolution and query results belong in the driver/analyzer so the CLI and the agent contract return the same model, per docs/cli/commands.md.
  • Output rules in docs/cli/presentation.md apply unchanged: one wright-result/v1 envelope on stdout in JSON mode, no ANSI or progress in plain/CI/JSON rendering.
  • No canonical Workshop data or semantics duplicated in Wright.

Acceptance criteria

  • wright symbols, wright refs, wright cfg, wright callgraph, and wright cost exist, run against a file or a project directory, and default to the current directory like the existing commands.
  • For each of the five commands, --format json returns a wright-result/v1 envelope whose result payload matches the corresponding agent operation's result for the same input. A test compares the two paths on one fixture per command.
  • wright refs <NAME> resolves a symbol by name with no integer id anywhere in the invocation, and its output includes the usage counts previously returned by usage.
  • wright cfg <RULE> resolves a rule by name. A test asserts that the rule named cake in tests/fixtures/workshop/real-world/overpy-cake.ws is reachable by name, where the agent contract currently requires index 0 while the same rule's symbol id is 3.
  • references, usage, and cfg accept a name on the agent contract. Existing numeric-id requests keep their current results; a test asserts both addressings return the same payload for the same target.
  • An unmatched name and an ambiguous name each produce a structured diagnostic with a stable code and a non-zero exit, not an empty success. Tests cover both.
  • capabilities continues to advertise wright-agent/v1 and every previously advertised operation. The existing schema compatibility tests pass unchanged.
  • wright analyze reports persistent Workshop object facts, and persistentObjects keeps returning the same data on the agent contract.
  • wright inspect text output names the specific command for each area it summarizes. Review check.
  • docs/cli/commands.md, docs/agent-contract.md, and docs/cli.md describe the new commands and the name addressing.
  • Ablation: removing name resolution from the driver and leaving it in the CLI makes the CLI/agent payload-equality tests fail.

Dependencies / ownership

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions