Skip to content

Initial rust bridge and CFFI release workflows - #4033

Closed
2kai2kai2 wants to merge 16 commits into
canaryfrom
kai/rust-bridge
Closed

2kai2kai2 wants to merge 16 commits into
canaryfrom
kai/rust-bridge

Conversation

@2kai2kai2

@2kai2kai2 2kai2kai2 commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor
  • Initial rust bridge + sdk generator, working with non-generic simple types
  • Release workflows for CFFI dylibs, for use by several different bridges

Summary by CodeRabbit

  • New Features
    • Added Rust SDK generation (including classes, enums, unions, generics, optionals, streaming, and error/callback support).
    • Introduced Rust runtime bridge with shared-library loading/caching, checksum-verified downloads, and sync/async invocation.
    • Extended release packaging to include platform CFFI engine assets and CFFI manifest entries.
  • Tests
    • Expanded Rust SDK integration/verification coverage (live engine round-trips, streaming, cancellation, and error contracts).
  • Documentation
    • Updated Rust SDK and SDK test harness documentation, including bridge CFFI regeneration and usage notes.

@vercel

vercel Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment Jul 15, 2026 1:59am
promptfiddle Ready Ready Preview, Comment Jul 15, 2026 1:59am
promptfiddle2 Ready Ready Preview, Comment Jul 15, 2026 1:59am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a6b55970-8489-4135-aedb-cab44ebf6164

📥 Commits

Reviewing files that changed from the base of the PR and between 638cb73 and 988cfb0.

📒 Files selected for processing (7)
  • baml_language/.cargo/size-gate.toml
  • baml_language/.ci/size-gate/aarch64-apple-darwin.toml
  • baml_language/.ci/size-gate/x86_64-pc-windows-msvc.toml
  • baml_language/.ci/size-gate/x86_64-unknown-linux-gnu.toml
  • baml_language/crates/bridge_ctypes/build.rs
  • baml_language/sdk_tests/harness_setup/src/rust.rs
  • baml_language/sdks/rust/bridge_rust/src/wire/baml_bridge.cffi.v1.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • baml_language/crates/bridge_ctypes/build.rs
  • baml_language/sdk_tests/harness_setup/src/rust.rs
  • baml_language/sdks/rust/bridge_rust/src/wire/baml_bridge.cffi.v1.rs

📝 Walkthrough

Walkthrough

Rust SDK generation, bridge runtime support, CFFI artifact builds, release-plan versioning, consumer verification, and Rust SDK test coverage were added. Release workflows now build, package, verify, publish, and expose Rust-related artifacts through toolchain manifests.

Changes

Rust SDK and release pipeline

Layer / File(s) Summary
CFFI build and publishing
.github/workflows/build2-bridge-cffi.reusable.yaml, .github/workflows/release-baml-language.yml, scripts/baml-release-manifests
Builds target-specific CFFI libraries, generates checksums, publishes immutable assets, and includes them in release manifests.
Bridge runtime and wire protocol
baml_language/sdks/rust/bridge_rust/..., baml_language/crates/bridge_ctypes/build.rs
Adds the Rust bridge crate, vendored protobuf wire types, dynamic loader, callbacks, encoding/decoding, runtime invocation, and typed errors.
Rust SDK generator
baml_language/sdks/rust/sdkgen_rust/..., baml_language/crates/baml_cli/...
Adds Rust output selection, type translation, module routing, union synthesis, code emission, generated crate assembly, and CLI integration.
Rust SDK test harness
baml_language/sdk_tests/harness_setup/..., baml_language/sdk_tests/crates/rust/..., .github/workflows/cargo-tests.reusable.yaml
Adds fixture generation, test gating, setup prewarming, nextest configuration, and a Rust SDK test matrix.
Rust behavior coverage
baml_language/sdk_tests/crates/rust/**
Adds tests for conversions, generics, errors, cancellation, host callables, streaming, documentation, and broad type-shape round trips.
Release verification
.github/workflows/build2-rust-sdk.reusable.yaml, .github/workflows/verify-rust-sdk.reusable.yaml, baml_language/sdks/rust/verify/*
Packages the bridge crate and verifies generated consumer builds, version handshakes, offline loading, downloads, checksums, and exported symbols.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Poem

A rabbit hops through Rusty wires,
With CFFI sparks and build fires.
Crates align, tests gleam bright,
Checksums guard the moonlit night.
“Ship it!” whispers the hare with delight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main theme: introducing the initial Rust bridge and CFFI release workflows.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch kai/rust-bridge

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

Perf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to canary/main.

To run them on this PR, do any of the following, then push a commit (or re-run CI):

  • Add RUN_CODSPEED=1 to the PR description, or
  • Include run-perf or /perf in the PR title or any commit message.

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 15, 2026 00:59 Inactive
@vercel
vercel Bot temporarily deployed to Preview – beps July 15, 2026 01:01 Inactive
@github-actions

github-actions Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

Binary size checks passed

✅ 7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
✅ baml-cli Linux 🔒 22.8 MB 9.7 MB file 22.8 MB +0 B (+0.0%) OK
✅ packed-program Linux 🔒 15.8 MB 6.7 MB file 15.8 MB +8.2 KB (+0.1%) OK
✅ baml-cli macOS 🔒 17.5 MB 8.5 MB file 17.5 MB +0 B (+0.0%) OK
✅ packed-program macOS 🔒 12.2 MB 5.9 MB file 12.2 MB +32 B (+0.0%) OK
✅ baml-cli Windows 🔒 19.1 MB 8.7 MB file 19.1 MB +0 B (+0.0%) OK
✅ packed-program Windows 🔒 13.1 MB 6.0 MB file 13.1 MB +7.1 KB (+0.1%) OK
✅ bridge_wasm WASM 14.6 MB 🔒 4.1 MB gzip 4.1 MB +4.7 KB (+0.1%) OK

🔒 = the size this artifact is GATED on (ceiling + delta). Binaries gate on file size (installed binary); WASM gates on gzip (download size). The other size is shown for information only.


Generated by cargo size-gate · workflow run

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 15, 2026 01:08 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 15, 2026 01:21 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (11)
baml_language/sdks/rust/bridge_rust/src/error.rs (2)

65-98: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider delegating Error::source() for wrapped errors.

Error::Decode and Error::Sdk wrap DecodeError/SdkError, both of which implement std::error::Error, but the blanket impl<E: fmt::Debug> std::error::Error for Error<E> {} never overrides source(). Consumers walking the error chain (e.g. via anyhow/eyre reporting, or tracing) will lose visibility into the underlying cause.

♻️ Proposed fix
-impl<E: fmt::Debug> std::error::Error for Error<E> {}
+impl<E: fmt::Debug> std::error::Error for Error<E> {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        match self {
+            Error::Decode(e) => Some(e),
+            Error::Sdk(e) => Some(e),
+            _ => None,
+        }
+    }
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/bridge_rust/src/error.rs` around lines 65 - 98,
Update the std::error::Error implementation for Error<E> to override source()
for Error::Decode and Error::Sdk, returning the wrapped errors as their
underlying causes; return None for all other variants and preserve the existing
Display behavior.

65-172: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No unit tests for Display formatting.

Error<E> and DecodeError's Display impls have branching logic (optional class_name, multi-line trace rendering) but no #[cfg(test)] coverage in this file, unlike download.rs in the same PR which does test its formatting helpers.

As per coding guidelines, **/*.rs: "Prefer writing Rust unit tests over integration tests where possible."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/bridge_rust/src/error.rs` around lines 65 - 172, Add
#[cfg(test)] unit tests in this file covering the Display implementations for
Error and DecodeError, including the optional class_name branches, multi-line
trace output, and each DecodeError variant. Assert the exact formatted strings
while keeping the production formatting logic in Error::fmt, DecodeError::fmt,
and write_trace unchanged.

Source: Coding guidelines

baml_language/sdk_tests/crates/rust/function_calls/customizable/test_cancellation.rs (1)

65-78: 🩺 Stability & Availability | 🔵 Trivial | ⚖️ Poor tradeoff

Timing-based cancellation assertions could be flaky under CI load.

Several tests rely on a fixed 50ms sleep racing a 2000ms call; under heavy CI contention the timer could fire late enough to cause spurious failures/successes. This mirrors the ported Python design, so it's a pre-existing trade-off rather than a regression — flagging for awareness only.

Also applies to: 89-96, 141-152

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@baml_language/sdk_tests/crates/rust/function_calls/customizable/test_cancellation.rs`
around lines 65 - 78, Review the timing-based cancellation assertions in the
scoped test around throws_test::SleepMs_with_ctx, along with the corresponding
cases at the other referenced ranges, and replace the fixed sleep/race
synchronization with a deterministic cancellation signal or readiness handshake.
Preserve the existing expectation that the call is cancelled and the
_assert_fast_cancellation validation remains intact.
baml_language/crates/bridge_ctypes/build.rs (1)

38-48: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Clear the vendor directory before regenerating to avoid stale committed files.

If a .proto message/package is renamed or removed, prost_build won't delete the old generated file from bridge_rust/src/wire, leaving a stale file committed and shipped in the published SDK even though the CI proto-sync job may only check freshness of files that still get regenerated.

♻️ Proposed fix
     let rust_vendor_out = manifest_dir.join("../../sdks/rust/bridge_rust/src/wire");
+    if rust_vendor_out.is_dir() {
+        std::fs::remove_dir_all(&rust_vendor_out)?;
+    }
     std::fs::create_dir_all(&rust_vendor_out)?;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/crates/bridge_ctypes/build.rs` around lines 38 - 48, Clear the
existing rust_vendor_out directory before prost_build regenerates files, then
recreate it and proceed with the current vendor_config compilation flow. Update
the build logic around rust_vendor_out so removed or renamed proto outputs
cannot remain committed as stale files.
baml_language/crates/bex_engine/src/conversion.rs (1)

73-86: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Address the cycle-detection bug.

The newly added comment documents a critical bug where self-referencing values cause infinite recursion.
Do you want me to generate a fix that implements the suggested HeapPtr cycle detection to prevent the engine from hanging?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/crates/bex_engine/src/conversion.rs` around lines 73 - 86,
Implement cycle detection in the recursive conversion function in conversion.rs
by tracking visited HeapPtr identities during traversal. When a HeapPtr is
encountered again, stop recursion and return an EngineError so callers receive
the envelope’s error arm instead of hanging; preserve existing conversion
behavior for acyclic values.
baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_forward_refs.rs (1)

18-49: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Empty test bodies silently "pass" instead of signaling pending work.

test_round_trip_rec_list and test_round_trip_rec_list_with_other compile and run as no-op passing tests. Marking them #[ignore = "..."] (using the existing DIVERGENCE comment as the reason) would make CI test reports accurately reflect that these are pending, not verified.

♻️ Suggested fix
 #[test]
+#[ignore = "recursive union alias — no Rust representation yet"]
 fn test_round_trip_rec_list() {
     // DIVERGENCE(rust): ...
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_forward_refs.rs`
around lines 18 - 49, Mark test_round_trip_rec_list and
test_round_trip_rec_list_with_other with #[ignore = "..."], using their existing
DIVERGENCE explanation as the ignore reason so CI reports them as pending rather
than passing no-op tests.
baml_language/sdks/rust/bridge_rust/src/baml_value.rs (1)

259-322: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate map encode/decode logic between IndexMap and HashMap impls.

The to_baml/from_baml bodies for IndexMap<K,V> and HashMap<K,V> are identical apart from the container type. Extracting shared helpers would prevent the two paths from silently diverging on future fixes (e.g. error handling changes).

♻️ Suggested refactor
+fn map_to_baml<K: BamlMapKey, V: __BamlValuePrivate>(
+    entries: impl Iterator<Item = (K, V)>,
+) -> wire::InboundValue {
+    inbound(In::MapValue(wire::InboundMapValue {
+        entries: entries
+            .map(|(k, v)| wire::InboundMapEntry {
+                key: Some(k.to_baml_key()),
+                value: Some(v.to_baml()),
+            })
+            .collect(),
+    }))
+}
+
+fn map_from_baml<K: BamlMapKey, V: __BamlValuePrivate, C: FromIterator<(K, V)>>(
+    v: wire::BamlOutboundValue,
+) -> Result<C, DecodeError> {
+    let v = unwrap(v);
+    match v.value {
+        Some(Out::MapValue(map)) => map
+            .entries
+            .into_iter()
+            .map(|entry| {
+                Ok((
+                    K::from_baml_key(&entry.key)?,
+                    V::from_baml(entry.value.unwrap_or_default())?,
+                ))
+            })
+            .collect(),
+        _ => Err(wrong_type("map", &v)),
+    }
+}
+
 impl<K: BamlMapKey, V: __BamlValuePrivate> __BamlValuePrivate for indexmap::IndexMap<K, V> {
     fn to_baml(&self) -> wire::InboundValue {
-        inbound(In::MapValue(wire::InboundMapValue {
-            entries: self
-                .iter()
-                .map(|(k, v)| wire::InboundMapEntry {
-                    key: Some(k.to_baml_key()),
-                    value: Some(v.to_baml()),
-                })
-                .collect(),
-        }))
+        map_to_baml(self.iter().map(|(k, v)| (k.clone(), /* borrow-based variant needed */ v)))
     }
     ...

Note: since to_baml takes &self, the shared helper would need a borrowing variant (Iterator<Item = (&K, &V)>) rather than owned tuples as sketched above; adjust signatures accordingly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/bridge_rust/src/baml_value.rs` around lines 259 -
322, Extract shared map encode/decode helpers for the identical logic used by
the IndexMap and HashMap implementations of __BamlValuePrivate, with the encode
helper accepting borrowed (&K, &V) iterator items as required by to_baml. Update
both impls to delegate to these helpers while preserving their
container-specific collection behavior and existing error handling.
baml_language/sdks/rust/bridge_rust/src/decode.rs (1)

1-223: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add unit tests for the decode logic in this module.

decode_result, ClassFields, enum_variant, and the literal/error-message helpers implement non-trivial protocol-decoding rules (exit-panic short-circuit, MissingField vs WrongType distinction, float-literal parse fallback, FQN mismatch checks) but ship with no #[cfg(test)] coverage in this diff, unlike translate_ty.rs in the same PR which tests its logic inline. As per coding guidelines, "Prefer writing Rust unit tests over integration tests where possible" — this module is a good candidate since it can be exercised directly with constructed wire::BamlOutboundValue/wire::BamlOutboundResult values without needing the full bridge/engine.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/bridge_rust/src/decode.rs` around lines 1 - 223, Add
a #[cfg(test)] module to decode.rs with focused unit tests for decode_result,
ClassFields, enum_variant, unwrap/literal_to_plain, and render_message.
Construct wire values directly and cover successful decoding, malformed/empty
envelopes, FQN mismatches, MissingField versus WrongType, float literal parse
fallback, error-message extraction, and non-exit panic handling; avoid testing
the process-terminating exit path.

Source: Coding guidelines

.github/workflows/build2-bridge-cffi.reusable.yaml (1)

212-224: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Route step outputs through env: instead of inline template expansion (zizmor: template-injection).

steps.artifact.outputs.dir/asset are interpolated directly into the run: script. Even though today's values are derived from the workflow's own hardcoded matrix, this bypasses shell quoting and is exactly the pattern zizmor flags. The "Stamp release plan" step above already uses the safer env: pattern — mirror it here.

🔒 Proposed fix
       - name: Smoke test the built library
         if: matrix._.smoke
         working-directory: baml_language
+        env:
+          ARTIFACT_DIR: ${{ steps.artifact.outputs.dir }}
+          ARTIFACT_ASSET: ${{ steps.artifact.outputs.asset }}
         run: |
           set -euo pipefail
           expected="$(jq -r .canonical_version ../release-plan.json)"
           python3 ../scripts/smoke-bridge-cffi.py \
-            "${{ steps.artifact.outputs.dir }}/${{ steps.artifact.outputs.asset }}" \
+            "${ARTIFACT_DIR}/${ARTIFACT_ASSET}" \
             "$expected"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build2-bridge-cffi.reusable.yaml around lines 212 - 224,
Update the “Smoke test the built library” step to pass
steps.artifact.outputs.dir and steps.artifact.outputs.asset through the step’s
env block, then reference those environment variables in the Python command
instead of inline GitHub template expressions. Preserve the existing smoke-test
arguments and behavior.

Source: Linters/SAST tools

baml_language/sdks/rust/sdkgen_rust/src/analyze.rs (1)

350-438: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add unit tests for compute_sccs and compute_renames.

Both are intricate, hand-rolled algorithms (iterative Tarjan SCC; cascading module-path renames) with correctness-critical outcomes (wrong output would emit stack-overflowing or non-compiling generated code), yet neither has any #[cfg(test)] coverage in this file, unlike routing.rs/capi.rs/manifest.rs elsewhere in this PR. Worth covering at least: a multi-class cycle, a self-loop-only class, and a rename cascading through 2+ nested collision levels.

As per coding guidelines, "Prefer writing Rust unit tests over integration tests where possible."

Also applies to: 443-495

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/sdkgen_rust/src/analyze.rs` around lines 350 - 438,
Add #[cfg(test)] unit tests in analyze.rs covering compute_sccs with a
multi-node cycle, a self-loop-only node, and non-cyclic nodes, plus
compute_renames with a rename cascading through at least two nested collision
levels. Assert the exact SCC membership/equality behavior and final renamed
paths, using the existing types and helpers exposed by these functions.

Source: Coding guidelines

baml_language/sdks/rust/sdkgen_rust/src/unions.rs (1)

1-327: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add unit tests for the pure union-shape helpers.

shape_key, strip_null, shape_error, variant_name, and arm_is_representable are all pure and easily testable (name derivation, string-literal edge cases, discriminability rules, generic-arg rejection), but this file has no #[cfg(test)] module — coverage currently relies entirely on the sdk_tests integration crate. As per coding guidelines, **/*.rs: "Prefer writing Rust unit tests over integration tests where possible."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/sdkgen_rust/src/unions.rs` around lines 1 - 327, Add
a #[cfg(test)] module in unions.rs with focused unit tests for shape_key,
strip_null, shape_error, variant_name, and arm_is_representable. Cover name
derivation, valid and invalid string literals, string-versus-literal
discriminability, null stripping, generic-argument rejection, and representative
supported/unsupported arms, using the existing Ty, Analysis, and SymbolPool test
construction patterns.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build2-rust-sdk.reusable.yaml:
- Around line 65-81: Update the “Package and verify the crate” step to
consistently use the artifact directory produced by cargo package with
--target-dir target/package-build: change the stale-artifact cleanup, crate
glob, and checksum-related paths from target/package to
target/package-build/package. Preserve the existing packaging and checksum flow.

In `@baml_language/sdk_tests/crates/rust/llm_functions/customizable/test_main.rs`:
- Around line 196-251: The two tests mutate the process-wide OPENAI_API_KEY
concurrently, causing a race. Update
test_extract_resume_build_request_includes_openai_api_key and
test_streaming_extract_build_request_includes_openai_api_key to run serially or
protect their environment-variable mutations with a shared mutex, ensuring the
guard is shared by both tests.

In `@baml_language/sdk_tests/crates/rust/setup.sh`:
- Around line 35-36: Update the Cargo build command in setup.sh to target the
declared bridge_ctypes package instead of bridge_cffi, preserving the existing
workspace directory and pre-warm flow.

In `@baml_language/sdks/rust/bridge_rust/src/encode.rs`:
- Around line 26-44: Update encode::class() so parameterized class instances
preserve their concrete generic arguments in BamlTyClass.type_args instead of
always emitting an empty vector. Thread the type arguments through the helper
and its generated-class callers, or provide a generic-aware encoder, while
keeping non-parameterized classes valid.

In `@baml_language/sdks/rust/bridge_rust/src/loader/mod.rs`:
- Around line 99-112: Update set_shared_library_path to acquire the
EXPLICIT_PATH lock before checking engine_loaded() and retain that guard through
the path update, coordinating with LoaderEnv::from_process() so the first-load
snapshot cannot race this setter. Preserve the existing warning and ignored-path
behavior when the engine is already loaded.

In `@baml_language/sdks/rust/bridge_rust/src/runtime.rs`:
- Around line 69-93: Update invoke_sync so wait_blocking cannot block
indefinitely: add a bounded timeout or an explicit cancellation path for the
dispatched receiver, and return the appropriate Error when it expires. Preserve
the existing synchronous-from-async guard and decode behavior for completed
responses.

In `@baml_language/sdks/rust/sdkgen_rust/src/idents.rs`:
- Around line 16-21: Update ident to require the first character of name to be
alphabetic or an underscore, while retaining the existing allowed-character
check for the remaining characters. Ensure digit-leading names such as 3d_shape
trigger the existing generator-bug assertion before Ident conversion.

In `@baml_language/sdks/rust/sdkgen_rust/src/lib.rs`:
- Around line 351-365: Update the name sanitization in routing::route to reserve
the generated internal module names _inlinedbaml and _runtime, preventing user
namespaces from producing conflicting segments while preserving existing keyword
sanitization behavior.

In `@scripts/baml-language-version`:
- Around line 486-496: Update the “rust bridge Cargo.toml version” check in
check_release() to compare against expected.crates_io_version instead of
expected.canonical_version, matching the value written by stamp() to
RUST_BRIDGE_CARGO_TOML. Leave the canonical version check for
RUST_BRIDGE_VERSION_RS unchanged.

---

Nitpick comments:
In @.github/workflows/build2-bridge-cffi.reusable.yaml:
- Around line 212-224: Update the “Smoke test the built library” step to pass
steps.artifact.outputs.dir and steps.artifact.outputs.asset through the step’s
env block, then reference those environment variables in the Python command
instead of inline GitHub template expressions. Preserve the existing smoke-test
arguments and behavior.

In `@baml_language/crates/bex_engine/src/conversion.rs`:
- Around line 73-86: Implement cycle detection in the recursive conversion
function in conversion.rs by tracking visited HeapPtr identities during
traversal. When a HeapPtr is encountered again, stop recursion and return an
EngineError so callers receive the envelope’s error arm instead of hanging;
preserve existing conversion behavior for acyclic values.

In `@baml_language/crates/bridge_ctypes/build.rs`:
- Around line 38-48: Clear the existing rust_vendor_out directory before
prost_build regenerates files, then recreate it and proceed with the current
vendor_config compilation flow. Update the build logic around rust_vendor_out so
removed or renamed proto outputs cannot remain committed as stale files.

In
`@baml_language/sdk_tests/crates/rust/function_calls/customizable/test_cancellation.rs`:
- Around line 65-78: Review the timing-based cancellation assertions in the
scoped test around throws_test::SleepMs_with_ctx, along with the corresponding
cases at the other referenced ranges, and replace the fixed sleep/race
synchronization with a deterministic cancellation signal or readiness handshake.
Preserve the existing expectation that the call is cancelled and the
_assert_fast_cancellation validation remains intact.

In
`@baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_forward_refs.rs`:
- Around line 18-49: Mark test_round_trip_rec_list and
test_round_trip_rec_list_with_other with #[ignore = "..."], using their existing
DIVERGENCE explanation as the ignore reason so CI reports them as pending rather
than passing no-op tests.

In `@baml_language/sdks/rust/bridge_rust/src/baml_value.rs`:
- Around line 259-322: Extract shared map encode/decode helpers for the
identical logic used by the IndexMap and HashMap implementations of
__BamlValuePrivate, with the encode helper accepting borrowed (&K, &V) iterator
items as required by to_baml. Update both impls to delegate to these helpers
while preserving their container-specific collection behavior and existing error
handling.

In `@baml_language/sdks/rust/bridge_rust/src/decode.rs`:
- Around line 1-223: Add a #[cfg(test)] module to decode.rs with focused unit
tests for decode_result, ClassFields, enum_variant, unwrap/literal_to_plain, and
render_message. Construct wire values directly and cover successful decoding,
malformed/empty envelopes, FQN mismatches, MissingField versus WrongType, float
literal parse fallback, error-message extraction, and non-exit panic handling;
avoid testing the process-terminating exit path.

In `@baml_language/sdks/rust/bridge_rust/src/error.rs`:
- Around line 65-98: Update the std::error::Error implementation for Error<E> to
override source() for Error::Decode and Error::Sdk, returning the wrapped errors
as their underlying causes; return None for all other variants and preserve the
existing Display behavior.
- Around line 65-172: Add #[cfg(test)] unit tests in this file covering the
Display implementations for Error and DecodeError, including the optional
class_name branches, multi-line trace output, and each DecodeError variant.
Assert the exact formatted strings while keeping the production formatting logic
in Error::fmt, DecodeError::fmt, and write_trace unchanged.

In `@baml_language/sdks/rust/sdkgen_rust/src/analyze.rs`:
- Around line 350-438: Add #[cfg(test)] unit tests in analyze.rs covering
compute_sccs with a multi-node cycle, a self-loop-only node, and non-cyclic
nodes, plus compute_renames with a rename cascading through at least two nested
collision levels. Assert the exact SCC membership/equality behavior and final
renamed paths, using the existing types and helpers exposed by these functions.

In `@baml_language/sdks/rust/sdkgen_rust/src/unions.rs`:
- Around line 1-327: Add a #[cfg(test)] module in unions.rs with focused unit
tests for shape_key, strip_null, shape_error, variant_name, and
arm_is_representable. Cover name derivation, valid and invalid string literals,
string-versus-literal discriminability, null stripping, generic-argument
rejection, and representative supported/unsupported arms, using the existing Ty,
Analysis, and SymbolPool test construction patterns.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cc541a02-e587-43ae-8da6-ea99767610cb

📥 Commits

Reviewing files that changed from the base of the PR and between ab43021 and 638cb73.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (105)
  • .github/workflows/build2-bridge-cffi.reusable.yaml
  • .github/workflows/build2-rust-sdk.reusable.yaml
  • .github/workflows/cargo-tests.reusable.yaml
  • .github/workflows/ci.yaml
  • .github/workflows/release-baml-language.yml
  • .github/workflows/verify-rust-sdk.reusable.yaml
  • baml_language/.config/nextest.toml
  • baml_language/Cargo.toml
  • baml_language/crates/baml_cli/Cargo.toml
  • baml_language/crates/baml_cli/src/generate.rs
  • baml_language/crates/baml_codegen_types/src/generator_fields.rs
  • baml_language/crates/baml_project/src/client_codegen.rs
  • baml_language/crates/baml_release/src/manifest.rs
  • baml_language/crates/bex_engine/src/conversion.rs
  • baml_language/crates/bridge_ctypes/README.md
  • baml_language/crates/bridge_ctypes/build.rs
  • baml_language/sdk_tests/DEVELOPMENT.md
  • baml_language/sdk_tests/README.md
  • baml_language/sdk_tests/crates/rust/Cargo.toml
  • baml_language/sdk_tests/crates/rust/build.rs
  • baml_language/sdk_tests/crates/rust/docstrings_etc/customizable/test_main.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/optional_args_static.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_cancellation.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_errors.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_generic_calls.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_generic_inference.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_host_callables.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_main.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_methods_on_classes.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_optional_args.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_raises.rs
  • baml_language/sdk_tests/crates/rust/function_calls/customizable/test_stdlib_entrypoints.rs
  • baml_language/sdk_tests/crates/rust/llm_functions/customizable/replay_harness.rs
  • baml_language/sdk_tests/crates/rust/llm_functions/customizable/test_main.rs
  • baml_language/sdk_tests/crates/rust/llm_functions/customizable/test_streaming_e2e.rs
  • baml_language/sdk_tests/crates/rust/setup.ps1
  • baml_language/sdk_tests/crates/rust/setup.sh
  • baml_language/sdk_tests/crates/rust/src/lib.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_aliases.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_class_refs.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_enums.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_forward_refs.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_generics.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_handles.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_lists.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_literals.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_maps.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_media.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_optional.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_primitives.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_recursion.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_routing.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_streams.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_symbol_collisions.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_unions.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/roundtrip_tests/test_void.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/test_complex_models.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/test_generic.rs
  • baml_language/sdk_tests/crates/rust/type_shapes/customizable/test_main.rs
  • baml_language/sdk_tests/harness_runner/src/lib.rs
  • baml_language/sdk_tests/harness_setup/Cargo.toml
  • baml_language/sdk_tests/harness_setup/src/lib.rs
  • baml_language/sdk_tests/harness_setup/src/rust.rs
  • baml_language/sdks/rust/bridge_rust/Cargo.toml
  • baml_language/sdks/rust/bridge_rust/README.md
  • baml_language/sdks/rust/bridge_rust/build-engine.ps1
  • baml_language/sdks/rust/bridge_rust/build-engine.sh
  • baml_language/sdks/rust/bridge_rust/src/baml_value.rs
  • baml_language/sdks/rust/bridge_rust/src/capi.rs
  • baml_language/sdks/rust/bridge_rust/src/completion.rs
  • baml_language/sdks/rust/bridge_rust/src/decode.rs
  • baml_language/sdks/rust/bridge_rust/src/encode.rs
  • baml_language/sdks/rust/bridge_rust/src/error.rs
  • baml_language/sdks/rust/bridge_rust/src/lib.rs
  • baml_language/sdks/rust/bridge_rust/src/loader/download.rs
  • baml_language/sdks/rust/bridge_rust/src/loader/log.rs
  • baml_language/sdks/rust/bridge_rust/src/loader/mod.rs
  • baml_language/sdks/rust/bridge_rust/src/runtime.rs
  • baml_language/sdks/rust/bridge_rust/src/test_support.rs
  • baml_language/sdks/rust/bridge_rust/src/version.rs
  • baml_language/sdks/rust/bridge_rust/src/wire/baml_bridge.cffi.v1.rs
  • baml_language/sdks/rust/bridge_rust/src/wire/mod.rs
  • baml_language/sdks/rust/bridge_rust/tests/common/mod.rs
  • baml_language/sdks/rust/bridge_rust/tests/conversions.rs
  • baml_language/sdks/rust/bridge_rust/tests/live_engine.rs
  • baml_language/sdks/rust/sdkgen_rust/Cargo.toml
  • baml_language/sdks/rust/sdkgen_rust/src/analyze.rs
  • baml_language/sdks/rust/sdkgen_rust/src/emit/class.rs
  • baml_language/sdks/rust/sdkgen_rust/src/emit/enum_.rs
  • baml_language/sdks/rust/sdkgen_rust/src/emit/function.rs
  • baml_language/sdks/rust/sdkgen_rust/src/emit/mod.rs
  • baml_language/sdks/rust/sdkgen_rust/src/emit/type_alias.rs
  • baml_language/sdks/rust/sdkgen_rust/src/emit/union.rs
  • baml_language/sdks/rust/sdkgen_rust/src/idents.rs
  • baml_language/sdks/rust/sdkgen_rust/src/lib.rs
  • baml_language/sdks/rust/sdkgen_rust/src/routing.rs
  • baml_language/sdks/rust/sdkgen_rust/src/translate_ty.rs
  • baml_language/sdks/rust/sdkgen_rust/src/unions.rs
  • baml_language/sdks/rust/verify/baml.toml
  • baml_language/sdks/rust/verify/baml_src/main.baml
  • baml_language/sdks/rust/verify/consumer_main.rs
  • baml_language/stow.toml
  • scripts/baml-language-version
  • scripts/baml-release-manifests
  • scripts/smoke-bridge-cffi.py

Comment on lines +65 to +81
- name: Package and verify the crate
working-directory: baml_language
run: |
set -euo pipefail
# Guard the glob below against any stale artifact (a fresh CI
# checkout has none, but keep the step idempotent).
rm -f target/package/baml_bridge-*.crate target/package/baml_bridge-*.crate.sha256
# --allow-dirty: the working tree carries the just-stamped version.
# `cargo package` verifies by compiling the packaged crate in
# isolation — its deps are all crates.io deps, so this proves the
# published `.crate` builds standalone. --target-dir isolates that
# verify build; the `.crate` itself still lands in target/package/.
cargo package -p baml_bridge --allow-dirty --target-dir target/package-build
crate="$(ls target/package/baml_bridge-*.crate)"
(cd "$(dirname "$crate")" && sha256sum "$(basename "$crate")" > "$(basename "$crate").sha256")
echo "Packaged ${crate}"
cat "${crate}.sha256"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: check what Cargo version the setup-rust action pins, and see if
# there is any existing project convention for cargo package + --target-dir.
cat .github/actions/setup-rust/action.yml 2>/dev/null || fd -a action.yml .github/actions/setup-rust
rg -n "target-dir" baml_language/sdks/rust/bridge_rust -C2

Repository: BoundaryML/baml

Length of output: 3982


🌐 Web query:

Cargo package --target-dir .crate output location package subdirectory target-dir Cargo book

💡 Result:

When you run cargo package with the --target-dir option, it directs Cargo to use the specified directory for all generated artifacts, including the final.crate file [1][2]. By default, cargo package stores the generated.crate file in a subdirectory named target/package [3]. If you specify a custom directory using --target-dir

, Cargo will use /package as the destination for the distributable.crate file [1][3]. Key points regarding this behavior: 1. Consistency: The --target-dir flag is supported by cargo package and behaves similarly to how it works for cargo build [4][5]. It overrides the default workspace target directory (which is normally target in the root of the workspace) [1][6]. 2. Environment Variables and Config: You can achieve the same effect without using the command-line flag by setting the CARGO_TARGET_DIR environment variable or by configuring build.target-dir in your Cargo configuration [1][6][7]. 3. Workspace Behavior: In a Cargo workspace, the default behavior often places artifacts in the target directory at the root of the workspace [6][7]. However, users have historically noted that cargo package might sometimes create target directories relative to the member crate's location depending on the execution context, so explicitly setting --target-dir is a reliable way to ensure a specific, predictable output location [8]. In summary, providing --target-dir effectively tells Cargo to place the packaged output in /package [1][3].

Citations:


--target-dir needs to be reflected in the artifact path.
cargo package --target-dir target/package-build writes baml_bridge-*.crate under target/package-build/package/, but this step still deletes and reads target/package/.... Update the glob and checksum path to match the overridden target dir, or remove --target-dir if target/package/ is intended.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build2-rust-sdk.reusable.yaml around lines 65 - 81, Update
the “Package and verify the crate” step to consistently use the artifact
directory produced by cargo package with --target-dir target/package-build:
change the stale-artifact cleanup, crate glob, and checksum-related paths from
target/package to target/package-build/package. Preserve the existing packaging
and checksum flow.

Comment on lines +99 to +112
pub fn set_shared_library_path(path: impl Into<PathBuf>) {
let path = path.into();
if crate::capi::engine_loaded() {
log::warn(&format!(
"set_shared_library_path called after the BAML library was initialized; \
path ignored: {}",
path.display()
));
return;
}
*EXPLICIT_PATH
.lock()
.expect("explicit library path lock poisoned") = Some(path);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -a capi.rs baml_language/sdks/rust/bridge_rust
rg -n 'engine_loaded|fn api\(' baml_language/sdks/rust/bridge_rust/src/capi.rs

Repository: BoundaryML/baml

Length of output: 322


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cd /home/jailuser/git

echo '--- loader/mod.rs around set_shared_library_path ---'
sed -n '1,140p' baml_language/sdks/rust/bridge_rust/src/loader/mod.rs

echo
echo '--- capi.rs around engine_loaded ---'
sed -n '1,180p' baml_language/sdks/rust/bridge_rust/src/capi.rs

echo
echo '--- search for EXPLICIT_PATH and any synchronization with engine_loaded ---'
rg -n 'EXPLICIT_PATH|engine_loaded\(|Once|Mutex|RwLock|static mut|Atomic' baml_language/sdks/rust/bridge_rust/src

Repository: BoundaryML/baml

Length of output: 15524


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cd /home/jailuser/git

echo '--- loader/mod.rs around LoaderEnv::from_process and explicit_path capture ---'
sed -n '140,220p' baml_language/sdks/rust/bridge_rust/src/loader/mod.rs

echo
echo '--- all EXPLICIT_PATH uses with context ---'
rg -n -C 3 'EXPLICIT_PATH' baml_language/sdks/rust/bridge_rust/src/loader/mod.rs

Repository: BoundaryML/baml

Length of output: 3789


Serialize the explicit-path update with the first-load snapshot
set_shared_library_path can race with LoaderEnv::from_process(): a concurrent first load may clone None before this write, so the new path is silently ignored and the warning never fires. Lock EXPLICIT_PATH before the engine_loaded() check/write, or otherwise coordinate this setter with the load path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/bridge_rust/src/loader/mod.rs` around lines 99 - 112,
Update set_shared_library_path to acquire the EXPLICIT_PATH lock before checking
engine_loaded() and retain that guard through the path update, coordinating with
LoaderEnv::from_process() so the first-load snapshot cannot race this setter.
Preserve the existing warning and ignored-path behavior when the engine is
already loaded.

Comment on lines +16 to +21
pub(crate) fn ident(name: &str) -> Ident {
assert!(
!name.is_empty() && name.chars().all(|c| c.is_alphanumeric() || c == '_'),
"generator bug: `{name}` is not representable as a Rust identifier; \
symbols with such names must be filtered or mangled before emission"
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

set -euo pipefail

printf '== idents.rs outline ==\n'
ast-grep outline baml_language/sdks/rust/sdkgen_rust/src/idents.rs --view expanded || true

printf '\n== idents.rs (lines 1-220) ==\n'
cat -n baml_language/sdks/rust/sdkgen_rust/src/idents.rs | sed -n '1,220p'

Repository: BoundaryML/baml

Length of output: 4068


🏁 Script executed:

set -euo pipefail

printf '== rust files mentioning ident() ==\n'
rg -n "fn ident\\(|ident\\(" baml_language/sdks/rust/sdkgen_rust/src -g '*.rs' || true

printf '\n== tests in idents.rs around identifier cases ==\n'
cat -n baml_language/sdks/rust/sdkgen_rust/src/idents.rs | sed -n '1,260p'

Repository: BoundaryML/baml

Length of output: 6213


🏁 Script executed:

set -euo pipefail

printf '== find name/identifier definitions feeding ident() ==\n'
rg -n "struct .*Name|type .*Name|enum .*Name|pub struct .*Name|identifier|identifi|lexical|alphanumeric" baml_language/sdks/rust/sdkgen_rust/src baml_language -g '*.rs' || true

printf '\n== trace rust_name fields and name types ==\n'
rg -n "rust_name|name\\.name\\.as_str\\(|name: &str" baml_language/sdks/rust/sdkgen_rust/src -g '*.rs' || true

Repository: BoundaryML/baml

Length of output: 50371


🏁 Script executed:

set -euo pipefail

printf '== file list in rust sdkgen source ==\n'
git ls-files baml_language/sdks/rust/sdkgen_rust/src | sed -n '1,200p'

printf '\n== likely parser/name files ==\n'
fd -a -t f . baml_language/sdks/rust/sdkgen_rust/src baml_language | sed -n '1,200p'

Repository: BoundaryML/baml

Length of output: 15378


Identifier check should reject digit-leading names. name.chars().all(|c| c.is_alphanumeric() || c == '_') still accepts 3d_shape, which is not a valid Rust identifier. Add a first-character check (is_alphabetic or _) so this fails with the intended generator-bug message instead of falling through to proc_macro2/syn.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/sdkgen_rust/src/idents.rs` around lines 16 - 21,
Update ident to require the first character of name to be alphabetic or an
underscore, while retaining the existing allowed-character check for the
remaining characters. Ensure digit-leading names such as 3d_shape trigger the
existing generator-bug assertion before Ident conversion.

Comment on lines +351 to +365
let (file_path, tokens) = if path.is_empty() {
(
PathBuf::from("src/lib.rs"),
quote! {
#![allow(non_camel_case_types, non_snake_case)]

mod _inlinedbaml;
mod _runtime;

pub use _runtime::init;

#(#mod_decls)*
#(#item_tokens)*
},
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n '"_inlinedbaml"|"_runtime"' baml_language/sdks/rust/sdkgen_rust/src/analyze.rs baml_language/sdks/rust/sdkgen_rust/src/routing.rs

Repository: BoundaryML/baml

Length of output: 153


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant files first.
ast-grep outline baml_language/sdks/rust/sdkgen_rust/src/analyze.rs --view expanded || true
ast-grep outline baml_language/sdks/rust/sdkgen_rust/src/routing.rs --view expanded || true

echo
echo "=== Search for module-name reservation / sanitization logic ==="
rg -n "reserve|reserved|sanitize|module|segment|namespace|path" \
  baml_language/sdks/rust/sdkgen_rust/src/analyze.rs \
  baml_language/sdks/rust/sdkgen_rust/src/routing.rs

Repository: BoundaryML/baml

Length of output: 6538


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== idents helpers ==="
ast-grep outline baml_language/sdks/rust/sdkgen_rust/src/idents.rs --view expanded || true

echo
echo "=== relevant dir_segment / sanitization code ==="
rg -n "fn dir_segment|dir_segment\\(|reserved|keyword|underscore|sanitize" \
  baml_language/sdks/rust/sdkgen_rust/src/idents.rs \
  baml_language/sdks/rust/sdkgen_rust/src/analyze.rs \
  baml_language/sdks/rust/sdkgen_rust/src/routing.rs

echo
echo "=== inspect routing/analyze around the key logic ==="
sed -n '1,120p' baml_language/sdks/rust/sdkgen_rust/src/routing.rs
echo "---"
sed -n '430,520p' baml_language/sdks/rust/sdkgen_rust/src/analyze.rs

Repository: BoundaryML/baml

Length of output: 6919


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,120p' baml_language/sdks/rust/sdkgen_rust/src/idents.rs

Repository: BoundaryML/baml

Length of output: 3082


Reserve the internal module names
src/lib.rs always emits mod _inlinedbaml; and mod _runtime;, but routing::route only sanitizes a few keywords, so a user namespace like _runtime can still produce the same segment and make the generated crate fail to compile with a duplicate module declaration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@baml_language/sdks/rust/sdkgen_rust/src/lib.rs` around lines 351 - 365,
Update the name sanitization in routing::route to reserve the generated internal
module names _inlinedbaml and _runtime, preventing user namespaces from
producing conflicting segments while preserving existing keyword sanitization
behavior.

Comment on lines +486 to +496
# Load-bearing beyond drift hygiene: the Rust bridge's loader
# handshakes the loaded engine's version() against this constant,
# in development builds too.
"rust bridge CANONICAL_VERSION": (
f'pub(crate) const CANONICAL_VERSION: &str = "{expected.canonical_version}";'
in RUST_BRIDGE_VERSION_RS.read_text(encoding="utf-8")
),
"rust bridge Cargo.toml version": (
f'version = "{expected.canonical_version}"'
in RUST_BRIDGE_CARGO_TOML.read_text(encoding="utf-8")
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Check the bridge Cargo.toml version against crates_io_version, not canonical_version.

stamp() writes RUST_BRIDGE_CARGO_TOML's version from plan.crates_io_version (line ~415), but check_release() verifies it against expected.canonical_version. These happen to be equal today (identity translation), but the check is validating the wrong property conceptually — if crates.io's encoding ever needs to diverge from canonical (as PyPI's already does), this check would keep comparing against the un-encoded value and could mask a real drift.

🛡️ Proposed fix
         "rust bridge Cargo.toml version": (
-            f'version = "{expected.canonical_version}"'
+            f'version = "{expected.crates_io_version}"'
             in RUST_BRIDGE_CARGO_TOML.read_text(encoding="utf-8")
         ),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Load-bearing beyond drift hygiene: the Rust bridge's loader
# handshakes the loaded engine's version() against this constant,
# in development builds too.
"rust bridge CANONICAL_VERSION": (
f'pub(crate) const CANONICAL_VERSION: &str = "{expected.canonical_version}";'
in RUST_BRIDGE_VERSION_RS.read_text(encoding="utf-8")
),
"rust bridge Cargo.toml version": (
f'version = "{expected.canonical_version}"'
in RUST_BRIDGE_CARGO_TOML.read_text(encoding="utf-8")
),
# Load-bearing beyond drift hygiene: the Rust bridge's loader
# handshakes the loaded engine's version() against this constant,
# in development builds too.
"rust bridge CANONICAL_VERSION": (
f'pub(crate) const CANONICAL_VERSION: &str = "{expected.canonical_version}";'
in RUST_BRIDGE_VERSION_RS.read_text(encoding="utf-8")
),
"rust bridge Cargo.toml version": (
f'version = "{expected.crates_io_version}"'
in RUST_BRIDGE_CARGO_TOML.read_text(encoding="utf-8")
),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/baml-language-version` around lines 486 - 496, Update the “rust
bridge Cargo.toml version” check in check_release() to compare against
expected.crates_io_version instead of expected.canonical_version, matching the
value written by stamp() to RUST_BRIDGE_CARGO_TOML. Leave the canonical version
check for RUST_BRIDGE_VERSION_RS unchanged.

- Doc comments
- size gate
- generated files formatting
@vercel
vercel Bot temporarily deployed to Preview – beps July 15, 2026 01:40 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 15, 2026 01:47 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 15, 2026 01:59 Inactive
@2kai2kai2 2kai2kai2 closed this Jul 15, 2026

This branch was previously deployed

3 inactive deployments
Preview – promptfiddle — 988cfb00 Deployed Jul 15, 2026 by vercel[bot]
Preview – promptfiddle2 — 988cfb00 Deployed Jul 15, 2026 by vercel[bot]
Preview – beps — 988cfb00 Deployed Jul 15, 2026 by vercel[bot]
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