You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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.
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
Owner: Wright (wright-cli, wright-driver, wright-analyzer, docs). No owner-repository change required; these queries read the canonical program that workshop-rs already provides.
Problem
Wright's semantic query surface is reachable only through
wright serve. The CLI has no access to it.crates/wright-cli/src/main.rscontains zero references toSymbols,References,Usage,Cfg,CallGraph,CostEstimate,PersistentObjects, orTargetMetadata. All eight operations exist only onwright-agent/v1.What a human gets from
wright inspecton a two-rule project: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.mdprinciple 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
cakeis symbol id3and rule index0:The response side already speaks names:
{"op":"usage","symbol":0}returns{"symbol":"cakePos","reads":16,"writes":1,...}.symbolsreturns anamefor 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
querysubcommand: discovery throughwright --helpis the shared human/agent affordance, and a nesting level that both audiences must learn adds no information.wright symbols [INPUT] [--kind <KIND>]symbolswright refs <NAME> [INPUT]references+usagewright cfg <RULE> [INPUT]cfgwright callgraph [INPUT]callGraphwright cost [INPUT]costEstimaterefsabsorbsusage: the counts are the header of the reference list, not a separate command.persistentObjectsfolds into theanalyzereport rather than becoming a command. It is a narrow fact list, empty for most programs, and does not earn a top-level entry.--kind,--locale,--root,--format,--renderer,--color) and returns awright-result/v1envelope under--format json, like every other workflow command.references,usage, andcfgaccept a name on the agent contract as well. This is an additivewright-agent/v1change; numeric ids remain accepted.wright inspectstays 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.wright-agent/v1operation or its numeric addressing.reload/incremental-update operation. The measurements above remove its justification.wright-analyzeralready computes.Constraints
wright-agent/v1is a stable versioned contract. Additive optional fields and additive addressing are permitted; changing or removing an operation is not. Seedocs/agent-contract.mdversioning.wright-driver. Name resolution and query results belong in the driver/analyzer so the CLI and the agent contract return the same model, perdocs/cli/commands.md.docs/cli/presentation.mdapply unchanged: onewright-result/v1envelope on stdout in JSON mode, no ANSI or progress in plain/CI/JSON rendering.Acceptance criteria
wright symbols,wright refs,wright cfg,wright callgraph, andwright costexist, run against a file or a project directory, and default to the current directory like the existing commands.--format jsonreturns awright-result/v1envelope 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 byusage.wright cfg <RULE>resolves a rule by name. A test asserts that the rule namedcakeintests/fixtures/workshop/real-world/overpy-cake.wsis reachable by name, where the agent contract currently requires index0while the same rule's symbol id is3.references,usage, andcfgaccept 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.capabilitiescontinues to advertisewright-agent/v1and every previously advertised operation. The existing schema compatibility tests pass unchanged.wright analyzereports persistent Workshop object facts, andpersistentObjectskeeps returning the same data on the agent contract.wright inspecttext output names the specific command for each area it summarizes. Review check.docs/cli/commands.md,docs/agent-contract.md, anddocs/cli.mddescribe the new commands and the name addressing.Dependencies / ownership
wright-cli,wright-driver,wright-analyzer, docs). No owner-repository change required; these queries read the canonical program thatworkshop-rsalready provides.SemanticIndexbacks both), Establish a product-level coding-agent benchmark for Workshop workflows #414 (agent benchmark; this issue changes the surface the benchmark audits), Add a first-party agent guide installer #415 (agent guide; a self-sufficient CLI surface is what shrinks the guide).