Skip to content

perf(core): emit Config::clone once, box cross-crate async entry points, ICF on Linux release - #7050

Merged
senamakel merged 14 commits into
tinyhumansai:mainfrom
senamakel:build-size-audit
Oct 7, 2026
Merged

senamakel merged 14 commits into
tinyhumansai:mainfrom
senamakel:build-size-audit

Conversation

@senamakel

@senamakel senamakel commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Hand-written Clone for Config marked #[inline(never)]. #[derive(Clone)] marks clone #[inline], so the ~48 KiB function was emitted 18 times in a release openhuman-core; it is now emitted once. Every field is listed in a struct literal, so a new Config field that is missing here is a compile error.
  • active_workspace_snapshot, start_chat and agent_chat_for now return a boxed future from an #[inline(never)] fn. Other crates (openhuman-rpc, openhuman-embed) await them, and an async fn body was being re-instantiated inside each calling crate. Call sites are unchanged (.await still works).
  • CoreContext::with_current_embedder_config(|c| …) reads the embedder config without cloning it. Three read-only callers used to clone a whole Config for one field or an is_some() check: active_workspace_snapshot, ambient_config_has_api_key and is_embedder_host.
  • Linux desktop release builds link with mold plus --icf=safe (fold byte-identical functions). MSVC already does this by default (/OPT:ICF) and Apple's ld deduplicates; GNU ld cannot.
  • AGENTS.md said release builds use one codegen unit; they use 16 (see 6941b18).

Problem

A build-size audit (cold release build, product features, cargo bloat) found that the shipped binary's size is dominated by first-party code, not dependencies. A large share of it is the same function emitted many times: #[inline] derives copied into each of the 16 codegen units, and async bodies re-instantiated in every crate that awaits them.

Solution / measurements

Release openhuman-core, product features, Linux x86_64, base ba1e9e6b4e vs this branch before the upstream merge:

base this PR this PR + --icf=safe
.text 75.47 MiB 73.39 MiB n/a
stripped binary 102.28 MiB 99.87 MiB 97.60 MiB
gzip 40.58 MiB 39.65 MiB n/a

Per function (cargo bloat):

  • <Config as Clone>::clone: 18 copies, 783 KiB → 1 copy.
  • active_workspace_snapshot: 66 KiB → 10 KiB.
  • start_chat: 142 KiB → 49 KiB.

--icf=all would save a little more (96.47 MiB), but it can fold functions whose addresses are compared, so this PR uses safe. Both the all and safe binaries started serve and answered /health and openhuman.config_get in a smoke test.

Submission Checklist

  • Tests added or updated: config_clone_tests.rs (field-for-field equality via serialization, plus independence of the clone) and the_current_embedder_config_can_be_read_without_cloning_it (scoped config and the no-config case).
  • Diff coverage ≥ 80%: new lines are covered by the tests above and existing callers; CI will confirm.
  • Coverage matrix: N/A, no feature rows change (behaviour-only refactor).
  • Feature IDs: N/A.
  • No new external network dependencies.
  • Manual smoke checklist: N/A. The release workflow change only affects how the Linux binary is linked.
  • Linked issue: N/A.

Impact

  • Runtime: no behaviour change. Boxing adds one heap allocation per call on three entry points that already do I/O.
  • Linux release builds: mold is installed in the build-desktop job (apt). The per-target rustflags env vars reach only the --target build, not build scripts.
  • Sentry symbolication: with ICF, folded identical functions share one address, so a crash frame inside a folded function may be reported under a sibling function's name. The code at that address is byte-identical, so line info stays meaningful. Revert the two env lines if this turns out to be a problem.

Related


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

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: build-size-audit
  • Commit SHA: cbcd899

Validation Run

  • pnpm --filter openhuman-app format:check: N/A, no frontend changes.
  • pnpm typecheck: N/A.
  • Focused tests: cargo test -p openhuman --lib with product features gave 8374 passed, 2 failed. The two failures (backend_dispatch_forwards_the_workflow_connection_id and persisted_mixed_case_cloud_default_uses_configured_slug_after_restart) pass when run alone, on this branch and on the base, so they are parallel-test races on shared global state.
  • Rust fmt/check: rustfmt on the changed files; cargo clippy -p openhuman --tests with product features is clean.
  • Tauri fmt/check: before the merge, openhuman-cli (which pulls in rpc, embed and tinyhumans) built in release. After merging upstream, openhuman-embed fails to compile on upstream main itself (previous_session_store, from da166ad / Host-injected session store: per-agent conversations outside the workspace #7044); this PR touches no embed files.
  • pnpm rust:layout fails on agent/session_host/builder/factory.rs (1003 > 1001 lines). That file is identical to upstream main.

Summary by CodeRabbit

  • Build Improvements
    • Linux desktop release builds now use optimized linking and updated compilation settings, which may reduce build times.
  • Bug Fixes
    • Workspace selection now respects the workspace directory provided by the active embedder configuration. When no such configuration is available, existing workspace resolution remains unchanged.

senamakel and others added 14 commits October 7, 2026 07:56
Added a Clone implementation for the config schema types so they can be duplicated when needed elsewhere in the core.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Added a Clone implementation for the config schema types so they can be duplicated when needed elsewhere in the core.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Added Clone implementations for the configuration schema types so they can be duplicated when needed elsewhere in the core.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce typed schema definitions for the configuration so values can be
validated and described consistently. This lays the groundwork for
surfacing config errors earlier and generating documentation from the
schema.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a CoreContext helper that borrows the current embedder config and
hands a reference to a closure, then switch the workspace snapshot,
gated-service check, and API-key probe to use it. These call sites only
needed a single field or predicate, so the previous full Config clone was
wasted work on every dispatch.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…omorphization

Wrap active_workspace_snapshot, agent_chat_for, and start_chat in
#[inline(never)] functions returning BoxFuture, delegating to private async
inner functions. Callers in openhuman-rpc and openhuman-embed previously
re-instantiated each async body inside their own state machines, so boxing
keeps a single compiled copy in this crate.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Release build guidance now records that 16 codegen units are used instead of one, since a single unit added 82% build time (tinyhumansai#5595).

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Document the project's conventions and working expectations in AGENTS.md so
automated agents and contributors have a single reference for how changes
should be made.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Install mold in the Linux build dependencies and set per-target
RUSTFLAGS to link with mold and fold byte-identical functions via
--icf=safe. The release profile's codegen units leave many duplicate
functions that MSVC and Apple's linker already deduplicate but GNU ld
does not, so this shrinks the stripped binary by roughly 2 MiB.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…ests.rs

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Added Clone implementations for the config schema types so they can be duplicated when needed. This makes it possible to snapshot or pass around configuration values without moving them.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The manual Clone implementation for Config called clone on fields that are
already Copy, so those calls were replaced with direct copies. This removes
needless work and quiets clippy's clone-on-copy lint without changing any
behaviour.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 368f24df-45ff-44ee-b59c-7c7aae052713
📥 Commits

Reviewing files that changed from the base of the PR and between 670903c and cbcd899.

📒 Files selected for processing (13)
  • .github/workflows/build-desktop.yml
  • AGENTS.md
  • crates/openhuman-core/src/config/schema/load/dirs.rs
  • crates/openhuman-core/src/config/schema/types.rs
  • crates/openhuman-core/src/config/schema/types/config.rs
  • crates/openhuman-core/src/config/schema/types/config_clone.rs
  • crates/openhuman-core/src/config/schema/types/config_clone_tests.rs
  • crates/openhuman-core/src/core/runtime/context.rs
  • crates/openhuman-core/src/core/runtime/context_tests.rs
  • crates/openhuman-core/src/inference/host_runtime/ops/agent_chat.rs
  • crates/openhuman-core/src/security/credentials/ops/gated_services.rs
  • crates/openhuman-core/src/security/credentials/session_support.rs
  • crates/openhuman-core/src/web_chat/ops/start_chat.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.


📝 Walkthrough

Walkthrough

The PR updates Linux desktop linker settings and release-build guidance. It also changes core configuration access and cloning, and updates several public async functions to return boxed futures.

Changes

Linux Desktop Build

Layer / File(s) Summary
Linux linker settings
.github/workflows/build-desktop.yml, AGENTS.md
The workflow installs mold and sets linker flags for x86_64 and aarch64 Linux builds. Release-build guidance changes to 16 codegen units and records build-time figures.

Core Configuration and Async APIs

Layer / File(s) Summary
Config clone implementation
crates/openhuman-core/src/config/schema/types.rs, crates/openhuman-core/src/config/schema/types/config.rs, crates/openhuman-core/src/config/schema/types/config_clone.rs, crates/openhuman-core/src/config/schema/types/config_clone_tests.rs
Config uses a manual Clone implementation. Tests compare selected fields and serialized values, and check that changing the clone does not change the original.
Embedder configuration access
crates/openhuman-core/src/core/runtime/context.rs, crates/openhuman-core/src/core/runtime/context_tests.rs, crates/openhuman-core/src/config/schema/load/dirs.rs, crates/openhuman-core/src/security/credentials/ops/gated_services.rs, crates/openhuman-core/src/security/credentials/session_support.rs
CoreContext adds a closure-based accessor for the current embedder config. Workspace snapshot resolution and credential checks use the accessor.
Boxed-future async APIs
crates/openhuman-core/src/inference/host_runtime/ops/agent_chat.rs, crates/openhuman-core/src/web_chat/ops/start_chat.rs
agent_chat_for and start_chat return boxed futures and delegate their async work to private inner functions.

Priority: ➖ Normal

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

Change: Refactor

Suggested reviewers: m3ga-mind, sanil-23

Merge Risk: ⚪ Minimal · up to cbcd8

The configuration and chat changes have no identified behavior regression, and the Linux linker change has no identified build failure. Merge after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to cbcd8

The inspected changes preserve existing authentication checks, embedder configuration authority, and protection of operator-wide active-user state. No introduced security concern was established. Credential persistence and Linux linker compatibility were not fully validated, so the assessment remains qualified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The inspected exposure remains authenticated socket chat requests, host-supplied embedding requests, and operator-local active-user state. The comparison establishes no new caller, expanded privilege, or broader filesystem authority through the changed entrypoints.

Trust Boundaries and Controls

  • observed — The socket handler rejects unauthenticated requests before calling start_chat and derives client identity from the socket. Request text and thread identifiers remain payload-controlled. Core input checks and prompt enforcement remain inside the unchanged async implementation; embedding turns retain the inference-domain gate and selected-agent runtime context.

Resilience and Maintainability Implications

  • observed — Credential mutations remain serialized, and active-user marker writes retain temporary-file creation, synchronization, atomic rename, and cache invalidation. The existing multi-step flow can still fail after activation before later rebinding completes; that recovery limitation predates this PR and is not an introduced concern.
🚥 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 summarizes the main performance changes: reducing Config::clone emission, boxing async entry points, and enabling ICF for Linux release builds.
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 16 functions across 11 files. (2 skipped: 2…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

I’m a rabbit with a linker tune,
I hop through builds beneath the moon.
A boxed future bounds ahead,
A config clone leaves fields well-read.
I nibble tests, then thump my feet,
These changed paths make a tidy beat.

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

@senamakel
senamakel merged commit 749e06a into tinyhumansai:main Oct 7, 2026
19 of 23 checks passed
senamakel pushed a commit that referenced this pull request Oct 7, 2026
- Config::clone lists voice_live: #7050's hand-written clone and #7046's
  new field merged separately and left main failing to compile.
- Conversations sends leave the model to the core by default again
  (composerModelOverride ?? undefined), as #6996 intended; #7048 had put
  hint:chat back while building on the damaged main, which also left the
  model-clear barrier unreachable.
- Japanese gets the 109 strings added while it was missing; Turkish gets
  those plus the 61 restored English keys, and drops six memory-engine
  keys #7029 removed.
- The legacy memory migration test checks that the sqlite backend key is
  gone, not that no key in the whole config contains "backend".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant