Skip to content

refactor(reborn): triggered-run-delivery store over RootFilesystem, delete InMemoryTriggeredRunDeliveryStore (§4.3) - #6213

Merged
ilblackdragon merged 3 commits into
mainfrom
refactor/reborn-consolidate-triggered-run-delivery-store
Jul 18, 2026
Merged

ilblackdragon merged 3 commits into
mainfrom
refactor/reborn-consolidate-triggered-run-delivery-store

Conversation

@ilblackdragon

Copy link
Copy Markdown
Member

What

Continues the §4.3 store consolidation, building directly on the A6 outbound work: deletes the hand-written InMemoryTriggeredRunDeliveryStore and uses the one production FilesystemOutboundStateStore — which already implements TriggeredRunDeliveryStore — over an in-memory backend.

InMemoryTriggeredRunDeliveryStore is entirely test-only (unlike its sibling InMemoryDeliveredGateRouteStore, which has a production default in DefaultProductWorkflow::new blocked on a 79-caller DI refactor — deferred with a plan in the worklog). After A6 closed the no-durable outbound gap, the production factory already uses FilesystemOutboundStateStore for the triggered-run-delivery role; only test doubles remained.

Changes

  • ironclaw_outbound: delete the InMemoryTriggeredRunDeliveryStore struct+impl from triggered_run_delivery.rs (keep the trait/record/enum) + its pub use; drop now-unused HashMap/Mutex imports. Own tests use the crate::test_support helper.
  • Test doubles (composition slack_delivery.rs, slack_serve/e2e_tests.rs, root tests/integration/triggered_delivery_outcome.rs) repointed to the A6 in_memory_backed_outbound_state_store() helper. Composition dev-dep already had ironclaw_outbound/test-support from A6; added it to the root crate's dev-dep for the integration test.
  • R1 ratchet: drop InMemoryTriggeredRunDeliveryStore from the frozen allowlist.

Net −40 lines.

Verification

  • ratchet 4, outbound 110, composition slack 387, reborn_integration_triggered_delivery_outcome 1 (the caller-supplied-store seam now injects the filesystem-backed store) — all pass
  • clippy -D warnings clean on outbound + composition
  • fmt + pre-commit clean

Stack

Stacked on #6212. Part of the incremental arch-simplification refactor.

🤖 Generated with Claude Code

@ironloopai

ironloopai Bot commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

🔎 IronLoop Review Status

Head: 6bbbbd2e46ff832a591a7fff12a488277ccfcf36
Result: One or more review results were superseded by a newer PR head.
Next: Run @ironloopai review on the latest PR head.
Updated: 2026-07-18T03:04:26.194Z

Current reviewers:

Reviewer State Verdict Findings Last update
ironloop/common-reviewer (reviewer) Superseded N/A N/A 2026-07-18T00:20:46.088Z
Reviewer summaries
Reviewer Detail
ironloop/common-reviewer (reviewer) Superseded by a newer PR head. New head: 699ce05. Previous verdict: Needs validation.
Recent activity
Time Reviewer State Detail
2026-07-17T23:47:12.649Z ironloop/common-reviewer (reviewer) Queued Accepted review request for head cf3ad9a.
2026-07-17T23:47:12.649Z ironloop/common-reviewer (reviewer) Queued Waiting for this reviewer lane to become available.
2026-07-17T23:47:12.932Z ironloop/common-reviewer (reviewer) Started Reviewer worker started.
2026-07-17T23:47:15.649Z ironloop/common-reviewer (reviewer) Workspace ready Prepared isolated checkout (merge_ref) at 9c2c32e.
2026-07-17T23:51:42.323Z ironloop/common-reviewer (reviewer) Result captured Needs validation; 0 blocking findings.
2026-07-17T23:51:42.323Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
2026-07-18T00:20:46.088Z ironloop/common-reviewer (reviewer) Superseded A newer PR head replaced this review (699ce05).
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-6213 July 17, 2026 23:47 Destroyed
@github-actions github-actions Bot added scope: dependencies Dependency updates size: M 50-199 changed lines risk: medium Business logic, config, or moderate-risk modules labels Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 17, 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: be97c73c-20fe-4ba0-8e18-0d90c9b3e8f2

📥 Commits

Reviewing files that changed from the base of the PR and between e057ea3 and 6bbbbd2.

📒 Files selected for processing (11)
  • Cargo.toml
  • crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs
  • crates/ironclaw_channel_delivery/src/tests.rs
  • crates/ironclaw_outbound/src/delivered_gate_routes.rs
  • crates/ironclaw_outbound/src/lib.rs
  • crates/ironclaw_outbound/src/triggered_run_delivery.rs
  • crates/ironclaw_product_workflow/src/workflow.rs
  • crates/ironclaw_product_workflow/tests/product_workflow_contract.rs
  • crates/ironclaw_reborn_composition/src/delivered_gate_routing.rs
  • crates/ironclaw_reborn_composition/src/slack/slack_serve/e2e_tests.rs
  • tests/integration/triggered_delivery_outcome.rs
💤 Files with no reviewable changes (1)
  • crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs

📝 Walkthrough

Summary by CodeRabbit

  • Refactor
    • Consolidated outbound delivery and route testing around a shared state-store implementation.
    • Removed legacy in-memory storage implementations from the public interface.
    • Added a safe no-op route store for workflows without configured route persistence.
    • Updated default workflow behavior and test coverage to use the unified storage approach.

Walkthrough

Legacy in-memory delivered-route and triggered-delivery stores are removed. Production workflow defaults use a noop route store, while tests and integration seams use the test-support filesystem-backed outbound-state store.

Changes

Outbound store consolidation

Layer / File(s) Summary
Store contracts and implementations
Cargo.toml, crates/ironclaw_outbound/..., crates/ironclaw_architecture/tests/...
Removes the legacy stores, adds NoopDeliveredGateRouteStore, updates public exports, and adjusts the architecture allowlist.
Channel delivery store migration
crates/ironclaw_channel_delivery/src/tests.rs
Migrates delivery and route test setup to in_memory_backed_outbound_state_store().
Workflow and composition wiring
crates/ironclaw_product_workflow/..., crates/ironclaw_reborn_composition/...
Updates workflow defaults and composition test harnesses to use noop or test-support-backed stores.
Triggered-delivery integration seam
Cargo.toml, tests/integration/triggered_delivery_outcome.rs
Enables the test-support feature and injects the filesystem-backed store into the outcome integration test.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: henrypark133

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Conventional Commits format is used and the title accurately matches the triggered-run-delivery store consolidation.
Description check ✅ Passed The description is detailed and covers what changed, why, verification, and stack context, matching the PR.
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.

@github-actions github-actions Bot added the contributor: core 20+ merged PRs label Jul 17, 2026

@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 removes the InMemoryTriggeredRunDeliveryStore implementation from ironclaw_outbound and refactors tests and compositions to use the in_memory_backed_outbound_state_store() helper (backed by FilesystemOutboundStateStore<InMemoryBackend>). This cleanup includes enabling the test-support feature for ironclaw_outbound in Cargo.toml and removing the deleted store from the architecture ratchet. I have no feedback to provide as there are no review comments and the changes are clean and consistent.

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.

@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
⚠️ Needs validation 0 1 1 cf3ad9a0b3f2

Head: cf3ad9a0b3f2db845abe1059674ead1f1c6e4923
Next: Human review or validation is required before merging.

Run details

Status: Current
Needs human: no
Needs validation: yes

Summary

Completed the focused stack-layer review of all 7 changed files. The filesystem-backed test-store substitution is consistent with the existing trait implementation, and no correctness or security regression was found. One non-blocking stale manifest comment remains. Runtime validation could not be performed because the Rust toolchain is unavailable in the review environment.

Findings

Blocking: 0 / Notes: 1

Non-blocking notes (1)
1. 💬 [LOW] Update the comment for the new test-support feature

Location: Cargo.toml:308
Enabling test-support here is now required for in_memory_backed_outbound_state_store, but the related comment remains at lines 356–358, still names the deleted InMemoryTriggeredRunDeliveryStore, and now appears to annotate ironclaw_embeddings. Move and update that explanation next to this dependency so the manifest accurately documents the feature.

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.

Comment thread Cargo.toml
# W6-COLD-SPOTS: `CommunicationPreferenceRecord`/`CommunicationPreferenceKey`
# for the outbound-store-durability reopen test.
ironclaw_outbound = { path = "crates/ironclaw_outbound", version = "0.1.0" }
ironclaw_outbound = { path = "crates/ironclaw_outbound", version = "0.1.0", features = ["test-support"] }

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.

Please move/update the related comment from lines 356–358. It still names the deleted InMemoryTriggeredRunDeliveryStore and now appears to describe ironclaw_embeddings; this feature enables in_memory_backed_outbound_state_store for the integration test.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in the follow-up commit on this branch: the root Cargo.toml dev-dep comment now describes what the integration proof actually injects (ironclaw_outbound/test-support's in-memory-backed FilesystemOutboundStateStore) instead of the deleted InMemoryTriggeredRunDeliveryStore, and it no longer reads as if it described the embeddings dep. Same commit also repoints main's new ironclaw_channel_delivery tests (landed via #6159 after this branch was cut) off the deleted store — the whole stack (#6212→#6218) is being restacked onto current main.

@railway-app

railway-app Bot commented Jul 18, 2026 •

Copy link
Copy Markdown

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

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 18, 2026 at 3:16 am

@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-outbound-state-store branch from 148039e to 07377bd Compare July 18, 2026 00:20
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-triggered-run-delivery-store branch from cf3ad9a to 699ce05 Compare July 18, 2026 00:20
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…ete InMemoryDeliveredGateRouteStore (§4.3)

Completes the §4.3 outbound-store consolidation (last of the outbound family
after A6 OutboundState + A7 TriggeredRunDelivery). Deletes the hand-written
`InMemoryDeliveredGateRouteStore` — a ~200-line HashMap store that
`FilesystemOutboundStateStore` already duplicates via its
`DeliveredGateRouteStore` impl.

The blocker (recorded in the worklog) was a load-bearing PRODUCTION default:
`DefaultProductWorkflow::new` (79 callers) set
`InMemoryDeliveredGateRouteStore::default()`, relied on by the OpenAI-compat
surface — which never routes gates (never produces approval/auth resolution
payloads), so the store is only ever READ (returns empty) there. Rather than a
79-caller DI refactor OR pulling a mandatory `ironclaw_filesystem` dep into
`product_workflow` (its filesystem dep is deliberately optional), the default
becomes a new filesystem-free **`NoopDeliveredGateRouteStore`** null object:
reads return empty, best-effort `remove`/`sweep` are no-ops, and `record`
fails **loud** (the workflow never records — verified: no
`record_delivered_gate_route` call in `product_workflow/src`; recording happens
in the composition slack-delivery path via a setter-injected real store). This
is behavior-identical to the old empty-in-memory default for the non-routing
surface, with no fail-silent hazard.

Changes:
- `ironclaw_outbound`: delete `InMemoryDeliveredGateRouteStore` struct+impl +
  its now-orphaned `RouteKey`/`ConversationIndexKey` helpers and
  `HashMap`/`Mutex`/`BTreeSet` imports; add `NoopDeliveredGateRouteStore`
  (null object next to the trait); own tests use the `crate::test_support`
  filesystem helper.
- `DefaultProductWorkflow::new` default → `NoopDeliveredGateRouteStore` (field
  type + signature + 79 callers all UNCHANGED — only the default value).
- Test doubles (composition slack_delivery/e2e_tests/delivered_gate_routing,
  product_workflow_contract) → the A6 `in_memory_backed_outbound_state_store()`
  helper (real storage, impls the trait).
- R1 ratchet: drop `InMemoryDeliveredGateRouteStore` from the frozen allowlist —
  the outbound family is now fully consolidated.

Net -178 lines. Verified: outbound 110, product_workflow 114, composition slack
387 + delivered_gate_routing 7 — all pass; `cargo build -p
ironclaw_reborn_composition` default (the Noop production-default path) clean;
clippy -D warnings clean on outbound + product_workflow + composition; ratchet 4;
fmt + pre-commit clean.

Stacked on #6213.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6213 July 18, 2026 00:20 Destroyed
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-outbound-state-store branch from 07377bd to cf89c39 Compare July 18, 2026 00:58
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…moryOutboundStateStore

Semantic rebase conflict: #6159 landed the new ironclaw_channel_delivery
crate on main with tests built against InMemoryOutboundStateStore, which
this slice deletes. Repointed to the test-support helper /
FilesystemOutboundStateStore<InMemoryBackend> (dev-dep feature added);
InMemoryTriggeredRunDeliveryStore / InMemoryDeliveredGateRouteStore refs
stay — their slices (#6213/#6214) own those repoints. 92 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…-delivery store; fix Cargo dev-dep comment

- ironclaw_channel_delivery (landed on main via #6159 after this branch
  was cut) had tests built against InMemoryTriggeredRunDeliveryStore;
  repointed to the all-roles FilesystemOutboundStateStore via the
  test-support helper, matching this slice's other repoints. 92 tests
  green.
- Root Cargo.toml: the dev-dep comment still named the deleted store and
  read as if it described ironclaw_embeddings (IronLoop finding on
  #6213) — it now describes the test-support helper the outcome-seam
  integration proof actually injects.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-triggered-run-delivery-store branch from 699ce05 to dff3188 Compare July 18, 2026 01:05
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6213 July 18, 2026 01:05 Destroyed
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-outbound-state-store branch from 522001b to e88508f Compare July 18, 2026 01:07
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-triggered-run-delivery-store branch from dff3188 to 5a9134c Compare July 18, 2026 01:07
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…ete InMemoryDeliveredGateRouteStore (§4.3)

Completes the §4.3 outbound-store consolidation (last of the outbound family
after A6 OutboundState + A7 TriggeredRunDelivery). Deletes the hand-written
`InMemoryDeliveredGateRouteStore` — a ~200-line HashMap store that
`FilesystemOutboundStateStore` already duplicates via its
`DeliveredGateRouteStore` impl.

The blocker (recorded in the worklog) was a load-bearing PRODUCTION default:
`DefaultProductWorkflow::new` (79 callers) set
`InMemoryDeliveredGateRouteStore::default()`, relied on by the OpenAI-compat
surface — which never routes gates (never produces approval/auth resolution
payloads), so the store is only ever READ (returns empty) there. Rather than a
79-caller DI refactor OR pulling a mandatory `ironclaw_filesystem` dep into
`product_workflow` (its filesystem dep is deliberately optional), the default
becomes a new filesystem-free **`NoopDeliveredGateRouteStore`** null object:
reads return empty, best-effort `remove`/`sweep` are no-ops, and `record`
fails **loud** (the workflow never records — verified: no
`record_delivered_gate_route` call in `product_workflow/src`; recording happens
in the composition slack-delivery path via a setter-injected real store). This
is behavior-identical to the old empty-in-memory default for the non-routing
surface, with no fail-silent hazard.

Changes:
- `ironclaw_outbound`: delete `InMemoryDeliveredGateRouteStore` struct+impl +
  its now-orphaned `RouteKey`/`ConversationIndexKey` helpers and
  `HashMap`/`Mutex`/`BTreeSet` imports; add `NoopDeliveredGateRouteStore`
  (null object next to the trait); own tests use the `crate::test_support`
  filesystem helper.
- `DefaultProductWorkflow::new` default → `NoopDeliveredGateRouteStore` (field
  type + signature + 79 callers all UNCHANGED — only the default value).
- Test doubles (composition slack_delivery/e2e_tests/delivered_gate_routing,
  product_workflow_contract) → the A6 `in_memory_backed_outbound_state_store()`
  helper (real storage, impls the trait).
- R1 ratchet: drop `InMemoryDeliveredGateRouteStore` from the frozen allowlist —
  the outbound family is now fully consolidated.

Net -178 lines. Verified: outbound 110, product_workflow 114, composition slack
387 + delivered_gate_routing 7 — all pass; `cargo build -p
ironclaw_reborn_composition` default (the Noop production-default path) clean;
clippy -D warnings clean on outbound + product_workflow + composition; ratchet 4;
fmt + pre-commit clean.

Stacked on #6213.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6213 July 18, 2026 01:07 Destroyed
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…deleted store

Addresses the IronLoop finding on #6213.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…ete InMemoryDeliveredGateRouteStore (§4.3)

Completes the §4.3 outbound-store consolidation (last of the outbound family
after A6 OutboundState + A7 TriggeredRunDelivery). Deletes the hand-written
`InMemoryDeliveredGateRouteStore` — a ~200-line HashMap store that
`FilesystemOutboundStateStore` already duplicates via its
`DeliveredGateRouteStore` impl.

The blocker (recorded in the worklog) was a load-bearing PRODUCTION default:
`DefaultProductWorkflow::new` (79 callers) set
`InMemoryDeliveredGateRouteStore::default()`, relied on by the OpenAI-compat
surface — which never routes gates (never produces approval/auth resolution
payloads), so the store is only ever READ (returns empty) there. Rather than a
79-caller DI refactor OR pulling a mandatory `ironclaw_filesystem` dep into
`product_workflow` (its filesystem dep is deliberately optional), the default
becomes a new filesystem-free **`NoopDeliveredGateRouteStore`** null object:
reads return empty, best-effort `remove`/`sweep` are no-ops, and `record`
fails **loud** (the workflow never records — verified: no
`record_delivered_gate_route` call in `product_workflow/src`; recording happens
in the composition slack-delivery path via a setter-injected real store). This
is behavior-identical to the old empty-in-memory default for the non-routing
surface, with no fail-silent hazard.

Changes:
- `ironclaw_outbound`: delete `InMemoryDeliveredGateRouteStore` struct+impl +
  its now-orphaned `RouteKey`/`ConversationIndexKey` helpers and
  `HashMap`/`Mutex`/`BTreeSet` imports; add `NoopDeliveredGateRouteStore`
  (null object next to the trait); own tests use the `crate::test_support`
  filesystem helper.
- `DefaultProductWorkflow::new` default → `NoopDeliveredGateRouteStore` (field
  type + signature + 79 callers all UNCHANGED — only the default value).
- Test doubles (composition slack_delivery/e2e_tests/delivered_gate_routing,
  product_workflow_contract) → the A6 `in_memory_backed_outbound_state_store()`
  helper (real storage, impls the trait).
- R1 ratchet: drop `InMemoryDeliveredGateRouteStore` from the frozen allowlist —
  the outbound family is now fully consolidated.

Net -178 lines. Verified: outbound 110, product_workflow 114, composition slack
387 + delivered_gate_routing 7 — all pass; `cargo build -p
ironclaw_reborn_composition` default (the Noop production-default path) clean;
clippy -D warnings clean on outbound + product_workflow + composition; ratchet 4;
fmt + pre-commit clean.

Stacked on #6213.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…deleted store

Addresses the IronLoop finding on #6213.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-triggered-run-delivery-store branch from baa5deb to 0979acf Compare July 18, 2026 01:20
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…ete InMemoryDeliveredGateRouteStore (§4.3)

Completes the §4.3 outbound-store consolidation (last of the outbound family
after A6 OutboundState + A7 TriggeredRunDelivery). Deletes the hand-written
`InMemoryDeliveredGateRouteStore` — a ~200-line HashMap store that
`FilesystemOutboundStateStore` already duplicates via its
`DeliveredGateRouteStore` impl.

The blocker (recorded in the worklog) was a load-bearing PRODUCTION default:
`DefaultProductWorkflow::new` (79 callers) set
`InMemoryDeliveredGateRouteStore::default()`, relied on by the OpenAI-compat
surface — which never routes gates (never produces approval/auth resolution
payloads), so the store is only ever READ (returns empty) there. Rather than a
79-caller DI refactor OR pulling a mandatory `ironclaw_filesystem` dep into
`product_workflow` (its filesystem dep is deliberately optional), the default
becomes a new filesystem-free **`NoopDeliveredGateRouteStore`** null object:
reads return empty, best-effort `remove`/`sweep` are no-ops, and `record`
fails **loud** (the workflow never records — verified: no
`record_delivered_gate_route` call in `product_workflow/src`; recording happens
in the composition slack-delivery path via a setter-injected real store). This
is behavior-identical to the old empty-in-memory default for the non-routing
surface, with no fail-silent hazard.

Changes:
- `ironclaw_outbound`: delete `InMemoryDeliveredGateRouteStore` struct+impl +
  its now-orphaned `RouteKey`/`ConversationIndexKey` helpers and
  `HashMap`/`Mutex`/`BTreeSet` imports; add `NoopDeliveredGateRouteStore`
  (null object next to the trait); own tests use the `crate::test_support`
  filesystem helper.
- `DefaultProductWorkflow::new` default → `NoopDeliveredGateRouteStore` (field
  type + signature + 79 callers all UNCHANGED — only the default value).
- Test doubles (composition slack_delivery/e2e_tests/delivered_gate_routing,
  product_workflow_contract) → the A6 `in_memory_backed_outbound_state_store()`
  helper (real storage, impls the trait).
- R1 ratchet: drop `InMemoryDeliveredGateRouteStore` from the frozen allowlist —
  the outbound family is now fully consolidated.

Net -178 lines. Verified: outbound 110, product_workflow 114, composition slack
387 + delivered_gate_routing 7 — all pass; `cargo build -p
ironclaw_reborn_composition` default (the Noop production-default path) clean;
clippy -D warnings clean on outbound + product_workflow + composition; ratchet 4;
fmt + pre-commit clean.

Stacked on #6213.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6213 July 18, 2026 01:20 Destroyed
@github-actions github-actions Bot added scope: docs Documentation size: XL 500+ changed lines and removed size: M 50-199 changed lines labels Jul 18, 2026
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-outbound-state-store branch from e88508f to e987437 Compare July 18, 2026 01:21
@ilblackdragon

Copy link
Copy Markdown
Member Author

✅ Ready for merge

CI green (all checks pass) on the restacked head. Stacked on #6212.

  • Review verdict: clean §4.3 slice — InMemoryTriggeredRunDeliveryStore deleted in favor of the all-roles FilesystemOutboundStateStore, ratchet trimmed in lock-step, repoints consistent.
  • Fixes: main's new ironclaw_channel_delivery tests repointed off the deleted store (the feat(reborn): telegram channel extension — admin bot setup, WebGeneratedCode pairing, DM entrypoint #6159 semantic conflict, 92 tests green); IronLoop's stale root-Cargo.toml dev-dep comment now describes the test-support helper actually injected (reply on thread).

🤖 Generated with Claude Code

Base automatically changed from refactor/reborn-consolidate-outbound-state-store to main July 18, 2026 03:02
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…ete InMemoryDeliveredGateRouteStore (§4.3) (#6214)

* refactor(reborn): delivered-gate-route store over RootFilesystem, delete InMemoryDeliveredGateRouteStore (§4.3)

Completes the §4.3 outbound-store consolidation (last of the outbound family
after A6 OutboundState + A7 TriggeredRunDelivery). Deletes the hand-written
`InMemoryDeliveredGateRouteStore` — a ~200-line HashMap store that
`FilesystemOutboundStateStore` already duplicates via its
`DeliveredGateRouteStore` impl.

The blocker (recorded in the worklog) was a load-bearing PRODUCTION default:
`DefaultProductWorkflow::new` (79 callers) set
`InMemoryDeliveredGateRouteStore::default()`, relied on by the OpenAI-compat
surface — which never routes gates (never produces approval/auth resolution
payloads), so the store is only ever READ (returns empty) there. Rather than a
79-caller DI refactor OR pulling a mandatory `ironclaw_filesystem` dep into
`product_workflow` (its filesystem dep is deliberately optional), the default
becomes a new filesystem-free **`NoopDeliveredGateRouteStore`** null object:
reads return empty, best-effort `remove`/`sweep` are no-ops, and `record`
fails **loud** (the workflow never records — verified: no
`record_delivered_gate_route` call in `product_workflow/src`; recording happens
in the composition slack-delivery path via a setter-injected real store). This
is behavior-identical to the old empty-in-memory default for the non-routing
surface, with no fail-silent hazard.

Changes:
- `ironclaw_outbound`: delete `InMemoryDeliveredGateRouteStore` struct+impl +
  its now-orphaned `RouteKey`/`ConversationIndexKey` helpers and
  `HashMap`/`Mutex`/`BTreeSet` imports; add `NoopDeliveredGateRouteStore`
  (null object next to the trait); own tests use the `crate::test_support`
  filesystem helper.
- `DefaultProductWorkflow::new` default → `NoopDeliveredGateRouteStore` (field
  type + signature + 79 callers all UNCHANGED — only the default value).
- Test doubles (composition slack_delivery/e2e_tests/delivered_gate_routing,
  product_workflow_contract) → the A6 `in_memory_backed_outbound_state_store()`
  helper (real storage, impls the trait).
- R1 ratchet: drop `InMemoryDeliveredGateRouteStore` from the frozen allowlist —
  the outbound family is now fully consolidated.

Net -178 lines. Verified: outbound 110, product_workflow 114, composition slack
387 + delivered_gate_routing 7 — all pass; `cargo build -p
ironclaw_reborn_composition` default (the Noop production-default path) clean;
clippy -D warnings clean on outbound + product_workflow + composition; ratchet 4;
fmt + pre-commit clean.

Stacked on #6213.

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

* refactor(reborn): Clone/Copy the Noop route store; refresh stale e2e harness doc

Gemini note on #6214 (stateless unit-struct null object derives Copy) and
the harness doc no longer describes the deleted store as the default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6213 July 18, 2026 03:03 Destroyed
ilblackdragon and others added 3 commits July 18, 2026 03:04
…elete InMemoryTriggeredRunDeliveryStore (§4.3)

Continues the §4.3 store consolidation and builds directly on the A6 outbound
work: delete the hand-written `InMemoryTriggeredRunDeliveryStore` and use the one
production `FilesystemOutboundStateStore` — which already implements
`TriggeredRunDeliveryStore` (filesystem_store.rs) — over an in-memory backend.

`InMemoryTriggeredRunDeliveryStore` is entirely test-only (unlike its sibling
`InMemoryDeliveredGateRouteStore`, which has a production default in
`DefaultProductWorkflow::new` blocked on a DI refactor — deferred). After A6
closed the no-durable outbound gap, the production factory already uses
`FilesystemOutboundStateStore` for the triggered-run-delivery role; only test
doubles remained.

Changes:
- `ironclaw_outbound`: delete the `InMemoryTriggeredRunDeliveryStore` struct+impl
  from `triggered_run_delivery.rs` (keep the trait/record/enum) + its `pub use`;
  remove now-unused `HashMap`/`Mutex` imports. Own tests use the `crate::test_support`
  helper.
- Test doubles (composition `slack_delivery.rs`, `slack_serve/e2e_tests.rs`, root
  `tests/integration/triggered_delivery_outcome.rs`) repointed to the A6
  `in_memory_backed_outbound_state_store()` helper (impls the trait). Composition
  dev-dep already had `ironclaw_outbound/test-support` from A6; added it to the
  root crate's dev-dep for the integration test.
- R1 ratchet: drop `InMemoryTriggeredRunDeliveryStore` from the frozen allowlist.

Net -40 lines. Verified: ratchet 4, outbound 110, composition slack 387,
`reborn_integration_triggered_delivery_outcome` 1 (the caller-supplied-store seam
now injects the filesystem-backed store) — all pass; clippy -D warnings clean on
outbound + composition; fmt + pre-commit clean.

Stacked on #6212.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…deleted store

Addresses the IronLoop finding on #6213.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ete InMemoryDeliveredGateRouteStore (§4.3) (#6214)

* refactor(reborn): delivered-gate-route store over RootFilesystem, delete InMemoryDeliveredGateRouteStore (§4.3)

Completes the §4.3 outbound-store consolidation (last of the outbound family
after A6 OutboundState + A7 TriggeredRunDelivery). Deletes the hand-written
`InMemoryDeliveredGateRouteStore` — a ~200-line HashMap store that
`FilesystemOutboundStateStore` already duplicates via its
`DeliveredGateRouteStore` impl.

The blocker (recorded in the worklog) was a load-bearing PRODUCTION default:
`DefaultProductWorkflow::new` (79 callers) set
`InMemoryDeliveredGateRouteStore::default()`, relied on by the OpenAI-compat
surface — which never routes gates (never produces approval/auth resolution
payloads), so the store is only ever READ (returns empty) there. Rather than a
79-caller DI refactor OR pulling a mandatory `ironclaw_filesystem` dep into
`product_workflow` (its filesystem dep is deliberately optional), the default
becomes a new filesystem-free **`NoopDeliveredGateRouteStore`** null object:
reads return empty, best-effort `remove`/`sweep` are no-ops, and `record`
fails **loud** (the workflow never records — verified: no
`record_delivered_gate_route` call in `product_workflow/src`; recording happens
in the composition slack-delivery path via a setter-injected real store). This
is behavior-identical to the old empty-in-memory default for the non-routing
surface, with no fail-silent hazard.

Changes:
- `ironclaw_outbound`: delete `InMemoryDeliveredGateRouteStore` struct+impl +
  its now-orphaned `RouteKey`/`ConversationIndexKey` helpers and
  `HashMap`/`Mutex`/`BTreeSet` imports; add `NoopDeliveredGateRouteStore`
  (null object next to the trait); own tests use the `crate::test_support`
  filesystem helper.
- `DefaultProductWorkflow::new` default → `NoopDeliveredGateRouteStore` (field
  type + signature + 79 callers all UNCHANGED — only the default value).
- Test doubles (composition slack_delivery/e2e_tests/delivered_gate_routing,
  product_workflow_contract) → the A6 `in_memory_backed_outbound_state_store()`
  helper (real storage, impls the trait).
- R1 ratchet: drop `InMemoryDeliveredGateRouteStore` from the frozen allowlist —
  the outbound family is now fully consolidated.

Net -178 lines. Verified: outbound 110, product_workflow 114, composition slack
387 + delivered_gate_routing 7 — all pass; `cargo build -p
ironclaw_reborn_composition` default (the Noop production-default path) clean;
clippy -D warnings clean on outbound + product_workflow + composition; ratchet 4;
fmt + pre-commit clean.

Stacked on #6213.

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

* refactor(reborn): Clone/Copy the Noop route store; refresh stale e2e harness doc

Gemini note on #6214 (stateless unit-struct null object derives Copy) and
the harness doc no longer describes the deleted store as the default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-triggered-run-delivery-store branch from fb2bc20 to 6bbbbd2 Compare July 18, 2026 03:04
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6213 July 18, 2026 03:04 Destroyed
@github-actions github-actions Bot added size: L 200-499 changed lines and removed size: XL 500+ changed lines labels Jul 18, 2026
@ilblackdragon

Copy link
Copy Markdown
Member Author

Restack note: #6212 merged (squash), and #6214 was merged into this PR's branch (it was this branch's base child), so this PR now delivers both the triggered-run-delivery and delivered-gate-route slices; rebased onto current main — conflict resolved, MERGEABLE again. CI rerunning on the restacked head.

@ilblackdragon

Copy link
Copy Markdown
Member Author

Post-restack confirmation: rebased onto main after #6212's squash-merge; this PR now carries both the triggered-run-delivery and delivered-gate-route slices (#6214 was merged into this branch). All CI checks green — 57 pass / 0 fail (only the Railway preview status finishing) on head 6bbbbd2e4. Ready for merge — merge this one first, the rest of the chain retargets down.

@github-actions

Copy link
Copy Markdown
Contributor

Coverage ratchet

Ratchet mode: ENFORCING

RATCHET PASS: global
  observed: 85.58% (306520 / 358149 lines)
  floor:    85.3% (tolerance 0.5pp -> effective floor 84.8%)
  denominator: 358149 lines now vs 320188 at floor capture (+37961 lines, +11.86%) — material change (>5%)

⚠️ 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.58% — 306520 / 358149 lines

Per-crate breakdown (65 crates, lowest-covered first)
Crate Line % Covered / Total
ironclaw_prompt_envelope 0% 0 / 88
ironclaw_scripts 0% 0 / 345
ironclaw_runtime_policy 31.75% 80 / 252
ironclaw_event_projections 43.31% 673 / 1554
ironclaw_observability 61.54% 16 / 26
ironclaw_authorization 62.46% 604 / 967
ironclaw_mcp 64.89% 595 / 917
ironclaw_triggers 65.44% 2142 / 3273
ironclaw_dispatcher 67.15% 92 / 137
ironclaw_filesystem 67.69% 3932 / 5809
ironclaw_channel_host 68.65% 219 / 319
ironclaw_memory 69.2% 773 / 1117
ironclaw_reborn_migration 71.64% 1551 / 2165
ironclaw_trust 72.88% 661 / 907
ironclaw_reborn_cli 73.98% 7095 / 9591
ironclaw_capabilities 74.36% 1685 / 2266
ironclaw_wasm_limiter 74.6% 47 / 63
ironclaw_reborn_event_store 74.67% 958 / 1283
ironclaw_extractors 74.72% 538 / 720
ironclaw_projects 76.48% 400 / 523
ironclaw_llm 78.27% 20216 / 25827
ironclaw_product_context 78.57% 11 / 14
ironclaw_telegram_extension 80.18% 4842 / 6039
ironclaw_wasm_product_adapters 80.36% 1448 / 1802
ironclaw_process_sandbox 80.65% 671 / 832
ironclaw_first_party_extensions 81.06% 5965 / 7359
ironclaw_memory_native 81.22% 3205 / 3946
ironclaw_events 81.43% 1539 / 1890
ironclaw_secrets 82.79% 2794 / 3375
ironclaw_network 82.98% 673 / 811
ironclaw_reborn_identity 83.59% 433 / 518
ironclaw_processes 83.76% 939 / 1121
ironclaw_run_state 83.96% 424 / 505
ironclaw_reborn_config 84.02% 1830 / 2178
ironclaw_wasm 84.44% 1069 / 1266
ironclaw_auth 84.81% 3233 / 3812
ironclaw_product_workflow 84.91% 11031 / 12992
ironclaw_turns 85.04% 13722 / 16136
ironclaw_host_api 85.37% 2701 / 3164
ironclaw_channel_delivery 85.79% 1383 / 1612
ironclaw_common 86.13% 1714 / 1990
ironclaw_threads 86.93% 4708 / 5416
ironclaw_slack_v2_adapter 87.3% 1491 / 1708
ironclaw_skills 87.6% 4471 / 5104
ironclaw_hooks 87.78% 9921 / 11302
ironclaw_product_adapter_registry 88.06% 531 / 603
ironclaw_product_adapters 88.1% 3384 / 3841
ironclaw_reborn_traces 88.2% 11946 / 13544
ironclaw_reborn_composition 88.38% 70499 / 79769
ironclaw_webui 88.42% 7333 / 8293
ironclaw_host_runtime 88.76% 18005 / 20284
ironclaw_extensions 89.38% 2971 / 3324
ironclaw_runner 89.5% 16990 / 18983
ironclaw_reborn_openai_compat 89.5% 3778 / 4221
ironclaw_telegram_v2_adapter 89.7% 2717 / 3029
ironclaw_approvals 90.18% 1598 / 1772
ironclaw_conversations 90.39% 3123 / 3455
ironclaw_event_streams 90.82% 1009 / 1111
ironclaw_resources 91.65% 4476 / 4884
ironclaw_loop_host 92.25% 15051 / 16316
ironclaw_attachments 93.06% 630 / 677
ironclaw_agent_loop 94.88% 9184 / 9680
ironclaw_safety 95.04% 3677 / 3869
ironclaw_outbound 95.52% 3451 / 3613
ironclaw_first_party_extension_ports 95.62% 3672 / 3840

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

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-6213 — 6bbbbd2e Deployed Jul 18, 2026 by railway-app[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: medium Business logic, config, or moderate-risk modules scope: dependencies Dependency updates scope: docs Documentation size: L 200-499 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant