Skip to content

fix(codegen): --format wit emits only WIT, not the Rust workspace#232

Merged
avrabe merged 1 commit into
mainfrom
fix/codegen-wit-strict-format
May 20, 2026
Merged

fix(codegen): --format wit emits only WIT, not the Rust workspace#232
avrabe merged 1 commit into
mainfrom
fix/codegen-wit-strict-format

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 20, 2026

Summary

Surfaced during the rules_wasm_component Bazel integration: spar codegen --format wit emits 7 files, not just WIT — it also writes the deployment config TOML + Cargo.toml + BUILD.bazel.

Root cause

spar-codegen/src/lib.rs::generate() gated the WIT and Rust file blocks on OutputFormat correctly, but two blocks ran unconditionally:

  • the config-file loop (deployment TOML per process)
  • the workspace_gen::generate_workspace call (Cargo.toml + BUILD.bazel)

So --format wit produced WIT files + config + workspace.

Fix

Gate both on Rust || Both:

  • Config TOML is deployment glue for the Rust components — not an interface definition.
  • A Cargo.toml/BUILD.bazel workspace is meaningless without Rust crates to build.

Strict-filter contract now holds:

--format output
wit only .wit interface files
rust Rust crates + Cargo.toml + BUILD.bazel + config
both everything

This gives rules_wasm_component a predictably-shaped tree artifact across spar versions.

Test plan

  • wit_format_emits_only_wit_files — asserts zero non-WIT leakage under OutputFormat::Wit
  • rust_format_still_emits_workspace — guards that gating didn't strip Cargo.toml/BUILD.bazel from rust/both
  • All 21 golden_test cases pass; cargo clippy -p spar-codegen --all-targets -D warnings clean
  • rivet validate PASS

Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com

`spar codegen --format wit` was emitting the deployment config TOML plus
the full Cargo.toml + BUILD.bazel workspace scaffolding alongside the
`.wit` files — 7 files instead of the expected interface-only set.

`generate()` correctly gated the WIT and Rust file blocks on
`OutputFormat`, but the config-file loop and the workspace_gen call ran
unconditionally. Gate both on `Rust || Both`:

- config TOML is deployment glue for the Rust components, not an
  interface definition
- a Cargo.toml / BUILD.bazel workspace is meaningless without Rust
  crates to build

Strict-filter contract now holds: `wit` → only `.wit`, `rust` → Rust
crates + workspace + config, `both` → everything. This gives the
rules_wasm_component Bazel ruleset a predictably-shaped tree artifact.

Tests: `wit_format_emits_only_wit_files` asserts zero non-WIT leakage;
`rust_format_still_emits_workspace` guards that gating did not strip
Cargo.toml / BUILD.bazel from the rust/both paths.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@avrabe avrabe enabled auto-merge (squash) May 20, 2026 18:47
@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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@avrabe avrabe merged commit 0afdc18 into main May 20, 2026
17 of 18 checks passed
@avrabe avrabe deleted the fix/codegen-wit-strict-format branch May 20, 2026 20:23
avrabe added a commit that referenced this pull request May 26, 2026
Workspace bump from 0.10.0 → 0.11.0 across all 22 spar crates (via
[workspace.package].version), plus the VS Code extension's
package.json — the two version surfaces the release workflow's
check-versions job compares against the tag.

What v0.11.0 ships, since v0.10.0:

  trace-topology reconciliation engine (incremental rollout):
    #239  IdentityUnknown check (PR 3a — component-borne MAC + chassis-id)
    #241  GptpOutOfBudget check  (PR 3b — single-budget case)

  trace-topology fixture pipeline:
    #233  Rust gen-fixtures tool (netns + TSN, RAII teardown)
    #234  NixOS guest + QEMU harness for fixture generation
    #238  corrected nixos/nix container digest (fd7a5c67…, multi-arch index)
    #240  podman runner label so workflows schedule on the only
          rootless-podman-capable runner in the fleet (runner9)

  codegen:
    #232  --format wit emits only WIT (strict-filter; no Rust/Bazel
          workspace leakage)
    #242  per-category file-count summary + hint when WIT was
          requested but the model has no `process` subcomponents
          (in-flight at bump time; auto-merge armed)

  release flow:
    #244  standardise on the synth reference — actions/attest-build-
          provenance@v2 + sigstore cosign sign-blob (v2.4.1) over
          SHA256SUMS.txt, build-env.txt; the v0.11.0 release is the
          first one to exercise the standardised cosign + SLSA chain.

Verification after release:
  cosign verify-blob \\
    --certificate-identity-regexp \\
      'https://github.com/pulseengine/spar/.github/workflows/release.yml@.*' \\
    --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \\
    --bundle SHA256SUMS.txt.cosign.bundle SHA256SUMS.txt
  gh attestation verify spar-v0.11.0-<triple>.tar.gz --repo pulseengine/spar

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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