Skip to content

test(reborn): freeze the InMemory*Store allowlist ratchet (§10) - #6204

Merged
ilblackdragon merged 3 commits into
mainfrom
refactor/reborn-inmemory-store-ratchet
Jul 17, 2026
Merged

ilblackdragon merged 3 commits into
mainfrom
refactor/reborn-inmemory-store-ratchet

Conversation

@ilblackdragon

Copy link
Copy Markdown
Member

§10 anti-slippage ratchet — freeze the InMemory*Store allowlist

Stacked on #6203. Implements the store-consolidation ratchet §10 of docs/reborn/2026-07-17-architecture-simplification-dto-dyn-local.md — the enforcement the doc says each axis needs during the migration, not only after.

Slice A has deleted the bespoke InMemory*Store for four domains (approvals #6195, authorization-lease #6197, processes #6200, run-state #6203). This test locks that in and prevents backsliding.

What it does

crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs scans crates/ for pub struct InMemory*Store definitions and asserts the set exactly equals a checked-in frozen allowlist (the current 13, post-A4):

  • a new InMemory*Store (not in the allowlist) → test fails: the debt can only shrink, never grow.
  • deleting a store without trimming the allowlist → test fails: the list is forced to shrink in lock-step as each domain lands, and reviewers watch it get shorter (§10: "compare set membership, never an aggregate count").

Definition of done for this axis (§10): the allowlist reaches the empty set — every store is Filesystem*Store<InMemoryBackend> in tests.

Remaining after this

The one remaining Slice-A domain is turns (InMemoryTurnStateStore + InMemory{Checkpoint,LoopCheckpoint,InstructionMaterialization}Store). Unlike A2–A4 it is not a mechanical delete: InMemoryTurnStateStore is 4,258 LOC (larger than the filesystem impl) and the inmemory-turn-state production runtime authority (the in-process turn-state coordinator that avoids per-user state.json CAS livelock). The allowlist documents it explicitly and it is deliberately left for a dedicated, stress-validated effort. The peripheral stores (budget/session/outbound/etc.) are listed to keep the ratchet exhaustive; whether each is in §4.3's domain-store scope is a separate call.

Safety

Test-only. Ships with its own scanner self-test (per "guardrails are code"). No production code touched.

🤖 Generated with Claude Code

@ironloopai

ironloopai Bot commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

🔎 IronLoop Review Status

Head: 93a8c39b5c98ff4ad61758f12f93196799a453f3
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-17T22:35:27.244Z

Current reviewers:

Reviewer State Verdict Findings Last update
ironloop/common-reviewer (reviewer) Superseded N/A N/A 2026-07-17T20:29:52.897Z
Reviewer summaries
Reviewer Detail
ironloop/common-reviewer (reviewer) Superseded by a newer PR head. New head: 92dbd8b. Previous verdict: Changes requested.
Recent activity
Time Reviewer State Detail
2026-07-17T20:12:46.594Z ironloop/common-reviewer (reviewer) Queued Accepted review request for head d0a8e97.
2026-07-17T20:12:46.594Z ironloop/common-reviewer (reviewer) Queued Waiting for this reviewer lane to become available.
2026-07-17T20:12:46.860Z ironloop/common-reviewer (reviewer) Started Reviewer worker started.
2026-07-17T20:12:49.730Z ironloop/common-reviewer (reviewer) Workspace ready Prepared isolated checkout (merge_ref) at cdcc207.
2026-07-17T20:17:57.395Z ironloop/common-reviewer (reviewer) Result captured Changes requested; 1 blocking finding.
2026-07-17T20:17:57.395Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
2026-07-17T20:29:52.897Z ironloop/common-reviewer (reviewer) Superseded A newer PR head replaced this review (92dbd8b).
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.

@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: a5c3a179-c74c-40c9-89c1-7df002fb5d8f

📥 Commits

Reviewing files that changed from the base of the PR and between 661b020 and 93a8c39.

📒 Files selected for processing (1)
  • crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs

📝 Walkthrough

Summary by CodeRabbit

  • Tests
    • Added automated safeguards to detect unintended additions or removals of in-memory store types across the workspace.
    • Added validation to ensure the inventory only includes store types with the expected public visibility.
    • The safeguards also prevent duplicate definitions and ensure the allowlist can only shrink over time, not grow.

Walkthrough

Adds an architecture test that scans workspace Rust sources for public InMemory*Store structs and enforces a frozen allowlist that may only shrink. The scanner handles comments and literals and includes self-tests for extraction and duplicate detection.

Changes

InMemory store inventory ratchet

Layer / File(s) Summary
Ratchet contract and validation
crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs
Defines the frozen store allowlist and rejects new names, duplicate definitions, or allowlist entries that no longer exist; self-tests cover extraction and multiplicity behavior.
Source scanning and collection
crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs
Computes the workspace root, recursively scans eligible Rust files, excludes non-production directories and the ratchet file, and extracts matching public declarations.
Comment and literal stripping
crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs
Adds a newline-preserving Rust-aware lexer for line comments, nested block comments, strings, raw strings, and char literals before declaration matching.

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

Possibly related PRs

  • nearai/ironclaw#6195: Deletes several InMemory*Store definitions tracked by this ratchet.
  • nearai/ironclaw#6203: Replaces tracked in-memory store types with filesystem-backed implementations and test helpers.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR explains the change, but it omits most required template sections like Change Type, Linked Issue, Validation, and Rollback Plan. Fill out the repository template sections, especially Change Type, Linked Issue, Validation, Security Impact, Blast Radius, and Rollback Plan.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Conventional Commits format is used and the title accurately summarizes the ratchet test addition.
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.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6204 July 17, 2026 20:12 Destroyed
@github-actions github-actions Bot added size: XS < 10 changed lines (excluding docs) risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jul 17, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

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

@ironloopai ironloopai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

❌ IronLoop Review: reviewer

Review at a glance

Verdict Blocking Notes Inline Head
❌ Changes requested 1 1 2 d0a8e978e6f7

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

Run details

Status: Current
Needs human: no
Needs validation: no

Summary

The stack layer is small and reviewable: one 155-line architecture test, and the 13-entry allowlist matches the current inventory. However, the ratchet collapses definitions by bare type name, allowing a new same-named store in another module to pass undetected. The scanner also misclassifies definition-shaped text inside multiline literals or block comments.

Findings

Blocking: 1 / Notes: 1

Blocking findings

1. ❌ [MEDIUM] Key the ratchet by qualified definition, not bare name

Location: crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs:144
found is keyed only by the struct identifier, so multiple definitions with the same name collapse into one BTreeSet entry. Rust permits the same type name in different modules or crates; adding another InMemorySessionStore, for example, would leave the discovered set unchanged and pass this ratchet despite introducing a new store. Freeze a qualified key such as relative source path plus identifier, and add a regression test covering same-named definitions in different files.

Non-blocking notes (1)
1. 💬 [LOW] Scanner counts definition-shaped text inside raw strings and block comments

Location: crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs:134-136
The prefix scan has no awareness of Rust comments or literals. A raw multiline fixture or block comment containing a line beginning pub struct InMemoryPhantomStore is reported as a real definition, contradicting the scanner contract and potentially breaking CI for legitimate fixtures. The current string-literal self-test does not exercise this because its literal contains no pub struct text. Parse or lex Rust source, or strip comments/literals, and add raw-string and block-comment cases.

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.

.take_while(|c| c.is_alphanumeric() || *c == '_')
.collect();
if ident.starts_with("InMemory") && ident.ends_with("Store") {
out.insert(ident);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This set is keyed only by the bare identifier, so same-named definitions in different modules collapse. Adding another InMemorySessionStore, for example, leaves found unchanged and passes the ratchet. Please freeze a qualified key such as relative path plus identifier and test the duplicate-name case.

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.

Addressed in 661b020: definitions are now collected as identifier → defining-file paths, and any name with more than one definition fails the ratchet with the files listed (duplicate_definitions + a dedicated self-test covering the two-files-same-name case). I kept identifiers (rather than frozen path+name keys) as the allowlist key so a pure file move doesn't trip the ratchet — the debt is the type's existence, not its location — while the multiplicity check closes the collapse hole you describe.

const MARKER: &str = "pub struct ";
for line in source.lines() {
let trimmed = line.trim_start();
let Some(rest) = trimmed.strip_prefix(MARKER) else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This line-based prefix check also matches definition-shaped lines inside raw multiline strings or block comments. The self-test's string case does not contain pub struct, so it does not verify the documented exclusion. Please add raw-string/block-comment cases and make the scanner token-aware or strip those regions.

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.

Addressed in 661b020: the scanner now strips line comments, nested/multiline block comments, plain string literals (with escapes), raw strings (r#\"…\"#, incl. b/c prefixes), and char literals before the line scan, and the self-test now exercises marker-bearing cases for each region (block comment, nested block comment, plain string, raw string) — the previous string case indeed never contained the marker. Bonus from the same review pass: the matcher also covers pub(crate)/pub(super)/pub(in …) visibility (three previously-invisible production stores are now frozen) and skips tests/ trees so test doubles stay out of scope.

@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-runstate-stores-over-rootfs branch from 1d293c8 to d163cbc Compare July 17, 2026 20:29
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-inmemory-store-ratchet branch from d0a8e97 to 92dbd8b Compare July 17, 2026 20:29
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6204 July 17, 2026 20:29 Destroyed
@railway-app

railway-app Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

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

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 17, 2026 at 10:46 pm

@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-runstate-stores-over-rootfs branch from d163cbc to f8a43b4 Compare July 17, 2026 20:45
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-inmemory-store-ratchet branch from 92dbd8b to 5d950f6 Compare July 17, 2026 20:45
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6204 July 17, 2026 20:45 Destroyed
Base automatically changed from refactor/reborn-runstate-stores-over-rootfs to main July 17, 2026 22:06
ilblackdragon and others added 2 commits July 17, 2026 22:14
…simplification)

Adds the anti-slippage ratchet §10 of
docs/reborn/2026-07-17-architecture-simplification-dto-dyn-local.md calls for on
the store-consolidation axis, locking in the Slice-A progress (approvals #6195,
authorization-lease #6197, processes #6200, run-state #6203 all deleted their
bespoke `InMemory*Store`s).

`crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs` scans
`crates/` for `pub struct InMemory*Store` definitions and asserts the set exactly
equals a checked-in frozen allowlist (the current 13, post-A4):

- a NEW `InMemory*Store` fails the test — the debt can only shrink, never grow;
- deleting a store without trimming the allowlist also fails — so the list is
  forced to shrink in lock-step as each domain lands (§10: compare set
  membership, never a count), and reviewers watch it get shorter.

Definition of done for the axis (§10): the allowlist reaches empty — every store
is `Filesystem*Store<InMemoryBackend>` in tests. The remaining Slice-A target is
the turns domain (`InMemoryTurnStateStore` + checkpoint/instruction stores), which
is reconcile-then-delete and also the `inmemory-turn-state` production runtime
authority — deliberately left for a dedicated, carefully-validated effort, not a
mechanical delete.

Ships with its own scanner self-test (per the "guardrails are code" rule).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…multiplicity, comments/strings)

Addresses the IronLoop findings on #6204 plus one more gap found in review:

- Visibility: the scanner matched only `pub struct`, so `pub(crate)`
  InMemory stores evaded the ratchet entirely. It now matches
  `pub`/`pub(crate)`/`pub(super)`/`pub(in path)` and the frozen list gains
  the three production pub(crate) stores that were invisible before
  (`InMemorySecretsStore`, `InMemorySlackChannelRouteStore`,
  `InMemorySlackPersonalDmTargetStore`); `tests/` trees are skipped so
  test doubles (e.g. tests/support recording stores) stay out of scope.
- Multiplicity: the set was keyed by bare identifier, so a second
  same-named store in another module collapsed into the allowlist entry.
  Definitions are now collected per path and any duplicate name fails with
  the defining files listed; covered by a dedicated self-test.
- Comments/strings: definition-shaped text inside block comments (incl.
  nested/multiline) and plain/raw string literals no longer matches — a
  minimal lexer strips them before the line scan. The self-test now
  exercises marker-bearing comment and string cases, which the previous
  string-literal case never did.

Also rebased onto main post-#6203 merge (drops the stacked A4 commit),
resolving the merge conflict.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-inmemory-store-ratchet branch from 5d950f6 to 661b020 Compare July 17, 2026 22:19
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6204 July 17, 2026 22:19 Destroyed
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-inmemory-store-ratchet branch from 661b020 to 47bc5b4 Compare July 17, 2026 22:20
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6204 July 17, 2026 22:20 Destroyed
@ilblackdragon
ilblackdragon force-pushed the refactor/reborn-inmemory-store-ratchet branch from 47bc5b4 to 661b020 Compare July 17, 2026 22:24

@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_architecture/tests/reborn_inmemory_store_ratchet.rs`:
- Around line 150-166: Update the source-scanning and duplicate-tracking logic
used by scan_source_for_inmemory_store_defs and duplicate_definitions so
multiple definitions of the same store in different modules of one file remain
distinct occurrences rather than being collapsed by the per-file BTreeSet. Add a
regression test covering two module-level InMemoryDupStore definitions in a
single file, asserting both occurrences are preserved and flagged as duplicates,
while retaining the existing separate-file coverage.
- Around line 19-21: Align the collector’s production-only behavior with its
guarantee-bearing documentation: exclude inline #[cfg(test)] modules as well as
examples/ and benches, or narrow the documented contract to match actual
scanning. Update the collector and its related assertions, including a
regression fixture containing an inline #[cfg(test)] store, and ensure test
doubles outside production code are not reported as debt.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: aa51c692-0963-4cbf-8d02-dba549ab76be

📥 Commits

Reviewing files that changed from the base of the PR and between 47bc5b4 and 661b020.

📒 Files selected for processing (1)
  • crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs

Comment thread crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs Outdated
Comment thread crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs
…duction-scope contract

Addresses the two CodeRabbit findings on #6204:

- Same-file multiplicity: the per-file BTreeSet collapsed two same-named
  definitions in different modules of one file before paths were recorded,
  so the duplicate check could not see them. The scan now returns
  occurrences in source order (no dedup) and a dedicated self-test covers
  the same-file/two-module case.
- Scope contract: the docs claimed "production code only", but the
  line-based scanner is not cfg-aware. The walk now also skips examples/
  and benches/ alongside tests/, and the docs + a self-test fixture state
  the actual semantics: an inline #[cfg(test)] store in src IS inventoried
  — keep test doubles under tests/ or justify an allowlist entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6204 July 17, 2026 22:35 Destroyed
@github-actions

Copy link
Copy Markdown
Contributor

Coverage ratchet

Ratchet mode: ENFORCING

RATCHET PASS: global
  observed: 85.94% (304827 / 354688 lines)
  floor:    85.3% (tolerance 0.5pp -> effective floor 84.8%)
  denominator: 354688 lines now vs 320188 at floor capture (+34500 lines, +10.77%) — 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.94% — 304827 / 354688 lines

Per-crate breakdown (62 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_memory 69.2% 773 / 1117
ironclaw_reborn_migration 71.57% 1551 / 2167
ironclaw_trust 72.88% 661 / 907
ironclaw_reborn_cli 74.19% 7010 / 9449
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.25% 20193 / 25805
ironclaw_product_context 78.57% 11 / 14
ironclaw_process_sandbox 80.65% 671 / 832
ironclaw_wasm_product_adapters 80.71% 1448 / 1794
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_reborn_identity 83.59% 433 / 518
ironclaw_processes 83.76% 939 / 1121
ironclaw_run_state 83.96% 424 / 505
ironclaw_wasm 83.97% 1011 / 1204
ironclaw_reborn_config 84.06% 1814 / 2158
ironclaw_auth 84.81% 3233 / 3812
ironclaw_turns 85.13% 13737 / 16136
ironclaw_host_api 85.34% 2695 / 3158
ironclaw_product_workflow 85.79% 10917 / 12725
ironclaw_network 86.12% 670 / 778
ironclaw_common 86.66% 1741 / 2009
ironclaw_slack_v2_adapter 86.79% 1806 / 2081
ironclaw_threads 86.93% 4708 / 5416
ironclaw_product_adapters 87.18% 3265 / 3745
ironclaw_skills 87.58% 4470 / 5104
ironclaw_hooks 87.78% 9921 / 11302
ironclaw_product_adapter_registry 88.06% 531 / 603
ironclaw_reborn_traces 88.19% 11946 / 13546
ironclaw_webui 88.42% 7333 / 8293
ironclaw_host_runtime 88.65% 17840 / 20123
ironclaw_reborn_composition 88.97% 75489 / 84850
ironclaw_extensions 89.38% 2971 / 3324
ironclaw_runner 89.5% 16990 / 18983
ironclaw_reborn_openai_compat 89.5% 3778 / 4221
ironclaw_approvals 90.18% 1598 / 1772
ironclaw_conversations 90.39% 3123 / 3455
ironclaw_event_streams 90.82% 1009 / 1111
ironclaw_resources 91.73% 4490 / 4895
ironclaw_loop_host 92.25% 15051 / 16316
ironclaw_attachments 93.06% 630 / 677
ironclaw_telegram_v2_adapter 93.91% 2592 / 2760
ironclaw_agent_loop 94.88% 9184 / 9680
ironclaw_safety 95.04% 3677 / 3869
ironclaw_outbound 95.59% 3556 / 3720
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

@ilblackdragon

Copy link
Copy Markdown
Member Author

✅ Ready for merge

Reviewed, all findings addressed, CI fully green (56 pass / 0 fail) on head 93a8c39b5.

What was done:

  • Rebased onto main post-refactor(reborn): run-state + approval stores over RootFilesystem, delete InMemory*Store (§4.3) #6203 merge — conflict resolved, the branch carries only the ratchet slice.
  • Review verdict: the §10 frozen-allowlist design is right (set membership both directions, scanner self-tests per "guardrails are code"). The scanner itself needed hardening, which this pass delivered across two commits:
    • 661b020be — visibility: matcher now covers pub(crate)/pub(super)/pub(in …); this surfaced three production stores that were invisible to the original scanner (InMemorySecretsStore, InMemorySlackChannelRouteStore, InMemorySlackPersonalDmTargetStore), now frozen. Multiplicity (IronLoop): duplicate names across files fail with defining paths listed. Comments/strings (IronLoop): a minimal lexer strips line/nested-block comments and plain/raw strings before matching, with marker-bearing self-test cases.
    • 93a8c39b5 — same-file duplicates (CodeRabbit): the scan preserves occurrences instead of deduplicating per file, with a two-modules-one-file self-test. Honest scope contract (CodeRabbit): examples//benches/ skipped alongside tests/, and docs + a fixture pin the actual semantics (inline #[cfg(test)] stores in src are inventoried — keep doubles under tests/).
  • All four review threads (2 IronLoop, 2 CodeRabbit) have fixes + replies.
  • Local gates: 4 ratchet tests + full architecture suite green; clippy -D warnings clean; pre-commit safety within budget.

Follow-up queued for #6205 (stacked): extract the hardened scanner into a shared test-support module so the LocalDev* ratchet reuses it instead of duplicating a weaker copy.

🤖 Generated with Claude Code

ilblackdragon added a commit that referenced this pull request Jul 17, 2026
…for LocalDev ratchet

Addresses the IronLoop finding on #6205 (line-oriented scan matches
comment/string text and misses `pub unsafe trait`) by consolidating both
§10 ratchets onto one hardened scanner instead of duplicating a weaker
copy:

- New `tests/ratchet_support/mod.rs`: comment/string-stripping lexer,
  `pub`/`pub(crate)`/`pub(super)`/`pub(in ...)` visibility, `unsafe`/`auto`
  modifiers, occurrence-preserving scans, production-scoped walk
  (skips tests/, examples/, benches/), and a multiplicity check.
- `reborn_inmemory_store_ratchet.rs` refactored onto the shared module
  (behavior identical; self-tests preserved).
- `reborn_localdev_typename_ratchet.rs` gains everything above plus
  cfg-aware multiplicity: the composition factory defines durable/
  no-durable alias pairs for the same `LocalDev*` name under mutually
  exclusive `#[cfg(...)]` gates (including rustfmt-split multi-line
  gates) — those are exempt from the duplicate check only when every
  occurrence is cfg-gated; a mixed pair still fails. Regression tests
  cover the cfg pair (single- and multi-line), the mixed pair, same-file
  duplicates, and marker-bearing comment/string fixtures.

Also rebased onto #6204's current head.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ilblackdragon
ilblackdragon merged commit d51cc14 into main Jul 17, 2026
65 checks passed
@ilblackdragon
ilblackdragon deleted the refactor/reborn-inmemory-store-ratchet branch July 17, 2026 23:18
ilblackdragon added a commit that referenced this pull request Jul 17, 2026
…for LocalDev ratchet

Addresses the IronLoop finding on #6205 (line-oriented scan matches
comment/string text and misses `pub unsafe trait`) by consolidating both
§10 ratchets onto one hardened scanner instead of duplicating a weaker
copy:

