Skip to content

Remove in-memory ratchet stores - #6430

Merged
ilblackdragon merged 13 commits into
mainfrom
agent/remove-inmemory-subagent-goal-store
Jul 21, 2026
Merged

ilblackdragon merged 13 commits into
mainfrom
agent/remove-inmemory-subagent-goal-store

Conversation

@ilblackdragon

@ilblackdragon ilblackdragon commented Jul 21, 2026 •

Copy link
Copy Markdown
Member

Summary

Removes the in-memory ratchet store allowances and migrates the durable cases onto filesystem-backed stores:

  • subagent goals use FilesystemSubagentGoalStore
  • OpenAI-compatible refs use FilesystemOpenAiCompatRefStore
  • instruction materialization is renamed to EphemeralInstructionMaterializationStore because it is intentionally per-run prompt staging and must not persist raw prompt material
  • extension installations now use a single FilesystemExtensionInstallationStore in ironclaw_extensions

For 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, and activation_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.json shape to row records:

  • /system/extensions/.installations/manifests/<hashed_extension_id>.json
  • /system/extensions/.installations/installations/<hashed_installation_id>.json

Hosted 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 --all
  • cargo check -p ironclaw_extensions
  • cargo test -p ironclaw_extensions installations
  • cargo test -p ironclaw_extensions --test installations_contract
  • cargo test -p ironclaw_product_adapter_registry --test registry_contract
  • cargo test -p ironclaw_reborn_migration --test migration_roundtrip
  • cargo test -p ironclaw_reborn_composition extension_installation_state_path
  • cargo test -p ironclaw_architecture reborn_inmemory_store_allowlist_is_frozen_and_only_shrinks
  • cargo clippy -p ironclaw_extensions --all-targets -- -D warnings
  • cargo clippy -p ironclaw_reborn_composition --lib --tests -- -D warnings
  • cargo clippy -p ironclaw_product_adapter_registry --all-targets -- -D warnings
  • cargo clippy -p ironclaw_reborn_migration --all-targets -- -D warnings
  • git diff --check

@ironloopai

ironloopai Bot commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

🔎 IronLoop Review Status

Head: a235407eb4439be88b64e40362c478fd0a97f287
Result: 1 blocking finding across 1 reviewer.
Next: Address the blocking findings, push fixes, then re-run the relevant reviewer.
Updated: 2026-07-21T22:26:14.115Z

Current reviewers:

Reviewer State Verdict Findings Last update
ironloop/common-reviewer (reviewer) Completed Changes requested 1 blocking finding / 0 notes 2026-07-21T22:26:14.107Z
Reviewer summaries
Reviewer Detail
ironloop/common-reviewer (reviewer) Changes requested; 1 blocking finding; Changes requested: manifest and installation rows are persisted non-atomically, so a crash can leave durable inconsistent extension state that blocks future installation.
Recent activity
Time Reviewer State Detail
2026-07-21T17:10:01.695Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
2026-07-21T17:18:29.436Z ironloop/common-reviewer (reviewer) Superseded A newer PR head replaced this review (79fc3fe).
2026-07-21T22:19:05.780Z ironloop/common-reviewer (reviewer) Queued Accepted review request for head a235407.
2026-07-21T22:19:05.780Z ironloop/common-reviewer (reviewer) Queued Waiting for this reviewer lane to become available.
2026-07-21T22:19:06.190Z ironloop/common-reviewer (reviewer) Started Reviewer worker started.
2026-07-21T22:19:09.165Z ironloop/common-reviewer (reviewer) Workspace ready Prepared isolated checkout (merge_ref) at 83b5b71.
2026-07-21T22:26:14.107Z ironloop/common-reviewer (reviewer) Result captured Changes requested; 1 blocking finding.
2026-07-21T22:26:14.107Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
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 21, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a68b445f-b5a1-4e9d-86c5-e3e7a8ba50ae

📥 Commits

