diff --git a/docs/bindings/python-codegen.md b/docs/bindings/python-codegen.md
index 8c7561fda..0edbb9226 100644
--- a/docs/bindings/python-codegen.md
+++ b/docs/bindings/python-codegen.md
@@ -293,7 +293,7 @@ flowchart TD
accTitle: Python bindings build process from cargo build to compiled output
accDescr: Running cargo build triggers build.rs which discovers ROS packages, parses msg files, resolves dependencies, then generates both Python type files and a Rust PyO3 module compiled into hiroz-msgs.
A["cargo build hiroz-msgs
--features python_registry"] --> B["build.rs executes"]
- B --> C["Discover ROS packages
(AMENT_PREFIX_PATH or bundled)"]
+ B --> C["Discover ROS packages
(bundled assets/<distro> only)"]
C --> D["Parse .msg/.srv files"]
D --> E["Resolve dependencies
(type hashes, nested types)"]
E --> F["Generate Python files"]
diff --git a/docs/getting-started/building.md b/docs/getting-started/building.md
index e32cd62df..5b7d62f11 100644
--- a/docs/getting-started/building.md
+++ b/docs/getting-started/building.md
@@ -149,15 +149,7 @@ cargo build --all
### Message Package Resolution
-The build system automatically locates ROS message definitions:
-
-**Search order:**
-
-1. System ROS installation (`AMENT_PREFIX_PATH`, `CMAKE_PREFIX_PATH`)
-2. Common ROS paths (`/opt/ros/{rolling,jazzy,kilted,lyrical,humble}`)
-3. Bundled assets (built-in message definitions in hiroz-codegen)
-
-This fallback mechanism enables builds without ROS 2 installed.
+`hiroz-msgs` generates message types entirely from the bundled asset trees in `hiroz-codegen` (`crates/hiroz-codegen/assets//`) — it never probes a system ROS 2 installation (`AMENT_PREFIX_PATH`, `CMAKE_PREFIX_PATH`, `/opt/ros/*`). The target distro (`humble`, `jazzy`, or `lyrical`) is selected by Cargo feature; a package requested by an enabled feature but missing from that distro's asset tree is a build error, not a silent fallback. This is why `hiroz-msgs` builds without ROS 2 installed.
### Common Development Commands
diff --git a/docs/reference/troubleshooting.md b/docs/reference/troubleshooting.md
index bd265ab84..304c8fec6 100644
--- a/docs/reference/troubleshooting.md
+++ b/docs/reference/troubleshooting.md
@@ -7,44 +7,30 @@
## Build Issues
-??? question "Build fails with 'package not found' or missing ROS 2 packages"
- **Root Cause:** ROS 2 environment not sourced or packages not installed.
+??? question "Build fails with 'feature requested package ... but it was not found in assets/DISTRO'"
+ **Root Cause:** `hiroz-msgs` generates messages entirely from `hiroz-codegen`'s bundled asset trees (`crates/hiroz-codegen/assets//`) — it does not read a system ROS 2 installation. An enabled package feature (e.g. `test_msgs`) has no matching package directory under the selected distro's tree.
**Solutions:**
- 1. **Source ROS 2 environment:**
+ 1. **Check which distro is selected** (`humble`, `jazzy`, or `lyrical` — defaults to `jazzy`):
```bash
- source /opt/ros/jazzy/setup.bash
- # or for rolling:
- source /opt/ros/rolling/setup.bash
+ cargo build -p hiroz-msgs --no-default-features --features core_msgs,jazzy
```
- 2. **Verify environment variables:**
+ 2. **Confirm the package exists in that distro's bundled tree:**
```bash
- echo $AMENT_PREFIX_PATH
- echo $CMAKE_PREFIX_PATH
+ ls crates/hiroz-codegen/assets/jazzy/example_interfaces
```
- 3. **Check package installation:**
- ```bash
- ros2 pkg prefix example_interfaces
- # If fails, install:
- sudo apt install ros-jazzy-example-interfaces
- ```
+ 3. **Only `humble`, `jazzy`, and `lyrical` ship a real asset tree today** — `rolling`/`kilted` features exist but have no bundled packages yet, so any package feature will fail for them.
- 4. **Clean and rebuild:**
+ 4. **Clean and rebuild after changing feature flags:**
```bash
cargo clean -p hiroz-msgs
cargo build -p hiroz-msgs
```
- **Common Error Messages:**
-
- | Error | Solution |
- |-------|----------|
- | "Package X not found" | Source ROS 2 environment |
- | "Cannot find ament_index" | Install ROS 2 or use bundled msgs |
- | "AMENT_PREFIX_PATH not set" | Run `source /opt/ros/jazzy/setup.bash` |
+ If the package is genuinely missing from a distro that should carry it, that's a gap in the bundled asset tree, not a local environment problem — file an issue rather than trying to source a system ROS 2 install.
??? question "Compiler error: cannot find crate hiroz_msgs"
**Root Cause:** `hiroz-msgs` is not part of default workspace members.
diff --git a/docs/user-guide/message-generation.md b/docs/user-guide/message-generation.md
index ccea1f9c6..01b7f1084 100644
--- a/docs/user-guide/message-generation.md
+++ b/docs/user-guide/message-generation.md
@@ -61,24 +61,19 @@ hiroz-codegen's orchestration capabilities:
```mermaid
sequenceDiagram
-accTitle: Package discovery sequence checking system then bundled message sources
-accDescr: build.rs asks the discovery layer to find packages, which checks AMENT_PREFIX_PATH then standard opt/ros paths and finally falls back to bundled assets before returning paths for Rust code generation.
+accTitle: Package discovery sequence resolving requested packages against the bundled distro asset tree
+accDescr: build.rs selects a distro from Cargo features, then asks the discovery layer to find each feature-requested package in that distro's bundled asset tree, returning paths for Rust code generation or failing the build if a requested package is missing.
participant B as build.rs
participant D as Discovery
- participant S as Sources
-
- B->>D: Find packages
- D->>S: Check AMENT_PREFIX_PATH
- alt Found in system
- S-->>D: System messages
- else Not found
- D->>S: Check /opt/ros/*
- alt Found in standard path
- S-->>D: System messages
- else Not found
- D->>S: Check bundled assets
- S-->>D: Bundled messages
- end
+ participant S as Bundled assets
+
+ B->>D: Find packages (distro, requested features)
+ D->>S: Check assets//
+ alt Present
+ S-->>D: Bundled messages
+ else Missing
+ S-->>D: Not found
+ D-->>B: Build error
end
D-->>B: Package paths
B->>B: Generate Rust code
@@ -180,24 +175,16 @@ let config = GeneratorConfig {
```mermaid
flowchart LR
-accTitle: Package discovery order by feature flags and ROS installation presence
-accDescr: Feature flags trigger discovery that checks for a system ROS installation via AMENT_PREFIX_PATH or standard distro paths, falling back to bundled assets when no ROS is installed.
- A[Feature Flags] --> B{System ROS?}
- B -->|Found| C[AMENT_PREFIX_PATH]
- B -->|Not Found| D{/opt/ros/distro?}
- D -->|Found| E[Standard paths]
- D -->|Not Found| F[Bundled assets]
-
- C --> G[Generate from system]
- E --> G
- F --> H[Generate from bundled]
+accTitle: Package discovery order by distro feature and requested package features
+accDescr: A distro Cargo feature selects one bundled asset tree; each enabled package feature is then resolved against that tree, generating from bundled assets on a match or failing the build if the package is missing.
+ A[Distro feature: humble/jazzy/lyrical] --> B[assets/<distro>/]
+ C[Package feature: std_msgs, geometry_msgs, ...] --> D{Package in tree?}
+ B --> D
+ D -->|Found| E[Generate from bundled]
+ D -->|Missing| F[Build error]
```
-1. **System ROS:** `$AMENT_PREFIX_PATH`, `$CMAKE_PREFIX_PATH`
-2. **Standard paths:** `/opt/ros/{rolling,jazzy,kilted,lyrical,humble}`
-3. **Bundled assets:** Built-in message definitions in hiroz-codegen
-
-This fallback enables development without ROS 2 installation.
+`hiroz-msgs` generates exclusively from `hiroz-codegen`'s bundled asset trees (`crates/hiroz-codegen/assets//`) — there is no system ROS 2 discovery (`$AMENT_PREFIX_PATH`, `$CMAKE_PREFIX_PATH`, `/opt/ros/*`). This is why builds work without a ROS 2 installation, and why a package requested by an enabled feature but absent from the selected distro's tree is a hard build error rather than a silent fallback.
## Using Generated Messages