- New `tests/ratchet_support/mod.rs`: comment/string-stripping lexer,
  `pub`/`pub(crate)`/`pub(super)`/`pub(in ...)` visibility, `unsafe`/`auto`
  modifiers, occurrence-preserving scans, production-scoped walk
  (skips tests/, examples/, benches/), and a multiplicity check.
- `reborn_inmemory_store_ratchet.rs` refactored onto the shared module
  (behavior identical; self-tests preserved).
- `reborn_localdev_typename_ratchet.rs` gains everything above plus
  cfg-aware multiplicity: the composition factory defines durable/
  no-durable alias pairs for the same `LocalDev*` name under mutually
  exclusive `#[cfg(...)]` gates (including rustfmt-split multi-line
  gates) — those are exempt from the duplicate check only when every
  occurrence is cfg-gated; a mixed pair still fails. Regression tests
  cover the cfg pair (single- and multi-line), the mixed pair, same-file
  duplicates, and marker-bearing comment/string fixtures.

Also rebased onto #6204's current head.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ilblackdragon added a commit that referenced this pull request Jul 17, 2026
* test(reborn): freeze the LocalDev* type-name ratchet (§4.4/§10, arch-simplification)

Adds the deployment-mode-as-type ratchet §4.4/§10 of
docs/reborn/2026-07-17-architecture-simplification-dto-dyn-local.md calls for on
the `Local*` axis, ahead of Slice B (collapsing the `LocalDev*` shadow runtime to
a `DeploymentConfig` value).

`crates/ironclaw_architecture/tests/reborn_localdev_typename_ratchet.rs` scans
`crates/` for `pub`/`pub(crate)` `LocalDev*` type definitions (struct/enum/trait/
type alias) and asserts the set exactly equals a checked-in frozen allowlist (the
current 31):

- a NEW `LocalDev*` type fails — a deployment mode must resolve to policy data at
  the composition edge, never grow another type;
- deleting one without trimming the allowlist also fails — so the list shrinks in
  lock-step as Slice B lands (§10: compare set membership, never a count).

Definition of done for this axis: the allowlist reaches empty — local-dev is one
`DeploymentConfig` constant, no `LocalDev*` type remains.

Scoped to `LocalDev*` specifically (clean empty-set goal); the broader §4.4 name
audit — Bucket 2 renames (`LocalFilesystem`->`DiskFilesystem`,
`LocalHostProcessPort`->`HostProcessPort`) and Bucket 3 false positives (`Locale`,
`HostedMcp*`, `LocalTraceSubmission*`) — is a separate concern.

Ships with its own scanner self-test (per "guardrails are code"). The scanner is
exhaustive: it surfaced 9 `LocalDev*` types a line-oriented grep had missed
(synthetic-capability + extension-surface + auth-read-model families).

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

* test(reborn): share hardened ratchet scanner; cfg-aware multiplicity for LocalDev ratchet

Addresses the IronLoop finding on #6205 (line-oriented scan matches
comment/string text and misses `pub unsafe trait`) by consolidating both
§10 ratchets onto one hardened scanner instead of duplicating a weaker
copy:

- New `tests/ratchet_support/mod.rs`: comment/string-stripping lexer,
  `pub`/`pub(crate)`/`pub(super)`/`pub(in ...)` visibility, `unsafe`/`auto`
  modifiers, occurrence-preserving scans, production-scoped walk
  (skips tests/, examples/, benches/), and a multiplicity check.
- `reborn_inmemory_store_ratchet.rs` refactored onto the shared module
  (behavior identical; self-tests preserved).
- `reborn_localdev_typename_ratchet.rs` gains everything above plus
  cfg-aware multiplicity: the composition factory defines durable/
  no-durable alias pairs for the same `LocalDev*` name under mutually
  exclusive `#[cfg(...)]` gates (including rustfmt-split multi-line
  gates) — those are exempt from the duplicate check only when every
  occurrence is cfg-gated; a mixed pair still fails. Regression tests
  cover the cfg pair (single- and multi-line), the mixed pair, same-file
  duplicates, and marker-bearing comment/string fixtures.

Also rebased onto #6204's current head.

Co-Authored-By: Claude Fable 5 <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-6204 — 93a8c39b Deployed Jul 17, 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: XS < 10 changed lines (excluding docs)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant