Remove in-memory ratchet stores - #6430
Conversation
🔎 IronLoop Review StatusHead: Current reviewers:
Reviewer summaries
Recent activity
Available commands
Run metadataAdmission: webhook accepted the request and IronLoop persisted reviewer state before this projection. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (90)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe PR replaces in-memory extension, subagent, prompt-materialization, OpenAI reference, and session stores with filesystem-backed or ephemeral implementations; adds CAS persistence and signed-session APIs; updates runtime wiring, migration paths, tests, architecture ratchets, and documentation. ChangesStore migrations
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related issues
Suggested reviewers: 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. Comment |
There was a problem hiding this comment.
⏭️ IronLoop Review Declined: reviewer
Review at a glance
| Disposition | Head |
|---|---|
| ⏭️ Review declined | 3143b942edf8 |
Head: 3143b942edf8ab5012978f7fe8ef556629bf108c
Reason: The diff spans 208 files across runner, persistence, security-sensitive runtime paths, composition, CI, migration, and WebUI (5,130 insertions and 10,442 deletions), substantially exceeding the PR’s stated scope.
Next: Split or rebase this into a focused PR containing only the subagent goal-store migration, then request review against the resulting narrow base-to-head diff. Review the remaining cross-cutting deletions and behavior changes as separately scoped PRs with targeted validation.
Run details
Status: Current
Trustworthy review produced: no
Summary
Skipped: the supplied base-to-head comparison is a mega, cross-cutting change that cannot be reliably reviewed as the narrowly described subagent goal-store change within this review scope.
There was a problem hiding this comment.
Code Review
This pull request replaces the custom InMemoryBoundedSubagentGoalStore with a FilesystemSubagentGoalStore backed by an InMemoryBackend across the codebase to unify test infrastructure. The reviewer suggests further improving maintainability by exposing scoped_goal_filesystem as a public helper and standardizing the use of in_memory_backed_subagent_goal_store across all test files to eliminate redundant boilerplate code.
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.
| #[cfg(test)] | ||
| pub(crate) fn in_memory_backed_subagent_goal_store() | ||
| -> FilesystemSubagentGoalStore<ironclaw_filesystem::InMemoryBackend> { | ||
| FilesystemSubagentGoalStore::new(scoped_goal_filesystem()) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| fn scoped_goal_filesystem() -> Arc<ScopedFilesystem<ironclaw_filesystem::InMemoryBackend>> { |
There was a problem hiding this comment.
To avoid duplicating the complex in-memory FilesystemSubagentGoalStore setup across multiple test files, we can expose in_memory_backed_subagent_goal_store and scoped_goal_filesystem as public helpers under #[cfg(any(test, feature = "test-support"))]. This centralizes the test harness configuration and improves maintainability.
| #[cfg(test)] | |
| pub(crate) fn in_memory_backed_subagent_goal_store() | |
| -> FilesystemSubagentGoalStore<ironclaw_filesystem::InMemoryBackend> { | |
| FilesystemSubagentGoalStore::new(scoped_goal_filesystem()) | |
| } | |
| #[cfg(test)] | |
| fn scoped_goal_filesystem() -> Arc<ScopedFilesystem<ironclaw_filesystem::InMemoryBackend>> { | |
| #[cfg(any(test, feature = "test-support"))] | |
| pub fn in_memory_backed_subagent_goal_store() | |
| -> FilesystemSubagentGoalStore<ironclaw_filesystem::InMemoryBackend> { | |
| FilesystemSubagentGoalStore::new(scoped_goal_filesystem()) | |
| } | |
| #[cfg(any(test, feature = "test-support"))] | |
| pub fn scoped_goal_filesystem() -> Arc<ironclaw_filesystem::ScopedFilesystem<ironclaw_filesystem::InMemoryBackend>> { |
References
- Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.
| let goal_mounts = MountView::new(vec![MountGrant::new( | ||
| MountAlias::new("/turns").unwrap(), | ||
| VirtualPath::new("/turns").unwrap(), | ||
| MountPermissions::read_write_list_delete(), | ||
| )]) | ||
| .unwrap(); | ||
| let goal_store = Arc::new(FilesystemSubagentGoalStore::new(Arc::new( | ||
| ScopedFilesystem::with_fixed_view(Arc::new(InMemoryBackend::new()), goal_mounts), | ||
| ))); |
There was a problem hiding this comment.
We can simplify this setup by reusing the public in_memory_backed_subagent_goal_store helper from ironclaw_runner instead of duplicating the mount and filesystem boilerplate.
let goal_store = Arc::new(ironclaw_runner::subagent::goal_store::in_memory_backed_subagent_goal_store());References
- Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.
| let await_edge_goal_mounts = MountView::new(vec![MountGrant::new( | ||
| MountAlias::new("/turns").unwrap(), | ||
| VirtualPath::new("/turns").unwrap(), | ||
| MountPermissions::read_write_list_delete(), | ||
| )]) | ||
| .unwrap(); | ||
| let await_edge_goal_store = Arc::new(FilesystemSubagentGoalStore::new(Arc::new( | ||
| ScopedFilesystem::with_fixed_view( | ||
| Arc::new(InMemoryBackend::new()), | ||
| await_edge_goal_mounts, | ||
| ), | ||
| ))); |
There was a problem hiding this comment.
We can simplify this setup by reusing the public in_memory_backed_subagent_goal_store helper from ironclaw_runner instead of duplicating the mount and filesystem boilerplate.
let await_edge_goal_store = Arc::new(ironclaw_runner::subagent::goal_store::in_memory_backed_subagent_goal_store());References
- Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.
| fn in_memory_subagent_goal_store() -> Arc<FilesystemSubagentGoalStore<InMemoryBackend>> { | ||
| let mounts = MountView::new(vec![MountGrant::new( | ||
| MountAlias::new("/turns").unwrap(), | ||
| VirtualPath::new("/turns").unwrap(), | ||
| MountPermissions::read_write_list_delete(), | ||
| )]) | ||
| .unwrap(); | ||
| let fs = Arc::new(ScopedFilesystem::with_fixed_view( | ||
| Arc::new(InMemoryBackend::new()), | ||
| mounts, | ||
| )); | ||
| Arc::new(FilesystemSubagentGoalStore::new(fs)) | ||
| } |
There was a problem hiding this comment.
We can simplify this setup by reusing the public in_memory_backed_subagent_goal_store helper from ironclaw_runner instead of duplicating the mount and filesystem boilerplate.
fn in_memory_subagent_goal_store() -> Arc<FilesystemSubagentGoalStore<InMemoryBackend>> {
Arc::new(ironclaw_runner::subagent::goal_store::in_memory_backed_subagent_goal_store())
}References
- Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.
| fn in_memory_subagent_goal_store() -> Arc<FilesystemSubagentGoalStore<InMemoryBackend>> { | ||
| let mounts = MountView::new(vec![MountGrant::new( | ||
| MountAlias::new("/turns").unwrap(), | ||
| VirtualPath::new("/turns").unwrap(), | ||
| MountPermissions::read_write_list_delete(), | ||
| )]) | ||
| .unwrap(); | ||
| let fs = Arc::new(ScopedFilesystem::with_fixed_view( | ||
| Arc::new(InMemoryBackend::new()), | ||
| mounts, | ||
| )); | ||
| Arc::new(FilesystemSubagentGoalStore::new(fs)) | ||
| } |
There was a problem hiding this comment.
We can simplify this setup by reusing the public in_memory_backed_subagent_goal_store helper from ironclaw_runner instead of duplicating the mount and filesystem boilerplate.
fn in_memory_subagent_goal_store() -> Arc<FilesystemSubagentGoalStore<InMemoryBackend>> {
Arc::new(ironclaw_runner::subagent::goal_store::in_memory_backed_subagent_goal_store())
}References
- Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.
|
🚅 Deployed to the ironclaw-pr-6430 environment in ironclaw-ci-preview
|
…-subagent-goal-store # Conflicts: # crates/ironclaw_reborn_composition/src/factory.rs # crates/ironclaw_reborn_composition/src/runtime.rs # crates/ironclaw_reborn_migration/src/extension_ownership.rs
Coverage ratchetReborn integration-tier coverageLine coverage (Reborn crates): 86.33% — 321376 / 372266 lines Per-crate breakdown (65 crates, lowest-covered first)
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)
|
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
There was a problem hiding this comment.
❌ IronLoop Review: reviewer
Review at a glance
| Verdict | Blocking | Notes | Inline | Head |
|---|---|---|---|---|
| ❌ Changes requested | 1 | 0 | 1 | a235407eb443 |
Head: a235407eb4439be88b64e40362c478fd0a97f287
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
Changes requested: manifest and installation rows are persisted non-atomically, so a crash can leave durable inconsistent extension state that blocks future installation.
Findings
Blocking: 1 / Notes: 0
Blocking findings
1. ❌ [HIGH] Persist the manifest/installation pair atomically
Location: crates/ironclaw_extensions/src/installations.rs:1233-1241
put_manifest(..., CasExpectation::Any) commits the manifest before the installation row. A crash after this write, or a concurrent writer between the two Any writes, can leave an orphan manifest or a manifest hash that does not match its installation; the rollback here only runs while this process remains alive. The lifecycle treats an orphan manifest as already installed, so after restart a fresh install is rejected despite there being no installation row. Use a durable transaction/journal or a versioned recoverable state transition for every manifest/install pair, and add restart/fault-injection coverage.
Developer follow-up
After fixing this feedback:
- Push the fix to this PR branch.
- Re-run this reviewer with
@ironloopai review --agent reviewerif you only changed this reviewer's findings. - Re-run all reviewers with
@ironloopai reviewwhen the fix may affect multiple areas.
| .insert(installation.installation_id().clone(), installation); | ||
| let extension_id = manifest.extension_id().clone(); | ||
| let prior_manifest = self.get_manifest(&extension_id).await?; | ||
| self.put_manifest(&manifest, CasExpectation::Any) |
There was a problem hiding this comment.
This commits the manifest before its installation row, with only in-process rollback. A crash here (or a concurrent Any write) can leave a durable orphan/mismatched pair; lifecycle installation treats an orphan manifest as occupied and rejects retries after restart. Please make the pair crash-consistent and add restart/fault-injection coverage.
…ead gates deleted (nearai#7373) * test(architecture): drop the dead ironclaw_storage row and arm the substrate list Gate-audit finding (open-and-shut): SUBSTRATE_CRATES in reborn_composition_boundaries.rs carried three rows of rot, all invisible because the loop's `let Some(..) else { continue }` silently skipped any entry that resolves to no workspace package: - "ironclaw_storage": no such package exists (verified against `cargo metadata --no-deps`; the only MISSING name of the 29 listed). - "ironclaw_approvals" and "ironclaw_assistant" were each listed twice. The silent skip is replaced with a panic naming the stale entry, so the list can no longer rot invisibly. Verified by sabotage: adding a bogus "ironclaw_zzz_probe" row now fails the test with "is listed in SUBSTRATE_CRATES but is not a workspace package"; the clean list passes (23/23). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): prune the dead sanctioned path from the specificity gate Gate-audit finding (open-and-shut): SANCTIONED_PATHS in reborn_extension_specificity.rs still exempted `extension_host/extension_installation_store.rs` — a file deleted by nearai#6430. No scanned path matches the fragment (verified with rg across crates/), so the entry exempted nothing; it is also the one exclusion surface in this gate with no staleness check, which is how it outlived its file. Full specificity suite green after removal (8/8). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): drop the v1 ironclaw_gateway/static exclusions from the telegram gates Gate-audit finding (open-and-shut): both cross-tree scans in telegram_extension_gates.rs still carved out `ironclaw_gateway/static` — the v1 monolith's embedded UI, whose crate was deleted with the src/ monolith (no crates/*/ironclaw_gateway directory exists). The exclusions matched nothing; scans now cover the whole tree with no dead carve-outs. Suite green after removal (12/12). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): make the dto-collapse gate's header describe the gate that exists Gate-audit finding (open-and-shut doc rot): the module doc still described the pre-nearai#6447 freeze design — a dangling doc-link to FROZEN_COLLAPSE_DTOS (renamed RETIRED_COLLAPSE_DTOS in nearai#6447), a promised delete-without-trimming failure and an empty-allowlist assertion that do not exist in the file, and a named owner for a collapse that completed. The mechanism itself is armed and untouched; the header now describes the permanent zero-gate it became, and records the two originally-frozen names that deliberately left governance (CapabilityOutcome via nearai#6299 deletion, CapabilityDispatchRequest blessed as the canonical port type). Suite green (2/2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): repoint the manifest-reparse allowlist note at the colocated asset Gate-audit finding (open-and-shut doc rot): the BundledAsset allowlist entry's justification still cited include_str! of assets/memory_native/manifest.toml — a path retired when WS2 (nearai#7037) colocated packages; the live include in memory_native_extension.rs reaches crates/extensions/packages/memory-native/manifest.toml. Comment only; the gate's mechanism and counts are untouched. Suite green (2/2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): give the memory-vocabulary gate the partial-tree floor its twin has Gate-audit finding: reborn_memory_retired_vocabulary.rs had no MIN_SCANNED_FILES floor, unlike its explicit twin reborn_retired_taxonomy.rs — so a partially-moved tree (the CHECKLIST WS0 / nearai#6963 'green while measuring nothing' shape) would scan a fraction of the files and still report the vocabulary clean. The gate was in fact born with an already-dead sanctioned path (its own header records this), so the rot class is not hypothetical for this file. Adds the same 500-file floor (real count ~4000), asserts it in the main gate, and pins the premise on a fixture: a 10-file partial tree scans clean and is rejected by the floor. Suite green (4/4); clippy clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): close the transport gate's nested-use-group fail-open Gate-audit finding (sabotage-verified): product_symbols_in's braced-group branch closed at the FIRST '}' (group.find('}')), so a nested group — use ironclaw_assistant::{m::{X}}; — truncated mid-element and recorded zero symbols. Probed live before the fix: appending use ironclaw_assistant::{zzz_audit::{ZzzProbe}}; to webui's lib.rs left transports_name_only_the_frozen_residue_of_product_symbols GREEN, while the plain-path spelling of the same import correctly failed. The same truncation dropped qualified elements inside flat groups ({qualified_module::X} recorded nothing). The group branch now does a balanced-brace walk, splits elements at depth-0 commas only, and records a qualified/nested element's leading path segment — the same key the single-path branch records for ironclaw_assistant::module::X. Flat-element semantics are byte-for-byte unchanged, so the frozen 100-row webui inventory is untouched (suite green 6/6 on the live tree). Regression fixtures added to import_scanner_reads_symbols_out_of_real_use_shapes; the original sabotage now fails with the gate's own message (re-verified). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: delete check-e2e-matrix-files.sh — a gate for a workflow that no longer exists Gate-audit finding (provably inert): the script's default target is .github/workflows/e2e.yml, deleted when the v1 e2e suites were retired (git log --diff-filter=D shows the removing commit); no workflow, script, hook, doc, or guidance file references check-e2e-matrix-files.sh (verified with rg across the repo including .github and .githooks). A checker nothing runs, pointed at a file nothing provides, is dead weight that reads as coverage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: delete the measured-broken check-boundaries.sh and its guidance references Gate-audit finding (provably inert, previously measured): crates/AGENTS.md recorded on 2026-08-05 that the script fails on a clean tree (check 5 false-positives on live test files) and that checks 1/2/3/6 target the deleted v1 src/ tree, passing vacuously. No workflow or hook runs it; its only callers were guidance files, two of which claimed it 'enforces' root-tests feature gating — an enforcement claim the skill-maintainer rules forbid for a check nothing executes. Removed the script and every live reference: the crates/AGENTS.md warning row becomes a tombstone note; the testing skill + exemplar reference drop the false enforcement parenthetical; the architecture-review skill's Verify line drops the dead command; deslop-reborn's allowed-tools drops the permission; .coderabbit.yaml's driver-leak instruction now points at the live enforcement (reborn_persistence_driver_boundary). Two dated docs/internal/ plan snapshots keep their historical mentions. Verified: python3 scripts/ci/check-guidance.py OK (2084 path references) and its self-test OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(product): stop hardcoding charter sub-owner counts in the family map Gate-audit finding (stale prose): crates/product/AGENTS.md said '19-sub-owner reborn_services charter map' — the enforced map has had 20 sub-owners since nearai#7235 added the inspector row (counted from the live table). Rather than chase the number, drop both inline counts: the owning maps and their gates are authoritative, and the re-verify commands are already inline (skill-maintainer rule: no counts without a regeneration recipe). check-guidance.py OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): correct the scanner-fixture file's name-filter claim Gate-audit finding (doc rot with a false coverage claim): the header said naming the FILE reborn_* makes code_style.yml's 'cargo test -p ironclaw_architecture_tests reborn' see it — but that argument is a test-NAME filter (the measurement is documented in reborn_contracts_vendor_census.rs), and none of this file's test fns contains the substring, so that smoke lane runs 0 of them (11 collected by the full plan). Comment-only; the note now records the real semantics so file names are not trusted for lane coverage. Suite green (11/11). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(internal): gate & ratchet audit report + proposed preflight gauntlet The audit the owner asked for after PR nearai#7157 went red six times across four gates: every architecture-test gate, module charter, CI script, and committed baseline inventoried with a verdict and evidence; the handful worth acting on ranked by friction x weakness; the CI-ergonomics analysis (why failures surface one per ~1h round-trip: no --no-fail-fast anywhere in CI, cancel-in-progress on push, sequential fast-checks steps — measured: two broken gates report 1 failure in 18s under the CI shape vs both in 211s with --no-fail-fast); and the sabotage log for every probe. scripts/preflight-gates.sh is the concrete pre-push proposal: the deterministic-gate classes only (script gates ~10s + architecture suite --no-fail-fast + changed-crate charter tests), covering all four nearai#7157 gate classes locally in one command. Unwired — nothing invokes it. Validated end-to-end on this branch: exit 0, 'every deterministic gate green', 402.8s including gate-binary recompiles. Placement verified: python3 scripts/ci/docs_publication_boundary.py OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci(planner): classify preflight-gates.sh and the deleted check-boundaries.sh The gate audit's own PR hit the planner's fail-closed arm — 'unmapped test or CI path: scripts/check-boundaries.sh' — exactly the class the arm exists to force a decision on (and the audit's report documents). Per the PR_STATIC_CONTROL_PATHS membership rule (no Reborn test lane exercises either file): - scripts/preflight-gates.sh — the audit's proposed local pre-push gauntlet; referenced by no workflow. - scripts/check-boundaries.sh — deleted by the audit; the entry lets the deletion diff (and any revert) classify instead of failing every downstream Reborn lane. Verified: the planner now produces mode=selected with the architecture-misc bucket for this branch's diff, and python3 scripts/ci/test_reborn_pr_test_plan.py is OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(internal): add the fold-tripped asymmetric-tolerance exhibit to the audit The strongest single exhibit for shortlist item 2, contributed by the nearai#7157 branch steward after this audit's cutoff and verified against the gate's code: TOLERANCE = 400 is consulted in exactly one direction (the banked-slack check, ceiling.saturating_sub(lines) > TOLERANCE); the growth check is a bare lines > ceiling. With the in-file 'set to current, not padded' instruction, every ceiling is a hard cap at the observed count — so one line landing on main in any contracts crate reds every open branch at its next fold until someone re-captures. Measured recurrence on nearai#7157: loop_contracts re-captured four times, ~once per fold (14,479 -> 13,850 -> 13,949 -> 13,115 -> 13,181), the last tripped by main's nearai#7361/nearai#7363 adding 66 lines to instruction_bundle.rs — nothing the branch wrote. All four deltas were <= 105 lines: either repair shape in §3.2 (one-line upward tolerance using the existing constant, or mid-window pinning) would have absorbed every one with zero red builds. This audit's own sabotage already proved the jaws (+1 line host_api red / -1 line common red); the fold history shows the operational cost. The repair stays a recommendation — adding growth headroom to a ratchet is the owner's call, not this PR's. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): give the contracts size ceiling upward working slack Owner-directed repair of the audit's sharpest finding (report §3.2): the gate's TOLERANCE = 400 was consulted in exactly one direction — the banked-slack check — while the growth check was a bare lines > ceiling. Combined with 'set to current, not padded' pins, every ceiling was a hard cap at the exact observed count, so one line landing on main in any contracts crate redded every open branch at its next fold until someone re-captured. Measured on nearai#7157: four loop_contracts re-captures, roughly once per fold, every delta <= 105 lines — the gate generating its own busywork. The growth check now allows GROWTH_TOLERANCE = 150 of working slack above each pin (sized to composition-budget precedent; the reviewed raises this gate has caught were +1,069 and +1,214 lines, far above it), and all six ceilings are re-pinned to the counts the test itself reported with every ceiling at 0 — which also removes the +400 seed padding on common/loop_contracts/prompt_envelope that contradicted the capture rule and put those crates one deleted line from the banked jaw. Sabotage-verified both ways: +1 line in host_api and -1 line in common — both red before this change — now pass; a +151-line probe still fails with the effective-ceiling arithmetic in the message. Full reborn_dependency_boundaries binary green (41/41); clippy clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci(budget): re-equalize composition pins to observed — restore the working window Owner-directed companion to the contracts-ceiling repair (same annoying class, other mass gate): merged main-side growth since the 2026-08-05 equalization had drifted +101 LOC and +5 Arc<dyn> sites through the tolerance windows, leaving 49 LOC / 10 sites of live headroom — the next routine composition PR would have gone red on wiring alone (the gate audit measured this the same day it was pinned). Per the TOML's own maintenance instructions: loc_ceiling/loc_observed 40423 -> 40524 and arc_dyn 814 -> 819, measured with the gate's --print, set to current not padded, dated notes appended (not overwritten), and the arch-test record (COMPOSITION_ABSOLUTE_SRC_LOC) moved in the same commit as its file requires. ceiling_bp stays 658 — the WS0 floor is deliberately not re-set. Verified: check-composition-budget.sh OK; its 76-case self-test green; reborn_restructure_baselines green; probe +100 LOC now passes (was red at 49 headroom), probe +160 LOC still fails. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(internal): record the landed zero-slack repairs in the audit report The §3.2 repair moved from recommendation to landed at owner direction; the report's answer, inventory rows, and §7 ledger now say so, with the counting-rule fix promoted to the top remaining recommendation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * gates: pin the ceiling-window arithmetic; fail preflight discovery closed Two review-round hardenings (the open CodeRabbit Majors): - reborn_dependency_boundaries.rs: extract the size-ceiling comparison into contracts_ceiling_verdict() and pin its four window edges with a committed regression test (contracts_size_ceiling_window_edges_hold) — accept at ceiling+GROWTH_TOLERANCE, reject one line past, accept at ceiling-TOLERANCE, reject one banked line further, and a zero-measure scan reads Banked, never a silent pass. The pre-repair asymmetry (tolerance consulted only downward) can no longer return silently. Live-gate behavior re-probed unchanged after the rewiring: +1 line to host_api passes, +151 fails with the same effective-ceiling message. - preflight-gates.sh: setup and changed-file discovery now fail closed — a missing repo root exits 2, and a failed merge-base/diff widens the charter run to all five crates instead of silently skipping them (the same fallback the missing-base branch already used). A broken setup may cost compile time, never a silent skip. Full boundary binary 42/42 green; clippy clean; preflight-gates.sh end-to-end green on this tree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ead gates deleted (nearai#7373) * test(architecture): drop the dead ironclaw_storage row and arm the substrate list Gate-audit finding (open-and-shut): SUBSTRATE_CRATES in reborn_composition_boundaries.rs carried three rows of rot, all invisible because the loop's `let Some(..) else { continue }` silently skipped any entry that resolves to no workspace package: - "ironclaw_storage": no such package exists (verified against `cargo metadata --no-deps`; the only MISSING name of the 29 listed). - "ironclaw_approvals" and "ironclaw_assistant" were each listed twice. The silent skip is replaced with a panic naming the stale entry, so the list can no longer rot invisibly. Verified by sabotage: adding a bogus "ironclaw_zzz_probe" row now fails the test with "is listed in SUBSTRATE_CRATES but is not a workspace package"; the clean list passes (23/23). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): prune the dead sanctioned path from the specificity gate Gate-audit finding (open-and-shut): SANCTIONED_PATHS in reborn_extension_specificity.rs still exempted `extension_host/extension_installation_store.rs` — a file deleted by nearai#6430. No scanned path matches the fragment (verified with rg across crates/), so the entry exempted nothing; it is also the one exclusion surface in this gate with no staleness check, which is how it outlived its file. Full specificity suite green after removal (8/8). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): drop the v1 ironclaw_gateway/static exclusions from the telegram gates Gate-audit finding (open-and-shut): both cross-tree scans in telegram_extension_gates.rs still carved out `ironclaw_gateway/static` — the v1 monolith's embedded UI, whose crate was deleted with the src/ monolith (no crates/*/ironclaw_gateway directory exists). The exclusions matched nothing; scans now cover the whole tree with no dead carve-outs. Suite green after removal (12/12). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): make the dto-collapse gate's header describe the gate that exists Gate-audit finding (open-and-shut doc rot): the module doc still described the pre-nearai#6447 freeze design — a dangling doc-link to FROZEN_COLLAPSE_DTOS (renamed RETIRED_COLLAPSE_DTOS in nearai#6447), a promised delete-without-trimming failure and an empty-allowlist assertion that do not exist in the file, and a named owner for a collapse that completed. The mechanism itself is armed and untouched; the header now describes the permanent zero-gate it became, and records the two originally-frozen names that deliberately left governance (CapabilityOutcome via nearai#6299 deletion, CapabilityDispatchRequest blessed as the canonical port type). Suite green (2/2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): repoint the manifest-reparse allowlist note at the colocated asset Gate-audit finding (open-and-shut doc rot): the BundledAsset allowlist entry's justification still cited include_str! of assets/memory_native/manifest.toml — a path retired when WS2 (nearai#7037) colocated packages; the live include in memory_native_extension.rs reaches crates/extensions/packages/memory-native/manifest.toml. Comment only; the gate's mechanism and counts are untouched. Suite green (2/2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): give the memory-vocabulary gate the partial-tree floor its twin has Gate-audit finding: reborn_memory_retired_vocabulary.rs had no MIN_SCANNED_FILES floor, unlike its explicit twin reborn_retired_taxonomy.rs — so a partially-moved tree (the CHECKLIST WS0 / nearai#6963 'green while measuring nothing' shape) would scan a fraction of the files and still report the vocabulary clean. The gate was in fact born with an already-dead sanctioned path (its own header records this), so the rot class is not hypothetical for this file. Adds the same 500-file floor (real count ~4000), asserts it in the main gate, and pins the premise on a fixture: a 10-file partial tree scans clean and is rejected by the floor. Suite green (4/4); clippy clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): close the transport gate's nested-use-group fail-open Gate-audit finding (sabotage-verified): product_symbols_in's braced-group branch closed at the FIRST '}' (group.find('}')), so a nested group — use ironclaw_assistant::{m::{X}}; — truncated mid-element and recorded zero symbols. Probed live before the fix: appending use ironclaw_assistant::{zzz_audit::{ZzzProbe}}; to webui's lib.rs left transports_name_only_the_frozen_residue_of_product_symbols GREEN, while the plain-path spelling of the same import correctly failed. The same truncation dropped qualified elements inside flat groups ({qualified_module::X} recorded nothing). The group branch now does a balanced-brace walk, splits elements at depth-0 commas only, and records a qualified/nested element's leading path segment — the same key the single-path branch records for ironclaw_assistant::module::X. Flat-element semantics are byte-for-byte unchanged, so the frozen 100-row webui inventory is untouched (suite green 6/6 on the live tree). Regression fixtures added to import_scanner_reads_symbols_out_of_real_use_shapes; the original sabotage now fails with the gate's own message (re-verified). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: delete check-e2e-matrix-files.sh — a gate for a workflow that no longer exists Gate-audit finding (provably inert): the script's default target is .github/workflows/e2e.yml, deleted when the v1 e2e suites were retired (git log --diff-filter=D shows the removing commit); no workflow, script, hook, doc, or guidance file references check-e2e-matrix-files.sh (verified with rg across the repo including .github and .githooks). A checker nothing runs, pointed at a file nothing provides, is dead weight that reads as coverage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci: delete the measured-broken check-boundaries.sh and its guidance references Gate-audit finding (provably inert, previously measured): crates/AGENTS.md recorded on 2026-08-05 that the script fails on a clean tree (check 5 false-positives on live test files) and that checks 1/2/3/6 target the deleted v1 src/ tree, passing vacuously. No workflow or hook runs it; its only callers were guidance files, two of which claimed it 'enforces' root-tests feature gating — an enforcement claim the skill-maintainer rules forbid for a check nothing executes. Removed the script and every live reference: the crates/AGENTS.md warning row becomes a tombstone note; the testing skill + exemplar reference drop the false enforcement parenthetical; the architecture-review skill's Verify line drops the dead command; deslop-reborn's allowed-tools drops the permission; .coderabbit.yaml's driver-leak instruction now points at the live enforcement (reborn_persistence_driver_boundary). Two dated docs/internal/ plan snapshots keep their historical mentions. Verified: python3 scripts/ci/check-guidance.py OK (2084 path references) and its self-test OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(product): stop hardcoding charter sub-owner counts in the family map Gate-audit finding (stale prose): crates/product/AGENTS.md said '19-sub-owner reborn_services charter map' — the enforced map has had 20 sub-owners since nearai#7235 added the inspector row (counted from the live table). Rather than chase the number, drop both inline counts: the owning maps and their gates are authoritative, and the re-verify commands are already inline (skill-maintainer rule: no counts without a regeneration recipe). check-guidance.py OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): correct the scanner-fixture file's name-filter claim Gate-audit finding (doc rot with a false coverage claim): the header said naming the FILE reborn_* makes code_style.yml's 'cargo test -p ironclaw_architecture_tests reborn' see it — but that argument is a test-NAME filter (the measurement is documented in reborn_contracts_vendor_census.rs), and none of this file's test fns contains the substring, so that smoke lane runs 0 of them (11 collected by the full plan). Comment-only; the note now records the real semantics so file names are not trusted for lane coverage. Suite green (11/11). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(internal): gate & ratchet audit report + proposed preflight gauntlet The audit the owner asked for after PR nearai#7157 went red six times across four gates: every architecture-test gate, module charter, CI script, and committed baseline inventoried with a verdict and evidence; the handful worth acting on ranked by friction x weakness; the CI-ergonomics analysis (why failures surface one per ~1h round-trip: no --no-fail-fast anywhere in CI, cancel-in-progress on push, sequential fast-checks steps — measured: two broken gates report 1 failure in 18s under the CI shape vs both in 211s with --no-fail-fast); and the sabotage log for every probe. scripts/preflight-gates.sh is the concrete pre-push proposal: the deterministic-gate classes only (script gates ~10s + architecture suite --no-fail-fast + changed-crate charter tests), covering all four nearai#7157 gate classes locally in one command. Unwired — nothing invokes it. Validated end-to-end on this branch: exit 0, 'every deterministic gate green', 402.8s including gate-binary recompiles. Placement verified: python3 scripts/ci/docs_publication_boundary.py OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci(planner): classify preflight-gates.sh and the deleted check-boundaries.sh The gate audit's own PR hit the planner's fail-closed arm — 'unmapped test or CI path: scripts/check-boundaries.sh' — exactly the class the arm exists to force a decision on (and the audit's report documents). Per the PR_STATIC_CONTROL_PATHS membership rule (no Reborn test lane exercises either file): - scripts/preflight-gates.sh — the audit's proposed local pre-push gauntlet; referenced by no workflow. - scripts/check-boundaries.sh — deleted by the audit; the entry lets the deletion diff (and any revert) classify instead of failing every downstream Reborn lane. Verified: the planner now produces mode=selected with the architecture-misc bucket for this branch's diff, and python3 scripts/ci/test_reborn_pr_test_plan.py is OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(internal): add the fold-tripped asymmetric-tolerance exhibit to the audit The strongest single exhibit for shortlist item 2, contributed by the nearai#7157 branch steward after this audit's cutoff and verified against the gate's code: TOLERANCE = 400 is consulted in exactly one direction (the banked-slack check, ceiling.saturating_sub(lines) > TOLERANCE); the growth check is a bare lines > ceiling. With the in-file 'set to current, not padded' instruction, every ceiling is a hard cap at the observed count — so one line landing on main in any contracts crate reds every open branch at its next fold until someone re-captures. Measured recurrence on nearai#7157: loop_contracts re-captured four times, ~once per fold (14,479 -> 13,850 -> 13,949 -> 13,115 -> 13,181), the last tripped by main's nearai#7361/nearai#7363 adding 66 lines to instruction_bundle.rs — nothing the branch wrote. All four deltas were <= 105 lines: either repair shape in §3.2 (one-line upward tolerance using the existing constant, or mid-window pinning) would have absorbed every one with zero red builds. This audit's own sabotage already proved the jaws (+1 line host_api red / -1 line common red); the fold history shows the operational cost. The repair stays a recommendation — adding growth headroom to a ratchet is the owner's call, not this PR's. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(architecture): give the contracts size ceiling upward working slack Owner-directed repair of the audit's sharpest finding (report §3.2): the gate's TOLERANCE = 400 was consulted in exactly one direction — the banked-slack check — while the growth check was a bare lines > ceiling. Combined with 'set to current, not padded' pins, every ceiling was a hard cap at the exact observed count, so one line landing on main in any contracts crate redded every open branch at its next fold until someone re-captured. Measured on nearai#7157: four loop_contracts re-captures, roughly once per fold, every delta <= 105 lines — the gate generating its own busywork. The growth check now allows GROWTH_TOLERANCE = 150 of working slack above each pin (sized to composition-budget precedent; the reviewed raises this gate has caught were +1,069 and +1,214 lines, far above it), and all six ceilings are re-pinned to the counts the test itself reported with every ceiling at 0 — which also removes the +400 seed padding on common/loop_contracts/prompt_envelope that contradicted the capture rule and put those crates one deleted line from the banked jaw. Sabotage-verified both ways: +1 line in host_api and -1 line in common — both red before this change — now pass; a +151-line probe still fails with the effective-ceiling arithmetic in the message. Full reborn_dependency_boundaries binary green (41/41); clippy clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci(budget): re-equalize composition pins to observed — restore the working window Owner-directed companion to the contracts-ceiling repair (same annoying class, other mass gate): merged main-side growth since the 2026-08-05 equalization had drifted +101 LOC and +5 Arc<dyn> sites through the tolerance windows, leaving 49 LOC / 10 sites of live headroom — the next routine composition PR would have gone red on wiring alone (the gate audit measured this the same day it was pinned). Per the TOML's own maintenance instructions: loc_ceiling/loc_observed 40423 -> 40524 and arc_dyn 814 -> 819, measured with the gate's --print, set to current not padded, dated notes appended (not overwritten), and the arch-test record (COMPOSITION_ABSOLUTE_SRC_LOC) moved in the same commit as its file requires. ceiling_bp stays 658 — the WS0 floor is deliberately not re-set. Verified: check-composition-budget.sh OK; its 76-case self-test green; reborn_restructure_baselines green; probe +100 LOC now passes (was red at 49 headroom), probe +160 LOC still fails. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(internal): record the landed zero-slack repairs in the audit report The §3.2 repair moved from recommendation to landed at owner direction; the report's answer, inventory rows, and §7 ledger now say so, with the counting-rule fix promoted to the top remaining recommendation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * gates: pin the ceiling-window arithmetic; fail preflight discovery closed Two review-round hardenings (the open CodeRabbit Majors): - reborn_dependency_boundaries.rs: extract the size-ceiling comparison into contracts_ceiling_verdict() and pin its four window edges with a committed regression test (contracts_size_ceiling_window_edges_hold) — accept at ceiling+GROWTH_TOLERANCE, reject one line past, accept at ceiling-TOLERANCE, reject one banked line further, and a zero-measure scan reads Banked, never a silent pass. The pre-repair asymmetry (tolerance consulted only downward) can no longer return silently. Live-gate behavior re-probed unchanged after the rewiring: +1 line to host_api passes, +151 fails with the same effective-ceiling message. - preflight-gates.sh: setup and changed-file discovery now fail closed — a missing repo root exits 2, and a failed merge-base/diff widens the charter run to all five crates instead of silently skipping them (the same fallback the missing-base branch already used). A broken setup may cost compile time, never a silent skip. Full boundary binary 42/42 green; clippy clean; preflight-gates.sh end-to-end green on this tree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Summary
Removes the in-memory ratchet store allowances and migrates the durable cases onto filesystem-backed stores:
FilesystemSubagentGoalStoreFilesystemOpenAiCompatRefStoreEphemeralInstructionMaterializationStorebecause it is intentionally per-run prompt staging and must not persist raw prompt materialFilesystemExtensionInstallationStoreinironclaw_extensionsFor extension installations, this removes the volatile/in-memory engine and deletes the composition-owned snapshot adapter. The filesystem store uses row-based records under the extension installation root and exact indexes for
extension_id,installation_id, andactivation_state, so list/read/update/delete paths use the filesystem query and CAS APIs directly instead of rewriting a whole snapshot file.Impact
The ratchet whitelist shrinks by removing all four prior allowed
InMemory*store names.Extension installation state moves from the old snapshot-style
/system/extensions/.installations/state.jsonshape to row records:/system/extensions/.installations/manifests/<hashed_extension_id>.json/system/extensions/.installations/installations/<hashed_installation_id>.jsonHosted composition uses the same shape below
/tenants/<tenant>/system/extensions/.installations. Activation and health mutations now operate on installation rows with bounded CAS retries.Compatibility / Rollback
This intentionally removes the old extension installation snapshot file path. Rollback is a branch revert; any deployment that already wrote row records would need an explicit data migration back to the old snapshot shape before reverting runtime code.
Validation
cargo fmt --allcargo check -p ironclaw_extensionscargo test -p ironclaw_extensions installationscargo test -p ironclaw_extensions --test installations_contractcargo test -p ironclaw_product_adapter_registry --test registry_contractcargo test -p ironclaw_reborn_migration --test migration_roundtripcargo test -p ironclaw_reborn_composition extension_installation_state_pathcargo test -p ironclaw_architecture reborn_inmemory_store_allowlist_is_frozen_and_only_shrinkscargo clippy -p ironclaw_extensions --all-targets -- -D warningscargo clippy -p ironclaw_reborn_composition --lib --tests -- -D warningscargo clippy -p ironclaw_product_adapter_registry --all-targets -- -D warningscargo clippy -p ironclaw_reborn_migration --all-targets -- -D warningsgit diff --check