Reviewing files that changed from the base of the PR and between 9c9c77b and a235407.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock, !**/Cargo.lock
📒 Files selected for processing (90)
  • Cargo.toml
  • crates/AGENTS.md
  • crates/ironclaw_architecture/tests/ratchet_support/mod.rs
  • crates/ironclaw_architecture/tests/reborn_composition_boundaries.rs
  • crates/ironclaw_architecture/tests/reborn_deployment_mode_typename_ratchet.rs
  • crates/ironclaw_architecture/tests/reborn_inmemory_store_ratchet.rs
  • crates/ironclaw_architecture/tests/reborn_localdev_typename_ratchet.rs
  • crates/ironclaw_extensions/src/installations.rs
  • crates/ironclaw_extensions/src/lib.rs
  • crates/ironclaw_extensions/tests/installations_contract.rs
  • crates/ironclaw_loop_host/tests/thread_loop_host_contract.rs
  • crates/ironclaw_product_adapter_registry/Cargo.toml
  • crates/ironclaw_product_adapter_registry/tests/registry_contract.rs
  • crates/ironclaw_product_workflow/Cargo.toml
  • crates/ironclaw_product_workflow/tests/inbound_turn_contract.rs
  • crates/ironclaw_product_workflow/tests/support/planned_agent_loop.rs
  • crates/ironclaw_reborn_cli/src/commands/serve.rs
  • crates/ironclaw_reborn_cli/src/commands/serve_sso.rs
  • crates/ironclaw_reborn_composition/CLAUDE.md
  • crates/ironclaw_reborn_composition/Cargo.toml
  • crates/ironclaw_reborn_composition/src/extension_host/extension_installation_store.rs
  • crates/ironclaw_reborn_composition/src/extension_host/extension_installation_store/tests.rs
  • crates/ironclaw_reborn_composition/src/extension_host/extension_lifecycle.rs
  • crates/ironclaw_reborn_composition/src/extension_host/mod.rs
  • crates/ironclaw_reborn_composition/src/factory.rs
  • crates/ironclaw_reborn_composition/src/factory/auth_tests.rs
  • crates/ironclaw_reborn_composition/src/factory/tests.rs
  • crates/ironclaw_reborn_composition/src/webui/facade/tests.rs
  • crates/ironclaw_reborn_composition/tests/admin_api_e2e.rs
  • crates/ironclaw_reborn_composition/tests/product_live_adapters.rs
  • crates/ironclaw_reborn_composition/tests/webui_v2_serve.rs
  • crates/ironclaw_reborn_migration/src/extension_ownership.rs
  • crates/ironclaw_reborn_migration/tests/migration_roundtrip.rs
  • crates/ironclaw_reborn_openai_compat/src/lib.rs
  • crates/ironclaw_reborn_openai_compat/src/refs.rs
  • crates/ironclaw_reborn_openai_compat/tests/chat_workflow_handlers_contract.rs
  • crates/ironclaw_reborn_openai_compat/tests/refs_contract.rs
  • crates/ironclaw_reborn_openai_compat/tests/responses_path_prefix_contract.rs
  • crates/ironclaw_reborn_openai_compat/tests/responses_temperature_contract.rs
  • crates/ironclaw_reborn_openai_compat/tests/responses_workflow_handlers_contract.rs
  • crates/ironclaw_reborn_openai_compat/tests/streaming_handlers_contract.rs
  • crates/ironclaw_reborn_openai_compat/tests/support/mod.rs
  • crates/ironclaw_runner/Cargo.toml
  • crates/ironclaw_runner/src/loop_driver_host.rs
  • crates/ironclaw_runner/src/model_gateway.rs
  • crates/ironclaw_runner/src/subagent/await_edge/boot_recovery.rs
  • crates/ironclaw_runner/src/subagent/await_edge/resolver.rs
  • crates/ironclaw_runner/src/subagent/flavors.rs
  • crates/ironclaw_runner/src/subagent/goal_store.rs
  • crates/ironclaw_runner/src/subagent/prompt_material.rs
  • crates/ironclaw_runner/tests/llm_gateway.rs
  • crates/ironclaw_runner/tests/loop_driver_host.rs
  • crates/ironclaw_turns/src/run_profile/instruction_bundle.rs
  • crates/ironclaw_turns/src/run_profile/mod.rs
  • crates/ironclaw_turns/src/run_profile/prompt.rs
  • crates/ironclaw_turns/tests/agent_loop_host_contract.rs
  • crates/ironclaw_webui/AGENTS.md
  • crates/ironclaw_webui/CLAUDE.md
  • crates/ironclaw_webui/Cargo.toml
  • crates/ironclaw_webui/README.md
  • crates/ironclaw_webui/src/auth/config.rs
  • crates/ironclaw_webui/src/auth/mod.rs
  • crates/ironclaw_webui/src/auth/routes.rs
  • crates/ironclaw_webui/src/auth/user_directory.rs
  • crates/ironclaw_webui/src/cli_token_login.rs
  • crates/ironclaw_webui/src/lib.rs
  • crates/ironclaw_webui/src/oidc.rs
  • crates/ironclaw_webui/src/session.rs
  • crates/ironclaw_webui/src/signed_session_login.rs
  • crates/ironclaw_webui/src/webui_serve.rs
  • crates/ironclaw_webui/tests/auth_route_contract.rs
  • crates/ironclaw_webui/tests/cli_token_login_route.rs
  • crates/ironclaw_webui/tests/github_oauth_routes.rs
  • crates/ironclaw_webui/tests/google_oauth_routes.rs
  • crates/ironclaw_webui/tests/network_limits_contract.rs
  • crates/ironclaw_webui/tests/session_round_trip.rs
  • crates/ironclaw_webui/tests/signed_session_multi_user.rs
  • docs/plans/2026-07-01-private-tool-installs.md
  • docs/reborn/2026-06-04-subagent-compaction-design.md
  • docs/reborn/2026-07-17-architecture-simplification-dto-dyn-local.md
  • docs/reborn/contracts/extensions.md
  • docs/reborn/security-parity/01-auth.md
  • docs/reborn/security-parity/03-headers-errors.md
  • docs/reborn/subagent-spawn/phase-1-contracts.md
  • docs/superpowers/plans/2026-07-13-extension-ownership-migration.md
  • docs/superpowers/specs/2026-06-26-reborn-integration-test-framework-design.md
  • tests/integration/subagent_await_edge.rs
  • tests/integration/support/group.rs
  • tests/integration/webui_v2_product_api.rs
  • tests/support/reborn_parity_qa/binary_e2e.rs

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Extension installation data is now stored as durable filesystem records, supporting persistence across restarts, indexed queries, safer concurrent updates, and recovery of legacy duplicate records.
    • WebUI authentication now uses signed session tokens with tenant-bound validation and revocation support.
    • Logout consistently returns success after processing a bearer token.
  • Bug Fixes

    • Improved extension lifecycle restoration and canonicalization of persisted installation state.
  • Documentation

    • Updated authentication, extension storage, security, and durability documentation to reflect the new behavior.

Walkthrough

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

Changes

Store migrations

Layer / File(s) Summary
Filesystem extension installations
crates/ironclaw_extensions/..., crates/ironclaw_reborn_composition/src/extension_host/...
Extension manifests and installations are persisted as indexed filesystem rows with CAS updates, retries, canonicalization, and reload coverage.
Signed sessions
crates/ironclaw_webui/src/session.rs, crates/ironclaw_webui/src/signed_session_login.rs, crates/ironclaw_webui/src/auth/...
Session authentication and OAuth wiring now use concrete signed-token stores; logout revocation returns 204 without propagating revocation errors.
Goal and prompt stores
crates/ironclaw_runner/..., crates/ironclaw_turns/...
Bounded in-memory goal storage is replaced by filesystem-backed test support, while instruction materialization is renamed to an ephemeral store.
OpenAI compatibility references
crates/ironclaw_reborn_openai_compat/...
The in-memory reference store is removed and tests construct filesystem-backed stores through shared helpers.
Runtime, migration, and contract wiring
crates/ironclaw_reborn_composition/src/factory.rs, crates/ironclaw_reborn_migration/..., tests/integration/..., docs/...
Factories and tests use .installations/ row directories, direct store APIs, updated feature flags, and revised persistence contracts.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Suggested reviewers: henrypark133


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-6430 July 21, 2026 17:09 Destroyed
@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 21, 2026

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

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

Comment on lines +247 to +254
#[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>> {

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

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.

Suggested change
#[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
  1. Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.

Comment on lines +459 to +467
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),
)));

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

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
  1. Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.

Comment on lines +374 to +385
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,
),
)));

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

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
  1. Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.

Comment on lines +70 to +82
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))
}

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

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
  1. Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.

Comment on lines +217 to +229
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))
}

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

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
  1. Encapsulate complex and repeated test logic into helper functions to simplify test code and provide a cleaner interface.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 17:18 Destroyed
@github-actions github-actions Bot added size: XL 500+ changed lines and removed size: L 200-499 changed lines labels Jul 21, 2026
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 17:23 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 17:32 Destroyed
@github-actions github-actions Bot added the scope: docs Documentation label Jul 21, 2026
@railway-app

railway-app Bot commented Jul 21, 2026 •

Copy link
Copy Markdown

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

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 21, 2026 at 9:44 pm

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 18:05 Destroyed
@github-actions github-actions Bot added the scope: dependencies Dependency updates label Jul 21, 2026
@ilblackdragon ilblackdragon changed the title Remove in-memory subagent goal store Remove in-memory ratchet stores Jul 21, 2026
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 18:11 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 19:15 Destroyed
…-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
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 20:40 Destroyed
@github-actions github-actions Bot added risk: medium Business logic, config, or moderate-risk modules and removed risk: low Changes to docs, tests, or low-risk modules labels Jul 21, 2026
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 20:45 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 21:10 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6430 July 21, 2026 21:21 Destroyed
@github-actions

Copy link
Copy Markdown
Contributor

Coverage ratchet

Ratchet mode: ENFORCING

RATCHET PASS: global
  observed: 86.33% (321376 / 372266 lines)
  floor:    85.3% (tolerance 0.5pp -> effective floor 84.8%)
  denominator: 372266 lines now vs 320188 at floor capture (+52078 lines, +16.26%) — 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): 86.33% — 321376 / 372266 lines

Per-crate breakdown (65 crates, lowest-covered first)
Crate Line % Covered / Total
ironclaw_prompt_envelope 0% 0 / 88
ironclaw_scripts 0% 0 / 345
ironclaw_event_projections 43.31% 673 / 1554
ironclaw_observability 61.54% 16 / 26
ironclaw_channel_host 62.08% 185 / 298
ironclaw_authorization 62.46% 604 / 967
ironclaw_dispatcher 62.88% 83 / 132
ironclaw_mcp 65.63% 611 / 931
ironclaw_filesystem 66.93% 4137 / 6181
ironclaw_memory 69.2% 773 / 1117
ironclaw_reborn_migration 72.54% 2518 / 3471
ironclaw_trust 72.88% 661 / 907
ironclaw_capabilities 74.59% 2516 / 3373
ironclaw_wasm_limiter 74.6% 47 / 63
ironclaw_extractors 74.72% 538 / 720
ironclaw_projects 76.48% 400 / 523
ironclaw_triggers 77.33% 2531 / 3273
ironclaw_reborn_cli 77.86% 10519 / 13511
ironclaw_llm 78.43% 20568 / 26224
ironclaw_product_context 78.57% 11 / 14
ironclaw_wasm_product_adapters 80.36% 1448 / 1802
ironclaw_process_sandbox 80.65% 671 / 832
ironclaw_first_party_extensions 81.06% 5965 / 7359
ironclaw_memory_native 81.17% 3195 / 3936
ironclaw_events 81.95% 1594 / 1945
ironclaw_telegram_extension 82.04% 4404 / 5368
ironclaw_network 82.98% 673 / 811
ironclaw_reborn_event_store 83.03% 1169 / 1408
ironclaw_reborn_identity 83.59% 433 / 518
ironclaw_processes 83.76% 939 / 1121
ironclaw_secrets 83.8% 2550 / 3043
ironclaw_wasm 84.44% 1069 / 1266
ironclaw_reborn_config 84.66% 2152 / 2542
ironclaw_product_workflow 84.89% 11373 / 13397
ironclaw_auth 84.97% 3279 / 3859
ironclaw_run_state 85.61% 458 / 535
ironclaw_channel_delivery 86.11% 1383 / 1606
ironclaw_hooks 86.57% 9930 / 11471
ironclaw_common 86.66% 1741 / 2009
ironclaw_extensions 86.66% 3203 / 3696
ironclaw_threads 87.08% 4844 / 5563
ironclaw_skills 87.6% 4471 / 5104
ironclaw_slack_v2_adapter 87.89% 2024 / 2303
ironclaw_host_api 87.97% 4645 / 5280
ironclaw_product_adapter_registry 88.06% 531 / 603
ironclaw_product_adapters 88.1% 3384 / 3841
ironclaw_reborn_traces 88.2% 11946 / 13544
ironclaw_turns 88.47% 14407 / 16284
ironclaw_host_runtime 88.89% 17766 / 19987
ironclaw_reborn_openai_compat 89.03% 3627 / 4074
ironclaw_webui 89.53% 7797 / 8709
ironclaw_telegram_v2_adapter 89.65% 2712 / 3025
ironclaw_reborn_composition 89.71% 73203 / 81596
ironclaw_approvals 90.18% 1598 / 1772
ironclaw_conversations 90.39% 3123 / 3455
ironclaw_event_streams 90.82% 1009 / 1111
ironclaw_runner 91.18% 16911 / 18547
ironclaw_resources 91.67% 4477 / 4884
ironclaw_loop_host 92.29% 16101 / 17447
ironclaw_attachments 93.06% 630 / 677
ironclaw_agent_loop 94.81% 9467 / 9985
ironclaw_safety 95.15% 3749 / 3940
ironclaw_outbound 95.52% 3451 / 3613
ironclaw_first_party_extension_ports 95.62% 3672 / 3840
ironclaw_runtime_policy 96.55% 811 / 840

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
ilblackdragon marked this pull request as ready for review July 21, 2026 22:19
@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.

@ilblackdragon
ilblackdragon merged commit 21bb07d into main Jul 21, 2026
68 of 69 checks passed
@ilblackdragon
ilblackdragon deleted the agent/remove-inmemory-subagent-goal-store branch July 21, 2026 22:22

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

  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.

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

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

personal-upstream-sync Bot pushed a commit to theredspoon/ironclaw that referenced this pull request Aug 12, 2026
…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>
l3ocifer pushed a commit to l3ocifer/frick-ironclaw that referenced this pull request Sep 3, 2026
…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>

This branch was successfully deployed

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant