Skip to content

chore: promote staging to staging-promote/73759253-23837266309 (2026-04-01 14:31 UTC)#1878

Merged
henrypark133 merged 16 commits intostaging-promote/73759253-23837266309from
staging-promote/27a2fab1-23853914907
Apr 1, 2026
Merged

chore: promote staging to staging-promote/73759253-23837266309 (2026-04-01 14:31 UTC)#1878
henrypark133 merged 16 commits intostaging-promote/73759253-23837266309from
staging-promote/27a2fab1-23853914907

Conversation

@ironclaw-ci
Copy link
Copy Markdown
Contributor

@ironclaw-ci ironclaw-ci bot commented Apr 1, 2026

Auto-promotion from staging CI

Batch range: 737592539bdf4bb194bd908537ab2264d8a42b2c..27a2fab17337d5b0fad55c03a58f11f3416f07fc
Promotion branch: staging-promote/27a2fab1-23853914907
Base: staging-promote/73759253-23837266309
Triggered by: Staging CI batch at 2026-04-01 14:31 UTC

Commits in this batch (1):

Current commits in this promotion (11)

Current base: staging-promote/73759253-23837266309
Current head: staging-promote/27a2fab1-23853914907
Current range: origin/staging-promote/73759253-23837266309..origin/staging-promote/27a2fab1-23853914907

Auto-updated by staging promotion metadata workflow

Waiting for gates:

  • Tests: pending
  • E2E: pending
  • Claude Code review: pending (will post comments on this PR)

Auto-created by staging-ci workflow

@github-actions github-actions bot added scope: channel/wasm WASM channel runtime scope: setup Onboarding / setup scope: docs Documentation size: S 10-49 changed lines risk: high Safety, secrets, auth, or critical infrastructure contributor: core 20+ merged PRs labels Apr 1, 2026
@claude
Copy link
Copy Markdown

claude bot commented Apr 1, 2026

Code review

No issues found.

@claude
Copy link
Copy Markdown

claude bot commented Apr 1, 2026

Code review

Found 1 potential issue:

  1. [MEDIUM:HIGH] Unbounded secret length parameter allows DoS during setup

The AutoGenerateSchema::length field is unbounded. A maliciously crafted capabilities file with "length": 1_000_000_000 could cause memory exhaustion during onboarding via vec![0u8; length] in setup code.

However: This is a pre-existing architectural concern in the auto-generate schema system, not introduced by this PR. This PR uses a safe value (64 bytes).

Recommendation: Add validation in a follow-up PR (e.g., MAX_AUTO_GENERATE_LENGTH = 512 bytes) to bound the length parameter across all channels.

let mut bytes = vec![0u8; length];

ilblackdragon and others added 15 commits April 1, 2026 16:57
* feat(config): unify all settings to DB > env > default priority

Previously only LLM settings used DB-first priority while all other
subsystems (agent, channels, tunnel, heartbeat, embeddings, sandbox,
wasm, safety, builder, transcription, routines, skills, hygiene,
search) used env-first. This made web UI settings changes unreliable
for non-LLM config — env vars would silently override DB values.

Now all subsystems follow the same priority: DB > env > TOML > default.

- Add db_first_or_default, db_first_bool, db_first_optional_string,
  db_first_option helpers to config/helpers.rs with shadow warnings
- Flip 10 Group 1 resolvers (agent, channels, tunnel, heartbeat,
  embeddings, sandbox, wasm, safety, builder, transcription) from
  parse_optional_env/parse_bool_env to db_first_* equivalents
- Add Settings structs for 4 Group 2 resolvers (routines, skills,
  hygiene, search) that previously had no DB persistence
- Update Config::build() call sites and cli/doctor.rs caller
- Security-sensitive fields stay env-only: allow_local_tools,
  allow_full_access, cost/rate limits, auth tokens, API keys
- Bootstrap configs (database, secrets) stay env-only

Closes #1119 (partial — config unification phases 1-2)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address PR review feedback

- Stop logging raw values in shadow warnings to prevent leaking
  sensitive data (tunnel tokens, API keys) to logs
- Propagate optional_env errors for OLLAMA_BASE_URL instead of
  silently swallowing them with .ok().flatten()
- Make tunnel auth tokens (cf_token, ngrok_token) env-only like
  gateway_auth_token — sensitive credentials should not come from DB
- Fix transcription enabled tri-state: explicit DB false now correctly
  overrides TRANSCRIPTION_ENABLED env var (was collapsing to "unset")
- Switch SearchSettings fts_weight/vector_weight to Option<f32> so
  0.5 can be explicitly configured without being treated as "unset"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address @ilblackdragon review feedback

- Document default-equality heuristic limitation in db_first_or_default
  (a DB value equal to the default is treated as "unset")
- Remove dead _db_value parameter from warn_if_db_shadows_env
- Replace misleading db_first_or_default for embedding dimension with
  direct parse_optional_env (dimension depends on model, not DB)
- Use db_first_option for search weights to emit shadow warnings
  consistently with other resolvers
- Add migration warnings for auth tokens (gateway_auth_token,
  cf_token, ngrok_token) that are now env-only — warns at startup
  if these fields are set in DB/TOML but being ignored
- Improve signal error message to mention signal_enabled setting
- Clarify module docs and TOML header about default-equality caveat

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: minor cleanups from self-review

- Simplify warn_if_db_shadows_env: use is_ok_and() instead of
  binding + drop
- Add comment explaining u32→usize cast for max_parallel_jobs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(jobs): per-job MCP server filtering and max_iterations cap

Add mcp_servers and max_iterations optional params to create_job.
mcp_servers filters which MCP servers are mounted into worker
containers (gated behind MCP_PER_JOB_ENABLED, default false).
max_iterations caps the worker agent loop (default 50, max 500).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address review feedback on per-job MCP filtering

- Fix max_iterations dead code: add env = "IRONCLAW_MAX_ITERATIONS"
  to clap arg so worker CLI reads the env var injected by orchestrator
- Fix max_iterations: 0 allowed: use .clamp(1, 500) instead of .min(500)
- Replace hardcoded /tmp/ironclaw-mcp-configs with std::env::temp_dir()
- Make MCP server name matching case-insensitive
- Add test for case-insensitive matching
- Add test verifying max_iterations env var name matches clap definition

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address Copilot review feedback on per-job MCP filtering

- Guard IRONCLAW_MAX_ITERATIONS injection to Worker mode only (ClaudeCode uses max_turns)
- Extract WORKER_MCP_CONFIG_PATH as constant (no more hardcoded path)
- Fix TOCTOU race in cleanup_job: use remove_file directly, match on NotFound
- Fix schema_version default: 0 → 1 to match McpServersFile default
- Propagate serialization errors instead of silently writing empty config
- Add type validation warnings for mcp_servers and max_iterations params

* test: add regression tests and security hardening for per-job MCP filtering

Add 5 regression tests covering CI-required scenarios:
- Filtered config contains only the requested server (no leaks)
- Feature flag disabled skips MCP filtering entirely
- Temp file cleanup removes per-job config
- cleanup_job is idempotent (no panic on missing file/handle)
- Temp directory has restrictive 0o700 permissions (unix)

Security: set 0o700 permissions on /tmp/ironclaw-mcp-configs/ to prevent
other users on the host from reading filtered MCP server configs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address code review — server-side clamp, JobCreationParams, name validation

Critical:
1. Server-side max_iterations clamp in create_job_inner — defense no longer
   relies solely on tool parameter parsing. Uses MAX_WORKER_ITERATIONS constant
   (matching worker/job.rs) so the cap is enforced even for direct API calls.

2. Introduce JobCreationParams struct to bundle credential_grants, mcp_servers,
   and max_iterations. Removes #[allow(clippy::too_many_arguments)] from both
   create_job and execute_sandbox (7→5 and 9→7 positional args).

Important:
3. Validate MCP server names: reject path separators (/\), null bytes, and
   names longer than 128 chars to prevent future misuse.

5. Add test verifying max_iterations is NOT injected for ClaudeCode mode.
   Add test verifying server-side clamp uses MAX_WORKER_ITERATIONS constant.
   Add test verifying name validation rejects path separators and null bytes.

* fix: async I/O in generate_worker_mcp_config, shared MAX_WORKER_ITERATIONS

1. Convert generate_worker_mcp_config from sync std::fs to async tokio::fs.
   The function is called from async create_job_inner — sync I/O was blocking
   the tokio runtime thread. All test callers converted to #[tokio::test].

2. Move MAX_WORKER_ITERATIONS (500) to ironclaw_common as single source of
   truth. Both src/orchestrator/job_manager.rs and src/worker/job.rs now
   import from the shared crate, preventing drift.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Improve command execution parameter validation

Enhance workdir and timeout parameter handling for command execution.

* fix(worker): refine timeout parameter validation logic

Refactor timeout parameter handling to ensure it is a positive integer.

* fix(shell): add timeout and workdir validation with regression tests

Parse timeout strictly: reject non-integer (float/string), zero, and null values; normalize blank/whitespace-only workdir to None.
Add six regression tests covering each edge case flagged in review.

* fix(shell): improve parameter validation consistency

Add "minimum": 1 to timeout schema so LLMs get constraint upfront
Reject non-string workdir types (was silently ignored before)
Clarify error message: "positive integer" instead of "integer"
Add test for non-string workdir rejection
…#1848)

For channel mentions, the relay channel used event.channel_id (e.g.
"C088K6C3SQZ") as the thread_id fallback. Slack requires thread_ts to
be a message timestamp, so it silently ignored this and posted a
top-level message instead of threading.

Now uses event.id (the Slack message ts, e.g. "1609459200.000100") as
the fallback, so responses are always threaded under the user's message.
Also fixes metadata["thread_id"] to use the same value.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test(routines): add issue 1781 coverage

* fix: address PR review feedback
* test(e2e): cover chat approval parity across channels

* fix: harden chat approval prompt rendering
* Expand GitHub WASM tool surface

* Tighten GitHub tool input validation
* test(e2e): add agent loop recovery coverage

* test(e2e): harden mock message text parsing
…5626

chore: promote staging to staging-promote/2f2ad260-23866616993 (2026-04-01 22:10 UTC)
…6993

chore: promote staging to staging-promote/510fe19a-23863770631 (2026-04-01 19:23 UTC)
…0631

chore: promote staging to staging-promote/eb3fa0e6-23858863254 (2026-04-01 18:14 UTC)
…3254

chore: promote staging to staging-promote/58b01f15-23856539614 (2026-04-01 16:18 UTC)
…9614

chore: promote staging to staging-promote/27a2fab1-23853914907 (2026-04-01 15:27 UTC)
@github-actions github-actions bot added scope: agent Agent core (agent loop, router, scheduler) scope: channel Channel infrastructure scope: channel/cli TUI / CLI channel scope: channel/web Web gateway channel and removed size: S 10-49 changed lines labels Apr 1, 2026
@github-actions github-actions bot added scope: tool Tool infrastructure scope: tool/builtin Built-in tools scope: tool/wasm WASM tool sandbox scope: orchestrator Container orchestrator scope: worker Container worker scope: config Configuration scope: ci CI/CD workflows size: XL 500+ changed lines labels Apr 1, 2026
@henrypark133 henrypark133 merged commit ab67242 into staging-promote/73759253-23837266309 Apr 1, 2026
13 checks passed
@henrypark133 henrypark133 deleted the staging-promote/27a2fab1-23853914907 branch April 1, 2026 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: high Safety, secrets, auth, or critical infrastructure scope: agent Agent core (agent loop, router, scheduler) scope: channel/cli TUI / CLI channel scope: channel/wasm WASM channel runtime scope: channel/web Web gateway channel scope: channel Channel infrastructure scope: ci CI/CD workflows scope: config Configuration scope: docs Documentation scope: orchestrator Container orchestrator scope: setup Onboarding / setup scope: tool/builtin Built-in tools scope: tool/wasm WASM tool sandbox scope: tool Tool infrastructure scope: worker Container worker size: XL 500+ changed lines staging-promotion

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants