Skip to content

Add durable recovery telemetry and close WS7 retry gaps - #6844

Merged
serrrfirat merged 6 commits into
mainfrom
codex/ws7-error-recoverability
Jul 29, 2026
Merged

serrrfirat merged 6 commits into
mainfrom
codex/ws7-error-recoverability

Conversation

@serrrfirat

@serrrfirat serrrfirat commented Jul 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add durable typed recovery numerator events at every live model and capability RecoveryOutcome application site.
  • Make recovery evidence must-succeed before retry/continuation, with a checkpointed per-run sequence and replay-stable event_id.
  • Preserve legacy milestone/runtime-event decoding and keep recovery projections non-terminal.
  • Keep the live canonical failure_lane and retry_disposition policies, remove only the zero-production-caller parallel classification module, and exercise automatic retry behavior through the runner.
  • Fix compaction secret scanning so dotted package names remain clean while JWT headers with legal leading JSON whitespace are still detected.
  • Add the missing crash-retry-exhausted failure summary and retain current GateDeclined/category behavior after verifying reachable production traces.

Change Type

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

The dependency change is test-only: the root integration harness consumes the existing event-projection crate.

Linked Issue

Related #6284. Follow-up to #5965.

Validation

  • cargo fmt --all -- --check
  • Clippy with -D warnings for every touched crate
  • cargo build
    • Covered by targeted test and clippy compilation.
  • Relevant unit, contract, caller-path, projection, integration, architecture, and binary E2E tests pass
  • cargo test --features integration
    • Not applicable: no database-backed integration behavior changed.
  • Manual testing
    • Not applicable: deterministic runtime/event policy is covered at production caller seams.
  • Multi-lens code review completed
    • Eight reviewer lenses completed exact diff coverage. Verified findings were fixed in 9dfa55801, f2a547742, and 6819ff961.

Test Strategy

User behavior:

Recovered model and capability failures contribute a durable recovery-rate numerator without terminating the run or duplicating a capability side effect. A recovery cannot proceed when its durable event append fails. Dotted package names such as com.fasterxml.jackson no longer poison compaction, while valid JWTs whose header JSON starts with whitespace remain redacted.

Risk areas:

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

Tests added or updated:

  • Unit/contract: recovery append failure gating, model-visible model recovery, direct tool-error recovery, retry recovery, sequence overflow mapping, legacy milestone/runtime-event decoding, JWT/package discrimination, full JWT/Telegram terminal-dash redaction, and custom-backend recovery-label projection sanitization, and oversized JWT fail-closed handling.
  • Caller path: agent loop → HostManagedLoopProgressPort → typed milestone; milestone → stable durable runtime event identity; recovery → final projection.
  • Reborn integration/binary E2E: existing model and capability recovery cases use the production durable milestone adapter and projection.
  • Recorded fixture: Not applicable; scripted deterministic gateway responses exercise the real caller path.
  • Browser E2E: Not applicable; no browser/frontend surface changed.
  • Backend/runtime: in-memory implementations of the durable event-log contract are replayed through the production projection service.
  • Live canary: Not applicable; no external provider or deployment is required.

What the tests prove:

  • Each applied recovery emits one ordered typed numerator event.
  • A recovery append failure gates the next model/capability side effect.
  • Replaying the event-append/checkpoint interruption window preserves the same logical event_id; a different recovery sequence produces a different identity.
  • Physical appends remain at-least-once across separate durable stores; metrics deduplicate with COUNT(DISTINCT event_id) rather than claiming a cross-store transaction.
  • Old milestone records without sequence and old runtime events without recovery fields remain readable.
  • Recovery events do not invent a terminal run transition.
  • JWT classification decodes the base64url JSON header instead of relying on an eyJ prefix.
  • JWT and Telegram matches consume a terminal base64url dash instead of leaving a one-character secret tail.
  • Projection re-sanitizes recovery labels returned by any durable event-log backend before exposing them.
  • Oversized JWT-shaped candidates fail closed before decode allocation or JSON parsing, while redaction still consumes the complete match.

Commands run:

CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo check -q \
  -p ironclaw_safety -p ironclaw_events -p ironclaw_turns \
  -p ironclaw_agent_loop -p ironclaw_runner
# passed

CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_safety bare_jwt_detector
# passed

CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_agent_loop recovery_
CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_agent_loop model_content_filter_gives_model_one_rephrase_attempt
CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_agent_loop repeated_capability_failures_do_not_trip_no_progress_and_run_can_recover
CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_agent_loop model_retry_transition_survives_checkpoint_reload_before_retry
CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_agent_loop resume_origin_backend_failure_does_not_die_as_scope_mismatch
# passed

CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_turns legacy_recovery_milestone_without_sequence_defaults_to_zero
CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_events failure_recovered_round_trips_and_old_events_default_recovery_fields
CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_runner recovery_
CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test -q \
  -p ironclaw_runner --test loop_milestone_event_projection \
  failure_recovery_milestone_is_durable_and_projected_exactly_once
# passed

CARGO_INCREMENTAL=0 CARGO_PROFILE_DEV_DEBUG=0 cargo clippy -q \
  -p ironclaw_safety -p ironclaw_events -p ironclaw_turns \
  -p ironclaw_agent_loop -p ironclaw_runner --all-targets -- -D warnings
# passed

# Earlier whole-path validation on this PR:
CARGO_PROFILE_TEST_DEBUG=0 CARGO_PROFILE_DEV_DEBUG=0 \
  cargo test -p ironclaw_reborn_integration_tests \
  --test reborn_failure_retry_resume_e2e
# 23 passed; 0 failed; 1 ignored (credential-dependent)

CARGO_PROFILE_TEST_DEBUG=0 CARGO_PROFILE_DEV_DEBUG=0 \
  cargo test -p ironclaw_architecture --test reborn_dependency_boundaries
# 30 passed

CARGO_PROFILE_TEST_DEBUG=0 CARGO_PROFILE_DEV_DEBUG=0 cargo test \
  -p ironclaw_safety -p ironclaw_events -p ironclaw_event_projections --locked
# passed: 279 safety + 51 events + 90 projection/contract tests

CARGO_PROFILE_TEST_DEBUG=0 CARGO_PROFILE_DEV_DEBUG=0 \
  cargo test -p ironclaw_reborn_integration_tests \
  --test reborn_failure_retry_resume_e2e --locked -- --nocapture
# 23 passed; 0 failed; 1 ignored (credential-dependent)

CARGO_PROFILE_TEST_DEBUG=0 CARGO_PROFILE_DEV_DEBUG=0 \
  bash scripts/reborn-e2e-rust.sh substrates
# passed

cargo clippy -p ironclaw_safety -p ironclaw_events \
  -p ironclaw_event_projections --all-targets --locked -- -D warnings
cargo fmt --all -- --check
git diff --check
# passed

Fuzzing: Not run locally because cargo-fuzz is not installed; exact adversarial regressions cover both affected terminal-dash matchers.

Security Impact

The compaction leak detector now recognizes bare JWTs by decoding the first base64url segment as a JSON object with an alg field. This avoids false positives for Java/package-like dotted strings without depending on the common-but-not-required eyJ prefix. JWT header validation also fails closed above 64 KiB before decode allocation or JSON parsing. No authentication, authorization, network, file-access, tool-execution, or sandbox policy changes are introduced.

Reborn Trust-Boundary Checklist

  • Typed policy/evidence vocabulary stays with the turns/events contract owners.
  • No untrusted prompt/content path changed.
  • Stable recovery IDs use domain-separated BLAKE3 over typed run identity plus sequence for deduplication, not authentication.
  • All new/changed enum and error match sites were enumerated and compiled.
  • Additive durability fields have compatibility tests and safe defaults.
  • The recovery sequence uses checked arithmetic.
  • Driver-visible errors preserve typed kind, safe summary, diagnostic reference, and redacted detail.
  • No sandbox/native/host naming boundary changed.

Database Impact

None. No migrations, SQL schema, or persistence backend selection changed. Runtime event JSON gains additive optional recovery fields; the loop/milestone sequence has a compatibility default.

Blast Radius

Touches turn progress vocabulary, checkpointed loop state, model/capability recovery application, runner milestone projection, durable event identity, compaction secret scanning, and failure-summary projection. Tests cover every consuming seam. No new production dependency edge was added by the review fixes.

Rollback Plan

Revert 6819ff961, f2a547742, 9dfa55801, and the preceding WS7 commits (579db8790, f501f6907, 000120759). Previously persisted runtime events remain readable because the additions are compatible/defaulted. This removes the recovery numerator and restores the prior scanner behavior; no data migration is required.

Review Follow-Through

The multi-review found and fixed:

  • a must-succeed durability/order gap in FailureRecovered;
  • replay identity ambiguity across the event-append/checkpoint window;
  • missing caller-path coverage for the production adapter and direct/model-visible recovery branches;
  • a JWT false negative for valid headers with leading JSON whitespace;
  • duplicated resume-origin retry continuation logic and recovery-only sanitizer naming;
  • unbounded allocation/JSON parsing for oversized JWT-shaped candidates.

Epic reconciliation evidence:

Those retracted claims were verified against current production call sites and intentionally received no behavior churn.


Review track: C (security/runtime/DB/CI)

@coderabbitai

coderabbitai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds durable FailureRecovered events with typed metadata, checkpointed sequencing, deterministic identities, runner wiring, projection support, and E2E validation. It also updates JWT detection, compaction coverage, failure summaries, and runner exports.

Changes

Durable recovery pipeline

Layer / File(s) Summary
Recovery contracts and projections
crates/ironclaw_turns/..., crates/ironclaw_events/..., crates/ironclaw_event_projections/..., docs/reborn/contracts/events.md
Adds recovery metadata, serialization compatibility, label sanitization, timeline projection, and non-terminal status handling.
Executor recovery emission and sequencing
crates/ironclaw_agent_loop/src/executor/..., crates/ironclaw_agent_loop/src/state.rs
Maps failures, emits checkpointed recovery events, handles append failures, and distinguishes retried from model-visible outcomes.
Milestone adaptation and deterministic projection
crates/ironclaw_runner/src/loop_driver_host/..., crates/ironclaw_runner/src/milestone_events.rs, crates/ironclaw_runner/tests/...
Forwards recovery milestones, derives replay-stable IDs, maps sequence exhaustion, and validates durable projection.
Binary harness and recovery E2E validation
tests/support/reborn_parity_qa/binary_e2e.rs, tests/reborn_failure_retry_resume_e2e.rs
Publishes durable milestones, replays runtime projections, and validates recovery metadata with finalized replies.

Related regression and cleanup changes

Layer / File(s) Summary
Runner failure summary cleanup
crates/ironclaw_runner/src/failure_summary.rs, crates/ironclaw_runner/src/lib.rs, crates/ironclaw_product/src/projection/tests/failure_explanation.rs
Adds the crash_retry_exhausted summary and removes the public failure-classification module.
Safety and compaction regressions
crates/ironclaw_safety/src/leak_detector.rs, crates/ironclaw_loop_host/tests/compaction_task_contract.rs
Validates decoded JWT headers, token endings, dotted package names, and persisted compaction summaries.

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

Sequence Diagram(s)

sequenceDiagram
  participant ModelStage
  participant CheckpointStage
  participant HostProgressPort
  participant DurableMilestoneSink
  participant ReplayProjection
  ModelStage->>CheckpointStage: emit recovery metadata
  CheckpointStage->>HostProgressPort: append FailureRecovered
  HostProgressPort->>DurableMilestoneSink: publish milestone
  DurableMilestoneSink->>ReplayProjection: replay durable event
  ReplayProjection-->>ModelStage: projected recovery timeline entry
Loading

Possibly related issues

Possibly related PRs

Suggested reviewers: think-in-universe

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title matches the PR’s main change: durable recovery telemetry plus retry-gap fixes.
Description check ✅ Passed The description largely fills the required template with summary, linked issue, validation, test strategy, and rollout details.

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.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6844 July 29, 2026 09:48 Destroyed
@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.

@github-actions github-actions Bot added size: XL 500+ changed lines scope: docs Documentation risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jul 29, 2026
@ironloopai

ironloopai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Review · PR #6844

🟢 Completed · Review submitted

3 actionable findings →

The recovery telemetry path has durability/exactly-once gaps, the revised JWT detector misses valid tokens, and removal of the public retry classifiers leaves an architecture snapshot test failing.

Automatic · PR opened · attempt 1 of 3 · completed in 2m 58s

Run details
  • Repository: nearai/ironclaw
  • Base: main at a0e91d1
  • Head: codex/ws7-error-recoverability at e4c12d0
  • Created: Jul 29, 2026, 9:53 AM UTC
  • Updated: Jul 29, 2026, 9:56 AM UTC
  • Run: 0748c67d-a351-492e-8e16-8f890a87ac71
  • Latest attempt: 1 · Completed · 500332d4-5c9b-494f-81bb-2ae1995b41d0

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

🔍 Review complete · PR #6844

⚠️ 3 findings · 3 blocking

The recovery telemetry path has durability/exactly-once gaps, the revised JWT detector misses valid tokens, and removal of the public retry classifiers leaves an architecture snapshot test failing.

Findings

  1. 🔴 High · Recovery events use a best-effort, non-idempotent progress path — crates/ironclaw_agent_loop/src/executor/model.rs:266-275
    Details are attached to the relevant diff.
  2. 🔴 High · Valid JWTs with whitespace in the protected header bypass scanning — crates/ironclaw_safety/src/leak_detector.rs:558-564
    Details are attached to the relevant diff.
  3. 🟠 Medium · Update the enforced composition public-surface snapshot — crates/ironclaw_reborn_composition/src/lib.rs:120
    Details are attached to the relevant diff.
Validation and technical details
  • Inspected the complete trusted comparison refs/ironloop/base...refs/ironloop/head across all 29 changed files and traced executor progress through runner milestones, durable events, projections, hooks, product summaries, and tests.
  • The repository codebase graph reported MISSING; review therefore used crate-local guidance, targeted ripgrep searches, and live source verification.
  • Confirmed programmatically that the current composition pub-use extraction does not match docs/plans/composition-pubuse.snapshot; the stale snapshot still contains the removed failure_lane export.
  • Constructed a valid JSON JWT header containing whitespace, base64url-encoded it to an eyA-prefixed compact token, and confirmed the new regex does not match it.
  • cargo is unavailable in the review environment, so Rust test execution could not be repeated; git diff --check completed successfully.
  • Base: main
  • Head: codex/ws7-error-recoverability at e4c12d0
  • Run: 0748c67d-a351-492e-8e16-8f890a87ac71

Comment thread crates/ironclaw_agent_loop/src/executor/model.rs Outdated
Comment thread crates/ironclaw_safety/src/leak_detector.rs Outdated
Comment thread crates/ironclaw_reborn_composition/src/lib.rs
@railway-app

railway-app Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

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

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

@serrrfirat
serrrfirat force-pushed the codex/ws7-error-recoverability branch from e4c12d0 to f501f69 Compare July 29, 2026 10:50
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6844 July 29, 2026 10:50 Destroyed
@github-actions github-actions Bot added scope: dependencies Dependency updates risk: medium Business logic, config, or moderate-risk modules and removed risk: low Changes to docs, tests, or low-risk modules labels Jul 29, 2026
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6844 July 29, 2026 11:11 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6844 July 29, 2026 11:29 Destroyed
@serrrfirat
serrrfirat marked this pull request as ready for review July 29, 2026 11:37
@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 commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Review · PR #6844

🔴 Failed

GitHub request failed

IronLoop could not complete a required GitHub request.

Automatic · PR opened · attempt 1 of 3 · failed after 2m 21s

Failure details
  • Repository: nearai/ironclaw
  • Base: main at de34247
  • Head: codex/ws7-error-recoverability at 9dfa558
  • Created: Jul 29, 2026, 11:42 AM UTC
  • Updated: Jul 29, 2026, 11:45 AM UTC
  • Run: 8a8c92e2-c776-40ec-8ca1-886126928307
  • Latest attempt: 1 · Completed · c61ea513-cc7f-4bc6-8973-b73ab94b5634
  • Failed during: GitHub writeback
  • Retryable: No
  • Failure: 3344aa45-cf10-4345-a7e5-6d547de0ee95

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

🤖 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_event_projections/src/lib.rs`:
- Around line 1713-1715: Before constructing the projection’s TimelineEntry,
re-sanitize event.recovery_stage, event.recovery_class, and
event.recovery_disposition with the sanitizer owned by the events component
rather than copying them directly. Add a regression covering a custom durable
backend that supplies unsafe sentinel recovery labels, and verify the published
projection contains only sanitized values.

In `@crates/ironclaw_safety/src/leak_detector.rs`:
- Around line 611-618: Update the bare_jwt regex in the LeakPattern definition
to remove the trailing word boundary or otherwise consume the full base64url
signature, including a final “-”, so matching and redaction never truncate the
token. Add a regression test in the leak detector test suite covering a JWT
whose signature ends with “-” and assert the entire token is redacted.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4632915e-baec-408a-bdae-e651d0bcdcda

📥 Commits

Reviewing files that changed from the base of the PR and between a0e91d1 and 9dfa558.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (33)
  • Cargo.toml
  • crates/ironclaw_agent_loop/src/executor.rs
  • crates/ironclaw_agent_loop/src/executor/capabilities.rs
  • crates/ironclaw_agent_loop/src/executor/checkpoint.rs
  • crates/ironclaw_agent_loop/src/executor/mapping.rs
  • crates/ironclaw_agent_loop/src/executor/model.rs
  • crates/ironclaw_agent_loop/src/executor/tests.rs
  • crates/ironclaw_agent_loop/src/state.rs
  • crates/ironclaw_event_projections/src/lib.rs
  • crates/ironclaw_event_projections/src/runtime_projection.rs
  • crates/ironclaw_event_projections/tests/replay_projection_contract.rs
  • crates/ironclaw_event_streams/tests/event_stream_manager_contract/support/builders.rs
  • crates/ironclaw_events/src/runtime_event.rs
  • crates/ironclaw_events/tests/durable_log_contract.rs
  • crates/ironclaw_hooks/src/dispatch/lifecycle_owner.rs
  • crates/ironclaw_loop_host/tests/compaction_task_contract.rs
  • crates/ironclaw_product/src/projection/tests/failure_explanation.rs
  • crates/ironclaw_runner/src/failure_classification.rs
  • crates/ironclaw_runner/src/failure_summary.rs
  • crates/ironclaw_runner/src/lib.rs
  • crates/ironclaw_runner/src/loop_driver_host/port_adapters.rs
  • crates/ironclaw_runner/src/loop_driver_host/tests.rs
  • crates/ironclaw_runner/src/milestone_events.rs
  • crates/ironclaw_runner/src/planned_driver.rs
  • crates/ironclaw_runner/tests/loop_milestone_event_projection.rs
  • crates/ironclaw_safety/src/leak_detector.rs
  • crates/ironclaw_turns/src/run_profile/host/mod.rs
  • crates/ironclaw_turns/src/run_profile/host/progress.rs
  • crates/ironclaw_turns/src/run_profile/milestones.rs
  • crates/ironclaw_turns/src/run_profile/mod.rs
  • docs/reborn/contracts/events.md
  • tests/reborn_failure_retry_resume_e2e.rs
  • tests/support/reborn_parity_qa/binary_e2e.rs
💤 Files with no reviewable changes (2)
  • crates/ironclaw_runner/src/failure_classification.rs
  • crates/ironclaw_runner/src/lib.rs

Comment thread crates/ironclaw_event_projections/src/lib.rs Outdated
Comment thread crates/ironclaw_safety/src/leak_detector.rs
@github-actions

github-actions Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Coverage ratchet

Ratchet mode: ENFORCING

RATCHET PASS: global
  observed: 85.74% (314336 / 366607 lines)
  floor:    80.81% (tolerance 0.5pp -> effective floor 80.31%)
  denominator: 366607 lines now vs 377084 at floor capture (-10477 lines, -2.78%) — not a material change

⚠️ 2 Reborn crate(s) have 0 int-tier coverage (target: 0) — ironclaw_prompt_envelope, ironclaw_scripts

Reborn integration-tier coverage

Line coverage (Reborn crates): 85.74% — 314336 / 366607 lines

Per-crate breakdown (60 crates, lowest-covered first)
Crate Line % Covered / Total
ironclaw_prompt_envelope 0% 0 / 88
ironclaw_scripts 0% 0 / 345
ironclaw_process_sandbox 33.91% 118 / 348
ironclaw_host_ingress 42.5% 17 / 40
ironclaw_event_projections 43.51% 684 / 1572
ironclaw_observability 61.54% 16 / 26
ironclaw_authorization 63.02% 610 / 968
ironclaw_memory 64.41% 959 / 1489
ironclaw_telegram_v2_adapter 69.69% 731 / 1049
ironclaw_trust 73.21% 664 / 907
ironclaw_wasm_limiter 74.6% 47 / 63
ironclaw_filesystem 74.64% 4829 / 6470
ironclaw_extractors 74.72% 538 / 720
ironclaw_capabilities 75.41% 2879 / 3818
ironclaw_projects 76.48% 400 / 523
ironclaw_mcp 76.6% 779 / 1017
ironclaw_reborn_cli 78.36% 10782 / 13760
ironclaw_wasm 79.72% 735 / 922
ironclaw_llm 80.07% 22136 / 27645
ironclaw_memory_native 81.02% 3299 / 4072
ironclaw_auth 81.88% 6679 / 8157
ironclaw_first_party_extensions 82.38% 6682 / 8111
ironclaw_processes 83.3% 933 / 1120
ironclaw_host_api 83.67% 9698 / 11591
ironclaw_reborn_identity 83.8% 450 / 537
ironclaw_events 84.06% 1687 / 2007
ironclaw_operator 84.41% 5561 / 6588
ironclaw_secrets 84.56% 2798 / 3309
ironclaw_reborn_config 85.23% 2101 / 2465
ironclaw_skills 85.27% 4493 / 5269
ironclaw_extension_host 85.34% 19110 / 22393
ironclaw_telegram_extension 85.4% 1299 / 1521
ironclaw_run_state 85.77% 458 / 534
ironclaw_reborn_composition 85.81% 24634 / 28709
ironclaw_triggers 85.92% 2783 / 3239
ironclaw_network 85.97% 913 / 1062
ironclaw_reborn_event_store 86.17% 1246 / 1446
ironclaw_webui 86.37% 11171 / 12934
ironclaw_hooks 86.72% 9949 / 11472
ironclaw_common 86.99% 1772 / 2037
ironclaw_approvals 87.07% 1542 / 1771
ironclaw_extensions 87.24% 4798 / 5500
ironclaw_threads 87.36% 4912 / 5623
ironclaw_product 87.42% 20309 / 23232
ironclaw_reborn_traces 88.13% 11987 / 13601
ironclaw_turns 88.32% 14481 / 16396
ironclaw_host_runtime 88.93% 19947 / 22429
ironclaw_slack_extension 89.26% 2027 / 2271
ironclaw_reborn_openai_compat 89.32% 3780 / 4232
ironclaw_conversations 90.03% 3171 / 3522
ironclaw_resources 90.84% 4474 / 4925
ironclaw_event_streams 91.24% 1063 / 1165
ironclaw_runner 91.32% 17376 / 19028
ironclaw_loop_host 91.98% 16586 / 18032
ironclaw_attachments 93.06% 630 / 677
ironclaw_outbound 93.91% 4101 / 4367
ironclaw_agent_loop 94.51% 10085 / 10671
ironclaw_safety 95.22% 3941 / 4139
ironclaw_first_party_extension_ports 95.62% 3672 / 3840
ironclaw_runtime_policy 96.56% 814 / 843

This table itself is informational and never gates the PR on its own — not the percentage, not the per-crate holes, not the 0-coverage callout. A separate coverage ratchet (dry-run until enforce=true; see tests/integration/coverage-floor.toml) can fail the build on specific configured floors.

Exemptions (3 entry/entries excluded from the accounting above)
Module / Crate Reason Issue
crate: ironclaw_embeddings v1-only: consumed only by root ironclaw (src/app.rs, src/tools/builtin/memory.rs, src/workspace/mod.rs, src/config/{mod,embeddings}.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_gateway v1-only: consumed only by root ironclaw (src/channels/web/platform/static_files.rs, src/channels/web/handlers/frontend.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_tui v1-only: consumed only by root ironclaw (src/main.rs, src/channels/tui.rs); no crates/* dependents. Crate's own doc comment confirms it bridges INTO v1, not Reborn. Covered by "Tests (Legacy)". #5657

@serrrfirat

Copy link
Copy Markdown
Collaborator Author

CI follow-up resolved in 579db8790: the ironclaw_event_streams contract fixture initialized TimelineEntry without the newly added recovery metadata fields, causing both all-features clippy and the events/conversations bucket to fail compilation. The fixture now sets the non-recovery fields to None.

Local verification:

  • cargo test -p ironclaw_event_streams --locked — 71 passed
  • cargo clippy -p ironclaw_event_streams --all-targets -- -D warnings — passed
  • cargo clippy --all --tests --examples --all-features -- -D warnings — passed
  • cargo fmt --all -- --check and git diff --check — passed

Final PR checks on head 9dfa55801: 58 passed, 7 intentionally skipped, 0 pending, 0 failed.

@coderabbitai coderabbitai Bot mentioned this pull request Jul 29, 2026
18 of 29 tasks
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6844 July 29, 2026 12:48 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 (2)
crates/ironclaw_events/src/runtime_event.rs (1)

123-128: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Use recovery-specific domain types instead of String.

failure_recovered accepts arbitrary strings and stores them in public Option<String> fields; bounded sanitization cannot enforce valid stage/class/disposition semantics at callers. Define enums/newtypes in ironclaw_events, with wire compatibility mapping unknown legacy values to unclassified.

As per coding guidelines, “Use strong types and enums for known domain shapes; keep raw strings at external boundaries.”

Also applies to: 710-723

🤖 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_events/src/runtime_event.rs` around lines 123 - 128, Replace
the public String-based recovery fields and the failure_recovered inputs with
recovery-specific enums or newtypes in ironclaw_events for stage, class, and
disposition. Update failure_recovered and related serialization/deserialization
to use these strong types, while mapping unknown legacy wire values to the
unclassified variant. Preserve wire compatibility and the existing
retried/model_visible semantics.

Source: Coding guidelines

crates/ironclaw_safety/src/leak_detector.rs (1)

611-618: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Bound bare-JTT candidates before decoding.

bare_jwt uses unbounded quantifiers, and each match is decoded and parsed by has_json_web_token_header. A hostile input can force excessive allocation/CPU in the safety boundary (crates/**/*.rs: safety path requires explicit bounds on user-controlled strings and fail-closed). Return false for oversized candidates so the match is still treated as blocked/redacted rather than skipped.

🤖 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_safety/src/leak_detector.rs` around lines 611 - 618, Bound
the three base64url segments in the bare_jwt LeakPattern regex to explicit
maximum lengths, and update has_json_web_token_header to return false for
candidates exceeding those bounds before decoding or parsing. Preserve oversized
matches as blocked/redacted rather than skipping them.

Source: Path instructions

🤖 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 `@crates/ironclaw_events/src/runtime_event.rs`:
- Around line 123-128: Replace the public String-based recovery fields and the
failure_recovered inputs with recovery-specific enums or newtypes in
ironclaw_events for stage, class, and disposition. Update failure_recovered and
related serialization/deserialization to use these strong types, while mapping
unknown legacy wire values to the unclassified variant. Preserve wire
compatibility and the existing retried/model_visible semantics.

In `@crates/ironclaw_safety/src/leak_detector.rs`:
- Around line 611-618: Bound the three base64url segments in the bare_jwt
LeakPattern regex to explicit maximum lengths, and update
has_json_web_token_header to return false for candidates exceeding those bounds
before decoding or parsing. Preserve oversized matches as blocked/redacted
rather than skipping them.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6fb5a6a9-c9dc-48f9-acc0-8566b14e28ad

📥 Commits

Reviewing files that changed from the base of the PR and between 9dfa558 and f2a5477.

📒 Files selected for processing (5)
  • crates/ironclaw_event_projections/src/lib.rs
  • crates/ironclaw_event_projections/tests/replay_projection_contract.rs
  • crates/ironclaw_events/src/lib.rs
  • crates/ironclaw_events/src/runtime_event.rs
  • crates/ironclaw_safety/src/leak_detector.rs

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6844 July 29, 2026 12:58 Destroyed
@serrrfirat

Copy link
Copy Markdown
Collaborator Author

Follow-up on CodeRabbit outside-diff review 4808372998: the oversized JWT allocation finding was valid and is fixed in commit 6819ff9. Validation now rejects allocation/JSON parsing above 64 KiB while treating the complete three-segment match as sensitive, so it fails closed and redacts the full token. The regex intentionally remains unbounded so it consumes the complete base64url run instead of recreating a tail leak. The recovery-domain-type suggestion does not fit the live ownership contract and received no code change: LoopRecoveryStage, LoopRecoveryClass, and LoopRecoveryDisposition are already strongly typed from the canonical loop through LoopHostMilestone in ironclaw_turns; the runner converts them to closed-vocabulary strings only at the lower, row-shaped RuntimeEvent substrate boundary documented in docs/reborn/contracts/events.md. Making ironclaw_events depend upward on ironclaw_turns or defining mirror enums would violate the dependency and shared-vocabulary rules. Verification: 279 ironclaw_safety tests passed; focused zero-warning clippy, fmt, and diff checks passed.

@serrrfirat
serrrfirat merged commit 1bf9be9 into main Jul 29, 2026
65 checks passed
@serrrfirat
serrrfirat deleted the codex/ws7-error-recoverability branch July 29, 2026 15:21
@ironclaw-ci ironclaw-ci Bot mentioned this pull request Jul 29, 2026
l3ocifer pushed a commit to l3ocifer/frick-ironclaw that referenced this pull request Sep 3, 2026
* Add durable recovery telemetry and remove dead retry policy

* test(reborn): cover durable recovery events end to end

* test(events): initialize recovery projection fields

* fix(recovery): make telemetry replay-stable

* fix(recovery): harden projected telemetry redaction

* fix(safety): bound JWT header validation

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-6844 — 6819ff96 Deployed Jul 29, 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: medium Business logic, config, or moderate-risk modules scope: dependencies Dependency updates scope: docs Documentation size: XL 500+ changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant