Skip to content

chore: promote staging to staging-promote/fcb295ba-24607448875 (2026-04-18 20:30 UTC) - #2657

Merged
henrypark133 merged 3 commits into
mainfrom
staging-promote/11f00698-24612972670
Apr 21, 2026
Merged

henrypark133 merged 3 commits into
mainfrom
staging-promote/11f00698-24612972670

Conversation

@ironclaw-ci

@ironclaw-ci ironclaw-ci Bot commented Apr 18, 2026 •

Copy link
Copy Markdown
Contributor

Auto-promotion from staging CI

Batch range: a53eac5c2dec6b6cd5c08189086093fde64aa9cb..11f006987d29174db4df1515fd4e9f2c1a12eac9
Promotion branch: staging-promote/11f00698-24612972670
Base: staging-promote/fcb295ba-24607448875
Triggered by: Staging CI batch at 2026-04-18 20:30 UTC

Commits in this batch (121):

Current commits in this promotion (3)

Current base: staging-promote/fcb295ba-24607448875
Current head: staging-promote/11f00698-24612972670
Current range: origin/staging-promote/fcb295ba-24607448875..origin/staging-promote/11f00698-24612972670

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

serrrfirat and others added 3 commits April 18, 2026 22:59
* fix(engine): allow completed event-driven missions to re-fire on new events

The /expected command returned "no self-improvement missions configured"
after the learning mission's first thread completed, because:

1. fire_on_system_event() only processed Active missions, skipping
   Completed ones. Event-driven missions should re-fire since each
   event is a fresh investigation.
2. fire_mission() rejected all terminal missions via is_terminal().
   Now Completed event-driven missions pass through.
3. threads_today counter never reset daily, permanently exhausting
   the daily budget after enough fires.
4. ensure_learning_missions was only called for the owner at init,
   so non-owner users never got learning missions.

Fixes: add is_event_driven() helper on Mission, allow Completed
event-driven missions in all three event-fire methods, add daily
reset for threads_today when last_fire_at is on a previous UTC day,
and call ensure_learning_missions in handle_expected before firing.

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

* fix: make daily reset persist best-effort (iteration 1)

The daily threads_today reset used `?` to propagate store errors,
which would abort fire_mission on a transient store failure. Changed
to log-and-continue so the in-memory reset still allows the mission
to fire.

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

* fix: resolve CI failures

- reduce WASM startup registration arguments via a context struct for clippy
- restore post-install auth gate naming and stabilize config tests
- make telegram approval fixture optional in tests
- add safety annotations for existing staged slice/expect patterns

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…2656)

Closes #2626.

`tests/e2e/helpers.py` used `.tab-bar button[data-tab="{tab}"]` to locate
every main-nav tab button. Commit 5058a1c removed the duplicate
right-side `status-logs-btn` Jobs button that was resolving that selector
to two elements on staging, so `test_connection.py` passes again. The
underlying selector is still fragile: any future auxiliary button or
`_addWidgetTab`-injected tab that reuses a built-in `data-tab` id (even
accidentally, as #2353 did) will make the selector resolve to multiple
elements and trip Playwright strict mode the next CI run.

Harden the selector in place — the issue's suggested direction of
scoping to a more specific parent region — so the regression can't
repeat without a test-side opt-in:

- `.tab-bar > button`: direct child, skipping any hypothetical nested
  buttons (e.g. menu popovers).
- `:not(.status-logs-btn)`: excludes the right-side logs/docs cluster
  that uses the same `data-tab` hook for click routing.
- `:not(.tab-btn)`: excludes widget-injected tabs (see `_addWidgetTab`
  in `crates/ironclaw_gateway/static/app.js`), which always carry the
  `tab-btn` class and could in principle collide with a built-in id.

Verified against a synthetic DOM with three colliding `data-tab="jobs"`
buttons (original, status-logs-btn duplicate, widget-injected): the old
selector matches 3 and trips strict mode on `.click()`; the new
selector matches 1 and clicks cleanly. No production HTML change is
required — the acceptance criterion explicitly forbids one.

`pytest tests/e2e/scenarios/test_connection.py -v` → 3 passed.
* fix(engine): make FINAL/FINAL_VAR awaitable in CodeAct scripts

LLMs frequently emit `await FINAL(answer)` by analogy with async tool
calls. The handler returned `MontyObject::None` synchronously, so the
subsequent `await` raised `TypeError: 'NoneType' object can't be
awaited` and the answer was dropped on the floor.

Route FINAL and FINAL_VAR through the existing `pending_futures`
mechanism with a trivially-resolving task. `final_answer` is set the
moment the call arrives, so both `FINAL(x)` (coroutine discarded) and
`await FINAL(x)` (resolves to None) succeed. Two regression tests in
`scripting::tests` pin both forms.

* fix(engine): normalize typographic punctuation before skill activation

iOS, macOS, and most rich-text inputs autocorrect `I'm` (ASCII U+0027)
to `I'm` (curly U+2019). Skill activation patterns like
`(?i)I'm a (CEO|...)` are authored with ASCII punctuation, so the
curly form silently failed to match — `ceo-setup` and any other skill
with apostrophes in its regex never activated for autocorrected input.

Add `normalize_punctuation()` in `default.py` that folds 8 typographic
quote variants and the en/em dashes to ASCII before scoring runs.
Implemented with chained `.replace()` because Monty does not expose
`str.maketrans`/`.translate()`. Runs once per turn on the goal text;
user content is untouched everywhere else.

Two regression tests under `executor::orchestrator::tests` drive
`normalize_punctuation` and `select_skills` end-to-end with the exact
ceo-setup pattern and a curly-apostrophe goal.

* docs(codeact): note closure capture quirk and Rust regex limits

Two recurring CodeAct failures got their own paragraphs in the
preamble:

- Function closures defined in one ```repl``` block do not reliably
  capture names (modules, top-level vars) defined in earlier blocks,
  producing spurious `NameError`. Authors must keep the helper, its
  imports, and its call sites in the same block.

- The embedded `re` is the Rust `regex` crate, not CPython: positional-
  only flag args, no lookaround, no backreferences. Lead with string
  methods (`in`, `startswith`, `splitlines`) and only reach for `re`
  when truly needed.

Pure docs change.

* fix(engine): adapt FINAL-await tests to staging CodeExecutionResult API

Replace `had_error` field references with `failure.is_none()` to match
the staging struct where `had_error: bool` was replaced by
`failure: Option<CodeExecutionFailure>`.

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

* fix(engine): address gemini-code-assist review — normalize before extraction, seed explicit skills (#2531)

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

* fix(skills): remove useless .into_iter() to satisfy clippy (#2531)

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

* fix(clippy): collapse nested if blocks into match guards (#2531)

Fixes collapsible_match lints in ironclaw_tui::render and
ironclaw_engine::runtime::mission triggered by Rust 1.95.

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

* fix(clippy): resolve collapsible_match and unnecessary_sort_by lints (#2531)

Fix 5 collapsible_match lints (responses_api, cli/tool, rig_adapter,
setup/prompts) and 2 unnecessary_sort_by lints (glob_tool, grep_tool)
triggered by Rust 1.95 clippy. Also fix rustfmt formatting for match
guards in render.rs.

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

* fix(clippy): group wasm startup channel registration context

---------

Co-authored-by: Illia Polosukhin <ilblackdragon@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size: XL 500+ changed lines scope: channel/cli TUI / CLI channel scope: pairing Pairing mode scope: docs Documentation risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs and removed size: XL 500+ changed lines labels Apr 18, 2026
@claude

claude Bot commented Apr 18, 2026

Copy link
Copy Markdown

No issues found.

Base automatically changed from staging-promote/fcb295ba-24607448875 to main April 21, 2026 03:18
@henrypark133
henrypark133 merged commit 11f0069 into main Apr 21, 2026
545 of 641 checks passed
@henrypark133
henrypark133 deleted the staging-promote/11f00698-24612972670 branch April 21, 2026 03:19

This branch had an error being deployed

6 failed deployments
venice-ironclaw / production — 11f00698 Deployed Apr 18, 2026 by railway-app[bot]
cosmose-ironclaw / production — 11f00698 Deployed Apr 18, 2026 by railway-app[bot]
Ironclaw-QA / production — 11f00698 Deployed Apr 18, 2026 by railway-app[bot]
humble-cat / staging-cameron — 11f00698 Deployed Apr 18, 2026 by railway-app[bot]
Near Foundation Ironclaw / production — 11f00698 Deployed Apr 18, 2026 by railway-app[bot]
ironclaw-nearai / production — 11f00698 Deployed Apr 18, 2026 by railway-app[bot]
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: low Changes to docs, tests, or low-risk modules scope: channel/cli TUI / CLI channel scope: docs Documentation scope: pairing Pairing mode staging-promotion

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants