Skip to content

fix(simulation): isolate CLI from physical defaults - #19

Merged
Mile-Away merged 3 commits into
mainfrom
codex/simulation-cli-isolation
Sep 26, 2026
Merged

Mile-Away merged 3 commits into
mainfrom
codex/simulation-cli-isolation

Conversation

@Mile-Away

@Mile-Away Mile-Away commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

What changed

lab serve --simulation now starts a pure virtual lab when no recipe is provided. It no longer enables the MQTT broker, loads the default UniLabOS registry, or opens ESP-NOW hardware by accident. A recipe's explicit simulation world is preserved when the flag is used, while physical dongles are ignored with a clear warning.

Validation

  • cargo test --workspace
  • Smoke-tested lab serve --simulation from a directory without a registry; the server stayed up without registry-load errors.

Sourcery 摘要

将模拟模式与实体实验室默认设置隔离,并支持在运行时为虚拟设备绑定视觉资源。

新功能:

  • 支持在运行时为虚拟模拟设备绑定和清除已发布的 Hub 资源。
  • 通过遥测公开模拟资源绑定信息,以便客户端保持视觉表示的一致性。

错误修复:

  • 在未提供配方时,避免模拟模式启用实体 MQTT、注册表或 ESP-NOW 默认设置。
  • 在模拟模式下忽略实体加密狗和配方中定义的 ESP-NOW 设备,同时保留显式配置的模拟世界。

文档:

  • 记录运行时模拟资源绑定及其与持久化资源引用之间的区别。

测试:

  • 增加对模拟配置隔离、配方世界保留,以及运行时资源绑定和清除的测试覆盖。
Original summary in English

Sourcery 总结

将模拟模式与物理实验室默认设置隔离,并支持为虚拟设备运行时绑定视觉资产。

新功能:

  • 支持为正在运行的虚拟模拟设备绑定和清除已发布的 Hub 视觉资产,并通过遥测公开绑定信息。

错误修复:

  • 防止在没有配方的情况下启用模拟模式时,加载物理 MQTT、注册表或 ESP-NOW 默认设置。
  • 在模拟模式下忽略物理加密狗和配方定义的 ESP-NOW 设备,同时保留显式配置的模拟世界。

文档:

  • 记录运行时模拟资产绑定,以及它们与持久化资产引用之间的区别。

测试:

  • 增加对模拟配置隔离、配方世界保留,以及运行时资产绑定和清除功能的测试覆盖。
Original summary in English

Summary by Sourcery

Isolate simulation mode from physical lab defaults and support runtime visual asset bindings for virtual devices.

New Features:

  • Support binding and clearing published Hub visual assets for running virtual simulation devices, with the binding exposed through telemetry.

Bug Fixes:

  • Prevent simulation mode without a recipe from enabling physical MQTT, registry, or ESP-NOW defaults.
  • Ignore physical dongles and recipe-defined ESP-NOW devices in simulation mode while preserving explicitly configured simulation worlds.

Documentation:

  • Document runtime simulation asset bindings and their distinction from persistent asset references.

Tests:

  • Add coverage for simulation configuration isolation, recipe world preservation, and runtime asset binding and clearing.

@sourcery-ai

sourcery-ai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

审查者指南

该 PR 将 --simulation 启动过程与 MQTT、注册表和 ESP-NOW 物理默认配置隔离,同时保留显式定义的配方世界,并为虚拟设备添加经过验证的运行时资产绑定,以及遥测和文档支持。

运行时模拟资产绑定时序图

sequenceDiagram
    participant Client
    participant SimulationTransport
    participant KinematicBackend
    participant Telemetry

    Client->>SimulationTransport: send(set_asset, namespace, name, version)
    SimulationTransport->>SimulationTransport: validate set_asset parameters
    SimulationTransport->>KinematicBackend: apply_action(set_asset, params)
    KinematicBackend-->>SimulationTransport: update simulation_asset
    SimulationTransport->>Telemetry: emit_status()
    Telemetry-->>Client: telemetry with simulation_asset

    Client->>SimulationTransport: send(clear_asset, params)
    SimulationTransport->>KinematicBackend: apply_action(clear_asset, params)
    KinematicBackend-->>SimulationTransport: remove simulation_asset
    SimulationTransport->>Telemetry: emit_status()
    Telemetry-->>Client: telemetry without simulation_asset
Loading

模拟配置隔离流程图

flowchart TD
    A[build_config] --> B{--simulation?}
    B -->|是,无配方| C[禁用 MQTT]
    C --> D[不使用物理适配器]
    D --> E[创建默认 SimulationConfig]
    B -->|是,有配方| F[保留配方中的模拟世界]
    F --> G[跳过注册表回退]
    G --> H[清除 ESP-NOW 加密狗]
    B -->|否| I[使用物理默认配置]
    I --> J[启用 MQTT 和 UniLabOS 适配器]
    I --> K[允许注册表和 ESP-NOW 配置]
Loading

文件级变更

变更 详细信息 文件
使模拟启动独立于物理实验室默认配置。
  • 当模拟没有配方时,避免启用 MQTT 和 UniLabOS 适配器。
  • 在模拟模式下跳过回退注册表发现。
  • 忽略已配置的 ESP-NOW 硬件,并在请求模拟时发出警告。
  • 仅当配方尚未定义模拟世界时,才创建默认模拟世界。
  • 增加对物理默认配置隔离和配方世界保留的覆盖测试。
crates/lab-cli/src/commands/serve.rs
支持虚拟设备的运行时视觉资产绑定。
  • 在默认模拟设备上公开 set_asset 和 clear_asset 操作。
  • 验证必需的资产标识字段和可选的版本值。
  • 在设备遥测状态中存储或移除模拟资产。
  • 增加用于绑定和清除资产的端到端传输测试。
crates/osdl-core/src/config.rs
crates/osdl-core/src/transport/simulation.rs
记录运行时模拟资产行为。
  • 描述 set_asset 和 clear_asset 的语义、遥测传播以及持久化 asset_ref 的使用方式。
docs/recipes/simulation-mode.md

提示和命令

与 Sourcery 交互

  • 触发新的审查: 在拉取请求中评论 @sourcery-ai review。
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 根据审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以使用 @sourcery-ai issue 回复审查评论,以根据该评论创建 issue。
  • 生成拉取请求标题: 在拉取请求标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title,以随时(重新)生成标题。
  • 生成拉取请求摘要: 在拉取请求正文中你希望摘要出现的位置写入 @sourcery-ai summary,即可随时在那里生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary,以随时(重新)生成摘要。
  • 生成审查者指南: 在拉取请求中评论 @sourcery-ai guide,即可随时(重新)生成审查者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,此功能会很有用。
  • 忽略所有 Sourcery 审查: 在拉取请求中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。如果你想从新的审查开始,这一功能尤其有用——别忘了评论 @sourcery-ai review 以触发新的审查!

自定义你的使用体验

访问你的控制面板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、审查者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

The PR isolates --simulation startup from MQTT, registry, and ESP-NOW physical defaults while preserving explicit recipe worlds, and adds validated runtime asset binding for virtual devices with telemetry and documentation support.

Sequence diagram for runtime simulation asset binding

sequenceDiagram
    participant Client
    participant SimulationTransport
    participant KinematicBackend
    participant Telemetry

    Client->>SimulationTransport: send(set_asset, namespace, name, version)
    SimulationTransport->>SimulationTransport: validate set_asset parameters
    SimulationTransport->>KinematicBackend: apply_action(set_asset, params)
    KinematicBackend-->>SimulationTransport: update simulation_asset
    SimulationTransport->>Telemetry: emit_status()
    Telemetry-->>Client: telemetry with simulation_asset

    Client->>SimulationTransport: send(clear_asset, params)
    SimulationTransport->>KinematicBackend: apply_action(clear_asset, params)
    KinematicBackend-->>SimulationTransport: remove simulation_asset
    SimulationTransport->>Telemetry: emit_status()
    Telemetry-->>Client: telemetry without simulation_asset
Loading

Flow diagram for simulation configuration isolation

flowchart TD
    A[build_config] --> B{--simulation?}
    B -->|yes, no recipe| C[Disable MQTT]
    C --> D[Use no physical adapters]
    D --> E[Create default SimulationConfig]
    B -->|yes, recipe| F[Preserve recipe simulation world]
    F --> G[Skip registry fallback]
    G --> H[Clear ESP-NOW dongles]
    B -->|no| I[Use physical defaults]
    I --> J[Enable MQTT and UniLabOS adapter]
    I --> K[Allow registry and ESP-NOW configuration]
