Skip to content

Fix main Reborn Playwright failures - #6554

Closed
ilblackdragon wants to merge 5 commits into
mainfrom
codex/reborn-product-surface-review-fixes
Closed

ilblackdragon wants to merge 5 commits into
mainfrom
codex/reborn-product-surface-review-fixes

Conversation

@ilblackdragon

@ilblackdragon ilblackdragon commented Jul 23, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Replaces Fix main Reborn Playwright failures #6546 and Fix main Reborn Playwright failures #6553, which GitHub left in an unreopenable stale pull-ref state after review-fix force-pushes.
  • Fix WebUI ProductSurface extension lifecycle ingress by carrying client_action_id through install/activate/remove/setup and deriving stable scoped activity IDs without the old channel envelope.
  • Address review feedback for provider display-name guards and LLM provider activity IDs by using own-property checks and excluding raw API-key bytes from deterministic UUID seeds.
  • Update Reborn WebUI, Rust integration, and Playwright expectations for the current ProductSurface extension/channel ingress contract.

Change Type

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • CI/Infrastructure
  • Security
  • Dependencies

Linked Issue

None.

Validation

  • cargo fmt --all -- --check
  • cargo clippy --all --benches --tests --examples --all-features -- -D warnings: Not run as full workspace; targeted touched-crate clippy command passed.
  • cargo build: covered by earlier cargo build -p ironclaw --bin ironclaw before review-fix amendments.
  • Relevant tests pass: see commands below.
  • cargo test --features integration if database-backed or integration behavior changed: targeted Reborn integration test passed.
  • Manual testing: targeted Playwright legacy extensions shard passed locally.
  • If a coding agent was used and supports it, review-pr or pr-shepherd --fix was run before requesting review: Not applicable; review comments were inspected and addressed manually.

Test Strategy

User behavior:
WebUI and CLI/channel ingress use ProductSurface as the product-facing boundary. Extension lifecycle gestures carry stable client action IDs so browser retries resolve to the same ProductSurface activity instead of dropping responses or colliding with unrelated requests.

Risk areas:

  • Model behavior
  • Browser
  • Side effect
  • Persistence
  • Security or permissions
  • External provider
  • Cross-component behavior

Tests added or updated:

  • Unit or contract: WebUI handler contract tests for extension lifecycle action IDs and deterministic ProductSurface activity IDs.
  • Reborn integration: reborn_integration_webui_v2_product_api updated to send lifecycle client_action_id through the production WebUI facade.
  • Recorded fixture: Not applicable: no model request-shape or tool-choice behavior changed.
  • Browser E2E: Reborn legacy extension Playwright shard updated and run locally.
  • Backend or runtime: targeted product-workflow, webui, composition, and integration commands below.
  • Live canary: Not applicable: no live provider behavior changed.

What the tests prove:
Extension lifecycle requests validate and preserve the client action ID from frontend/e2e/integration ingress, deterministic activity IDs are stable for retried install gestures, setup still forwards the expected product capability input, and the browser legacy extension flow matches the new API contract.

Commands run:

  • cargo fmt --all -- --check
  • git diff --check
  • cargo build -p ironclaw --bin ironclaw
  • cargo test -p ironclaw_product_workflow --test product_commands_contract
  • cargo test -p ironclaw_reborn_composition --test webui_v2_e2e
  • cargo test -p ironclaw_reborn_composition product_invocation_mounts_grants_extension_lifecycle_mounts
  • corepack pnpm --dir crates/ironclaw_webui/frontend lint:conventions && corepack pnpm --dir crates/ironclaw_webui/frontend typecheck
  • corepack pnpm --dir crates/ironclaw_webui/frontend test -- src/pages/extensions/lib/extensions-api.test.ts src/pages/extensions/hooks/useExtensions-catalog.test.ts
  • python3 -m pytest scenarios/test_emulate_reborn_provider_contracts.py::test_emulate_google_covers_reborn_gsuite_read_inputs scenarios/test_emulate_reborn_provider_contracts.py::test_emulate_google_covers_reborn_docs_contract scenarios/test_emulate_reborn_provider_contracts.py::test_emulate_google_covers_reborn_sheets_contract -q from tests/e2e (1 passed, 2 skipped because Emulate 0.7.0 lacks Docs/Sheets endpoints)
  • python3 -m pytest scenarios/test_reborn_qa_trace_full_path.py -q from tests/e2e (13 passed, 17 skipped for Emulate 0.7.0 unsupported Docs/Sheets/Slack GET routes)
  • Full Reborn Playwright workflow matrix locally from tests/e2e: python3 -m pytest <reborn-playwright matrix files> -k 'not test_reborn_legacy_always_approve_survives_reborn_restart' -q --timeout=120 --durations=25 (204 passed, 1 deselected)

Security Impact

No new authentication bypass, network access, or secret exposure. The LLM provider activity seed now records secret presence without hashing raw API-key bytes. Lifecycle action IDs are validated as WebUI client action IDs before being converted into scoped ProductSurface activity IDs.

Reborn Trust-Boundary Checklist

  • Public policy/evidence/trust-bearing types: who can construct them? ProductSurface remains the ingress boundary; WebUI action IDs are validated before use.
  • Untrusted content enters prompts only through an envelope/escaping primitive. Not applicable: no prompt path changes.
  • Hashes declare purpose; trust/binding/authenticity uses SHA-256/BLAKE3 or separate authenticity check. Deterministic UUID seeding no longer includes secret bytes.
  • New/changed status, exit, policy, runtime, or error variants: downstream match sites audited. No variants added or changed.
  • Security/durability serde(default) fields fail closed or have migration tests. Optional client action fields are accepted only at compatibility seams; route validation still requires them for lifecycle POSTs.
  • Queues/maps/buffers/counters have bounds and overflow-safe arithmetic. Not applicable.
  • Driver/operator-visible errors have stable class semantics (Transient, Permanent, Misconfigured, PolicyDenied or equivalent). Existing validation error mapping retained.
  • Sandbox/native/host names accurately describe trust boundary. ProductSurface naming retained.

Database Impact

None.

Blast Radius

Touches WebUI extension lifecycle handlers, ProductSurface inbound request shaping, frontend/e2e lifecycle calls, and production WebUI integration fixtures. A regression would most likely appear as install/activate/remove validation failure, retry idempotency mismatch, or stale extension setup input shape.

Rollback Plan

Revert this PR and continue using the prior extension lifecycle request contract while the ProductSurface migration is revisited. This is source-compatible for persistence because no database schema changes are included.

Review Follow-Through

Review comments from #6546 were addressed here. #6546 is closed and #6553 will be closed because GitHub refused to reopen it after its pull ref stopped tracking the branch.


Review track: C (runtime/permissions/browser CI)

@ironloopai

ironloopai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

🔎 IronLoop Review Status

Head: 9b11181e37fdf8fcb8a1ee1a5ba8ba89768f8331
Result: 1 blocking finding across 1 reviewer.
Next: Address the blocking findings, push fixes, then re-run the relevant reviewer.
Updated: 2026-07-23T09:03:55.834Z

Current reviewers:

Reviewer State Verdict Findings Last update
ironloop/common-reviewer (reviewer) Completed Changes requested 1 blocking finding / 0 notes 2026-07-23T09:03:55.825Z
Reviewer summaries
Reviewer Detail
ironloop/common-reviewer (reviewer) Changes requested; 1 blocking finding; Found a blocking lifecycle-retry defect: stable activity IDs are not backed by replay/deduplication in the real Reborn execution path.
Recent activity
Time Reviewer State Detail
2026-07-23T07:34:10.403Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
2026-07-23T08:24:23.435Z ironloop/common-reviewer (reviewer) Superseded A newer PR head replaced this review (c26d188).
2026-07-23T08:51:20.476Z ironloop/common-reviewer (reviewer) Queued Accepted review request for head 9b11181.
2026-07-23T08:51:20.476Z ironloop/common-reviewer (reviewer) Queued Waiting for this reviewer lane to become available.
2026-07-23T08:51:21.024Z ironloop/common-reviewer (reviewer) Started Reviewer worker started.
2026-07-23T08:51:24.246Z ironloop/common-reviewer (reviewer) Workspace ready Prepared isolated checkout (merge_ref) at 6b6b88d.
2026-07-23T09:03:55.825Z ironloop/common-reviewer (reviewer) Result captured Changes requested; 1 blocking finding.
2026-07-23T09:03:55.825Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
Available commands
  • @ironloopai help
  • @ironloopai agents
  • @ironloopai review
  • @ironloopai review --agent <agent>
Run metadata

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

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6554 July 23, 2026 07:24 Destroyed
@github-actions github-actions Bot added size: XL 500+ changed lines risk: low Changes to docs, tests, or low-risk modules labels Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Extension install, activate, remove, and setup (WebUI v2) now accept client action identifiers and use them for consistent action/activity tracking across retries.
    • Extension lifecycle capabilities are routed to the correct WebUI controls/mounts.
  • Bug Fixes
    • Removing an already-absent extension now completes safely without impacting later reinstall/activation.
    • Hosted MCP removals now unpublish the correct active package during teardown.
    • Client-side attachment fallback limit increased to 10 MB per file.
    • Extension lifecycle command parsing now accepts both id and extension_id.
    • Gate outcomes for deny/cancel flows now resolve as “declined”.

Walkthrough

WebUI extension mutations now carry client action identifiers through frontend requests, handlers, activity IDs, and tests. Extension removal uses active package snapshots and supports already-absent cleanup. Lifecycle mounts, command parsing, frontend presentation, attachment limits, and E2E contracts are also updated.

Changes

WebUI action identity propagation

Layer / File(s) Summary
Client action contracts
crates/ironclaw_product_workflow/src/*, crates/ironclaw_product_workflow/tests/*
Setup DTOs accept optional client_action_id, parsing is publicly re-exported, and extension lifecycle command references accept extension_id.
Frontend mutation payloads
crates/ironclaw_webui/frontend/src/lib/*, crates/ironclaw_webui/frontend/src/pages/extensions/*
Install, activate, remove, and setup requests generate or preserve client action identifiers.
Deterministic activity ID routing
crates/ironclaw_webui/src/webui_v2/handlers.rs
Lifecycle, setup, outbound preference, and LLM provider routes use specialized activity-ID derivation.
Action identity validation
crates/ironclaw_webui/tests/*, tests/e2e/scenarios/*, tests/integration/*
Tests verify payload propagation and stable activity IDs across retries and lifecycle calls.

Extension lifecycle removal and mounting

Layer / File(s) Summary
Active package removal compensation
crates/ironclaw_reborn_composition/src/extension_host/*
Removal and compensation use active package snapshots and cover already-absent cleanup.
Lifecycle capability mounting
crates/ironclaw_reborn_composition/src/factory.rs, src/webui/*, src/webui/facade/tests.rs
Extension lifecycle capabilities resolve to system extension mounts and are exercised through install, activate, and remove flows.
Outbound type import wiring
crates/ironclaw_reborn_composition/src/outbound/*, src/runtime*
The outbound registration outcome type is imported directly from ironclaw_outbound.

WebUI contract and presentation updates

Layer / File(s) Summary
Frontend display and attachment contracts
crates/ironclaw_webui/frontend/src/pages/chat/*, tests/e2e/scenarios/test_reborn_webui_v2_legacy_attachments.py
Provider display mappings and the fallback attachment limit are updated.
Legacy extension request assertions
tests/e2e/scenarios/test_reborn_webui_v2_legacy_extensions.py
Shared helpers validate client action IDs and normalize install/setup request assertions.
Legacy WebUI and provider scenarios
tests/e2e/scenarios/test_reborn_webui_v2_legacy_*.py, test_reborn_webui_v2_automation_trace_outbound_api.py, test_reborn_qa_trace_full_path.py
Resolution labels, extension surfaces, channel search, outbound route checks, trace normalization, and optional provider availability handling are updated.
Emulate process infrastructure
tests/e2e/conftest.py, tests/e2e/scenarios/test_emulate_reborn_provider_contracts.py
Emulate teardown targets subprocess groups, provider ports are re-reserved with retries, and unavailable provider routes cause contract tests to skip.

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

Possibly related issues

Possibly related PRs

Suggested reviewers: serrrfirat, henrypark133, think-in-universe

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is clearly related to the PR’s main change, though it is not in Conventional Commits form.
Description check ✅ Passed The description largely follows the template and includes summary, validation, test strategy, security, rollback, and review follow-through.
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

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@ironloopai ironloopai 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.

❌ IronLoop Review: reviewer

Review at a glance

Verdict Blocking Notes Inline Head
❌ Changes requested 1 0 1 3d648f4f1289

Head: 3d648f4f12897c2397c10fda9d8c3a85fc13c085
Next: Fix the blocking findings, push the PR branch, then re-run this reviewer.

Run details

Status: Current
Needs human: no
Needs validation: no

Summary

The backend preserves supplied lifecycle action IDs, but the browser generates a new ID on each mutation call, so response-lost retries cannot reuse the ProductSurface activity ID.

Findings

Blocking: 1 / Notes: 0

Blocking findings

1. ❌ [MEDIUM] Lifecycle retries mint a new client action ID

Location: crates/ironclaw_webui/frontend/src/pages/extensions/lib/extensions-api.ts:22
The ID is generated inside each helper call, and install/activate/remove do not accept an ID from a retry layer; setup similarly omits one when calling setupExtension. Retrying after a lost response therefore creates a different extension_lifecycle_activity_id, so the backend's retry identity guarantee is unreachable from the browser. Generate and retain one ID per user gesture, pass it through every retry, and cover that behavior in a frontend test.

Developer follow-up

After fixing this feedback:

  1. Push the fix to this PR branch.
  2. Re-run this reviewer with @ironloopai review --agent reviewer if you only changed this reviewer's findings.
  3. Re-run all reviewers with @ironloopai review when the fix may affect multiple areas.

body: JSON.stringify({ package_ref: packageRef }),
body: JSON.stringify({
package_ref: packageRef,
client_action_id: clientActionId(),

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.

This ID is minted per helper invocation, not per user gesture. A response-lost retry calls the helper again and gets a new ID, producing a different ProductSurface activity instead of the stable retry identity tested by the handler contract. Retain/pass an action ID from the mutation or retry layer, including setup.

@railway-app

railway-app Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

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

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 23, 2026 at 9:00 am

@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: 3

Caution

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

⚠️ Outside diff range comments (2)
crates/ironclaw_reborn_composition/src/webui/product_capability.rs (1)

252-267: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Route extension-lifecycle mounts through the Production/LocalDev branch.

product_invocation_mounts() only branches ProductCapabilityMounts for skill management, while extension install/activate/remove always calls crate::local_dev_mounts::system_extensions_lifecycle_mount_view() from a local-dev module and tests only ProductCapabilityMounts::LocalDev. Add/cover the intended production mount path so production capability invocations do not get an unscopable or stale mount view.

Compliance: violation of codebase invariant from crates/ironclaw_reborn_composition/src/webui/product_capability.rs that production capability grants use ProductCapabilityMounts::Production and fail closed for missing/incorrect mounts.

🤖 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/webui/product_capability.rs` around
lines 252 - 267, Update product_invocation_mounts so extension-lifecycle
capabilities also branch on ProductCapabilityMounts::LocalDev versus
ProductCapabilityMounts::Production instead of always calling
system_extensions_lifecycle_mount_view. Add or reuse the production-specific
mount-view function for the Production branch, preserve scoped local-dev
behavior, and ensure missing or incorrect production mounts fail closed.
crates/ironclaw_webui/src/webui_v2/handlers.rs (1)

2267-2292: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated parse-then-derive-activity-id boilerplate across all four lifecycle handlers.

install_extension, activate_extension, remove_extension, setup_extension each repeat:

let client_action_id = parse_webui_client_action_id(body.client_action_id...).map_err(RebornServicesError::from)?;
let activity_id = extension_lifecycle_activity_id(&caller, CAPABILITY, &package_ref, client_action_id.as_str())?;

As per coding guidelines, "Keep functions focused and extract helpers when logic is reused." Extracting a single helper reduces the risk of one call site drifting (e.g., forgetting the .map_err mapping) as this pattern grows.

♻️ Proposed helper
fn parse_extension_lifecycle_activity_id(
    caller: &WebUiAuthenticatedCaller,
    capability: ProductCapabilityDescriptor,
    package_ref: &LifecyclePackageRef,
    client_action_id: Option<String>,
) -> Result<ActivityId, RebornServicesError> {
    let client_action_id =
        parse_webui_client_action_id(client_action_id).map_err(RebornServicesError::from)?;
    extension_lifecycle_activity_id(caller, capability, package_ref, client_action_id.as_str())
}

Each handler then calls parse_extension_lifecycle_activity_id(&caller, CAPABILITY, &package_ref, body.client_action_id)?.

Also applies to: 2318-2347, 2350-2379, 2555-2605

🤖 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_webui/src/webui_v2/handlers.rs` around lines 2267 - 2292,
Extract the repeated client-action parsing and lifecycle activity-ID derivation
from install_extension, activate_extension, remove_extension, and
setup_extension into a shared parse_extension_lifecycle_activity_id helper.
Preserve the existing parse_webui_client_action_id error mapping and pass each
handler’s caller, capability, package_ref, and body.client_action_id through the
helper.

Source: Coding guidelines

🤖 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_host/extension_lifecycle.rs`:
- Around line 2184-2189: In the active package selection near
active_extensions.snapshot().get_extension(), add a concise inline comment
documenting that hosted-MCP discovery can make the active-registry package
differ from lifecycle_package, so the snapshot lookup is preferred and
lifecycle_package is only the fallback.

In
`@crates/ironclaw_webui/frontend/src/pages/chat/components/auth-oauth-card.tsx`:
- Around line 45-54: Update PROVIDER_DISPLAY_NAMES to include the
github-to-GitHub override, then remove the separate providerId === ["git",
"hub"].join("") branch from providerDisplayName so all provider display-name
overrides use the map.

In `@crates/ironclaw_webui/frontend/src/pages/extensions/lib/extensions-api.ts`:
- Around line 17-43: Update installExtension, activateExtension, and
removeExtension to accept an optional caller-supplied client action ID and use
it instead of always invoking clientActionId(), matching setupExtension’s
override behavior. Propagate this stable ID through the related hook and
mutation paths so retries reuse the same activity identity while preserving
generated IDs when no override is provided.

---

Outside diff comments:
In `@crates/ironclaw_reborn_composition/src/webui/product_capability.rs`:
- Around line 252-267: Update product_invocation_mounts so extension-lifecycle
capabilities also branch on ProductCapabilityMounts::LocalDev versus
ProductCapabilityMounts::Production instead of always calling
system_extensions_lifecycle_mount_view. Add or reuse the production-specific
mount-view function for the Production branch, preserve scoped local-dev
behavior, and ensure missing or incorrect production mounts fail closed.

In `@crates/ironclaw_webui/src/webui_v2/handlers.rs`:
- Around line 2267-2292: Extract the repeated client-action parsing and
lifecycle activity-ID derivation from install_extension, activate_extension,
remove_extension, and setup_extension into a shared
parse_extension_lifecycle_activity_id helper. Preserve the existing
parse_webui_client_action_id error mapping and pass each handler’s caller,
capability, package_ref, and body.client_action_id through the helper.
🪄 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: b4181f0f-dec3-4be4-a62a-4c4ea7b794f1

📥 Commits

Reviewing files that changed from the base of the PR and between 342bb85 and 3d648f4.

📒 Files selected for processing (30)
  • crates/ironclaw_product_workflow/src/lib.rs
  • crates/ironclaw_product_workflow/src/reborn_services/extension_setup_credentials.rs
  • crates/ironclaw_product_workflow/src/webui_inbound.rs
  • crates/ironclaw_product_workflow/tests/reborn_services_contract.rs
  • crates/ironclaw_reborn_composition/src/extension_host/extension_lifecycle.rs
  • crates/ironclaw_reborn_composition/src/extension_host/extension_lifecycle_capabilities.rs
  • crates/ironclaw_reborn_composition/src/outbound/mod.rs
  • crates/ironclaw_reborn_composition/src/runtime.rs
  • crates/ironclaw_reborn_composition/src/runtime/tests/core.rs
  • crates/ironclaw_reborn_composition/src/runtime/tests/outbound_delivery.rs
  • crates/ironclaw_reborn_composition/src/webui/facade/tests.rs
  • crates/ironclaw_reborn_composition/src/webui/product_capability.rs
  • crates/ironclaw_webui/frontend/src/lib/api.test.ts
  • crates/ironclaw_webui/frontend/src/lib/api.ts
  • crates/ironclaw_webui/frontend/src/pages/chat/components/auth-oauth-card.tsx
  • crates/ironclaw_webui/frontend/src/pages/chat/lib/attachments.ts
  • crates/ironclaw_webui/frontend/src/pages/extensions/lib/extensions-api.test.ts
  • crates/ironclaw_webui/frontend/src/pages/extensions/lib/extensions-api.ts
  • crates/ironclaw_webui/src/webui_v2/handlers.rs
  • crates/ironclaw_webui/tests/webui_v2_handlers_contract.rs
  • tests/e2e/scenarios/test_reborn_qa_trace_full_path.py
  • tests/e2e/scenarios/test_reborn_slack_channel_e2e.py
  • tests/e2e/scenarios/test_reborn_webui_v2_automation_trace_outbound_api.py
  • tests/e2e/scenarios/test_reborn_webui_v2_extensions_api.py
  • tests/e2e/scenarios/test_reborn_webui_v2_legacy_approval.py
  • tests/e2e/scenarios/test_reborn_webui_v2_legacy_attachments.py
  • tests/e2e/scenarios/test_reborn_webui_v2_legacy_auth_flows.py
  • tests/e2e/scenarios/test_reborn_webui_v2_legacy_extensions.py
  • tests/e2e/scenarios/test_reborn_webui_v2_legacy_settings_search.py
  • tests/integration/webui_v2_product_api.rs
💤 Files with no reviewable changes (1)
  • tests/e2e/scenarios/test_reborn_webui_v2_automation_trace_outbound_api.py

Comment thread crates/ironclaw_webui/frontend/src/pages/chat/components/auth-oauth-card.tsx Outdated
Comment thread crates/ironclaw_webui/frontend/src/pages/extensions/lib/extensions-api.ts Outdated
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6554 July 23, 2026 08:24 Destroyed
@ilblackdragon

Copy link
Copy Markdown
Member Author

@ironloopai review --agent reviewer

@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 `@tests/e2e/scenarios/test_emulate_reborn_provider_contracts.py`:
- Around line 231-232: Restrict the 404 skip branches around the Google Docs and
corresponding provider readback checks to the fixture’s declared Emulate 0.7.0
version or explicit unsupported-capability flag. Allow all other 404 responses
to continue through the normal assertions so incorrect routes, authentication
failures, fixture issues, and regressions fail the tests; preserve provider
readback/state assertions for supported capabilities.
🪄 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: 7aa6e9c6-ae54-4196-8ca4-244c22af4208

📥 Commits

Reviewing files that changed from the base of the PR and between 3d648f4 and c26d188.

📒 Files selected for processing (11)
  • crates/ironclaw_product_workflow/src/commands.rs
  • crates/ironclaw_product_workflow/tests/product_commands_contract.rs
  • crates/ironclaw_reborn_composition/src/factory.rs
  • crates/ironclaw_reborn_composition/src/webui/product_capability.rs
  • crates/ironclaw_reborn_composition/tests/webui_v2_e2e.rs
  • crates/ironclaw_webui/frontend/src/pages/extensions/hooks/useExtensions-catalog.test.ts
  • crates/ironclaw_webui/frontend/src/pages/extensions/hooks/useExtensions.ts
  • crates/ironclaw_webui/frontend/src/pages/extensions/lib/extensions-api.test.ts
  • crates/ironclaw_webui/frontend/src/pages/extensions/lib/extensions-api.ts
  • tests/e2e/scenarios/test_emulate_reborn_provider_contracts.py
  • tests/e2e/scenarios/test_reborn_qa_trace_full_path.py

Comment on lines +231 to +232
if created.status_code == 404:
pytest.skip("Emulate 0.7.0 does not expose the Google Docs API")

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 | 🟠 Major | ⚡ Quick win

Narrow the 404 skip to the known unsupported Emulate capability.

These branches skip on any 404, so wrong routes, fixture misconfiguration, auth failures, or emulator regressions become green skipped tests. Gate the skip on the fixture’s declared Emulate version/capability; let unrelated 404 responses fail normally.

As per coding guidelines, Emulate-backed provider tests must assert provider readback/state; this broad skip weakens that contract.

Also applies to: 277-278

🤖 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 `@tests/e2e/scenarios/test_emulate_reborn_provider_contracts.py` around lines
231 - 232, Restrict the 404 skip branches around the Google Docs and
corresponding provider readback checks to the fixture’s declared Emulate 0.7.0
version or explicit unsupported-capability flag. Allow all other 404 responses
to continue through the normal assertions so incorrect routes, authentication
failures, fixture issues, and regressions fail the tests; preserve provider
readback/state assertions for supported capabilities.

Source: Coding guidelines

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6557 July 23, 2026 08:52 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)
tests/e2e/scenarios/test_reborn_qa_trace_full_path.py (1)

787-799: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Single-caller wrapper — inline into its only caller.

_install_inline_trace only wraps a POST to /__mock/llm_trace and is called once, from test_provider_operation_case_executes_with_provider_readback (line 1365). Based on learnings, prefer a cohesive single-operation implementation over extracting a helper used by only one caller when it doesn't materially reduce complexity — this is exactly the "wrapper around a fetch flow" case called out.

♻️ Inline into the single caller
-async def _install_inline_trace(
-    mock_llm_server: str,
-    source: str,
-    trace: dict,
-) -> None:
-    async with httpx.AsyncClient() as client:
-        response = await client.post(
-            f"{mock_llm_server}/__mock/llm_trace",
-            json={"source": source, "trace": trace},
-            timeout=15,
-        )
-    response.raise_for_status()
-
-
 def _provider_operation_trace(case: ProviderOperationCase) -> dict:

And at the call site:

     await operation_case.assert_baseline(emulate_url)
-    await _install_inline_trace(mock_llm_server, source, trace)
+    async with httpx.AsyncClient() as client:
+        response = await client.post(
+            f"{mock_llm_server}/__mock/llm_trace",
+            json={"source": source, "trace": trace},
+            timeout=15,
+        )
+    response.raise_for_status()
🤖 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 `@tests/e2e/scenarios/test_reborn_qa_trace_full_path.py` around lines 787 -
799, Remove the single-use _install_inline_trace helper and inline its HTTP POST
and response.raise_for_status flow directly into
test_provider_operation_case_executes_with_provider_readback, preserving the
existing request payload, timeout, and async client behavior.

Source: Learnings

🤖 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 `@tests/e2e/scenarios/test_reborn_qa_trace_full_path.py`:
- Around line 787-799: Remove the single-use _install_inline_trace helper and
inline its HTTP POST and response.raise_for_status flow directly into
test_provider_operation_case_executes_with_provider_readback, preserving the
existing request payload, timeout, and async client behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f6b4e9f3-ca2f-477c-bf20-b2d8ea998e59

📥 Commits

Reviewing files that changed from the base of the PR and between c26d188 and 9b11181.

📒 Files selected for processing (5)
  • crates/ironclaw_reborn_composition/src/extension_host/extension_lifecycle.rs
  • crates/ironclaw_webui/frontend/src/pages/chat/components/auth-oauth-card.tsx
  • tests/e2e/conftest.py
  • tests/e2e/scenarios/test_emulate_reborn_provider_contracts.py
  • tests/e2e/scenarios/test_reborn_qa_trace_full_path.py

@ironloopai ironloopai 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.

❌ IronLoop Review: reviewer

Review at a glance

Verdict Blocking Notes Inline Head
❌ Changes requested 1 0 1 9b11181e37fd

Head: 9b11181e37fdf8fcb8a1ee1a5ba8ba89768f8331
Next: Fix the blocking findings, push the PR branch, then re-run this reviewer.

Run details

Status: Current
Needs human: no
Needs validation: no

Summary

Found a blocking lifecycle-retry defect: stable activity IDs are not backed by replay/deduplication in the real Reborn execution path.

Findings

Blocking: 1 / Notes: 0

Blocking findings

1. ❌ [HIGH] Stable lifecycle IDs do not replay retries

Location: crates/ironclaw_webui/src/webui_v2/handlers.rs:2281
Passing a stable activity ID here does not make a retry idempotent. The runtime invoker calls HostRuntime::invoke_capability again; its durable run-state store rejects the same invocation ID as InvocationAlreadyExists instead of replaying the first outcome. Extension setup takes the other branch and executes its direct product operation again because that branch ignores activity_id. A response-lost retry therefore fails or repeats the side effect. Add a ProductSurface-level replay/deduplication path for all four lifecycle operations and cover it with a real-runtime retry test.

Developer follow-up

After fixing this feedback:

  1. Push the fix to this PR branch.
  2. Re-run this reviewer with @ironloopai review --agent reviewer if you only changed this reviewer's findings.
  3. Re-run all reviewers with @ironloopai review when the fix may affect multiple areas.

&package_ref,
client_action_id.as_str(),
)?;
let resolution = invoke_product_capability_with_activity_id(

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.

The stable activity ID is not sufficient by itself: the real runtime re-enters HostRuntime::invoke_capability, whose run-state store rejects the already-used invocation ID rather than replaying the first outcome. Setup instead re-executes because its direct ProductOperation path ignores activity_id. A response-lost lifecycle retry therefore fails or duplicates work; add ProductSurface-level replay/deduplication and test a real-runtime retry.

@ilblackdragon

Copy link
Copy Markdown
Member Author

Replaced by #6558, which carries the latest main merge and CI/review fixes on a fresh pull ref.

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-6557 — 9b11181e Deployed Jul 23, 2026 by railway-app[bot]
ironclaw-ci-preview / ironclaw-pr-6554 — 9b11181e Deployed Jul 23, 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: XL 500+ changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant