Skip to content

feat(core): compile-time flows feature gate (#4797)#4912

Open
oxoxDev wants to merge 11 commits into
tinyhumansai:mainfrom
oxoxDev:feat/4797-flows-feature-gate
Open

feat(core): compile-time flows feature gate (#4797)#4912
oxoxDev wants to merge 11 commits into
tinyhumansai:mainfrom
oxoxDev:feat/4797-flows-feature-gate

Conversation

@oxoxDev

@oxoxDev oxoxDev commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a compile-time Cargo flows feature (default-ON) gating the openhuman::flows + tinyflows + rhai_workflows domains, composing with the runtime DomainSet::flows flag from feat(core): DomainSet on CoreBuilder + DomainRegistration filter seam (feature-gate prerequisite) #4796.
  • Default build is byte-identical — every change is cfg-off-only, so the desktop/CLI app is unchanged. Slim builds opt out via cargo build --no-default-features --features "<gates without flows>".
  • The only gate in this epic that sheds real dependencies — 5 crates: tinyflows, jaq-core, jaq-std, jaq-json, rhai. Proven, not argued: cargo tree -i <crate> returns nothing on the slim build and all 5 resolve on default.
  • Leaf-gate, zero stub files. Nothing inside flows/, tinyflows/, or rhai_workflows/ changed.
  • 25 flow tools + RhaiTool gated; 8 pre-existing test sites cfg'd.

Problem

#4795 wants one compile-time feature gate per subsystem family so slim harness builds drop code and deps; #4796 shipped the runtime DomainSet axis. This PR adds the compile-time half for the flows family.

Two scope realities the issue statement under-specified, both confirmed by a call-graph sweep:

  • "Sheds the rhai scripting engine" is true only at the feature level. rhai is not a direct dependency of this crate — it arrives transitively via tinyagents/repl. So the gate must be flows = ["dep:tinyflows", "tinyagents/repl"], and the direct tinyagents dep drops repl. The tinyagents crate itself cannot be shed: 26+ domains consume it.
  • The tool count is 25 + RhaiTool, not 14. The issue's 14 counted names in a const table, not registrations.

Solution

  • Cargo.toml: flows = ["dep:tinyflows", "tinyagents/repl"] added to default; tinyflows made optional; the direct tinyagents dep no longer enables repl.
  • Leaf-gate with no stub files. #[cfg(feature = "flows")] sits on the module declarations and on each registration site — controller, subscriber, boot reconcile, agent tools, and the workflow_builder / flow_discovery built-ins. No stub.rs anywhere, deliberately: every externally-reached symbol in this family is a registration site, and registration sites want absence. A stub that registers a controller which then errors is the opposite of the DoD — the namespace would still appear in /schema.
  • Tests (src/core/all_tests.rs, ops_tests.rs): directional on/off coverage for controller + tool registration. 8 pre-existing test sites cfg'd for the disabled config — jsonrpc_tests.rs, builtin_definitions.rs, definition_tests.rs, and the loader tests (4 of these were not in the original plan).
  • App forwarding (app/src-tauri/Cargo.toml): the openhuman_core dep is default-features = false, so flows is added explicitly to keep the domain in the shipped desktop app. Verified with cargo tree -e features -i openhuman.
  • CI: no functional change needed — the rust-feature-gate-smoke lane in ci-lite.yml is a deny-by-default allow-list (--no-default-features --features tokenjuice-treesitter), so a new default-ON gate is excluded automatically and the disabled combination is already covered. The only edit is a step-label rename ("Check core builds with the voice gate disabled""...with the default domain gates disabled"), since the lane now covers more than voice.

When off: the flows RPC namespace is absent from /schema and its methods return a clean JSON-RPC unknown-method (-32000); the 25 flow tools + RhaiTool are absent from the tool belt; tinyflows + jaq-* + rhai leave the build.

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy — directional on/off registration tests in both feature configs, plus 8 pre-existing sites cfg'd for the disabled build.
  • N/A: no instrumented changed lines — the diff is compile-config only (#[cfg] attrs, a Cargo feature, a doc block); diff-cover reports no coverable lines. The directional gate tests cover the on/off behaviour. — Diff coverage ≥ 80%
  • N/A: compile-time build-config change, no user-facing feature row — Coverage matrix updated
  • N/A: no matrix rows affected — All affected feature IDs from the matrix are listed in the PR description under ## Related
  • No new external network dependencies introduced (mock backend used per Testing Strategy) — no deps added; tinyflows is an existing dep made optional.
  • N/A: default build is byte-identical, so no release-cut surface changes — Manual smoke checklist updated if this touches release-cut surfaces (docs/RELEASE-MANUAL-SMOKE.md)
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Desktop / CLI / mobile / web: no behaviour change — default keeps flows on and the build is byte-identical.
  • Slim builds: drop the flows domain, its 25 tools + RhaiTool, and 5 crates (tinyflows, jaq-core, jaq-std, jaq-json, rhai). This is the epic's only real binary-size win so far.
  • Security: reduced attack surface in slim builds — the rhai script engine is gone entirely rather than merely unreachable.
  • Migration / compatibility: none. Additive and default-preserving.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A — GitHub-issue driven, no Linear ticket.
  • URL: N/A

Commit & Branch

  • Branch: feat/4797-flows-feature-gate
  • Commit SHA: b25121bb3d3d59d7c6e37107da9861a87c7fce82 (8 commits, 16 files, +204/-10)

Validation Run

  • N/A: no frontend changes — pnpm --filter openhuman-app format:check
  • N/A: no frontend changes — pnpm typecheck
  • Focused tests: scoped enabled-config tests pass; directional gate tests pass in both configs.
  • Rust fmt/check (if changed): cargo fmt clean · enabled cargo check 0 errors · disabled cargo check --no-default-features --features tokenjuice-treesitter 0 errors · clippy clean in both directions.
  • N/A: manifest-only change to app/src-tauri/Cargo.toml (one dep line), no Tauri Rust source touched — forwarding verified via cargo tree -e features -i openhuman — Tauri fmt/check (if changed)

Boot smoke (both directions, 2 runs for repeatability) — both configs built, linked, booted, and served /rpc:

  • Gate ON: flows namespace present in /schema; probe openhuman.flows_list{"result":{"logs":["flows listed"],"result":[]}}.
  • Gate OFF: namespace absent from /schema; the method returns a clean JSON-RPC unknown-method (-32000); the process survives.

Validation Blocked

  • command: cargo test --no-default-features
  • error: 2 pre-existing failures on main today — group_mapping_smoke and harness_excludes_gated_namespaces, both asserting the voice namespace uncfg'd (fallout from the merged voice gate feat(core): feature gate — voice #4803). CI cannot see them: the feature-gate smoke lane runs cargo check, which never compiles test code.
  • impact: Not introduced by this PR and not fixed by it. This PR cfg'd its own asserts and left voice's alone; the voice asserts are a separate, epic-level fix that is pending. Scoped enabled-config tests and both-direction cargo check are green.

Behavior Changes

  • Intended behavior change: new default-ON flows compile-time gate. Default build unchanged.
  • User-visible effect: none by default. Slim builds omit the flows domain, its 25 tools + RhaiTool, and 5 crates.

Parity Contract

  • Legacy behavior preserved: yes — every change is cfg-off-only, so the default build is byte-identical.
  • Guard/fallback/dispatch parity checks: gate ON reproduces current registration exactly (verified by boot smoke against the live /rpc); gate OFF yields absence at every registration site — no half-registered controller, no stub that registers-then-errors. Composes with, and does not replace, the runtime DomainSet::flows guard from feat(core): DomainSet on CoreBuilder + DomainRegistration filter seam (feature-gate prerequisite) #4796.

Duplicate / Superseded PR Handling

Summary by CodeRabbit

  • New Features

    • Introduced a compile-time flows option that enables workflow/flow capabilities, including the related REPL and workflow agent set.
  • Bug Fixes

    • Prevented flow controllers, RPC subscribers, cron reconciliation, and workflow tools/agents from being referenced or registered in builds where flows is disabled.
  • Tests

    • Added and adjusted feature-gated unit, integration, and E2E coverage to verify flow functionality is present or omitted correctly.
  • Documentation

    • Expanded guidance on the flows feature behavior and highlighted CI smoke test limitations.

oxoxDev added 8 commits July 15, 2026 17:54
Gates the flows automation domains at compile time, composing with the
runtime DomainSet::flows axis from tinyhumansai#4796. Default-ON, so the desktop
build is unchanged.

Makes `tinyflows` optional and moves `tinyagents`'s `repl` feature
behind the gate: `repl` is the only thing pulling `rhai`, and it is
consumed solely by `rhai_workflows`. A slim build therefore sheds
tinyflows + jaq-core/jaq-std/jaq-json + rhai. `tinyagents` itself
cannot be shed — 26+ domains consume it.
…tinyhumansai#4797)

Leaf-gate: no stub facade. Every symbol reached from outside these three
modules is a registration site, and registration sites want ABSENCE — a
stub returning `Err("flows disabled")` would register a controller that
then fails at runtime, the opposite of the intended unknown-method
behaviour. Call sites carry their own #[cfg] instead.
…tinyhumansai#4797)

Three core-side registration sites for the flows domain:
- all.rs: the flows controller push (keeps its DomainGroup::Flows tag —
  that is the orthogonal runtime axis).
- jsonrpc.rs: the FlowTriggerSubscriber registration. The existing
  `if plan.flows` runtime guard does not help here — the type path must
  still resolve for the block to compile.
- services.rs: reconcile_schedule_triggers_on_boot.

Each disabled path keeps a debug log, per the logging convention.
…ansai#4797)

Gates the four glob re-exports and, per element, the 25 flows-owned tools
in the default registry — the same construct the voice gate already uses
on elements of this vec!. Also gates the rhai_workflows tool, whose
engine the gate sheds via tinyagents/repl.

`const FLOWS: &[&str]` in tool_group() stays UNgated: it is an inert
&str table referencing no flows types, so the tool-group classification
keeps working (and its tests keep passing) in a slim build.
…built-ins (tinyhumansai#4797)

This module is always compiled, so the two BuiltinAgent entries' prompt_fn
paths break without a cfg. Gating the element also drops its include_str!
of the agent TOML — correct: a slim build must not advertise an agent
whose entire tool belt is absent.

#[cfg] on const-slice elements is stable (attributes on array-literal
elements) and verified in both directions here.
…inyhumansai#4797)

The CI smoke lane runs `cargo check` only, never
`cargo test --no-default-features` — so CI stays green while the
disabled-build test suite breaks. Six pre-existing sites hard-assert
that flows exists and fail (or panic) once the gate lands:

- all_tests.rs: `full_ns.contains("flows")`, `group_for_namespace`,
  and two `.expect("a flows.* method exists")` vehicles.
- jsonrpc_tests.rs: the transport-layer gated-method vehicle.
- builtin_definitions.rs + definition_tests.rs: built-in agent id and
  max-iterations tables listing the two flows agents.

Adds directional tests: controllers registered when the feature is on,
absent when off (one namespace — tinyflows registers no controllers and
rhai_workflows is AgentOnly), plus a tools test proving all 25 flow
tools and rhai_workflows leave the registry when the gate is off.
SecurityPolicy::default() is Supervised, so the rhai assertion is real.
…nsai#4797)

The shell sets default-features = false, so without this the shipped app
would silently lose the entire Flows surface. Multi-line array so the
sibling gates append cleanly.
…nsai#4797)

Adds the gate-table row and the leaf-gate rationale (why registration
sites want absence, not a stub).

Corrects the issue's dep claim: the gate does NOT shed tinyagents (26+
domains consume it). "Sheds the rhai scripting engine" is true only at
the feature level — rhai arrives via tinyagents/repl, which flows now
owns. Also notes that compiling clean is not proof of a dep shed, and
records the disabled-build test gap for future gates.

The ci-lite smoke lane needs no functional change: its
`--features tokenjuice-treesitter` is an explicit allow-list, so a new
default-ON gate is excluded automatically. Only the stale step name
("the voice gate disabled") is corrected.
@oxoxDev oxoxDev requested a review from a team July 15, 2026 14:33
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 25 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 208b9424-3ab9-4f73-b132-f27a92477440

📥 Commits

Reviewing files that changed from the base of the PR and between f14c34b and 26ee61d.

📒 Files selected for processing (5)
  • .github/workflows/ci-lite.yml
  • Cargo.toml
  • app/src-tauri/Cargo.toml
  • src/openhuman/agent_registry/agents/loader.rs
  • tests/json_rpc_e2e.rs
📝 Walkthrough

Walkthrough

This change adds a compile-time flows feature gate, makes flow dependencies optional, and conditionally excludes flow modules, controllers, tools, agents, subscribers, cron reconciliation, and dependent tests from slim builds.

Changes

Flows feature gate

Layer / File(s) Summary
Feature and dependency contract
Cargo.toml, app/src-tauri/Cargo.toml
Adds the flows feature, makes tinyflows optional, separates tinyagents/repl, and enables flows for the Tauri application.
Leaf modules, tools, and agents
src/openhuman/mod.rs, src/openhuman/tools/*, src/openhuman/agent_registry/agents/loader.rs
Gates flow modules, re-exports, workflow tools, scripting support, and workflow agent definitions behind flows.
Core controller and runtime wiring
src/core/all.rs, src/core/jsonrpc.rs, src/core/runtime/services.rs
Conditionally registers Flows controllers, subscribers, and cron reconciliation, logging when the subscriber is unavailable.
Feature-specific validation and guidance
src/core/*_tests.rs, src/openhuman/**/*tests.rs, tests/json_rpc_e2e.rs, AGENTS.md, .github/workflows/ci-lite.yml
Updates feature-sensitive assertions, adds disabled-build absence tests, gates flow E2E tests, and documents the gate and testing requirements.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

  • tinyhumansai/openhuman#4795 — Tracks the broader feature-gating work implemented here.
  • tinyhumansai/openhuman#4801 — Covers the same compile-time removal pattern for subsystem controllers, tools, dependencies, and runtime registrations.

Possibly related PRs

Suggested labels: feature, rust-core

Suggested reviewers: senamakel, sanil-23, senamakel-droid

Poem

A rabbit hops where flow gates glow,
Tools hide when slim builds grow.
Controllers rest, subscribers sleep,
Cargo guards the paths they keep.
“Compile clean!” the bunny sings.

🚥 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 matches the main change: adding a compile-time flows feature gate to core.
Linked Issues check ✅ Passed The changes align with #4797 by gating flows domains, updating defaults, tests, docs, and CI for enabled and disabled builds.
Out of Scope Changes check ✅ Passed The diff stays focused on flows gating, dependency pruning, and related tests/documentation without obvious unrelated changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. labels Jul 15, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b25121bb3d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/core/all.rs
Comment on lines +236 to 237
#[cfg(feature = "flows")]
push(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Gate the flows JSON-RPC E2E tests

When this cfg is off in the documented slim validation (cargo test --no-default-features --features tokenjuice-treesitter), the flows controllers become unknown methods, but tests/json_rpc_e2e.rs still runs unconditional flows cases such as json_rpc_flows_lifecycle_round_trip, json_rpc_flows_suggestion_lifecycle_methods_are_wired, and json_rpc_flows_validate_reports_warnings_and_errors that call openhuman.flows_* and assert success. Please cfg-gate those integration tests (or require the flows feature for the test target) so the disabled-build test suite does not fail as soon as these controllers are compiled out.

Useful? React with 👍 / 👎.

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/openhuman/tools/ops.rs (1)

280-383: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Align runtime flow filtering with every gated tool.

When flows is compiled in but DomainSet::flows is disabled, tool_group only recognizes a subset of these tools. Names such as edit_workflow, validate_workflow, create_workflow, duplicate_flow, list_flow_runs, resume_flow_run, cancel_flow_run, list_connectable_toolkits, list_node_kinds, get_node_kind_contract, and rhai_workflows fall through to DomainGroup::Platform and remain callable.

Add every flow-owned tool to the FLOWS classification list and add a runtime test covering the full registry with flows disabled.

Suggested classification additions
 const FLOWS: &[&str] = &[
+    "edit_workflow",
+    "validate_workflow",
+   +    "get_flow_history",
+    "list_flow_runs",
+    "resume_flow_run",
+    "cancel_flow_run",
+    "create_workflow",
+    "duplicate_flow",
+    "list_connectable_toolkits",
+    "list_node_kinds",
+    "get_node_kind_contract",
+    "rhai_workflows",
 ];

Also applies to: 1097-1121

🤖 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 `@src/openhuman/tools/ops.rs` around lines 280 - 383, Update the runtime flow
classification in tool_group so every flow-owned tool registered under the flows
feature—including edit_workflow, validate_workflow, create_workflow,
duplicate_flow, list_flow_runs, resume_flow_run, cancel_flow_run,
list_connectable_toolkits, list_node_kinds, get_node_kind_contract,
rhai_workflows, and the remaining flow tools—belongs to DomainGroup::Flows
rather than Platform. Add a runtime test that disables DomainSet::flows and
verifies the full registered flow-tool set is classified consistently and cannot
remain callable.
.github/workflows/ci-lite.yml (1)

359-386: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

CI still doesn't run the disabled-feature test suite — only cargo check.

The renamed step continues to run only cargo check (lib target, no --tests) against --no-default-features. New #[cfg(not(feature = "flows"))] tests introduced across this cohort (e.g. flows_controllers_absent_when_feature_off in src/core/all_tests.rs, default_tools_omits_flows_tools_when_feature_off in src/openhuman/tools/ops_tests.rs) — and any #[cfg]-on-expression compile errors in the test files — will never actually run in CI. As per coding guidelines: "Tests that assert the presence of feature-gated domains must be gated with the same Cargo feature. Run the disabled-feature test suite, not only cargo check."

🔧 Proposed addition
       - name: Check core builds with the default domain gates disabled
         run: bash scripts/ci-cancel-aware.sh cargo check --manifest-path Cargo.toml --no-default-features --features tokenjuice-treesitter
+
+      - name: Check disabled-gate test suite compiles and runs
+        run: bash scripts/ci-cancel-aware.sh cargo test --manifest-path Cargo.toml --no-default-features --features tokenjuice-treesitter --lib core::
🤖 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/ci-lite.yml around lines 359 - 386, Update the
rust-feature-gate-smoke step’s command to run the disabled-feature test suite,
not only the library build check. Preserve --manifest-path Cargo.toml,
--no-default-features, and --features tokenjuice-treesitter, and invoke the
appropriate cargo test flow so cfg-gated tests such as
flows_controllers_absent_when_feature_off and
default_tools_omits_flows_tools_when_feature_off are compiled and executed.

Source: Coding guidelines

🧹 Nitpick comments (1)
src/core/runtime/services.rs (1)

130-131: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Log the intentionally skipped reconciliation in slim builds.

When flows is disabled, this #[cfg] removes the reconciliation call without emitting any boot diagnostic. Add a stable [flows] debug message, consistent with the subscriber path in src/core/jsonrpc.rs, so operators can distinguish intentional feature omission from a missing or failed reconciliation path.

As per coding guidelines, changed Rust flows should log branches with stable grep-friendly prefixes.
[details]

Proposed change
 #[cfg(feature = "flows")]
 if let Err(e) =
     crate::openhuman::flows::ops::reconcile_schedule_triggers_on_boot(&config).await
 {
     log::warn!(
         "[flows] boot reconciliation of schedule-trigger cron jobs failed: {e}"
     );
 }
+#[cfg(not(feature = "flows"))]
+log::debug!(
+    "[flows] boot schedule-trigger reconciliation SKIPPED — flows feature disabled at compile time"
+);
🤖 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 `@src/core/runtime/services.rs` around lines 130 - 131, Update the cfg-gated
reconciliation flow around the `#[cfg(feature = "flows")]` branch to add a
slim-build `#[cfg(not(feature = "flows"))]` debug log with the stable `[flows]`
prefix. Match the existing subscriber-path logging convention in `jsonrpc.rs`,
and ensure the message clearly indicates reconciliation was intentionally
skipped because flows are disabled.

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 `@src/openhuman/agent/harness/definition_tests.rs`:
- Around line 377-381: Update the definition test fixture containing the flow
entries to remove #[cfg] attributes from expressions inside the slice literal.
Build the base entries separately, then conditionally append ("flow_discovery",
50) and ("workflow_builder", 50) through a cfg-controlled Vec/extend path so it
compiles on the pinned stable toolchain.

---

Outside diff comments:
In @.github/workflows/ci-lite.yml:
- Around line 359-386: Update the rust-feature-gate-smoke step’s command to run
the disabled-feature test suite, not only the library build check. Preserve
--manifest-path Cargo.toml, --no-default-features, and --features
tokenjuice-treesitter, and invoke the appropriate cargo test flow so cfg-gated
tests such as flows_controllers_absent_when_feature_off and
default_tools_omits_flows_tools_when_feature_off are compiled and executed.

In `@src/openhuman/tools/ops.rs`:
- Around line 280-383: Update the runtime flow classification in tool_group so
every flow-owned tool registered under the flows feature—including
edit_workflow, validate_workflow, create_workflow, duplicate_flow,
list_flow_runs, resume_flow_run, cancel_flow_run, list_connectable_toolkits,
list_node_kinds, get_node_kind_contract, rhai_workflows, and the remaining flow
tools—belongs to DomainGroup::Flows rather than Platform. Add a runtime test
that disables DomainSet::flows and verifies the full registered flow-tool set is
classified consistently and cannot remain callable.

---

Nitpick comments:
In `@src/core/runtime/services.rs`:
- Around line 130-131: Update the cfg-gated reconciliation flow around the
`#[cfg(feature = "flows")]` branch to add a slim-build `#[cfg(not(feature =
"flows"))]` debug log with the stable `[flows]` prefix. Match the existing
subscriber-path logging convention in `jsonrpc.rs`, and ensure the message
clearly indicates reconciliation was intentionally skipped because flows are
disabled.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 475a2ff6-040e-45ca-a431-a609b0c8e9f9

📥 Commits

Reviewing files that changed from the base of the PR and between 2dcaaba and b25121b.

📒 Files selected for processing (16)
  • .github/workflows/ci-lite.yml
  • AGENTS.md
  • Cargo.toml
  • app/src-tauri/Cargo.toml
  • src/core/all.rs
  • src/core/all_tests.rs
  • src/core/jsonrpc.rs
  • src/core/jsonrpc_tests.rs
  • src/core/runtime/services.rs
  • src/openhuman/agent/harness/builtin_definitions.rs
  • src/openhuman/agent/harness/definition_tests.rs
  • src/openhuman/agent_registry/agents/loader.rs
  • src/openhuman/mod.rs
  • src/openhuman/tools/mod.rs
  • src/openhuman/tools/ops.rs
  • src/openhuman/tools/ops_tests.rs

Comment on lines +377 to 381
// Gated with `flows` (#4797) — absent from a slim build.
#[cfg(feature = "flows")]
("flow_discovery", 50),
#[cfg(feature = "flows")]
("workflow_builder", 50),

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 | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '350,395p' src/openhuman/agent/harness/definition_tests.rs
rustc --version
python3 - <<'PY'
print("Need source inspection and language-level confirmation before rewriting the comment.")
PY

Repository: tinyhumansai/openhuman

Length of output: 2260


🌐 Web query:

Rust stable #[cfg] on array or slice literal elements stmt_expr_attributes status

💡 Result:

The use of #[cfg] attributes on individual elements within an array or slice literal (e.g., &[1, #[cfg(feature = "x")] 2, 3]) is not stable in Rust [1]. While this behavior has historically functioned in some contexts, it is not an officially stabilized feature [1]. The broader underlying feature, stmt_expr_attributes, which tracks the ability to place attributes on expressions and non-item statements, remains unstable [2][3][4]. Recent efforts in the Rust compiler, such as the merging of pull request #124099 in 2024, have aimed to restrict "ambiguous" outer attributes on expressions to clarify and move forward the path toward stabilization [5][6]. While certain expressions that are unambiguous (such as those enclosed in braces or parentheses) have been considered for more consistent support, applying #[cfg] directly to elements within a list or array literal remains unsupported on stable Rust [1][5]. For conditional inclusion of elements in arrays or slices in stable Rust, standard practice is to use alternative approaches, such as macros (e.g., macro_rules!) to generate the array or slice at compile time based on configuration predicates [1][7].

Citations:


🏁 Script executed:

set -euo pipefail

printf '--- rust-toolchain files ---\n'
git ls-files | rg '(^|/)(rust-toolchain(\.toml)?|Cargo\.toml|lib\.rs|main\.rs)$' || true

printf '\n--- feature-gate search ---\n'
rg -n 'stmt_expr_attributes|#!\[feature\(' -g 'Cargo.toml' -g '*.rs' -g 'rust-toolchain*' .

printf '\n--- top-level toolchain hints ---\n'
for f in rust-toolchain rust-toolchain.toml; do
  if [ -f "$f" ]; then
    echo "## $f"
    cat "$f"
  fi
done

Repository: tinyhumansai/openhuman

Length of output: 251


🏁 Script executed:

set -euo pipefail

echo '--- rust-toolchain files ---'
git ls-files | rg '(^|/)(rust-toolchain(\.toml)?|Cargo\.toml|lib\.rs|main\.rs)$' || true

echo
echo '--- feature-gate search ---'
rg -n 'stmt_expr_attributes|#!\[feature\(' -g 'Cargo.toml' -g '*.rs' -g 'rust-toolchain*' .

echo
echo '--- top-level toolchain hints ---'
for f in rust-toolchain rust-toolchain.toml; do
  if [ -f "$f" ]; then
    echo "## $f"
    cat "$f"
  fi
done

Repository: tinyhumansai/openhuman

Length of output: 519


🏁 Script executed:

sed -n '1,120p' rust-toolchain.toml
sed -n '370,385p' src/openhuman/agent/harness/definition_tests.rs

Repository: tinyhumansai/openhuman

Length of output: 1349


Avoid #[cfg] inside the slice literal src/openhuman/agent/harness/definition_tests.rs:377-381 — these gated entries sit inside a &[(&str, usize)] literal, so the attributes land on expressions and won’t compile on the pinned stable toolchain. Move the gated values into a separate Vec/extend path or another cfg-controlled helper.

🤖 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 `@src/openhuman/agent/harness/definition_tests.rs` around lines 377 - 381,
Update the definition test fixture containing the flow entries to remove #[cfg]
attributes from expressions inside the slice literal. Build the base entries
separately, then conditionally append ("flow_discovery", 50) and
("workflow_builder", 50) through a cfg-controlled Vec/extend path so it compiles
on the pinned stable toolchain.

oxoxDev and others added 3 commits July 15, 2026 20:16
…ture-gate

# Conflicts:
#	.github/workflows/ci-lite.yml
#	AGENTS.md
#	Cargo.toml
#	app/src-tauri/Cargo.toml
…inyhumansai#4797)

The flows controllers are cfg-gated out of the slim build (src/core/all.rs),
so openhuman.flows_* become unknown JSON-RPC methods there. The eight flows
cases in tests/json_rpc_e2e.rs called them unconditionally and asserted
success, which would fail once the target compiles in the slim direction.

Gate the eight tests plus their four flows-only helpers so the disabled-build
suite skips them. Verified with voice on / flows off (isolating the
pre-existing voice test_seam gap tracked in tinyhumansai#4916):
  cargo check --no-default-features --features tokenjuice-treesitter,voice --test json_rpc_e2e
-> 0 errors, no unused-helper warnings. Default build unchanged.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26ee61d665

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// ungated capability.
// ungated capability. Gated with `flows` — the whole tool (and the `rhai`
// engine behind it, via `tinyagents/repl`) is absent from a slim build.
#[cfg(feature = "flows")]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Gate the Rhai prompt when the tool is compiled out

When the new flows feature is disabled, this cfg removes rhai_workflows from the tool registry, but the always-registered orchestrator still includes the unconditional “Language workflows (Rhai)” section in src/openhuman/agent_registry/agents/orchestrator/prompt.md that tells the model to use the rhai_workflows tool. In slim builds (--no-default-features --features tokenjuice-treesitter), tasks requiring branching or fan-out can now be steered toward a tool that is not registered and will fail as an unavailable tool; render that prompt section only when the feature/tool is present.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(core): feature gate — flows/workflows

2 participants