Loading

File-Level Changes

Change Details Files
Make simulation startup independent of physical-lab defaults.
  • Avoid enabling MQTT and UniLabOS adapters when simulation has no recipe.
  • Skip fallback registry discovery in simulation mode.
  • Ignore configured ESP-NOW hardware and warn when simulation is requested.
  • Create a default simulation world only when the recipe does not already define one.
  • Add coverage for physical-default isolation and recipe-world preservation.
crates/lab-cli/src/commands/serve.rs
Support runtime visual-asset binding for virtual devices.
  • Expose set_asset and clear_asset actions on default simulation devices.
  • Validate required asset identity fields and optional version values.
  • Store or remove the simulation asset in device telemetry state.
  • Add an end-to-end transport test for binding and clearing an asset.
crates/osdl-core/src/config.rs
crates/osdl-core/src/transport/simulation.rs
Document runtime simulation asset behavior.
  • Describe set_asset and clear_asset semantics, telemetry propagation, and durable asset_ref usage.
docs/recipes/simulation-mode.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

您好——我发现了 1 个问题

面向 AI Agent 的提示
请处理本次代码审查中的评论:

## 个别评论

### 评论 1
<location path="crates/lab-cli/src/commands/serve.rs" line_range="481-484" />
<code_context>
                 a.registry_path = Some(reg_str.clone());
             }
         }
-    } else {
+    } else if !args.simulation {
         // Final fallback for adapters with no registry configured — pick
         // the registry that ships next to the config file. With a config
</code_context>
<issue_to_address>
**issue (broader_impact):** `--simulation --registry PATH` 仍会添加一个 `unilabos` 适配器,导致引擎加载物理注册表,尽管模拟模式的设计目标是将 CLI 与物理默认设置隔离。模拟模式会明确忽略 dongle 覆盖设置,但等效的注册表覆盖设置却不会被忽略。

**触发条件:** 将 `--simulation` 与 `--registry` 结合使用时。

**建议修复:** 在模拟模式下忽略 `--registry`,或者像处理 dongle 覆盖设置一样,在两者组合使用时给出明确警告并拒绝该组合。
</issue_to_address>

Sourcery 对开源项目免费——如果您喜欢我们的审查,请考虑分享 ✨
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="crates/lab-cli/src/commands/serve.rs" line_range="481-484" />
<code_context>
                 a.registry_path = Some(reg_str.clone());
             }
         }
-    } else {
+    } else if !args.simulation {
         // Final fallback for adapters with no registry configured — pick
         // the registry that ships next to the config file. With a config
</code_context>
<issue_to_address>
**issue (broader_impact):** `--simulation --registry PATH` still adds a `unilabos` adapter, causing the engine to load a physical registry even though simulation mode is intended to isolate the CLI from physical defaults. The dongle override is explicitly ignored in simulation, but the equivalent registry override is not.

**Triggers:** When `--simulation` is combined with `--registry`.

**Suggested fix:** Ignore `--registry` in simulation mode, or reject the combination with a clear warning, just as the dongle override is handled.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment on lines 481 to +484
a.registry_path = Some(reg_str.clone());
}
}
} else {
} else if !args.simulation {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (broader_impact): --simulation --registry PATH 仍会添加一个 unilabos 适配器,导致引擎加载物理注册表,尽管模拟模式的设计目标是将 CLI 与物理默认设置隔离。模拟模式会明确忽略 dongle 覆盖设置,但等效的注册表覆盖设置却不会被忽略。

触发条件: 将 --simulation 与 --registry 结合使用时。

建议修复: 在模拟模式下忽略 --registry,或者像处理 dongle 覆盖设置一样,在两者组合使用时给出明确警告并拒绝该组合。

Original comment in English

issue (broader_impact): --simulation --registry PATH still adds a unilabos adapter, causing the engine to load a physical registry even though simulation mode is intended to isolate the CLI from physical defaults. The dongle override is explicitly ignored in simulation, but the equivalent registry override is not.

Triggers: When --simulation is combined with --registry.

Suggested fix: Ignore --registry in simulation mode, or reject the combination with a clear warning, just as the dongle override is handled.

@Mile-Away
Mile-Away merged commit 9e0085c into main Sep 26, 2026
14 checks passed
@Mile-Away
Mile-Away deleted the codex/simulation-cli-isolation branch September 26, 2026 18:31
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