feat(core): compile-time flows feature gate (#4797)#4912
Conversation
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.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 27 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
📝 WalkthroughWalkthroughThis change adds a compile-time ChangesFlows feature gate
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related issues
Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
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 winAlign runtime flow filtering with every gated tool.
When
flowsis compiled in butDomainSet::flowsis disabled,tool_grouponly recognizes a subset of these tools. Names such asedit_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, andrhai_workflowsfall through toDomainGroup::Platformand remain callable.Add every flow-owned tool to the
FLOWSclassification 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 winCI 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_offinsrc/core/all_tests.rs,default_tools_omits_flows_tools_when_feature_offinsrc/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 onlycargo 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 winLog the intentionally skipped reconciliation in slim builds.
When
flowsis disabled, this#[cfg]removes the reconciliation call without emitting any boot diagnostic. Add a stable[flows]debug message, consistent with the subscriber path insrc/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
📒 Files selected for processing (16)
.github/workflows/ci-lite.ymlAGENTS.mdCargo.tomlapp/src-tauri/Cargo.tomlsrc/core/all.rssrc/core/all_tests.rssrc/core/jsonrpc.rssrc/core/jsonrpc_tests.rssrc/core/runtime/services.rssrc/openhuman/agent/harness/builtin_definitions.rssrc/openhuman/agent/harness/definition_tests.rssrc/openhuman/agent_registry/agents/loader.rssrc/openhuman/mod.rssrc/openhuman/tools/mod.rssrc/openhuman/tools/ops.rssrc/openhuman/tools/ops_tests.rs
…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.
There was a problem hiding this comment.
💡 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".
…ture-gate # Conflicts: # Cargo.toml # app/src-tauri/Cargo.toml
The runtime DomainSet post-filter (tinyhumansai#4796) uses tool_group() to drop tools whose DomainGroup is disabled. The FLOWS classification list was missing 12 flow-owned tools (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), so with the flows feature compiled in but DomainSet::flows disabled at runtime they fell through to Platform and stayed callable — leaking the flows surface past the runtime gate. List every flow-owned tool explicitly (now the same 26 names as the compile-time #[cfg(feature = "flows")] registrations and default_tools_omits_flows_tools_when_feature_off) and add a regression loop to tool_group_classifies_gate_and_harness_families.
|
Maintainer review changes (1 commit pushed,
Addresses the CodeRabbit "Align runtime flow filtering with every gated tool" comment. Replies to the other two CodeRabbit comments below. |
|
@coderabbitai Declining the Critical inline comment on
Two independent proofs:
Same reasoning covers the sibling occurrences in |
|
@coderabbitai Re: the
Tracking this as a follow-up: add a disabled-feature test lane (covering all gates, correct filter) to |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🤖 web_search executed:
Length of output: 13248 This confirms the maintainer's technical claim: rust-lang/rust#32796 explicitly documents
Combined with your CI-green evidence and the standalone (=^・ω・^=) ノ” confirmed and noted for next time ✏️ Learnings added
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
AGENTS.md (1)
251-251: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRun the disabled-feature tools test in the documented check.
The
core::filter excludesdefault_tools_omits_flows_tools_when_feature_offinsrc/openhuman/tools/ops_tests.rs. Add an explicit invocation for that test, or remove the filter so the documented disabled-build validation actually covers flow tool omission.Proposed change
Run `GGML_NATIVE=OFF cargo test --lib --no-default-features --features tokenjuice-treesitter core::` locally before pushing any gate change. +Also run `GGML_NATIVE=OFF cargo test --lib --no-default-features --features tokenjuice-treesitter default_tools_omits_flows_tools_when_feature_off`.🤖 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 `@AGENTS.md` at line 251, Update the documented disabled-build validation command to execute default_tools_omits_flows_tools_when_feature_off in src/openhuman/tools/ops_tests.rs, either by adding an explicit invocation alongside the existing core:: check or by removing the restrictive filter. Keep the command’s other feature and environment settings unchanged.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.
Outside diff comments:
In `@AGENTS.md`:
- Line 251: Update the documented disabled-build validation command to execute
default_tools_omits_flows_tools_when_feature_off in
src/openhuman/tools/ops_tests.rs, either by adding an explicit invocation
alongside the existing core:: check or by removing the restrictive filter. Keep
the command’s other feature and environment settings unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 31a221c9-261b-402b-a40e-82d15923ad68
📒 Files selected for processing (10)
.github/workflows/ci-lite.ymlAGENTS.mdCargo.tomlapp/src-tauri/Cargo.tomlsrc/core/all_tests.rssrc/core/jsonrpc_tests.rssrc/openhuman/agent_registry/agents/loader.rssrc/openhuman/tools/mod.rssrc/openhuman/tools/ops.rssrc/openhuman/tools/ops_tests.rs
🚧 Files skipped from review as they are similar to previous changes (7)
- .github/workflows/ci-lite.yml
- app/src-tauri/Cargo.toml
- src/core/jsonrpc_tests.rs
- Cargo.toml
- src/openhuman/agent_registry/agents/loader.rs
- src/core/all_tests.rs
- src/openhuman/tools/mod.rs
|
Not blocking this PR on it. Would you like me to open a follow-up GitHub issue to track adding the disabled-feature test lane to ✅ Action performedComments resolved and changes approved. |
|
Maintainer sync: merged current main (includes #4949, the fix for the red-main typecheck failure tracked in #4948 — the two |
# Conflicts: # AGENTS.md # Cargo.toml # app/src-tauri/Cargo.toml # src/core/all_tests.rs
|
Maintainer conflict resolution: merged current main (now includes #4915, the meet gate #4800). All conflicts were the expected mechanical drift between sibling feature-gate PRs in the #4797–#4800 series — each gate edits the same shared registration sites — and every one resolved to the union of both gates.
Auto-merged cleanly (no conflict): Semantic check: the two gates are independent domains and share no symbols. The |
…conflicts Both sibling gates append their feature to the default set and add docs; kept both: default now includes skills (from tinyhumansai#4913, merged) and flows (this PR). AGENTS.md feature table + gate-pattern docs keep both the skills and flows sections.
|
Maintainer sync: merged current main to resolve conflicts introduced when sibling gate #4913 ( Conflicts resolved (kept both sides — the two gates are additive, not competing):
All Rust registration sites ( |
M3gA-Mind
left a comment
There was a problem hiding this comment.
Approving — both conditions genuinely met, on the re-synced head.
CI: fully green — 19/19 lanes pass, zero pending, zero failing. Includes Rust Quality (fmt, clippy), Rust Feature-Gate Smoke (gates off), Rust Core Coverage, Rust Tauri Coverage, Frontend Checks, Test Inventory, and PR CI Gate.
Review state: no CHANGES_REQUESTED; CodeRabbit's earlier block is cleared.
Verified beyond CI:
- A real defect was found and fixed here, not just a rubber stamp. CodeRabbit's "align runtime flow filtering with every gated tool" was correct: the runtime
FLOWSlist was incomplete, so ~26 flow tools (list_flow_runs,resume_flow_run,create_workflow,rhai_workflows, …) fell through toDomainGroup::Platformand stayed callable underDomainSet { platform: true, flows: false }— leaking the surface past the runtime gate. Each name was verified against the tools' actualfn name(), andops_tests.rsnow loops over all 26 as a regression guard rather than spot-checking two. - CodeRabbit's "
#[cfg]in a slice literal won't compile on stable" (raised as Critical) was correctly declined as a false positive, with proof:#[cfg]is cfg-stripped before thestmt_expr_attributesgate, so it is stable on array/slice-literal elements — demonstrated both by the already-green Rust lanes compiling these files and by standalonerustc 1.97.0(the pinned toolchain). - The "CI doesn't run the disabled-feature test suite" item was deferred with reason to a dedicated infra PR — it is a cross-cutting lane change affecting every gate, and the suggested
core::filter would not even run the newops_teststest. - Re-synced onto current
main(now includes #4913's skills gate and #4915's meet gate); conflicts resolved to the union — every gate's rows, feature lines, and registration entries retained.
Leaf-gate design is right: registration sites want absence, not a stub that registers a controller returning "flows disabled" — that would make flows.* a known method failing at runtime, the opposite of the intended unknown-method behaviour.
Not merging — that is the maintainer's call.
|
@coderabbitai review |
|
@coderabbitai full review Requesting a full re-review of the current head ( What has changed since your last look:
All 19 CI lanes are green on this head, including |
…ate conflicts tinyhumansai#4912 (flows) merged into main since the last sync, re-introducing sibling drift. Kept all gates (additive, not competing): - Cargo.toml [features].default: [..., "meet", "skills", "flows", "mcp"] - AGENTS.md: kept skills + flows + mcp feature-table rows and the flows leaf-gate doc block alongside this PR's mcp gate section - src/core/all_tests.rs: kept BOTH the mcp directional-gate tests (registered/absent) and main's flows directional-gate tests (registered/absent) — the conflict fused their shared trailing braces - app/src-tauri/Cargo.toml auto-merged: forwards all 8 gates incl. flows + mcp
… feature The tinyhumansai#4912 flows gate (merged after this branch was cut) put `openhuman::tinyflows` behind `#[cfg(feature = "flows")]`, so the gates-off build could not compile contract_gate.rs's unconditional `tinyflows::caps` import (E0433 in the "Rust Feature-Gate Smoke (gates off)" lane). The contract gate's live-catalog lookup is sourced entirely from the flows/tinyflows caps layer. With flows compiled out there is no catalog source, so the gate simply has no fuller contract to surface and always proceeds (the per-action Composio tool still runs; it just loses the pre-execute contract nudge). Guard the import and the lookup/format helpers on `feature = "flows"` in lockstep, restructure `consult` to Proceed when the feature is off, and gate the flows-seeding unit tests (contract_gate_tests.rs + the action_tool retry test) on the same feature. No behavior change in the default (flows-on) build.
…humansai#4912) Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai> Co-authored-by: M3gA-Mind <elvin@tinyhumans.ai>
Summary
flowsfeature (default-ON) gating theopenhuman::flows+tinyflows+rhai_workflowsdomains, composing with the runtimeDomainSet::flowsflag from feat(core): DomainSet on CoreBuilder + DomainRegistration filter seam (feature-gate prerequisite) #4796.cargo build --no-default-features --features "<gates without flows>".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.flows/,tinyflows/, orrhai_workflows/changed.RhaiToolgated; 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
DomainSetaxis. 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:
rhaiis not a direct dependency of this crate — it arrives transitively viatinyagents/repl. So the gate must beflows = ["dep:tinyflows", "tinyagents/repl"], and the directtinyagentsdep dropsrepl. Thetinyagentscrate itself cannot be shed: 26+ domains consume it.RhaiTool, not 14. The issue's 14 counted names in a const table, not registrations.Solution
Cargo.toml:flows = ["dep:tinyflows", "tinyagents/repl"]added todefault;tinyflowsmadeoptional; the directtinyagentsdep no longer enablesrepl.#[cfg(feature = "flows")]sits on the module declarations and on each registration site — controller, subscriber, boot reconcile, agent tools, and theworkflow_builder/flow_discoverybuilt-ins. Nostub.rsanywhere, 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.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/src-tauri/Cargo.toml): theopenhuman_coredep isdefault-features = false, soflowsis added explicitly to keep the domain in the shipped desktop app. Verified withcargo tree -e features -i openhuman.rust-feature-gate-smokelane inci-lite.ymlis 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
flowsRPC namespace is absent from/schemaand its methods return a clean JSON-RPC unknown-method (-32000); the 25 flow tools +RhaiToolare absent from the tool belt;tinyflows+jaq-*+rhaileave the build.Submission Checklist
#[cfg]attrs, a Cargo feature, a doc block);diff-coverreports no coverable lines. The directional gate tests cover the on/off behaviour. — Diff coverage ≥ 80%## Relatedtinyflowsis an existing dep madeoptional.docs/RELEASE-MANUAL-SMOKE.md)Closes #NNNin the## RelatedsectionImpact
flowson and the build is byte-identical.RhaiTool, and 5 crates (tinyflows,jaq-core,jaq-std,jaq-json,rhai). This is the epic's only real binary-size win so far.rhaiscript engine is gone entirely rather than merely unreachable.Related
DomainSetseam; follows the feat(core): feature gate — voice #4803 voice pathfinder and the feat(core): feature gate — media generation #4804 media leaf gate (PR feat(core): compile-time media feature gate (media_generation + image) (#4804) #4840). Sibling gates: feat(core): feature gate — skills #4798 (skills), feat(core): feature gate — MCP #4799 (mcp), feat(core): feature gate — meet #4800 (meet), feat(core): feature gate — web3 #4802 (web3, PR feat(web3): compile-time web3 feature gate for wallet/web3/x402 (#4802) #4855).voiceandtokenjuice-treesitterare currently not forwarded inapp/src-tauri/Cargo.toml(whoseopenhuman_coredep isdefault-features = false), so those two domains are missing from the shipped desktop app today. Pre-existing regression, out of scope here — being fixed epic-level.AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
feat/4797-flows-feature-gateb25121bb3d3d59d7c6e37107da9861a87c7fce82(8 commits, 16 files, +204/-10)Validation Run
pnpm --filter openhuman-app format:checkpnpm typecheckcargo fmtclean · enabledcargo check0 errors · disabledcargo check --no-default-features --features tokenjuice-treesitter0 errors · clippy clean in both directions.app/src-tauri/Cargo.toml(one dep line), no Tauri Rust source touched — forwarding verified viacargo 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:flowsnamespace present in/schema; probeopenhuman.flows_list→{"result":{"logs":["flows listed"],"result":[]}}./schema; the method returns a clean JSON-RPC unknown-method (-32000); the process survives.Validation Blocked
command:cargo test --no-default-featureserror:2 pre-existing failures onmaintoday —group_mapping_smokeandharness_excludes_gated_namespaces, both asserting thevoicenamespace uncfg'd (fallout from the merged voice gate feat(core): feature gate — voice #4803). CI cannot see them: the feature-gate smoke lane runscargo 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-directioncargo checkare green.Behavior Changes
flowscompile-time gate. Default build unchanged.RhaiTool, and 5 crates.Parity Contract
/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 runtimeDomainSet::flowsguard from feat(core): DomainSet on CoreBuilder + DomainRegistration filter seam (feature-gate prerequisite) #4796.Duplicate / Superseded PR Handling
Summary by CodeRabbit
flowsoption (now included in default builds) to enable workflow/flow capabilities and related tooling.flowsis disabled, improving slim build behavior.flowsnamespaces/endpoints and tool/agent sets appear only when enabled.flowsfeature gate matrix and clarified CI’scargo check-only limitation for disabled-feature behavior.