Skip to content

feat(core): compile-time skills feature gate (#4798)#4913

Merged
M3gA-Mind merged 17 commits into
tinyhumansai:mainfrom
oxoxDev:feat/4798-skills-feature-gate
Jul 16, 2026
Merged

feat(core): compile-time skills feature gate (#4798)#4913
M3gA-Mind merged 17 commits into
tinyhumansai:mainfrom
oxoxDev:feat/4798-skills-feature-gate

Conversation

@oxoxDev

@oxoxDev oxoxDev commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a compile-time Cargo skills feature (default-ON) gating the openhuman::skills + skill_runtime + skill_registry domains, composing with the runtime DomainSet::skills 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. Slim builds opt out via cargo build --no-default-features --features "<gates without skills>".
  • skills is not a leaf — it is partly load-bearing infrastructure. tools/traits.rs re-exports the unified ToolResult/ToolContent out of skills::types, and 236 files depend on them. Gating the domain wholesale would take down the entire tool trait system.
  • Pattern: facade+stub ×3 plus a type carve-outskills::types and skills::ops_types stay unconditionally compiled; only behaviour is gated.
  • Sheds zero dependencies (skills = []). The value is LOC, RPC surface, tool-belt size and attack surface — not binary size.

Problem

#4795 wants one compile-time feature gate per subsystem family; #4796 shipped the runtime DomainSet axis. This PR adds the compile-time half for the skills family.

The blocking discovery: skills is not a self-contained leaf. The unified tool-result types (ToolResult / ToolContent) live in skills::types, and tools/traits.rs re-exports them as the canonical path. 236 files consume that path, and mcp_client and runtime_node import it directly. A naive #[cfg] over pub mod skills deletes those types and fails the build of every tool in the crate — the exact "toggling the gate must not break the core" constraint from the epic.

Second, the epic's ## Definition of Done carries two bullets that do not apply here:

Solution

  • Cargo.toml: skills = [] added to default — dep list intentionally empty, with a comment saying so, so nobody "fixes" it later.
  • Type carve-out (the headline). skills::types + skills::ops_types stay unconditionally compiled — they are inert serde types with no behavioural deps. Only the behaviour behind them is gated. The stub therefore mirrors functions only, never types, which is strictly less drift surface than mirroring both: a field added to ToolResult cannot desync across configs because there is exactly one definition.
  • Facade+stub ×3 (skills/, skill_runtime/, skill_registry/): pub mod stays always-compiled, real submodules go behind #[cfg(feature = "skills")], and each stub.rs re-exposes the always-on caller surface with disabled-error / empty bodies. Aggregator entry points return empty, so core/all.rs needs no call-site cfg.
  • One exception — get_workflow could not be stubbed. It returns a type that #[serde(flatten)]s and is destructured by its caller, so a stub return value cannot satisfy the caller's shape. The dispatch branch is gated instead (agent/task_dispatcher/executor.rs).
  • 16 skill agent tools dropped from the tool belt when off; skill built-in agents dropped from the registry.
  • App forwarding (app/src-tauri/Cargo.toml): openhuman_core is default-features = false, so skills is added explicitly to keep the domain in the shipped desktop app. Verified via cargo tree -e features -i openhuman.
  • CI: no change needed — the rust-feature-gate-smoke lane 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.
  • Docs (AGENTS.md): gate-table row + the generalizable lesson — put inert serde types in a dep-free submodule, leave it ungated, and stub only behaviour.

When off: the skills / skill_runtime / skill_registry namespaces are absent from /schema and their methods return a clean JSON-RPC unknown-method (-32000); the 16 skill tools are absent; the tool trait system still compiles and works.

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 — both-direction registration coverage in core/all_tests.rs, plus skills-dependent harness tests cfg'd for the disabled build.
  • N/A: no instrumented changed lines — the diff is compile-config only (#[cfg] attrs, a Cargo feature, stub facades, docs); 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 or removed; skills = [].
  • 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 skills on and the build is byte-identical.
  • Slim builds: drop 3 RPC namespaces + 16 agent tools + the skill built-in agents. The tool trait system is unaffected by design (type carve-out).
  • Performance / size: no binary-size win — zero deps shed. The win is tool-belt size, prompt bloat, startup cost and attack surface.
  • Security: slim builds lose remote skill-catalog fetch + SKILL.md execution — a meaningful attack-surface reduction for headless deployments.
  • 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/4798-skills-feature-gate
  • Commit SHA: cb274f28dba3b0f518366a6a81745bd784ebeb3e (11 commits, 17 files, +430/-8)

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; both-direction gate tests pass in their 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: all 3 namespaces present in /schema; probe openhuman.skills_list{"result":{"workflows":[]}}.
  • Gate OFF: all 3 namespaces absent; methods return a clean JSON-RPC unknown-method (-32000); the process survives — and the tool trait system still works with skills off, which is what proves the type carve-out.

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 skills compile-time gate. Default build unchanged.
  • User-visible effect: none by default. Slim builds omit 3 skill namespaces + 16 agent tools.

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, with stubs returning disabled-errors on the always-on caller surface. skills::types / ::ops_types have a single definition shared by both configs, so field drift between on/off is structurally impossible. Composes with, and does not replace, the runtime DomainSet::skills guard from feat(core): DomainSet on CoreBuilder + DomainRegistration filter seam (feature-gate prerequisite) #4796.

Duplicate / Superseded PR Handling

Summary by CodeRabbit

  • New Features
    • Added a compile-time Skills feature gate (enabled by default) and ensured embedded builds forward it consistently.
    • Skills runtime modules/controllers/tools are now exposed only when the gate is on.
  • Bug Fixes
    • When Skills is disabled, the system now falls back to safe empty/no-op behavior: Skills-related controllers/tools/agents are omitted and boot-time catalog refresh is skipped.
  • Tests
    • Updated and feature-gated Skills tests to assert correct namespace and tool presence/absence depending on the gate.

oxoxDev added 11 commits July 15, 2026 17:29
Declares the compile-time gate for the skills / skill_runtime /
skill_registry domains. Default-ON so the desktop build is unchanged;
slim builds opt out via --no-default-features.

The dep list is intentionally empty: unlike `voice` (hound/lettre),
these domains have no exclusive dependencies — every crate they touch is
shared with always-on domains, and runtime_node/runtime_python are used
by Agent/Flows/Memory too. The gate's value is tool-surface, prompt
bloat and startup cost, not binary size.
…e carve-out (tinyhumansai#4798)

Turns skills/mod.rs into an always-compiled facade: behavioural
submodules are #[cfg(feature = "skills")], with a stub taking their
place when the gate is off.

skills is NOT a leaf — it is partly load-bearing infrastructure.
tools/traits.rs re-exports the crate's unified ToolResult/ToolContent
out of skills::types and ~236 files consume them; mcp_client and
runtime_node import that path directly. So skills::types and
skills::ops_types stay compiled in BOTH directions (inert serde/std-only
definitions, zero coupling to gated siblings) and only behaviour is
gated. Gating them wholesale would take down the entire tool trait
system, MCP, and the Node runtime.

The stub therefore mirrors FUNCTIONS ONLY and re-exports the real types,
so there is zero type duplication — less drift surface than the voice
stub, which had to re-declare SttResult + SttProvider.
…ature (tinyhumansai#4798)

Same facade+stub shape as the skills domain — the three skill domains
ship as one unit under one gate.

The stub is deliberately tiny: every caller of the run machinery
(spawn_workflow_run_background, await_run_outcome, WorkflowRunStarted)
lives inside code gated by the same feature — the run_workflow agent
tool, the openhuman.skills_* handlers, and this domain's own tests — so
they vanish together. It owes only what always-on code reaches: the
controller aggregators (src/core/all.rs).
…feature (tinyhumansai#4798)

Same facade+stub shape. The stub mirrors only what always-on code
reaches: the boot catalog refresh kicked off unconditionally by
core::runtime::services, plus the controller aggregators. The catalog
store, wire types and skill_setup agent are only referenced from code
gated by the same feature.
…humansai#4798)

Concrete tool types in a Vec can't be stubbed away, so the registrations
are #[cfg]-gated: RunWorkflowTool/AwaitWorkflowTool, the Workflow*
metadata tools, the SkillRegistry* tools, and SkillRuntimeResolveRuntimes.
Per the DoD the tool list OMITS gated tools rather than degrading them to
a disabled-error.

agent/tools.rs gates `run_workflow` — it sits in the always-on agent
domain but is a pure skill_runtime client.

The three tools/mod.rs re-export globs are #[cfg]'d rather than backed by
empty stub `tools` modules, mirroring how the voice gate handles
audio_toolkit::tools::* — an empty stub module re-exports nothing and
trips unused_imports at the glob site.

skill_allowlist feeds only the gated registrations, so it is explicitly
discarded when the feature is off.
…ls` is off (tinyhumansai#4798)

Two sites the stub facade deliberately does not reach:

loader.rs — the skill_setup/skill_executor BuiltinAgent entries must be
#[cfg], not stubbed: include_str! embeds the agent TOML from disk
regardless of module gating, so the entry itself has to disappear.

task_dispatcher/executor.rs — the workflow-resolution branch.
registry::get_workflow returns Option<WorkflowDefinition>, which flattens
in AgentDefinition and is destructured at the call site; stubbing it would
mean re-declaring that struct, which is exactly the type duplication the
carve-out exists to avoid. With the domain compiled out no handle can ever
resolve to a skill, so falling through to the builtin-agent branch is the
correct behaviour, not a degradation.
…ai#4798)

Mirrors the voice pair: with the feature on all three skill namespaces
must be registered; with it off none may reach the registry (the
stub-facade correctness gate).

Also cfg's the pre-existing group_mapping_smoke assert for `skills` —
group_for_namespace is registry-derived, so a compile-time-gated domain
has no controller to map. CI cannot catch this class of break: the smoke
lane runs cargo check, which never compiles test code.
…ansai#4798)

openhuman_core is depended on with default-features = false, so the new
default-ON gate must be named explicitly or the desktop app would ship
without the skill domains. Multi-line array so sibling gates append
cleanly.
…tinyhumansai#4798)

Adds the gate-table row and a per-gate note covering the carve-out — the
generalizable rule for the remaining gates: put a domain's inert types in
a dep-free submodule and leave it ungated; stub only the behaviour. Also
records why the two #[cfg] call sites can't be stubbed, and why the dep
list is intentionally empty.

ci-lite: no functional change. The smoke lane is an allow-list
(--no-default-features --features tokenjuice-treesitter), so every new
default-ON gate is exercised in its disabled direction automatically.
Renames the step off "voice gate" since it now covers all of them.
tinyhumansai#4798)

Three tests hard-assert skills-domain behaviour and break only under
--no-default-features, which CI never test-runs (the smoke lane is
cargo check, which does not compile test code):

- definition_tests: the effective-max-iterations table panics with
  "missing built-in agent definition: skill_executor" once the
  skill_setup/skill_executor BuiltinAgent entries are gated out.
- session::tests refresh_workflows_{picks_up,retracts}_skill_*: both
  exercise real SKILL.md discovery from disk, which the disabled facade
  answers with an empty catalog by design.

Found by sweeping the full disabled --lib suite rather than the scoped
core::all filter; the mcp_agent/mcp_setup rows in the same table belong
to tinyhumansai#4799 and are left untouched.
…t line (tinyhumansai#4798)

No functional change either way: the smoke lane's
`--no-default-features --features tokenjuice-treesitter` is an explicit
ALLOW-LIST, so the new default-ON `skills` gate is already exercised in
its disabled direction with no workflow edit at all.

tinyhumansai#4797 renamed the same step first and logged it in the coordination
Conflict Log; dropping our identical-intent rename leaves a
conflict-free merge. The allow-list rationale is documented durably in
AGENTS.md instead.
@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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 83c35ed6-5919-46d4-b003-b81722e18ada

📥 Commits

Reviewing files that changed from the base of the PR and between aec00af and ab948de.

📒 Files selected for processing (5)
  • AGENTS.md
  • Cargo.toml
  • app/src-tauri/Cargo.toml
  • src/core/all_tests.rs
  • src/openhuman/agent/harness/session/tests.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • app/src-tauri/Cargo.toml
  • src/openhuman/agent/harness/session/tests.rs
  • Cargo.toml
  • src/core/all_tests.rs
  • AGENTS.md

📝 Walkthrough

Walkthrough

The PR adds a default-enabled skills Cargo feature, gates skill behavior and integrations, supplies disabled-mode facades, forwards the feature to the Tauri app, and updates tests for enabled and disabled builds.

Changes

Skills feature gate

Layer / File(s) Summary
Feature contract and build wiring
AGENTS.md, Cargo.toml, app/src-tauri/Cargo.toml
Documents the skills gate, adds it to default features, and enables it for the Tauri dependency.
Disabled skills facades
src/openhuman/skills/..., src/openhuman/skill_runtime/..., src/openhuman/skill_registry/...
Compiles operational modules only when enabled and provides empty or no-op stubs when disabled.
Conditional agents and tools
src/openhuman/agent/..., src/openhuman/agent_registry/..., src/openhuman/tools/...
Gates workflow resolution, built-in skill agents, workflow exports, and skill-related tool registrations.
Feature-aware validation
src/core/all_tests.rs, src/openhuman/agent/harness/...
Adjusts controller, agent, group mapping, and disk-refresh tests for feature-dependent behavior.

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

Possibly related issues

Possibly related PRs

Suggested labels: feature, rust-core

Suggested reviewers: m3ga-mind

Poem

A rabbit hops through Cargo’s gate,
Skills bloom early, or wait in state.
Empty stubs keep callers sound,
Workflow tools vanish underground.
Tests now know which paths to trace.

🚥 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 is concise and accurately summarizes the main change: adding a compile-time skills feature gate.
Linked Issues check ✅ Passed The changes implement the default-enabled skills gate, forward it to Tauri, hide gated schemas/tools/agents when disabled, and add tests/docs.
Out of Scope Changes check ✅ Passed The diff stays focused on skills gating, related stubs, feature forwarding, tests, and docs, with no clearly 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 agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. 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: cb274f28db

ℹ️ 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/openhuman/agent_registry/agents/loader.rs
Comment thread src/openhuman/agent_registry/agents/loader.rs

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

🧹 Nitpick comments (2)
src/openhuman/agent/harness/session/tests.rs (1)

488-492: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the disabled refresh contract explicitly.

These gates remove both tests from --no-default-features builds. Add a #[cfg(not(feature = "skills"))] regression test (or equivalent) asserting that on-disk SKILL.md files are not discovered and refresh/retraction state remains empty. The supplied src/openhuman/skills/stub.rs:50-80 contract should be tested, not only compiled out.

As per coding guidelines, tests are required for new behavior; untested code is incomplete.

Also applies to: 558-561

🤖 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/session/tests.rs` around lines 488 - 492, Add a
complementary #[cfg(not(feature = "skills"))] regression test alongside the
existing skill discovery tests, exercising the disabled facade’s
load_workflow_metadata/refresh path with an on-disk SKILL.md fixture. Assert
that no skills are discovered and refresh/retraction state remains empty,
covering the contract implemented by the skills stub rather than compiling the
test out.

Source: Coding guidelines

src/openhuman/tools/ops.rs (1)

228-231: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a feature-state diagnostic for the gated skill-tool registry.

When skills is disabled, these registrations silently disappear; when enabled, there is no stable signal describing the resulting tool surface. Add one tracing::debug! summary per build mode (or an equivalent count) around these blocks so boot diagnostics can explain the registry contents.

As per coding guidelines, **/*.rs requires diagnostic logging for new or changed flows, including branches and state transitions.

Also applies to: 474-514

🤖 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 228 - 231, Add a single
tracing::debug! diagnostic around the skill-gated tool registration in the
registry-building flow, covering both the enabled and disabled cfg(feature =
"skills") build modes. Report the resulting skill-tool registration state or
count, and preserve the existing RunWorkflowTool and AwaitWorkflowTool
registrations 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.

Inline comments:
In `@AGENTS.md`:
- Around line 236-239: Update the slim-build example referenced by the voice
facade documentation so its description matches the enabled features: either add
skills to the --no-default-features feature list or revise the “everything
except voice” wording to acknowledge that skills are also disabled. Keep the
voice stub guidance consistent with the resulting build command.

In `@app/src-tauri/Cargo.toml`:
- Around line 135-137: Update the openhuman_core dependency feature list in
Cargo.toml to also enable the core crate’s tokenjuice-treesitter and voice
features alongside skills, so the Tauri build matches the intended default
feature set.

In `@src/openhuman/skill_runtime/mod.rs`:
- Around line 8-16: Update the module-level documentation near the compile-time
gate description to remove the cfg-sensitive rustdoc link to stub, replacing it
with plain code formatting or feature-specific documentation while preserving
the existing explanation.

In `@src/openhuman/skills/mod.rs`:
- Around line 5-11: Update the module-level documentation in the skills facade
to remove the claim that the disabled stub exposes skills::tools, while
preserving the accurate list of other always-available exports and the
no-op/empty behavior description.

In `@src/openhuman/skills/stub.rs`:
- Around line 61-68: In src/openhuman/skills/stub.rs lines 61-68, add stable
debug logs to both all_skills_registered_controllers and
all_skills_controller_schemas before returning empty results; in
src/openhuman/skills/stub.rs lines 94-96, log the cleanup subscriber no-op; and
in src/openhuman/skill_registry/stub.rs lines 18-28, add corresponding debug
logs to both empty controller/schema aggregators. Keep the existing no-op return
behavior unchanged.

---

Nitpick comments:
In `@src/openhuman/agent/harness/session/tests.rs`:
- Around line 488-492: Add a complementary #[cfg(not(feature = "skills"))]
regression test alongside the existing skill discovery tests, exercising the
disabled facade’s load_workflow_metadata/refresh path with an on-disk SKILL.md
fixture. Assert that no skills are discovered and refresh/retraction state
remains empty, covering the contract implemented by the skills stub rather than
compiling the test out.

In `@src/openhuman/tools/ops.rs`:
- Around line 228-231: Add a single tracing::debug! diagnostic around the
skill-gated tool registration in the registry-building flow, covering both the
enabled and disabled cfg(feature = "skills") build modes. Report the resulting
skill-tool registration state or count, and preserve the existing
RunWorkflowTool and AwaitWorkflowTool registrations unchanged.
🪄 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: 0cb23710-9830-45af-ac4b-26efb7fb1f00

📥 Commits

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

📒 Files selected for processing (17)
  • AGENTS.md
  • Cargo.toml
  • app/src-tauri/Cargo.toml
  • src/core/all_tests.rs
  • src/openhuman/agent/harness/definition_tests.rs
  • src/openhuman/agent/harness/session/tests.rs
  • src/openhuman/agent/task_dispatcher/executor.rs
  • src/openhuman/agent/tools.rs
  • src/openhuman/agent_registry/agents/loader.rs
  • src/openhuman/skill_registry/mod.rs
  • src/openhuman/skill_registry/stub.rs
  • src/openhuman/skill_runtime/mod.rs
  • src/openhuman/skill_runtime/stub.rs
  • src/openhuman/skills/mod.rs
  • src/openhuman/skills/stub.rs
  • src/openhuman/tools/mod.rs
  • src/openhuman/tools/ops.rs

Comment thread AGENTS.md
Comment thread app/src-tauri/Cargo.toml
Comment thread src/openhuman/skill_runtime/mod.rs
Comment thread src/openhuman/skills/mod.rs Outdated
Comment thread src/openhuman/skills/stub.rs
oxoxDev and others added 2 commits July 15, 2026 20:24

@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: 85f6db6dc2

ℹ️ 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".

Comment thread src/openhuman/tools/ops.rs
…ature-gate

# Conflicts:
#	Cargo.toml
#	app/src-tauri/Cargo.toml
#	src/core/all_tests.rs
@coderabbitai coderabbitai Bot removed the agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. label Jul 16, 2026
The skills disabled-facade stub deliberately has no `tools` module (the
`skills::tools` glob is `#[cfg(feature = "skills")]` at its re-export site
in `tools/mod.rs`, mirroring the voice gate). The module doc listed `tools`
as part of the stub surface, which was inaccurate. Addresses CodeRabbit review.
@M3gA-Mind

Copy link
Copy Markdown
Collaborator

Maintainer review changes + CodeRabbit disposition.

Change pushed (aec00afe7, one commit on the PR head — no merge noise):

  • src/openhuman/skills/mod.rs — corrected the facade module doc. It listed tools as part of the disabled-stub surface, but the stub deliberately has no tools module: the skills::tools glob is #[cfg(feature = "skills")] at its re-export site in tools/mod.rs, mirroring the voice gate. Doc now says so. Doc-only; zero behaviour change.

CodeRabbit comments — disposition:

Fixed

  • skills/mod.rs stub surface lists tools → fixed as above (the stub does not re-export tools).

Declined, with reason

  • skill_runtime/mod.rs & skills/mod.rs: [stub] intra-doc link is cfg-sensitive — Declined for consistency: the already-merged voice pathfinder (src/openhuman/voice/mod.rs:17) uses the identical [stub] link, and this PR follows that established convention verbatim. All CI (incl. Rust Quality / rustdoc, Markdown Link Check) is green in both directions. If this is worth changing it is a cross-gate cleanup, not scoped to feat(core): feature gate — skills #4798.
  • skills/stub.rs & skill_registry/stub.rs: add debug logs to the empty controller/schema aggregators — Declined for consistency: the merged web3 stub's empty aggregators (src/openhuman/wallet/stub.rs:260-266, all_wallet_registered_controllers / all_wallet_controller_schemas) return Vec::new() with no logging. The skills stubs match that precedent exactly; the behaviour-bearing stub fns here (load_workflow_metadata, init_workflows_dir, catalog refresh, subscribers) already log. Adding logs only to the pure-empty aggregators would be inconsistent with the sibling gates.
  • tools/ops.rs 228-231 / 474-514: add a tracing::debug! summary of the gated skill-tool registry — Declined: the sibling voice/web3/media gates add no per-registration diagnostic at their tools/ops.rs #[cfg] sites, and the tool surface is already observable via the tool-list. Adding it only for skills is inconsistent and low-value; out of scope for this gate.
  • session/tests.rs: add a #[cfg(not(feature = "skills"))] disabled-facade regression test — Declined as already-covered: the disabled facade's correctness is asserted by the new skill_controllers_absent_when_feature_off test in src/core/all_tests.rs (namespaces absent from /schema when the feature is off). Note the gates-off CI lane (Rust Feature-Gate Smoke) runs cargo check, not cargo test, so a #[cfg(not(feature="skills"))] test would compile but never execute in CI — limited added value over the existing on/off directional coverage.
  • app/src-tauri/Cargo.toml: also forward voice + tokenjuice-treesitter — Declined (partly stale, partly out of scope): voice is already forwarded (app/src-tauri/Cargo.toml:160), alongside media/web3/skills. tokenjuice-treesitter being un-forwarded is a pre-existing gap explicitly documented in the manifest comment (line 156) and called out in this PR's ## Related as tracked epic-level — deliberately not in scope for the skills gate.
  • AGENTS.md ~236: update the voice slim-build example — Declined: that is unchanged pre-existing text in the voice facade section, and --no-default-features --features tokenjuice-treesitter is the canonical all-gates-off disabled build (the intended drift-catcher example). This PR does not alter the voice surface.

@M3gA-Mind

Copy link
Copy Markdown
Collaborator

Maintainer sync: merged current main (includes #4949, commit 74091df4c, the fix for the red-main typecheck failure tracked in #4948 — the two ToolTimelineEntry test fixtures in Conversations.render.test.tsx were missing the seq property that #4945 introduced). The "Frontend Checks (quality, i18n, docs, coverage)" failure on this PR was inherited from main, not caused by this PR's Rust skills-feature-gate changes. The merge was clean — no conflicts to resolve. Verified both fixture lines now carry seq: 0 on upstream/main.

@M3gA-Mind

Copy link
Copy Markdown
Collaborator

@coderabbitai review

The head has moved on since the standing review: every actionable comment has been addressed (fixed, or declined in-thread with reasoning), and the branch has since been re-synced onto current main — which now includes #4949, the fix for the red-main typecheck failure tracked in #4948. Requesting a re-review of the current head so the stale CHANGES_REQUESTED state reflects the actual tree.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@M3gA-Mind Understood — kicking off a fresh review of the current head to reflect the doc fix and the sync onto main (with #4949 included).

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 16, 2026
@M3gA-Mind

Copy link
Copy Markdown
Collaborator

Maintainer conflict resolution: merged current main (now includes #4915, the meet gate #4800) into this branch. All conflicts were the expected mechanical drift from two sibling gates in the #4797#4800 series editing the same shared registration sites — resolved by union (both gates kept), file by file:

  • Cargo.toml — two hunks. (1) default = [...] list: kept both new gates → ["tokenjuice-treesitter", "voice", "web3", "media", "meet", "skills"]. (2) [features] block: kept both the meet = [] comment block (from main) and the skills = [] comment block (this PR); no dep lines dropped, both feature stanzas intact.
  • app/src-tauri/Cargo.toml — the forwarded openhuman_core feature list conflicted only on skills-vs-meet; resolved to include both → media, voice, tokenjuice-treesitter, web3, meet, skills. (Note: tokenjuice-treesitter was already added to this list by main and auto-merged cleanly; the comment above it still says it's "un-forwarded / tracked in AST-aware code compression silently disabled in desktop builds (tokenjuice-treesitter dropped) #4918" — that stale comment is inherited from main, not introduced here, so left untouched for AST-aware code compression silently disabled in desktop builds (tokenjuice-treesitter dropped) #4918.)
  • AGENTS.md (CLAUDE.md is a symlink to it) — two hunks: the gate table gained both a meet row and a skills row; the gate-description section kept both the full meet gate write-up and the skills type-carve-out write-up. Ordered meet-then-skills to match the table + Cargo list.

No blanket --ours/--theirs; each hunk read and merged by hand.

Semantic check (a textually clean merge can still be broken): The two gates target disjoint domains (skills/skill_runtime/skill_registry vs meet/meet_agent/agent_meetings). Verified: (a) the auto-merged src/core/all.rs retains both registration designs — skills via facade (all_skills_registered_controllers() stubs to empty, no call-site cfg) and meet via call-site #[cfg(feature = "meet")]; (b) src/openhuman/mod.rs keeps both gatings; (c) no cross-references between the two domains' always-compiled surfaces (meet_agent::wav / agent_meetings stub ↔ skills mod/stub/types/ops_types) — so the gates-off build (--no-default-features), which now compiles both stubs together for the first time, has no shared-symbol trap (the #4914 failure mode does not apply here). The feature-gate smoke lane (both gates off) will confirm on CI.

@M3gA-Mind M3gA-Mind left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving — both conditions genuinely met.

CI: fully green. 13 pass, 5 skipped by changed-area detection (correct for a Rust-only change), zero pending, zero failing. The lanes that matter here all pass: Rust Quality (fmt, clippy), Rust Feature-Gate Smoke (gates off) — the only lane that ever compiles stub.rs files and therefore the sole guard against stub drift — plus Rust Core Coverage, Rust Tauri Coverage, and PR CI Gate.

Review state: no CHANGES_REQUESTED. CodeRabbit's earlier block was stale (raised ~18h and several commits before the current head); it has since re-reviewed and approved.

Verified beyond CI:

  • The skills gate follows the established voice/web3 facade+stub pattern; default build is byte-identical.
  • One real doc defect was found and fixed (aec00afe7): the facade module doc claimed tools was part of the disabled-stub surface, but the stub deliberately has no tools module (the glob is #[cfg(feature="skills")] at its re-export site, mirroring voice). Wording corrected — zero behaviour change.
  • The six declined CodeRabbit items were each grounded in the already-merged voice/web3 pathfinder gates or explicit out-of-scope, and answered in-thread rather than silently dropped.
  • Re-synced onto current main (includes #4915's meet gate); the resulting conflicts were resolved to the union — both gates' rows, feature lines, and registration entries retained.

Not merging — that is the maintainer's call.

@M3gA-Mind M3gA-Mind merged commit 8674c22 into tinyhumansai:main Jul 16, 2026
22 checks passed
M3gA-Mind added a commit to oxoxDev/openhuman that referenced this pull request Jul 16, 2026
…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.
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 — skills

4 participants