Skip to content

fix(codegen): per-category summary + hint when WIT requested but none emitted#242

Open
avrabe wants to merge 1 commit into
mainfrom
fix/v0.11.0-codegen-summary-hint
Open

fix(codegen): per-category summary + hint when WIT requested but none emitted#242
avrabe wants to merge 1 commit into
mainfrom
fix/v0.11.0-codegen-summary-hint

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 24, 2026

Summary

spar codegen previously printed a bare Generated N files in <dir>/,
which silently hid the most common confusing case: a model with
threads but no process subcomponents run under the default
--format both emits Rust + Cargo.toml + BUILD.bazel and zero
.wit files
(because WIT generation is per-process). Operators and
agents read the output as "the other files but no wit" with no clue
why.

This is a no-functional-change diagnostic improvement: replace the
summary with a per-category breakdown and add a focused hint when WIT
was requested but none came out.

Before

Generating code for Threads::Sys. (2 components)
Generated 3 files in /tmp/threads-out/

After

Generating code for Threads::Sys. (2 components)
codegen: wrote 3 files (1 .rs, 2 workspace) (format: both) to /tmp/threads-out/
hint: --format both emits one .wit interface per AADL `process` subcomponent;
      this model has 0 processes — add `process` declarations to the system
      implementation, or pass --format rust for thread skeletons only.

The hint fires only when WIT was requested (--format wit or the
default --format both) and zero .wit files came out.

Smoke matrix

Case Format Expectation Result
Threads-only model both (default) hint fires, (1 .rs, 2 workspace)
Process + --format wit wit (1 .wit), no hint
Threads + --format rust rust (1 .rs, 2 workspace), no hint (user didn't ask for WIT)

Files

  • crates/spar-cli/src/main.rscmd_codegen calls two new helpers:
    summarise_codegen_output and maybe_print_empty_wit_hint. Both
    are pure functions of &[GeneratedFile] + OutputFormat, suitable
    for golden-test promotion later if the stdout shape is contracted.
  • Artifacts: REQ-CODEGEN-SUMMARY + TEST-CODEGEN-SUMMARY-HINT.

Test plan

  • Three smoke cases above all match expectations
  • cargo clippy -p spar --all-targets — clean
  • cargo fmt --check — clean
  • rivet validate — 0 broken cross-refs; totals byte-identical to baseline

🤖 Generated with Claude Code

… emitted

`spar codegen` previously printed a bare `Generated N files in <dir>/`,
which silently hid the most common confusing case: a model with
threads but no `process` subcomponents run under the default
`--format both` emits Rust + Cargo.toml + BUILD.bazel and zero `.wit`
files (because WIT generation is per-process). Operators and agents
read the output as "the other files but no wit" with no clue why.

Replace the summary with a per-category breakdown and add a focused
hint when WIT was requested but none came out:

  codegen: wrote 3 files (1 .rs, 2 workspace) (format: both) to gen/
  hint: --format both emits one .wit interface per AADL `process`
        subcomponent; this model has 0 processes — add `process`
        declarations to the system implementation, or pass --format
        rust for thread skeletons only.

The format label answers "did spar honour my --format?"; the
per-category count answers "what got produced?"; the hint answers
"why didn't I get what I asked for?" The dry-run path gets the same
shape (without writing files). Three smoke cases cover the matrix:
threads + default => hint; process + --format wit => no hint; threads
+ --format rust => no hint (user did not request WIT).

Helpers are pure functions of `&[GeneratedFile]` + `OutputFormat`,
suitable for promotion to golden tests if the stdout shape is later
contracted.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@avrabe avrabe enabled auto-merge (squash) May 24, 2026 13:30
@github-actions
Copy link
Copy Markdown

Rivet verification gate

20/20 passed

count
Passed 20
Failed 0
Skipped (no steps) 0

Filter: (and (= type "feature") (or (has-tag "v093") (has-tag "v0100")))

Failed artifacts

(none)

Updated automatically by tools/post_verification_comment.py. Source of truth: artifacts/verification.yaml.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant