Skip to content

fix(ci): stabilize Slack live QA harness - #5632

Merged
serrrfirat merged 5 commits into
mainfrom
codex/slack-live-canary-harness-fix
Jul 4, 2026
Merged

serrrfirat merged 5 commits into
mainfrom
codex/slack-live-canary-harness-fix

Conversation

@serrrfirat

Copy link
Copy Markdown
Collaborator

Summary

  • accept the current Slack pairing-code copy in the Reborn WebUI v2 live QA connect check
  • steer Slack routine QA prompts toward the configured DM delivery target instead of Slack auth/activation
  • remove unnecessary Slack extension authentication from QA 7C setup while retaining Google Drive/Sheets setup

Verification

  • python3 scripts/reborn_webui_v2_live_qa/test_run_live_qa.py
  • python3 -m py_compile scripts/reborn_webui_v2_live_qa/run_live_qa.py scripts/reborn_webui_v2_live_qa/test_run_live_qa.py
  • git diff --check

Context: main live canary run https://github.com/nearai/ironclaw/actions/runs/28700688649 showed Google fixed and remaining Reborn WebUI v2 failures isolated to Slack pairing/harness behavior.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5632 July 4, 2026 09:35 Destroyed
@github-actions github-actions Bot added size: M 50-199 changed lines risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jul 4, 2026
@coderabbitai

coderabbitai Bot commented Jul 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9ed9dbe4-6075-4dc8-a6dd-05dbeb4aaf21

📥 Commits

Reviewing files that changed from the base of the PR and between d9f7e45 and f70eb2f.

📒 Files selected for processing (2)
  • scripts/reborn_webui_v2_live_qa/run_live_qa.py
  • scripts/reborn_webui_v2_live_qa/test_run_live_qa.py

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Improved Slack live QA flows with pairing-code based setup checks and clearer preflight guidance for delivery targets.
    • Added optional follow-up instruction after routine confirmations (including timezone-aware responses).
    • Enhanced “latest GitHub release” retrieval to use available credentials for authenticated requests.
  • Bug Fixes
    • Updated external-channel extension search guidance to recommend explicit connect and avoid unnecessary activation steps.
    • Refined Slack routine preparation so the correct existing delivery target behavior is used consistently.

Walkthrough

Extension search guidance now points callers toward explicit connect and outbound delivery targets. Live QA Slack cases now use pairing-code wording, DM targets, and routine-confirmation follow-ups, with updated validation and setup. GitHub latest-release requests can now send a bearer token from configured environment variables.

Changes

Extension search guidance changes

Layer / File(s) Summary
Search guidance and manifest text
crates/ironclaw_reborn_composition/src/extension_lifecycle.rs, crates/ironclaw_reborn_composition/src/extension_lifecycle_capabilities.rs
Updates the external-channel search response text, the builtin.extension_search capability description, and the corresponding assertions and test name to match the revised guidance.

Live QA Slack and GitHub request changes

Layer / File(s) Summary
Slack prompt, connect, and routine wiring
scripts/reborn_webui_v2_live_qa/run_live_qa.py, scripts/reborn_webui_v2_live_qa/test_run_live_qa.py
Rewrites Slack QA prompt text for DM delivery, adds Slack instruction validation, changes connect-body checks to pairing-code wording, adds routine-confirmation follow-up handling, updates QA 7a and QA 7c wiring, and adjusts the related acceptance tests and mocks.
GitHub release token auth
scripts/reborn_webui_v2_live_qa/run_live_qa.py, scripts/reborn_webui_v2_live_qa/test_run_live_qa.py
Updates the latest-release request to read a GitHub token from configured environment variables and send it as a bearer authorization header, with matching test coverage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • nearai/ironclaw#5034: Same extension search guidance and capability-description path in extension_lifecycle and extension_lifecycle_capabilities.
  • nearai/ironclaw#5485: Same Slack connect QA flow and pairing-code wording in run_live_qa.py and tests.
  • nearai/ironclaw#5436: Same live-QA prompt/assertion surfaces for Slack and GitHub-related cases.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description omits most required template sections, including Change Type, Linked Issue, Security, trust-boundary, Database Impact, Blast Radius, and Rollback. Fill in the missing template sections, especially Change Type, Linked Issue, Security Impact, Trust-Boundary Checklist, Database Impact, Blast Radius, Rollback Plan, Review Follow-Through, and Review track.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change and follows Conventional Commits style.
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.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the live QA script and its tests to support a pre-configured Slack DM delivery target and ingress, adjusting several QA prompts to instruct the model not to authenticate or install Slack. It also introduces a helper function _slack_connect_instructions_look_valid to handle both old and new Slack connection instructions. However, a potential issue was identified where the assertion on the page content strictly expects 'pairing code', which will fail if the environment still serves the older instructions. A regex-based assertion is suggested to maintain backward compatibility.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

raise AssertionError(f"unexpected Slack connect instructions: {instructions!r}")
await expect(page.locator("body")).to_contain_text(title, timeout=15000) # type: ignore[attr-defined]
await expect(page.locator("body")).to_contain_text("Message the Slack app", timeout=15000) # type: ignore[attr-defined]
await expect(page.locator("body")).to_contain_text("pairing code", timeout=15000) # type: ignore[attr-defined]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The helper _slack_connect_instructions_look_valid was introduced to support both the old instructions ("Message the Slack app...") and the new instructions ("Message the IronClaw Reborn app in Slack to get a pairing code..."). However, the strict assertion await expect(page.locator("body")).to_contain_text("pairing code", timeout=15000) will fail if the live environment still serves the old instructions, as they do not contain the substring "pairing code".

To ensure the stabilization is robust and backward-compatible as intended, use a regular expression that matches either instruction variant.

Suggested change
await expect(page.locator("body")).to_contain_text("pairing code", timeout=15000) # type: ignore[attr-defined]
await expect(page.locator("body")).to_contain_text(re.compile(r"Message the Slack app|pairing code"), timeout=15000) # type: ignore[attr-defined]

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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 `@scripts/reborn_webui_v2_live_qa/run_live_qa.py`:
- Around line 1932-1934: The Slack instruction validator in
_slack_connect_instructions_look_valid accepts two shapes, but the later
pairing-code text check is always applied and may fail for the “message the
slack app” branch. Update the logic around this helper so the
to_contain_text("pairing code") assertion only runs when the Slack/pairing-code
branch matched, or make that assertion case-insensitive with ignore_case=True.
Use the existing _slack_connect_instructions_look_valid and to_contain_text call
sites to keep the branching consistent.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ad1c2e04-8d14-44cc-9e6d-26e9f99e157a

📥 Commits

Reviewing files that changed from the base of the PR and between 63d4882 and ab8cb43.

📒 Files selected for processing (2)
  • scripts/reborn_webui_v2_live_qa/run_live_qa.py
  • scripts/reborn_webui_v2_live_qa/test_run_live_qa.py

Comment on lines +1932 to +1934
def _slack_connect_instructions_look_valid(instructions: str) -> bool:
text = instructions.lower()
return "message the slack app" in text or ("slack" in text and "pairing code" in text)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== run_live_qa.py slice ==\n'
sed -n '1910,2005p' scripts/reborn_webui_v2_live_qa/run_live_qa.py

printf '\n== search to_contain_text usages ==\n'
rg -n "to_contain_text\(" scripts/reborn_webui_v2_live_qa/run_live_qa.py scripts -g '!**/node_modules/**' || true

printf '\n== relevant repo guidance ==\n'
rg -n "Playwright|to_contain_text|ignoreCase|ignore_case|pairing code|slack connect" -g 'CLAUDE.md' -g 'AGENTS.md' -g '.claude/**' -g '*.md' .

Repository: nearai/ironclaw

Length of output: 18420


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Playwright docs quick check ==\n'
python3 - <<'PY'
import urllib.request
url = "https://playwright.dev/python/docs/api/class-locatorassertions#locator-assertions-to-contain-text"
with urllib.request.urlopen(url, timeout=20) as r:
    text = r.read().decode("utf-8", "ignore")
for needle in ["ignore_case", "ignoreCase", "Case-insensitive"]:
    idx = text.find(needle)
    print(f"{needle}: {idx}")
    if idx != -1:
        print(text[max(0, idx-200): idx+500])
PY

Repository: nearai/ironclaw

Length of output: 2782


🌐 Web query:

Playwright Python expect(locator).to_contain_text default case sensitivity ignore_case documentation

💡 Result:

In Playwright Python, the expect(locator).to_contain_text() assertion performs a case-sensitive match by default when using a string [1][2]. To perform a case-insensitive match, you must explicitly set the ignore_case option to True [1][2]: python from playwright.sync_api import expect # Case-insensitive assertion expect(locator).to_contain_text("Expected Text", ignore_case=True) The ignore_case option was added in version 1.23 [1][2]. When provided, it takes precedence over the corresponding flags in regular expressions if one is passed instead of a string [1][2]. Note that this behavior is specific to the expect(locator).to_contain_text() assertion [1]. Other Playwright features, such as page.get_by_text() or the :has-text() selector, have different default behaviors regarding case sensitivity [3][4].

Citations:


Align the Slack body check with the accepted instruction shapes. The helper allows either "message the slack app" or "slack" + "pairing code", but the later to_contain_text("pairing code") runs unconditionally and is case-sensitive by default. Gate that assertion on the matched branch or use ignore_case=True.

🤖 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 `@scripts/reborn_webui_v2_live_qa/run_live_qa.py` around lines 1932 - 1934, The
Slack instruction validator in _slack_connect_instructions_look_valid accepts
two shapes, but the later pairing-code text check is always applied and may fail
for the “message the slack app” branch. Update the logic around this helper so
the to_contain_text("pairing code") assertion only runs when the
Slack/pairing-code branch matched, or make that assertion case-insensitive with
ignore_case=True. Use the existing _slack_connect_instructions_look_valid and
to_contain_text call sites to keep the branching consistent.

@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

⚠️ 3 Reborn crate(s) have 0 int-tier coverage (target: 0) — ironclaw_reborn_identity, ironclaw_reborn_traces, ironclaw_webui_v2

Reborn integration-tier coverage

Line coverage (Reborn crates): 17.19% — 11063 / 64362 lines

Per-crate breakdown (11 crates, lowest-covered first)
Crate Line % Covered / Total
ironclaw_reborn_identity 0% 0 / 230
ironclaw_reborn_traces 0% 0 / 6769
ironclaw_webui_v2 0% 0 / 2785
ironclaw_reborn_event_store 0.73% 6 / 825
ironclaw_reborn_config 1.31% 15 / 1142
ironclaw_product_adapter_registry 5.12% 25 / 488
ironclaw_product_workflow 7.23% 716 / 9905
ironclaw_product_adapters 12.55% 283 / 2255
ironclaw_reborn 23.44% 2041 / 8707
ironclaw_reborn_composition 25.5% 7966 / 31242
ironclaw_product_context 78.57% 11 / 14

This signal is informational: coverage never gates the PR — not the percentage, not the per-crate holes, not the 0-coverage callout.

@railway-app

railway-app Bot commented Jul 4, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the ironclaw-pr-5632 environment in ironclaw-ci-preview

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 4, 2026 at 1:23 pm

@ironloopai

ironloopai Bot commented Jul 4, 2026 •

Copy link
Copy Markdown
Contributor

IronLoop Review Status

Head: f4ba566356eae2a587f497cdcbbe00cde85abf6e
Updated: 2026-07-04T10:25:28.537Z

Current reviewers:

Reviewer State Verdict What it means Last update
none Queued n/a No reviewer jobs scheduled yet. n/a
Recent activity
Time Reviewer State Detail
n/a n/a Waiting No progress events recorded yet.
Available commands
  • @ironloop review
  • @ironloop review --agent <agent-id-or-alias>
  • @ironloop status
  • @ironloop agents
Run metadata

Admission: webhook accepted the request and IronLoop persisted review state before this projection.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5632 July 4, 2026 10:17 Destroyed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/reborn_webui_v2_live_qa/test_run_live_qa.py (1)

277-294: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Cover the legacy Slack copy in _slack_connect_case

test_slack_connect_instruction_validation_accepts_pairing_copy only hits _slack_connect_instructions_look_valid; add the old Message the Slack app, then enter the code here. path through _slack_connect_case too so the unconditional body assertion at run_live_qa.py:2000 is exercised for both instruction variants.

🤖 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 `@scripts/reborn_webui_v2_live_qa/test_run_live_qa.py` around lines 277 - 294,
The Slack connect test only validates _slack_connect_instructions_look_valid,
but it should also exercise _slack_connect_case for the legacy “Message the
Slack app, then enter the code here.” copy so the unconditional body assertion
is covered. Update
test_slack_connect_instruction_validation_accepts_pairing_copy to drive both
instruction variants through _slack_connect_case in run_live_qa.py, alongside
the existing validation checks, using the _slack_connect_case and
_slack_connect_instructions_look_valid symbols to locate the flow.
♻️ Duplicate comments (1)
scripts/reborn_webui_v2_live_qa/run_live_qa.py (1)

1943-2003: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Unconditional "pairing code" body assertion still not gated on the matched branch.

_slack_connect_instructions_look_valid accepts either "message the slack app" or "slack"+"pairing code", but Line 2000 asserts the body always contains "pairing code" regardless of which branch matched. If production instructions ever return the legacy "Message the Slack app" copy (no "pairing code" substring), this check fails even though the instructions validator passed. This is the same defect flagged in a prior review round on this helper and was not resolved.

♻️ Proposed fix: gate the assertion on the matched branch
-        instructions = str(action_body.get("instructions") or "")
-        if not _slack_connect_instructions_look_valid(instructions):
-            raise AssertionError(f"unexpected Slack connect instructions: {instructions!r}")
-        await expect(page.locator("body")).to_contain_text(title, timeout=15000)  # type: ignore[attr-defined]
-        await expect(page.locator("body")).to_contain_text("pairing code", timeout=15000)  # type: ignore[attr-defined]
+        instructions = str(action_body.get("instructions") or "")
+        if not _slack_connect_instructions_look_valid(instructions):
+            raise AssertionError(f"unexpected Slack connect instructions: {instructions!r}")
+        await expect(page.locator("body")).to_contain_text(title, timeout=15000)  # type: ignore[attr-defined]
+        if "pairing code" in instructions.lower():
+            await expect(page.locator("body")).to_contain_text(
+                "pairing code", timeout=15000
+            )  # type: ignore[attr-defined]
🤖 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 `@scripts/reborn_webui_v2_live_qa/run_live_qa.py` around lines 1943 - 2003, The
Slack connect flow in _slack_connect_case still unconditionally checks for
“pairing code” even when _slack_connect_instructions_look_valid matches the
legacy “message the slack app” branch. Update the assertion logic around the
body text checks so it follows the same branch used by the validator, and only
require “pairing code” when the instructions actually contain the newer Slack
pairing-code copy. Keep the fix localized to _slack_connect_case and the helper
_slack_connect_instructions_look_valid.
🤖 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.

Outside diff comments:
In `@scripts/reborn_webui_v2_live_qa/test_run_live_qa.py`:
- Around line 277-294: The Slack connect test only validates
_slack_connect_instructions_look_valid, but it should also exercise
_slack_connect_case for the legacy “Message the Slack app, then enter the code
here.” copy so the unconditional body assertion is covered. Update
test_slack_connect_instruction_validation_accepts_pairing_copy to drive both
instruction variants through _slack_connect_case in run_live_qa.py, alongside
the existing validation checks, using the _slack_connect_case and
_slack_connect_instructions_look_valid symbols to locate the flow.

---

Duplicate comments:
In `@scripts/reborn_webui_v2_live_qa/run_live_qa.py`:
- Around line 1943-2003: The Slack connect flow in _slack_connect_case still
unconditionally checks for “pairing code” even when
_slack_connect_instructions_look_valid matches the legacy “message the slack
app” branch. Update the assertion logic around the body text checks so it
follows the same branch used by the validator, and only require “pairing code”
when the instructions actually contain the newer Slack pairing-code copy. Keep
the fix localized to _slack_connect_case and the helper
_slack_connect_instructions_look_valid.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 288ae9b5-5ec6-4cff-8ff8-7142d2772ba0

📥 Commits

Reviewing files that changed from the base of the PR and between ab8cb43 and ad183af.

📒 Files selected for processing (2)
  • scripts/reborn_webui_v2_live_qa/run_live_qa.py
  • scripts/reborn_webui_v2_live_qa/test_run_live_qa.py

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5632 July 4, 2026 10:25 Destroyed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/reborn_webui_v2_live_qa/test_run_live_qa.py (1)

135-276: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Test doesn't cover the legacy "message the slack app" instructions against the hard "pairing code" body assertion.

The mocked payload always uses pairing-code copy, so this test can't catch the case where _slack_connect_instructions_look_valid accepts legacy copy but the unconditional to_contain_text("pairing code") in run_live_qa.py would fail for it. Root cause tracked in the corresponding run_live_qa.py comment.

🤖 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 `@scripts/reborn_webui_v2_live_qa/test_run_live_qa.py` around lines 135 - 276,
The Slack connect test only uses pairing-code copy, so it never exercises the
legacy “message the Slack app” instructions path that the UI validation still
needs to handle. Update the mocked payload in
test_slack_connect_case_uses_extensions_channels_surface to include a legacy
instructions variant alongside the current pairing-code variant, and assert
behavior for both so the test covers _slack_connect_instructions_look_valid as
well as the unconditional pairing code expectation in _slack_connect_case. Keep
the existing checks on fetched_paths, expected_texts, and result.details, but
add coverage that would fail if legacy copy is treated as valid without the
“pairing code” body text.
🤖 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.

Outside diff comments:
In `@scripts/reborn_webui_v2_live_qa/test_run_live_qa.py`:
- Around line 135-276: The Slack connect test only uses pairing-code copy, so it
never exercises the legacy “message the Slack app” instructions path that the UI
validation still needs to handle. Update the mocked payload in
test_slack_connect_case_uses_extensions_channels_surface to include a legacy
instructions variant alongside the current pairing-code variant, and assert
behavior for both so the test covers _slack_connect_instructions_look_valid as
well as the unconditional pairing code expectation in _slack_connect_case. Keep
the existing checks on fetched_paths, expected_texts, and result.details, but
add coverage that would fail if legacy copy is treated as valid without the
“pairing code” body text.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8430627a-6c98-4a49-99c2-13a66c4809a8

📥 Commits

Reviewing files that changed from the base of the PR and between ad183af and f4ba566.

📒 Files selected for processing (2)
  • scripts/reborn_webui_v2_live_qa/run_live_qa.py
  • scripts/reborn_webui_v2_live_qa/test_run_live_qa.py

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5632 July 4, 2026 12:43 Destroyed
@github-actions github-actions Bot added size: L 200-499 changed lines and removed size: M 50-199 changed lines labels Jul 4, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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 `@crates/ironclaw_reborn_composition/src/extension_lifecycle.rs`:
- Around line 224-227: The guidance text in search() is duplicated with the
builtin.extension_search manifest description, so the two hand-maintained
strings can drift. Extract the shared “prefer the configured outbound delivery
target over activating” wording into a shared const/helper and have
extension_lifecycle.rs and extension_lifecycle_capabilities.rs compose their
messages from that single source of truth. Update the related tests to assert
against the shared text via the symbols search() and builtin.extension_search so
both call sites stay aligned.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 49db9186-8ebb-4186-9e95-ae3d4c1b938b

📥 Commits

Reviewing files that changed from the base of the PR and between f4ba566 and d9f7e45.

📒 Files selected for processing (4)
  • crates/ironclaw_reborn_composition/src/extension_lifecycle.rs
  • crates/ironclaw_reborn_composition/src/extension_lifecycle_capabilities.rs
  • scripts/reborn_webui_v2_live_qa/run_live_qa.py
  • scripts/reborn_webui_v2_live_qa/test_run_live_qa.py

Comment on lines 224 to 227
response.message = Some(
"Search found installed external channel results. Search cannot prove the calling user's channel account is personally connected, so do not treat those results as ready for delivery or message access. Call builtin.extension_activate now for the matching extension id; activation surfaces the channel-specific pairing/setup instructions and, for proof-code flows, the user must paste the code into the WebChat connection panel rather than normal chat."
"Search found installed external channel results. Search cannot prove the calling user's channel account is personally connected. For an explicit connect, pair, authenticate, or account-access request, call builtin.extension_activate for the matching extension id so channel-specific pairing/setup instructions can be surfaced. For routine, trigger, or notification delivery, prefer the configured outbound delivery target when one is available; do not activate the channel just to send to an already configured delivery target."
.to_string(),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Guidance text duplicated by hand across two files.

This search() message and the builtin.extension_search manifest description in extension_lifecycle_capabilities.rs (line 71) both encode the same "prefer the configured outbound delivery target over activating" rule in independently-worded, hand-maintained strings, only cross-checked via substring assertions in each file's tests. A future edit to one could silently drift from the other since nothing enforces they agree.

Consider extracting the shared clause(s) into a const/helper so both call sites compose from one source of truth.

🤖 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 `@crates/ironclaw_reborn_composition/src/extension_lifecycle.rs` around lines
224 - 227, The guidance text in search() is duplicated with the
builtin.extension_search manifest description, so the two hand-maintained
strings can drift. Extract the shared “prefer the configured outbound delivery
target over activating” wording into a shared const/helper and have
extension_lifecycle.rs and extension_lifecycle_capabilities.rs compose their
messages from that single source of truth. Update the related tests to assert
against the shared text via the symbols search() and builtin.extension_search so
both call sites stay aligned.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5632 July 4, 2026 13:22 Destroyed
@serrrfirat
serrrfirat merged commit 2603114 into main Jul 4, 2026
129 checks passed
@serrrfirat
serrrfirat deleted the codex/slack-live-canary-harness-fix branch July 4, 2026 16:43

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-5632 — f70eb2f6 Deployed Jul 4, 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 size: L 200-499 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant