Skip to content

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

Merged
ilblackdragon merged 2 commits into
refactor/reborn-consolidate-triggered-run-delivery-storefrom
refactor/reborn-consolidate-delivered-gate-route-store
Jul 18, 2026
Merged

ilblackdragon merged 2 commits into
refactor/reborn-consolidate-triggered-run-delivery-storefrom
refactor/reborn-consolidate-delivered-gate-route-store

Conversation

@ilblackdragon

Copy link
Copy Markdown
Member

What

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

The blocker + resolution

DefaultProductWorkflow::new (79 callers) set a load-bearing production default 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 a mandatory ironclaw_filesystem dep on product_workflow (its filesystem dep is deliberately optional), the default becomes a new filesystem-free NoopDeliveredGateRouteStore null object: reads empty, best-effort remove/sweep no-op, record fails loud. The workflow never records (verified: no record_delivered_gate_route call in product_workflow/src — recording is in the composition slack-delivery path via a setter-injected real store), so this is behavior-identical to the old empty-in-memory default with no fail-silent hazard.

Changes

  • ironclaw_outbound: delete InMemoryDeliveredGateRouteStore struct+impl + orphaned RouteKey/ConversationIndexKey + unused imports; add NoopDeliveredGateRouteStore. Own tests → crate::test_support filesystem helper.
  • DefaultProductWorkflow::new default → NoopDeliveredGateRouteStore (field type + new() 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.
  • R1 ratchet: drop InMemoryDeliveredGateRouteStore — the outbound family is now fully consolidated.

Net −178 lines.

Verification

  • 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

Stack

Stacked on #6213.

🤖 Generated with Claude Code

@ironloopai

ironloopai Bot commented Jul 18, 2026 •

Copy link
Copy Markdown
Contributor

🔎 IronLoop Review Status

Head: 8d453ff13c259958f5e10671c66b16d67276d0b4
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-18T01:20:44.160Z

Current reviewers:

Reviewer State Verdict Findings Last update
ironloop/common-reviewer (reviewer) Superseded N/A N/A 2026-07-18T00:20:47.316Z
Reviewer summaries
Reviewer Detail
ironloop/common-reviewer (reviewer) Superseded by a newer PR head. New head: 66d7cf2. Previous verdict: Approved.
Recent activity
Time Reviewer State Detail
2026-07-18T00:16:08.032Z ironloop/common-reviewer (reviewer) Queued Accepted review request for head 9f230ee.
2026-07-18T00:16:08.032Z ironloop/common-reviewer (reviewer) Queued Waiting for this reviewer lane to become available.
2026-07-18T00:16:08.673Z ironloop/common-reviewer (reviewer) Started Reviewer worker started.
2026-07-18T00:16:11.054Z ironloop/common-reviewer (reviewer) Workspace ready Prepared isolated checkout (merge_ref) at f90d3df.
2026-07-18T00:20:26.253Z ironloop/common-reviewer (reviewer) Result captured Approved; 0 blocking findings.
2026-07-18T00:20:26.253Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
2026-07-18T00:20:47.316Z ironloop/common-reviewer (reviewer) Superseded A newer PR head replaced this review (66d7cf2).
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-6214 July 18, 2026 00:16 Destroyed
@coderabbitai

coderabbitai Bot commented Jul 18, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • staging
  • reborn-integration

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d1ec08dc-2cd7-4cdd-b673-82dc826ae314

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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 size: L 200-499 changed lines risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jul 18, 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 InMemoryDeliveredGateRouteStore and replaces it with a stateless NoopDeliveredGateRouteStore for surfaces that do not route delivered gates. Test suites across multiple crates have been updated to use the in_memory_backed_outbound_state_store() helper instead of the deleted in-memory store. The feedback suggests deriving Clone and Copy on the new NoopDeliveredGateRouteStore struct to make it more flexible and easier to pass around.

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.

Comment on lines +169 to +170
#[derive(Debug, Default)]
pub struct NoopDeliveredGateRouteStore;

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.

medium

Since NoopDeliveredGateRouteStore is a stateless unit struct, it is highly recommended to derive Clone and Copy in addition to Debug and Default. This makes the null object much more flexible to use and pass around in various contexts (e.g., when stored in structures that require these bounds) without needing to wrap it in an Arc or reference.

Suggested change
#[derive(Debug, Default)]
pub struct NoopDeliveredGateRouteStore;
#[derive(Debug, Clone, Copy, Default)]
pub struct NoopDeliveredGateRouteStore;

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.

Applied in the follow-up commit on this branch: NoopDeliveredGateRouteStore now derives Clone and Copy alongside Debug/Default.

@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
✅ Approved 0 0 0 9f230ee8e9e5

Head: 9f230ee8e9e533e3b0ad1f410c03fa1b66090cc8
Next: No reviewer action needed.

Run details

Status: Current
Needs human: no
Needs validation: no

Summary

Reviewed the complete, bounded stack-layer delta (8 files, 123 additions/299 deletions). The no-op workflow default preserves the prior empty-store behavior, while the Slack production path continues to inject the shared filesystem-backed route store. No concrete correctness, security, or data-loss issue was found.

Findings

None.

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.

@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-triggered-run-delivery-store branch from cf3ad9a to 699ce05 Compare July 18, 2026 00:20
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-delivered-gate-route-store branch from 9f230ee to 66d7cf2 Compare July 18, 2026 00:20
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6214 July 18, 2026 00:20 Destroyed
@railway-app

railway-app Bot commented Jul 18, 2026 •

Copy link
Copy Markdown

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

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

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
ilblackdragon force-pushed the refactor/reborn-consolidate-triggered-run-delivery-store branch 2 times, most recently from dff3188 to 5a9134c Compare July 18, 2026 01:07
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-delivered-gate-route-store branch from 66d7cf2 to 154913a Compare July 18, 2026 01:07
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…evable-floor status

The mechanical §4.3 store consolidations are complete (A1–A8: approvals,
authorization, processes, run-state, budget-gate, and the whole outbound family —
OutboundState/TriggeredRunDelivery/DeliveredGateRoute). Every entry still in
`FROZEN_INMEMORY_STORES` is blocked on non-mechanical work OR is a justified keep,
so the §10 "shrink to empty" goal is not reachable by a swap.

This annotates each remaining allowlist entry with its VERIFIED status so the
next contributor picks up a scoped task instead of re-deriving the blocker
(comments are stripped by the scanner — documentation only, the enforced string
set is unchanged; entries reordered to group the justified keeps):

- turns cluster — DEFERRED (production `inmemory-turn-state` authority; needs a
  no-livelock concurrency proof + a built filesystem variant, some cross-crate).
- `InMemoryBoundedSubagentGoalStore`, `InMemoryOpenAiCompatRefStore` — JUSTIFIED
  bounded CACHES (capacity-bounded evict-oldest / bounded-LRU + filesystem-free
  contract boundary), NOT persistence debt; a durable variant would be wrong.
- `InMemoryExtensionInstallationStore` — BLOCKED cross-crate (the Filesystem
  variant in composition depends on a composition-internal contract registry;
  can't move down to `ironclaw_extensions`).
- `InMemorySecretStore` — security-sensitive.
- `InMemorySessionStore` — BUILD-FIRST (no filesystem variant; auth-adjacent).

Also reconciles the module-doc "definition of done" to note the two justified
caches. No production code changes; ratchet self-tests + the frozen-set contract
still pass (4 tests).

Stacked on #6214.

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-6214 July 18, 2026 01:07 Destroyed
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…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>
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-delivered-gate-route-store branch from 154913a to b375388 Compare July 18, 2026 01:10
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6214 July 18, 2026 01:10 Destroyed
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…evable-floor status

The mechanical §4.3 store consolidations are complete (A1–A8: approvals,
authorization, processes, run-state, budget-gate, and the whole outbound family —
OutboundState/TriggeredRunDelivery/DeliveredGateRoute). Every entry still in
`FROZEN_INMEMORY_STORES` is blocked on non-mechanical work OR is a justified keep,
so the §10 "shrink to empty" goal is not reachable by a swap.

This annotates each remaining allowlist entry with its VERIFIED status so the
next contributor picks up a scoped task instead of re-deriving the blocker
(comments are stripped by the scanner — documentation only, the enforced string
set is unchanged; entries reordered to group the justified keeps):

- turns cluster — DEFERRED (production `inmemory-turn-state` authority; needs a
  no-livelock concurrency proof + a built filesystem variant, some cross-crate).
- `InMemoryBoundedSubagentGoalStore`, `InMemoryOpenAiCompatRefStore` — JUSTIFIED
  bounded CACHES (capacity-bounded evict-oldest / bounded-LRU + filesystem-free
  contract boundary), NOT persistence debt; a durable variant would be wrong.
- `InMemoryExtensionInstallationStore` — BLOCKED cross-crate (the Filesystem
  variant in composition depends on a composition-internal contract registry;
  can't move down to `ironclaw_extensions`).
- `InMemorySecretStore` — security-sensitive.
- `InMemorySessionStore` — BUILD-FIRST (no filesystem variant; auth-adjacent).

Also reconciles the module-doc "definition of done" to note the two justified
caches. No production code changes; ratchet self-tests + the frozen-set contract
still pass (4 tests).

Stacked on #6214.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ilblackdragon and others added 2 commits July 18, 2026 01:20
…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>
…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>
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-triggered-run-delivery-store branch from baa5deb to 0979acf Compare July 18, 2026 01:20
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-consolidate-delivered-gate-route-store branch from b375388 to 8d453ff Compare July 18, 2026 01:20
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…evable-floor status

The mechanical §4.3 store consolidations are complete (A1–A8: approvals,
authorization, processes, run-state, budget-gate, and the whole outbound family —
OutboundState/TriggeredRunDelivery/DeliveredGateRoute). Every entry still in
`FROZEN_INMEMORY_STORES` is blocked on non-mechanical work OR is a justified keep,
so the §10 "shrink to empty" goal is not reachable by a swap.

This annotates each remaining allowlist entry with its VERIFIED status so the
next contributor picks up a scoped task instead of re-deriving the blocker
(comments are stripped by the scanner — documentation only, the enforced string
set is unchanged; entries reordered to group the justified keeps):

- turns cluster — DEFERRED (production `inmemory-turn-state` authority; needs a
  no-livelock concurrency proof + a built filesystem variant, some cross-crate).
- `InMemoryBoundedSubagentGoalStore`, `InMemoryOpenAiCompatRefStore` — JUSTIFIED
  bounded CACHES (capacity-bounded evict-oldest / bounded-LRU + filesystem-free
  contract boundary), NOT persistence debt; a durable variant would be wrong.
- `InMemoryExtensionInstallationStore` — BLOCKED cross-crate (the Filesystem
  variant in composition depends on a composition-internal contract registry;
  can't move down to `ironclaw_extensions`).
- `InMemorySecretStore` — security-sensitive.
- `InMemorySessionStore` — BUILD-FIRST (no filesystem variant; auth-adjacent).

Also reconciles the module-doc "definition of done" to note the two justified
caches. No production code changes; ratchet self-tests + the frozen-set contract
still pass (4 tests).

Stacked on #6214.

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-6214 July 18, 2026 01:20 Destroyed
@ilblackdragon

Copy link
Copy Markdown
Member Author

✅ Ready for merge

CI green (18 pass / 0 fail) on the restacked head. Stacked on #6213.

  • Review verdict: clean §4.3 slice — InMemoryDeliveredGateRouteStore deleted; the new NoopDeliveredGateRouteStore null object is a sensible non-routing default, now deriving Clone/Copy (Gemini note, reply on thread).
  • Fixes: ironclaw_channel_delivery route-store doubles repointed (the feat(reborn): telegram channel extension — admin bot setup, WebGeneratedCode pairing, DM entrypoint #6159 semantic conflict); the slack_serve e2e harness conflict against main's FinalReplyDeliveryServices rename resolved keeping both sides' changes; stale harness doc describing the deleted store refreshed.

🤖 Generated with Claude Code

@ilblackdragon
ilblackdragon merged commit fb2bc20 into refactor/reborn-consolidate-triggered-run-delivery-store Jul 18, 2026
20 checks passed
@ilblackdragon
ilblackdragon deleted the refactor/reborn-consolidate-delivered-gate-route-store branch July 18, 2026 03:03
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>
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…evable-floor status

The mechanical §4.3 store consolidations are complete (A1–A8: approvals,
authorization, processes, run-state, budget-gate, and the whole outbound family —
OutboundState/TriggeredRunDelivery/DeliveredGateRoute). Every entry still in
`FROZEN_INMEMORY_STORES` is blocked on non-mechanical work OR is a justified keep,
so the §10 "shrink to empty" goal is not reachable by a swap.

This annotates each remaining allowlist entry with its VERIFIED status so the
next contributor picks up a scoped task instead of re-deriving the blocker
(comments are stripped by the scanner — documentation only, the enforced string
set is unchanged; entries reordered to group the justified keeps):

- turns cluster — DEFERRED (production `inmemory-turn-state` authority; needs a
  no-livelock concurrency proof + a built filesystem variant, some cross-crate).
- `InMemoryBoundedSubagentGoalStore`, `InMemoryOpenAiCompatRefStore` — JUSTIFIED
  bounded CACHES (capacity-bounded evict-oldest / bounded-LRU + filesystem-free
  contract boundary), NOT persistence debt; a durable variant would be wrong.
- `InMemoryExtensionInstallationStore` — BLOCKED cross-crate (the Filesystem
  variant in composition depends on a composition-internal contract registry;
  can't move down to `ironclaw_extensions`).
- `InMemorySecretStore` — security-sensitive.
- `InMemorySessionStore` — BUILD-FIRST (no filesystem variant; auth-adjacent).

Also reconciles the module-doc "definition of done" to note the two justified
caches. No production code changes; ratchet self-tests + the frozen-set contract
still pass (4 tests).

Stacked on #6214.

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

* refactor(reborn): triggered-run-delivery store over RootFilesystem, delete 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>

* docs(reborn): dev-dep comment names the test-support helper, not the deleted store

Addresses the IronLoop finding on #6213.

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

* refactor(reborn): delivered-gate-route store over RootFilesystem, delete 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>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…evable-floor status

The mechanical §4.3 store consolidations are complete (A1–A8: approvals,
authorization, processes, run-state, budget-gate, and the whole outbound family —
OutboundState/TriggeredRunDelivery/DeliveredGateRoute). Every entry still in
`FROZEN_INMEMORY_STORES` is blocked on non-mechanical work OR is a justified keep,
so the §10 "shrink to empty" goal is not reachable by a swap.

This annotates each remaining allowlist entry with its VERIFIED status so the
next contributor picks up a scoped task instead of re-deriving the blocker
(comments are stripped by the scanner — documentation only, the enforced string
set is unchanged; entries reordered to group the justified keeps):

- turns cluster — DEFERRED (production `inmemory-turn-state` authority; needs a
  no-livelock concurrency proof + a built filesystem variant, some cross-crate).
- `InMemoryBoundedSubagentGoalStore`, `InMemoryOpenAiCompatRefStore` — JUSTIFIED
  bounded CACHES (capacity-bounded evict-oldest / bounded-LRU + filesystem-free
  contract boundary), NOT persistence debt; a durable variant would be wrong.
- `InMemoryExtensionInstallationStore` — BLOCKED cross-crate (the Filesystem
  variant in composition depends on a composition-internal contract registry;
  can't move down to `ironclaw_extensions`).
- `InMemorySecretStore` — security-sensitive.
- `InMemorySessionStore` — BUILD-FIRST (no filesystem variant; auth-adjacent).

Also reconciles the module-doc "definition of done" to note the two justified
caches. No production code changes; ratchet self-tests + the frozen-set contract
still pass (4 tests).

Stacked on #6214.

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

* test(reborn): annotate the §4.3 store ratchet with the per-entry achievable-floor status

The mechanical §4.3 store consolidations are complete (A1–A8: approvals,
authorization, processes, run-state, budget-gate, and the whole outbound family —
OutboundState/TriggeredRunDelivery/DeliveredGateRoute). Every entry still in
`FROZEN_INMEMORY_STORES` is blocked on non-mechanical work OR is a justified keep,
so the §10 "shrink to empty" goal is not reachable by a swap.

This annotates each remaining allowlist entry with its VERIFIED status so the
next contributor picks up a scoped task instead of re-deriving the blocker
(comments are stripped by the scanner — documentation only, the enforced string
set is unchanged; entries reordered to group the justified keeps):

- turns cluster — DEFERRED (production `inmemory-turn-state` authority; needs a
  no-livelock concurrency proof + a built filesystem variant, some cross-crate).
- `InMemoryBoundedSubagentGoalStore`, `InMemoryOpenAiCompatRefStore` — JUSTIFIED
  bounded CACHES (capacity-bounded evict-oldest / bounded-LRU + filesystem-free
  contract boundary), NOT persistence debt; a durable variant would be wrong.
- `InMemoryExtensionInstallationStore` — BLOCKED cross-crate (the Filesystem
  variant in composition depends on a composition-internal contract registry;
  can't move down to `ironclaw_extensions`).
- `InMemorySecretStore` — security-sensitive.
- `InMemorySessionStore` — BUILD-FIRST (no filesystem variant; auth-adjacent).

Also reconciles the module-doc "definition of done" to note the two justified
caches. No production code changes; ratchet self-tests + the frozen-set contract
still pass (4 tests).

Stacked on #6214.

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

* docs(reborn): correct the ratchet per-entry annotations (IronLoop findings on #6216)

- Drop the reference to a worklog not present in the tree.
- InMemoryCheckpointStateStore: FilesystemCheckpointStateStore already
  exists in ironclaw_loop_host (contract-tested, composition-wired) — the
  entry needs a test-seam swap, not a store built; LoopCheckpoint/
  InstructionMaterialization still need variants built.
- Justified-keeps section acknowledges the production filesystem variants
  that already exist and are wired (FilesystemSubagentGoalStore,
  FilesystemOpenAiCompatRefStore) — the in-memory types are the bounded
  volatile role beside them, not missing consolidations.
- OpenAiCompatRef eviction described as oldest-created (min created_at,
  reads do not refresh recency), not LRU.
- Completeness claim softened: the pub(crate) trio is explicitly
  untriaged rather than claimed verified.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ilblackdragon added a commit that referenced this pull request Jul 18, 2026
…> CompositeRootFilesystem (§4.4.1) (#6218)

* test(reborn): annotate the §4.3 store ratchet with the per-entry achievable-floor status

The mechanical §4.3 store consolidations are complete (A1–A8: approvals,
authorization, processes, run-state, budget-gate, and the whole outbound family —
OutboundState/TriggeredRunDelivery/DeliveredGateRoute). Every entry still in
`FROZEN_INMEMORY_STORES` is blocked on non-mechanical work OR is a justified keep,
so the §10 "shrink to empty" goal is not reachable by a swap.

This annotates each remaining allowlist entry with its VERIFIED status so the
next contributor picks up a scoped task instead of re-deriving the blocker
(comments are stripped by the scanner — documentation only, the enforced string
set is unchanged; entries reordered to group the justified keeps):

- turns cluster — DEFERRED (production `inmemory-turn-state` authority; needs a
  no-livelock concurrency proof + a built filesystem variant, some cross-crate).
- `InMemoryBoundedSubagentGoalStore`, `InMemoryOpenAiCompatRefStore` — JUSTIFIED
  bounded CACHES (capacity-bounded evict-oldest / bounded-LRU + filesystem-free
  contract boundary), NOT persistence debt; a durable variant would be wrong.
- `InMemoryExtensionInstallationStore` — BLOCKED cross-crate (the Filesystem
  variant in composition depends on a composition-internal contract registry;
  can't move down to `ironclaw_extensions`).
- `InMemorySecretStore` — security-sensitive.
- `InMemorySessionStore` — BUILD-FIRST (no filesystem variant; auth-adjacent).

Also reconciles the module-doc "definition of done" to note the two justified
caches. No production code changes; ratchet self-tests + the frozen-set contract
still pass (4 tests).

Stacked on #6214.

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

* docs(reborn): correct the ratchet per-entry annotations (IronLoop findings on #6216)

- Drop the reference to a worklog not present in the tree.
- InMemoryCheckpointStateStore: FilesystemCheckpointStateStore already
  exists in ironclaw_loop_host (contract-tested, composition-wired) — the
  entry needs a test-seam swap, not a store built; LoopCheckpoint/
  InstructionMaterialization still need variants built.
- Justified-keeps section acknowledges the production filesystem variants
  that already exist and are wired (FilesystemSubagentGoalStore,
  FilesystemOpenAiCompatRefStore) — the in-memory types are the bounded
  volatile role beside them, not missing consolidations.
- OpenAiCompatRef eviction described as oldest-created (min created_at,
  reads do not refresh recency), not LRU.
- Completeness claim softened: the pub(crate) trio is explicitly
  untriaged rather than claimed verified.

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

* refactor(reborn): inline the redundant LocalDevRootFilesystem alias -> CompositeRootFilesystem (§4.4.1)

First §4.4.1 slice (deployment-mode-as-type cleanup), on a fresh axis now that the
mechanical §4.3 store family is complete. `LocalDevRootFilesystem` was a
`pub(crate) type LocalDevRootFilesystem = CompositeRootFilesystem;` alias — a pure
redundant indirection whose `LocalDev` prefix falsely read as a deployment tier
when it is just the composition's `CompositeRootFilesystem` (the same type
factory.rs already used directly, interchangeably, in dozens of places). This is
the doc's §4.4.1 bucket-(b): mis-prefixed shared substrate → de-prefix to the
honest type.

Inlined the alias to `ironclaw_filesystem::CompositeRootFilesystem` across the 4
composition files that used it (factory/runtime/openai_compat_serve/turn_run_snapshot,
~54 sites), deleted the alias, and repointed the imports (the alias was exported
from `crate::factory`; consumers now import the real type from
`ironclaw_filesystem`). The private, genuinely-local-dev
`LocalDevRootFilesystemBundle` struct keeps its name (word-boundary rename left it
untouched; it is not on the ratchet — visibility-aware scanner skips private types).

R2 ratchet (`reborn_localdev_typename`): drop `LocalDevRootFilesystem` from the
frozen allowlist — one fewer deployment-mode-as-type leak.

Pure type-alias inline, semantically identical. Verified: `cargo build -p
ironclaw_reborn_composition` (default + libsql+slack) clean; localdev ratchet 4;
clippy -D warnings clean; local_dev composition tests 233 pass; fmt + pre-commit clean.

Stacked on #6216.

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

---------

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

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-6214 — 8d453ff1 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: low Changes to docs, tests, or low-risk modules size: L 200-499 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant