* fix(tests): eliminate env mutex poison cascade and fix test flakiness
The shared ENV_MUTEX used by ~68 config tests would cascade a single
test panic into failures across every module. Replace all .unwrap() /
.expect() lock acquisitions with a poison-recovering lock_env() helper.
Consolidate rogue module-local ENV_LOCK instances (workspace, orchestrator,
bootstrap) onto the shared global mutex to prevent cross-module races.
Also fixes:
- gateway user_id fallback was hardcoded to "default" instead of owner_id
- test_ironclaw_env_path used LazyLock which is order-dependent
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* test(helpers): add regression test for lock_env poison recovery
Satisfies the regression-test-check CI gate by adding a test that
intentionally poisons ENV_MUTEX and verifies lock_env() recovers.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix(ci): detect test changes inside #[cfg(test)] regions
The regression test check relied on git diff -W to expand context to
function boundaries, but git doesn't recognize Rust `mod tests {}` as a
function boundary. Changes to imports, helpers, or lock calls inside
test modules were invisible to the check.
Add a line-level fallback: for each changed .rs file, find where
#[cfg(test)] starts and check if any diff hunk targets a line at or
after that boundary. This catches edits anywhere inside test modules
regardless of git's language awareness.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix: address PR review feedback
- Clear ENV_MUTEX poison after regression test so it doesn't leave
global state dirty for subsequent tests.
- Fix CI regression-test-check to match #[cfg(test)] only when followed
by `mod` (the test module pattern), avoiding false positives from
standalone #[cfg(test)] items like statics or functions.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
* refactor: simplify config resolution and consolidate main.rs init into AppBuilder
- Add parse_bool_env() and parse_string_env() helpers to eliminate repetitive
5-line optional_env/parse/map_err/unwrap_or boilerplate across 12 config files
- Add EmbeddingsConfig::create_provider() to centralize embeddings construction
(fixes hardcoded 1536 dimensions and missing Ollama provider in app.rs)
- Extract init_cli_tracing(), setup_wasm_channels(), start_tunnel(),
run_memory_command(), run_worker(), run_claude_bridge() from main.rs
- Replace ~600 lines of inline init in main.rs with AppBuilder::build_all()
- Expose catalog_entries from AppComponents for gateway registry entries
- Net reduction: ~738 lines across 15 files
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: propagate dev_loaded_tool_names from AppBuilder and add parse_option_env helper
Address PR review feedback:
- Capture dev_loaded_tool_names from WASM loading in init_extensions()
and expose via AppComponents so bootstrap_hooks receives the actual
dev tool names instead of an empty slice (fixes silent hook skip)
- Add parse_option_env<T>() helper for Option<T> config fields,
simplifying max_cost_per_day_cents and max_actions_per_hour in agent.rs
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: fetch real NEAR AI pricing and unify cost calculation path
CostGuard was independently looking up pricing via costs::model_cost(),
falling back to GPT-4o default rates when NEAR AI model names didn't
match the static table — causing ~3x cost overestimates in logs.
- Add pricing map to NearAiChatProvider that fetches real rates from
/v1/model/list at startup (background, non-blocking)
- Update cost_per_token() to check fetched pricing first, then static
table, then default
- Add cost_per_token parameter to CostGuard::record_llm_call() so the
dispatcher passes provider-sourced rates directly
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* chore: update default NEAR AI model to GLM-latest
Replace fireworks llama4-maverick-instruct-basic with zai-org/GLM-latest
as the default model in config and setup wizard.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: align wizard default model name with config
Change "zai/GLM-latest" to "zai-org/GLM-latest" in wizard.rs to match
the default in config/llm.rs.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
* refactor: split large files and consolidate test stubs for contributor velocity
- Extract 7 Database sub-traits (ConversationStore, JobStore, SandboxStore,
RoutineStore, ToolFailureStore, SettingsStore, WorkspaceStore) with Database
as a supertrait combining them all
- Split libsql_backend.rs (2769 lines) into src/db/libsql/ directory with
one file per sub-trait implementation
- Split config.rs (1753 lines) into src/config/ directory with 16 domain files
- Consolidate 3 duplicate test LLM stubs into shared StubLlm in src/testing.rs
- Split server.rs handlers into src/channels/web/handlers/ directory
- Extract main.rs init phases into AppBuilder (src/app.rs)
- Add developer setup script (scripts/dev-setup.sh)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* refactor: move heartbeat test from examples/ to tests/
Convert standalone example binary into a proper #[ignore] integration
test, matching the convention of the other integration tests.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* style: fix rustfmt formatting for CI
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: address PR review comments from Copilot
- tunnel.rs: replace .ok().flatten() with ? to propagate env var errors
- secrets.rs: remove misleading "process-wide cache" comment
- database.rs: use uppercase "DATABASE_URL" in error key
- testing.rs: gate harness tests with #[cfg(feature = "libsql")]
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Illia Polosukhin <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>