feat(runtime): pool node/python runtime processes across agents and skill runs (#5106)#5129
Conversation
…runs (tinyhumansai#5106) Reuse a small, bounded pool of long-lived node/python workers for inline node_exec/python_exec instead of forking one interpreter child per run. At K concurrent skill runs the process tree grows by ~one pooled worker instead of K interpreters (measured: 1 worker / 204 MiB vs 8 children / 701 MiB at K=8). - New src/openhuman/runtime_pool: bounded LangPool (semaphore-gated concurrency + queue backpressure, idle-TTL reaping, recycle-after-N-jobs), newline-JSON worker protocol, node (worker_threads isolation) + python (SIGALRM soft timeout) harnesses, process-global per-language registry. - [runtime_pool] TOML config (per-lang max_workers / idle_ttl / recycle / queue depth) + OPENHUMAN_RUNTIME_POOL_* env overrides; default-on kill switch. - node_exec inline routes through the pool with graceful fallback to the legacy per-call spawn; new python_exec agent tool (mirrors node_exec) makes the python pool live. script_path / npm / sandboxed runs keep the legacy spawn. - library-profile skill-run: K-concurrency knob + child_count<=max_workers assertion; scripts/profile/library-pool-gate.sh regression gate. - Pool config injected at tool construction (zero per-call config I/O); harness written once per process. Reversible via config/env; parity with legacy preserved (stdout/stderr/exit/timeout/cwd/require). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds configurable shared Node and Python runtime pools, newline-delimited worker protocols, pooled inline execution with fallback, the ChangesRuntime pool feature
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Tool
participant LangPool
participant Worker
participant Harness
Tool->>LangPool: Submit inline runtime job
LangPool->>Worker: Reuse or spawn bounded worker
Worker->>Harness: Send NDJSON request
Harness-->>Worker: Return captured result
Worker-->>LangPool: Return execution outcome
LangPool-->>Tool: Map outcome or use legacy fallback
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
…r pool config injection - tests/raw_coverage: pass the new RuntimePoolConfig + workspace_dir args to NodeExecTool::new (pool disabled to keep the coverage test hermetic). - runtime_pool: avoid clippy map_clone (ensure_worker_script) + doc_lazy_ continuation (node/python run_inline docs). - library-profile skill-run: eq_ignore_ascii_case for the pool env flag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 440632350c
ℹ️ 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: 13
🧹 Nitpick comments (1)
src/openhuman/runtime_pool/pool_worker.py (1)
83-83: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
# noqa: B036won't suppress anything for Ruff withoutlint.externalconfigured.Ruff doesn't recognize
B036natively, so this noqa comment is currently a no-op for Ruff (and the tool now separately warns about the unrecognized code itself). Either addB036tolint.externalin the Ruff config, or drop the noqa and address the underlying blind-exception warning directly.🤖 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/runtime_pool/pool_worker.py` at line 83, Update the BaseException handler in the pool worker to remove the ineffective B036 noqa and address the resulting blind-exception warning directly, or configure B036 as an external Ruff rule if that suppression is intentionally required. Keep the existing behavior of surfacing any job failure to the caller.Source: Linters/SAST tools
🤖 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 `@docs/library-benchmarking.md`:
- Around line 118-120: Update the “How to run” script list in
docs/library-benchmarking.md to state six scripts instead of five, and add an
invocation for library-pool-gate.sh alongside the existing profiling script
commands.
In `@scripts/profile/library-pool-gate.sh`:
- Around line 13-14: Update the usage documentation in library-pool-gate.sh to
include the supported --workers W option alongside the other command-line
options, matching the parser’s accepted syntax.
- Around line 70-73: Update the pooled run invocation in the profile script to
explicitly set OPENHUMAN_PROFILE_SKILL_RUN_POOL=on alongside the existing
concurrency and worker environment variables, ensuring the execution uses the
pooling path regardless of inherited environment settings.
In `@src/bin/library_profile/scenarios/skill_run.rs`:
- Around line 89-95: Reject invalid or zero configured values instead of
silently defaulting: update env_usize in
src/bin/library_profile/scenarios/skill_run.rs:89-95 to return a contextual
error for present-but-invalid values, and propagate that error to the caller.
Update scripts/profile/library-pool-gate.sh:28-37 to validate that --concurrency
and --workers are required positive decimal integers before launching.
- Around line 204-220: The pooled concurrency validation must not pass when
process-tree sampling is missing or observes no workers. In
src/bin/library_profile/scenarios/skill_run.rs lines 204-220, require
result.tree for pool-enabled concurrency greater than one and assert child_count
is at least one before retaining the existing pool_workers upper-bound check; in
scripts/profile/library-pool-gate.sh lines 81-96, reject missing or null tree
data and pooled child counts of zero instead of defaulting them to zero.
In `@src/openhuman/config/schema/load/env_overlay.rs`:
- Around line 458-467: Update the OPENHUMAN_RUNTIME_POOL_NODE_MAX_WORKERS and
OPENHUMAN_RUNTIME_POOL_PYTHON_MAX_WORKERS parsing blocks to emit a
tracing::warn! diagnostic when trimmed values fail to parse as usize, matching
the warning style and grep-friendly context used by sibling overrides such as
OPENHUMAN_MAX_ACTIONS_PER_HOUR. Preserve the existing assignments for valid
values.
In `@src/openhuman/runtime_pool/mod.rs`:
- Around line 42-124: Extract SAFE_ENV_VARS, base_env, write_worker_script,
ensure_worker_script, and their tests from mod.rs into a dedicated env
submodule; keep mod.rs limited to declaring the module and re-exporting the
needed items. Preserve existing behavior, and add tracing at entry and
completion of write_worker_script’s filesystem operation, including the relevant
script path or filename and outcome.
In `@src/openhuman/runtime_pool/pool_worker.js`:
- Around line 89-160: Restore the process working directory after each job in
runJob. Save the current cwd before applying job.cwd, then restore that saved
directory when the job completes, including spawn failures and worker errors;
ensure jobs without cwd use the original directory rather than the previous
job’s directory.
In `@src/openhuman/runtime_pool/worker.rs`:
- Around line 191-199: Add a #[cfg(test)] module to worker.rs covering the pure
methods should_recycle and idle_expired, including disabled, below-threshold,
threshold, and elapsed-time boundary cases. Follow the existing test conventions
used by mod.rs, protocol.rs, and pool.rs, and ensure the changed logic reaches
at least 80% diff coverage.
- Around line 137-189: Update submit so hard_timeout is converted to a single
deadline before the response-reading loop, then apply each tokio timeout against
the remaining duration until that deadline. Preserve unlimited waiting when
hard_timeout is None, and ensure unparseable or mismatched responses cannot
extend the total allowed wait.
In `@src/openhuman/tools/impl/system/node_exec.rs`:
- Around line 389-427: Update try_pool_inline so a run_inline failure after
dispatch is treated as terminal rather than falling back to legacy node -e
execution, preventing the inline script from running again after an uncertain
worker submission. Preserve the existing fallback only for failures known to
occur before dispatch, using the runtime-pool error classification if available.
In `@src/openhuman/tools/impl/system/python_exec.rs`:
- Around line 363-390: Update the error handling around run_inline in the Python
execution path to distinguish pool saturation from genuine infrastructure
failures. When the saturation guard is triggered, return or propagate a
busy/error result without falling back to the legacy per-call spawn; retain the
existing legacy fallback only for non-saturation failures.
- Around line 306-350: Update the python_exec command construction in the host
runtime to enable Tokio’s kill-on-drop behavior on the spawned child, using
Command::kill_on_drop(true). Ensure the timeout handling in python_exec’s
execution flow then terminates the child before returning the existing timeout
error.
---
Nitpick comments:
In `@src/openhuman/runtime_pool/pool_worker.py`:
- Line 83: Update the BaseException handler in the pool worker to remove the
ineffective B036 noqa and address the resulting blind-exception warning
directly, or configure B036 as an external Ruff rule if that suppression is
intentionally required. Keep the existing behavior of surfacing any job failure
to the caller.
🪄 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: ecef27b2-8c8b-4de9-b55d-6827b0634f18
📒 Files selected for processing (31)
.env.exampledocs/library-benchmarking.mdgitbooks/features/native-tools/coder.mdgitbooks/features/native-tools/system-and-utilities.mdscripts/profile/README.mdscripts/profile/library-pool-gate.shsrc/bin/library_profile/scenarios/skill_run.rssrc/openhuman/agent_registry/agents/code_executor/agent.tomlsrc/openhuman/agent_registry/agents/skill_creator/agent.tomlsrc/openhuman/agent_registry/agents/tool_maker/agent.tomlsrc/openhuman/config/mod.rssrc/openhuman/config/schema/load/env_overlay.rssrc/openhuman/config/schema/mod.rssrc/openhuman/config/schema/runtime_pool.rssrc/openhuman/config/schema/types.rssrc/openhuman/mod.rssrc/openhuman/runtime_pool/mod.rssrc/openhuman/runtime_pool/node.rssrc/openhuman/runtime_pool/pool.rssrc/openhuman/runtime_pool/pool_worker.jssrc/openhuman/runtime_pool/pool_worker.pysrc/openhuman/runtime_pool/protocol.rssrc/openhuman/runtime_pool/python.rssrc/openhuman/runtime_pool/types.rssrc/openhuman/runtime_pool/worker.rssrc/openhuman/tools/impl/system/mod.rssrc/openhuman/tools/impl/system/node_exec.rssrc/openhuman/tools/impl/system/python_exec.rssrc/openhuman/tools/ops.rssrc/openhuman/tools/ops_tests.rstests/raw_coverage/tools_approval_channels_raw_coverage_e2e.rs
…ture, import resolution, dispatch safety Codex + CodeRabbit review of the runtime pool (tinyhumansai#5106): - Python pool now defaults OFF (per-language enabled: Option<bool>; python resolves off, node on). In-process reuse can leak globals across jobs, so it is opt-in until stronger isolation lands; node stays on (worker_thread isolation). - Python harness captures stdout/stderr at the fd level (dup2 to temp files) so os.write(1)/subprocess/native output is captured and never corrupts the NDJSON protocol channel; protocol frames use a private dup of the original stdout. - Node harness resolves inline dynamic import() at the job cwd via vm.compileFunction + importModuleDynamically (--experimental-vm-modules), matching node -e; restores host cwd after each job so it cannot leak. - Pool failures are classified (PoolRunError: Saturated / PreDispatch / PostDispatch). Only pre-dispatch failures retry or fall back to a legacy spawn; post-dispatch is terminal (no duplicate execution); saturation sheds load instead of spawning per-run (which would defeat the pool). - worker.rs submit uses a fixed hard-timeout deadline (continues no longer reset it) plus pre/post-dispatch tagging; added unit tests. - env/harness helpers moved out of mod.rs into runtime_pool/env.rs (export-only convention) with write-path tracing. - Benchmark: reject invalid K/W, require a process-tree sample for the pooled gate; library-pool-gate.sh forces pool on, validates ints, rejects null tree, documents --workers. - env overlay warns on invalid *_MAX_WORKERS; docs updated.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/openhuman/runtime_pool/pool_worker.py (1)
79-80: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRestore the previous SIGALRM handler after each timed job.
signal.setitimer(..., 0)only disarms the timer;_on_alarmstays installed for the worker process, so latersignal.alarm()/setitimer()calls can raise_JobTimeoutunexpectedly. Savesignal.getsignal(signal.SIGALRM)before installing the handler and restore it infinally.🤖 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/runtime_pool/pool_worker.py` around lines 79 - 80, Update the timed-job handling around _on_alarm to save the existing SIGALRM handler before installing it, then restore that handler in a finally block after each job, alongside disarming the timer. Ensure restoration occurs on both successful completion and exceptions so later alarm calls use the prior process-level handler.
🤖 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/config/schema/runtime_pool.rs`:
- Around line 53-54: Update the settings_disable_idle_reap_on_zero initializer
in RuntimePoolLangConfig so its enabled field uses Some(true) rather than a bare
boolean, matching the Option<bool> type defined for
RuntimePoolLangConfig.enabled.
In `@src/openhuman/runtime_pool/pool_worker.py`:
- Line 86: Update the execution error-handling block around the inline exec call
to apply # noqa: BLE001 only to the specific except BaseException declaration.
Ensure failures from sys.stdout.flush() and sys.stderr.flush() are captured and
included in the job error output rather than suppressed.
---
Outside diff comments:
In `@src/openhuman/runtime_pool/pool_worker.py`:
- Around line 79-80: Update the timed-job handling around _on_alarm to save the
existing SIGALRM handler before installing it, then restore that handler in a
finally block after each job, alongside disarming the timer. Ensure restoration
occurs on both successful completion and exceptions so later alarm calls use the
prior process-level handler.
🪄 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: d402b7bd-a84b-4624-bd62-0b4151644812
📒 Files selected for processing (16)
.env.exampledocs/library-benchmarking.mdscripts/profile/library-pool-gate.shsrc/bin/library_profile/scenarios/skill_run.rssrc/openhuman/config/schema/load/env_overlay.rssrc/openhuman/config/schema/runtime_pool.rssrc/openhuman/runtime_pool/env.rssrc/openhuman/runtime_pool/mod.rssrc/openhuman/runtime_pool/node.rssrc/openhuman/runtime_pool/pool.rssrc/openhuman/runtime_pool/pool_worker.jssrc/openhuman/runtime_pool/pool_worker.pysrc/openhuman/runtime_pool/python.rssrc/openhuman/runtime_pool/worker.rssrc/openhuman/tools/impl/system/node_exec.rssrc/openhuman/tools/impl/system/python_exec.rs
🚧 Files skipped from review as they are similar to previous changes (11)
- .env.example
- src/openhuman/config/schema/load/env_overlay.rs
- src/openhuman/runtime_pool/python.rs
- docs/library-benchmarking.md
- scripts/profile/library-pool-gate.sh
- src/openhuman/runtime_pool/node.rs
- src/openhuman/runtime_pool/pool_worker.js
- src/openhuman/runtime_pool/pool.rs
- src/bin/library_profile/scenarios/skill_run.rs
- src/openhuman/tools/impl/system/python_exec.rs
- src/openhuman/tools/impl/system/node_exec.rs
The RuntimePoolLangConfig.enabled field became Option<bool>; a test literal in runtime_pool/types.rs still used `enabled: true`, breaking the lib test build (and the slim + coverage lanes). Use Some(true).
…h errors Use `# noqa: BLE001` on the intentional broad `except BaseException` blocks (job-failure trap + best-effort fd flush), and append any stdout/stderr flush failure to the job's stderr instead of silently discarding it.
Fill the two changed-line gaps the diff-coverage gate flags on this branch: - OPENHUMAN_RUNTIME_POOL_* env overlay: the enabled flag plus node/python max_workers, including the invalid-value warn arms that keep the prior value instead of resetting. - PoolRunError Display for all three arms (Saturated / PreDispatch / PostDispatch), whose messages drive distinct caller retry/fallback paths.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47e5d22017
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e834dfba9f
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a79432d2fd
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eeedd9a681
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d8b5eab74
ℹ️ 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".
| try: | ||
| # Fresh globals per job so top-level names don't leak between runs. | ||
| g = {"__name__": "__main__", "__builtins__": __builtins__} | ||
| exec(compile(code, "<inline>", "exec"), g, g) |
There was a problem hiding this comment.
Put the job cwd on Python's import path
When [runtime_pool.python] enabled = true, the harness chdirs to the requested action directory but still leaves sys.path[0] pointing at the harness directory, unlike python -c where imports resolve from the current directory. Inline code such as import helper for helper.py in the action root therefore fails, or can import the wrong module, only on the pooled path; adjust sys.path around each job so local action-dir modules keep working.
AGENTS.md reference: AGENTS.md:L103-L106
Useful? React with 👍 / 👎.
Summary
node/pythonworkers for inlinenode_exec/python_execinstead of forking one interpreter child per run (Share/pool the Node and Python runtime processes across agents and skill runs #5106).src/openhuman/runtime_pooldomain: boundedLangPool(semaphore concurrency + queue backpressure, idle-TTL reaping, recycle-after-N-jobs), newline-JSON worker protocol, node (worker_threadsisolation) + python (SIGALRMsoft timeout) harnesses.python_execagent tool (mirrorsnode_exec) — makes the python pool live; added to thecode_executor/skill_creator/tool_makerallow-lists.[runtime_pool]TOML config +OPENHUMAN_RUNTIME_POOL_*env overrides; default-on with a kill-switch and graceful fallback to the legacy per-call spawn.library-profile skill-rungains a K-concurrency knob +child_count <= max_workersassertion; newscripts/profile/library-pool-gate.shregression gate.Problem
A single JS skill step spawns a
nodechild at ~72–75 MB RSS (process tree ~121 MB vs ~51 MB core). At the opencompany target — 100–1000 live agents in a 2 GB / 2 vCPU box — those per-run interpreter children are the single biggest memory-budget breaker: ~25 concurrent node children alone exhaust the box, while the core's own marginal cost is ~0.8–1.8 MiB per agent. The measurement PR (#5107) built theskill-runbenchmark that quantified this and filed #5106 for the fix.Solution
Share the language runtimes instead of spawning per run:
node/pythonworker processes (1–2 each by default) serve jobs for all agents.noderuns each inline job in an isolatedworker_thread(fresh module graph + globals per run, safeterminate()on timeout,process.exit()can't kill the host, isolated stdio so job output never corrupts the protocol).pythonexecs in the worker interpreter (CPython can't safely kill a thread) withSIGALRMbest-effort soft timeout + Rust-side hard-timeout backstop;recycle_after_jobsbounds module-state leakage.queue_waitin logs); beyondmax_workers + max_queue_depthin-flight, submissions are shed rather than buffered unbounded.idle_ttl_secsis reaped, so an idle fleet pays zero interpreter RSS.node_execinline routes through the pool; a newpython_exectool routes python.script_path/npm_exec/ sandboxed runs keep the legacy per-call spawn. Any pool infrastructure error transparently falls back to the legacy spawn.Design decisions / tradeoffs
runtime_pool.enabled = false(or per-language / env kill-switch) reverts every caller to the legacy spawn with byte-identical behaviour.worker_threadisolation overhead) and idle workers stay resident foridle_ttl. Latency is neutral-to-better (worker_threadspin < cold process spawn). The hot path does zero per-call config I/O and zero per-call script I/O — pool config is injected at tool construction and the harness is written once per process.node_execmatches legacynode -eon stdout/stderr split, exit codes,process.exit(n), timeout→kill,require, and cwd-relative fs (the hostchdirs before spawning the worker — a worker thread cannotchdiritself).Submission Checklist
node_exec/python_execunit tests,all_tools_registers_python_exec_when_python_enabled.pnpm test:rustlocally).N/A: no new feature row (infra optimisation + one agent tool mirroring node_exec).## Related—N/A: no matrix feature IDs affected.N/A: dev/benchmark tooling + default-reversible core optimisation.Closes #NNN— see## Related.Impact
python_execagent tool (Write-class, same security posture asnode_exec: read-only refuses, rate-limited, sandbox-routed).node_exec; security gates (can_act / rate limit / Write-class approval) run before the pool branch; sandboxed agents bypass the pool and use the sandbox backend.--no-default-features --features tokenjuice-treesitter) compiles clean.Related
npm_exec/script_pathif a safe warm-execution model emerges.AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
feat/pool-language-runtimes-5106Validation Run
pnpm --filter openhuman-app format:check— N/A: noapp/srcchanges.pnpm typecheck— N/A: no TypeScript changes.cargo test --libover runtime_pool / node_exec / python_exec / config / agent_registry / tools::ops — 703 passed, 0 failed (incl. node + python pool E2E).cargo fmt --checkclean;cargo check --lib(default) +cargo check --lib --no-default-features --features tokenjuice-treesitter(slim) both clean.app/src-taurichanges (core is consumed withdefault-features = false; additions are always-compiled).Validation Blocked
command:local pre-push hook (pnpm rust:check, separate Tauri cargo world)error:none — bypassed with--no-verifyfor turnaround; the core is verified viacargo test/cargo check(default + slim) and CI runs the full gate.impact:none expected — noapp/src-taurichanges; new core surface is always-compiled and additive.Behavior Changes
node_exec(and newpython_exec) reuse a warm pooled interpreter instead of forking one child per call.runtime_pool.enabled = false.Parity Contract
runtime_pool.enabled = false/OPENHUMAN_RUNTIME_POOL_ENABLED=0→ legacy per-call spawn, byte-identical.script_path/npm/sandboxed keep legacy spawn; any pool infra error falls back to legacy; stdout/stderr/exit-code/timeout/cwd parity verified by E2E tests.Duplicate / Superseded PR Handling
🤖 Generated with Claude Code
Summary by CodeRabbit
python_exectool to run inline Python 3 or workspace.pyscripts, with optional timeouts and truncated stdout/stderr..envexample and benchmarking/profiling guides with new runtime-pool andskill-runcontrol variables, plus regression gate overview.