Search/Develop a Rust Dataflow Framework for Robots and AI, Picking the Right Tests for Each Change

Develop a Rust Dataflow Framework for Robots and AI, Picking the Right Tests for Each Change

Use when an AI works on a Rust dataflow framework for robots and AI. It keeps message rules clear, runs checks before each commit, picks deeper tests by risk, and reports which tests ran.

To use this AI rule
## Set Up the Rust Workspace and Split the Runtime Into Four Roles Organize the system as a Rust workspace with bindings for Python, C, and C++. Keep minimum toolchain and shared package metadata at the workspace root, while allowing explicitly documented crates or examples to pin independent versions. Use four runtime roles with clear responsibility: - A command-line client builds, starts, stops, and inspects dataflows. - A coordinator manages distributed lifecycle across machines. - One daemon per machine spawns nodes and manages local and remote communication. - Nodes run user code as processes, while operators run in-process when lower overhead is required. Keep message and protocol definitions in a shared library, descriptor parsing and build utilities in a core library, and language APIs in separate packages. Do not let language-binding build requirements contaminate normal Rust-only builds. ## Build Language Bindings Separately From the Rust Workspace Build the Rust workspace while excluding language-binding packages that require a separate packaging tool. Build those packages through their native binding toolchain instead of forcing them through the ordinary workspace command. Support three iteration levels: the full workspace, one package, and one test target. Run checks, tests, lint, and formatting through the workspace's canonical commands, and install local command-line tools with locked dependencies. Build before running lint, tests, integration snapshots, or documentation checks. Example targets need an explicit example check because a general workspace check may not compile them. Keep quick package tests for iteration, but return to the full affected workspace before publishing. If a new example dataflow is added, run the example smoke suite in the supported language mode. ## Keep the Three Message Patterns and the Shared-Memory Rule Explicit Define dataflows declaratively. Nodes subscribe to named outputs and declare their own outputs. Provide timer sources and keep their frequency or interval explicit in the descriptor. Preserve three distinct user-facing communication patterns: - Topic is the default publish/subscribe flow. - Service is request/reply and correlates messages through a `request_id`. - Action represents goal, feedback, result, and cancellation through `goal_id` and `goal_status`. Use bounded multi-producer channels for internal event routing and an async runtime for orchestration. Use a distributed publish/subscribe transport across machines and a hybrid logical clock for causal ordering. For local node traffic, send messages larger than 4 KB through zero-copy shared memory and smaller messages through TCP. Keep the threshold, ownership, and fallback behavior explicit; never collapse local shared-memory and remote network semantics into one undocumented path. ## Review and Simplify Every Commit Before Running Tests Every commit must complete these gates before publication: 1. Review the diff for structural, security, and logic defects. 2. Simplify unnecessary complexity, duplication, and inefficiency. 3. Verify formatting, lint with warnings treated as errors, run at least the affected package tests, and run the full workspace tests before publishing. 4. Compile example targets so API signature breaks cannot hide outside the normal workspace graph. Use a fast local gate before each commit, including formatting, lint, dependency audit, unsafe-shortcut budget, and typo checks. Then run the full required test command before publishing. Do not skip a failed gate or rely on slower remote CI to catch it. Fix the failure and rerun the affected gate. Preserve the order: review and simplification make design defects cheaper to correct before broad tests. ## Choose Deep Tests by Risk Instead of Running Them on Every Commit Do not run every deep suite on every commit or add all of them to pull-request CI. Select them by change scope: - Use the full local suite, including coverage, before a significant publication when extra confidence is needed. - Use deep validation with mutation and compatibility analysis for high-risk or Tier 1 changes. - Use multi-hour nightly parity for cross-platform, property, interpreter, formal-proof, and end-to-end coverage. - Use the release gate before distribution; keep independent security review, dogfooding, and migration validation as separate human-led gates. - Use a full mutation audit only for release-quality test assessment or focused investigation because it can take 10 to 18 hours. - Run example dataflows end to end after changing node APIs, command behavior, or descriptors. - Run formal proofs when changing proof-gated modules, and run profile-guided optimization on the target OS and architecture because profiles do not transfer. Treat coverage, mutation, compatibility, examples, formal verification, and performance profiling as complementary evidence, not interchangeable substitutes. ## Keep Pull-Request CI Fast and Run Long Jobs Nightly Keep pull-request CI lean enough to provide fast blocking feedback. It should cover formatting, warnings-as-errors lint, core tests, end-to-end fault paths, semantic contracts, benchmark regression, typos, supply-chain checks, unsafe-shortcut budgets, and licensing. Do not expand the blocking pipeline with multi-hour jobs. Schedule broad validation separately: - Run platform tests on Linux, macOS, and Windows. - Exercise examples, command-line templates, dynamic-language nodes, benchmarks, and cross-compilation. - Cover distributed lifecycle, record/replay, reconnection, state reconstruction, CPU affinity, storage backends, and bridge adapters. - Verify the minimum supported compiler and any formal proof harnesses. Nightly failures should create a tracked regression signal but need not block an unrelated pull request. Before merge, run local non-default-platform or example checks when the change depends on those paths. ## Write a Failing Test First, Then Only the Code That Makes It Pass All new features and bug fixes follow RED-GREEN-IMPROVE: 1. RED: write the smallest test that defines the expected behavior and verify that it fails for the intended reason. 2. GREEN: implement only enough code to make that test pass. 3. IMPROVE: refactor while keeping the focused and affected-package tests green. Choose the first test tier by behavior. Start library functions with unit tests, coordinator or daemon behavior with integration tests, command changes with networked smoke tests, dataflow features with both networked and local smoke tests, and bug fixes with the narrowest regression test that reproduces the defect. After the focused test passes, run the affected package, warnings-as-errors lint, and formatting checks. If the change touches the command client, coordinator, or daemon, also run smoke tests serially where shared ports or processes require isolation. ## Run Example Dataflows in Both Networked and Local Smoke Modes Provide two smoke modes: - Networked mode starts the distributed runtime, launches a detached dataflow, polls for completion, then stops and tears down the runtime. - Local mode runs the dataflow in one process with an explicit stop deadline. New example dataflows should pass both modes. Share expensive build preparation through a one-time guard instead of rebuilding per test. Keep end-to-end tests for command transport and fault tolerance separate from ordinary unit tests. Smoke suites must clean up processes and ports on both success and failure so later tests are not contaminated. Exclude examples requiring unavailable hardware, interactive input, multi-machine setup, or unsupported native toolchains from the default smoke set, but document the skip boundary and provide a targeted way to run them. ## Keep Patches Small and Report Exactly Which Checks Ran Format with the repository's default formatter before submitting changes. Discuss non-trivial design changes through the project's decision channel before implementation. Do not fix unrelated warnings or refactor unrelated code in the same change. Keep the patch scoped so failures, review, and rollback remain attributable. Treat language packages and command-line binaries as separate distribution surfaces. Verify the appropriate package, binding, compatibility, and release checks for each one. Use an optimized release profile only after correctness gates pass. Performance work must report the target platform and compare a reproducible baseline with the optimized build. Before handoff, report which fast, full, deep, nightly, example, proof, or performance gates were actually run and which remain unverified. Never imply that one green tier proves another tier passed.