Skip to content

test(reborn): storage-mode audit + operator LLM-config tier-2 coverage - #6131

Closed
henrypark133 wants to merge 2 commits into
mainfrom
test/reborn-storage-mode-audit-tool-call-durable
Closed

henrypark133 wants to merge 2 commits into
mainfrom
test/reborn-storage-mode-audit-tool-call-durable

Conversation

@henrypark133

@henrypark133 henrypark133 commented Jul 15, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Lane 1 of a 4-lane parallel extension to the Reborn tier-2 integration harness. Two pieces now in this PR:

  1. Section 1 of the tier-2 extension plan ("Storage-mode audit: InMemory vs LibSql") — audited all 86 test-module files across the 50 reborn_* bins for assertions reading back persisted state without opting into StorageMode::LibSql.
  2. A scoped follow-up ("§5b, operator API zero-to-one gap") — the plan doc's own audit flagged "Operator API has zero tier-2 coverage: LLM-provider CRUD (including the api_key never echoed back redaction invariant) ... no tests/integration/ file touches any of it." Closed that specific gap.

Two other requested follow-ups were investigated and NOT implemented — see "Scope note" below for why.

1. Storage-mode audit

Method: re-verified against current main that 4 of 50 bins already opt into LibSql (backend_matrix.rs, reopen_resume_through_gate.rs, webui_v2_product_api.rs, group_approvals's approvals_group_libsql_e2e). Went file-by-file through the remaining 82 files: keyword grep (reopen|restart|rehydrat|cold_get|survive|durab|reload|fresh|storage_root_for_test|open_local_dev_|byte_exact|offset|libsql), then for every hit, traced the actual store being asserted against back to its construction to determine whether it's genuinely gated by RebornIntegrationHarness's StorageMode, or a separate always-on-disk local-dev store.

Finding — one genuine candidate: tests/integration/tool_call.rs::result_read_continues_a_durable_result_byte_exactly. Traced install_durable_capability_io → group.rs's group_thread_harness.service → base.composite → build_storage_composite(self.storage, ...) — i.e. .with_durable_capability_io_file_tools()'s content storage genuinely round-trips through whichever backend StorageMode selects. This test reads a byte-exact continuation slice at a specific offset from persisted content — the one test in the suite doing that — and rode InMemory only.

Change: parametrized it with #[rstest] #[case(StorageMode::InMemory)] #[case(StorageMode::LibSql)], following tests/integration/backend_matrix.rs's established convention exactly.

Left alone (with reasoning): sibling test in the same file (backend-agnostic truncation decision, no new signal from LibSql); approval-request/trigger-repository/extension-installation/outbound-preferences/secret-store reopen tests (all confirmed always-on-disk local-dev stores independent of StorageMode, several self-documented "C-DURABLE"); group_multiuser/scenario_turn_state_isolation_across_actors.rs (traced FilesystemTurnStateStore::get_run_state — the scope-isolation check delegates to backend-agnostic shared code); all *_cross_thread/*_isolation group scenarios (same-process shared Arc, proving live visibility not durability); auth_failure.rs/top-level secrets.rs (feature-gated or bypass StorageMode entirely).

2. Operator API — LLM-provider CRUD (new)

New file: tests/integration/operator_llm_config.rs (dedicated bin — webui_v2_product_api.rs is already 1300+ lines covering a different set of route families; operator/LLM-config is its own first-class, zero-to-one area).

Drives the REAL webui_v2_router + REAL RebornLlmConfigService (not a stub), reusing the exact runtime-construction pattern already established 4× in webui_v2_product_api.rs (RebornBuildInput::local_dev → build_reborn_runtime → build_webui_services), plus one new step: .with_boot_config(...) on RebornRuntimeInput, which is what makes the WebUI facade actually wire the real LLM-config service (crates/ironclaw_reborn_composition/src/webui/facade.rs's build_llm_config_service only fires when a boot config is present).

One cohesive test (upsert_llm_provider_never_echoes_api_key_then_get_then_delete) covers the full CRUD path: upsert a provider with an API key → assert the key value never appears anywhere in the response and api_key_set flips true → GET re-fetch → same redaction assertion on read (not just write) → delete → assert gone → delete again → assert 404 (the unknown-provider-id branch — not covered by any existing crate-tier unit test or the webui_v2_handlers_contract.rs contract suite, which only exercises 403-unauthorized and happy-delete for this handler).

One infrastructure line required, not a .rs production change: root-llm-provider was missing from the root Cargo.toml's ironclaw_reborn_composition dev-dependency feature list — without it, .with_boot_config and the real LLM-config service don't exist in the tests/integration build at all. Added it, with a rationale comment matching the file's own established convention for that line. Verified dev-dependency-only and behavior-neutral: the shipped ironclaw-reborn binary (ironclaw_reborn_cli) already has default = ["root-llm-provider"], so production behavior is unchanged. Confirmed with a clean build and the existing webui_v2_product_api.rs suite passing identically (21/21, same tests) before vs. after enabling the feature.

Scope note — two items investigated, not implemented

Filesystem/project-browsing API tier-2 coverage (also flagged as a zero-to-one gap): investigated and found genuinely blocked without a production crate-source change. The concrete reader types (ProjectScopedFilesystemReader, MountScopedFilesystemReader) and the RebornRuntime accessors that would hand back an instance are pub(crate) to ironclaw_reborn_composition — tests/integration is a separate crate and can't name either. The one already-public test-support escape hatch (local_dev_profile_filesystem_for_test) only exposes the raw RootFilesystem, which would mean reimplementing the production reader's path-scoping/traversal-protection logic in test code — testing a reimplementation, not the real production code, which would be worse than no coverage. Closing this for real needs a new #[cfg(feature = "test-support")] accessor in crates/ironclaw_reborn_composition/src/factory.rs (precedented by 3 sibling _for_test accessors in that exact file, but still a production-crate diff). Not implementing per the test-only constraint on this PR; reporting instead.

golden_payload.rs:232-242's two "NOT implemented — blocked" compaction gaps (classify_compaction_message, ActiveTaskPreservingCompactionStrategy::should_compact): read the comment and both functions directly. Turns out both are already genuinely covered at tier-2 through a real turn — tests/integration/http_matcher.rs::multi_tool_turn_survives_failed_forced_compaction_after_results scripts enough content to trip the real ~8,000-token force-compaction threshold and reach both functions, asserted via assert_compaction_failed_since(..., "security rejected"). golden_payload.rs's own docstring states its design constraint ("curated scenario set... add a scenario only when an existing one can't absorb it") — the multi-thousand-token transcript needed would produce an unreviewable golden snapshot, so that file's exclusion is a correct, deliberate scope decision already satisfied elsewhere, not an actual gap. Nothing to add for the two named functions. (A smaller, separate, genuinely-real gap exists — only the Include/security-reject disposition of classify_compaction_message is exercised through a real turn, the other 3 dispositions are unit-tested only — but closing it needs new test-support harness scaffolding to seed specific message statuses, a distinct piece of design work, not a one-scenario add. Flagging as a follow-up, not bolting it onto this PR.)

Verification

  • cargo test --test reborn_integration_tool_call — 28/28 pass, including both new StorageMode cases.
  • cargo test --test reborn_integration_operator_llm_config — 13/13 pass; mutation-tested the core assertion (flipped an expected value, confirmed the test fails for the right reason with the real provider snapshot in the panic message) to confirm it's genuinely discriminating, not vacuous.
  • cargo test --test reborn_integration_webui_v2_product_api --test reborn_integration_webui_v2_router_smoke — unchanged 21+1/22 pass before/after the root-llm-provider feature flip, confirming zero behavioral effect on existing coverage.
  • cargo test -p ironclaw_architecture — 34/34 pass (dependency/composition boundaries unaffected).
  • cargo fmt --check / cargo clippy --all-features on all touched files — clean, zero warnings.
  • Reviewed both plans with thermo-nuclear-code-quality-review before implementing (twice total across the two work items), and the final diffs after (twice) — no structural blockers either pass.
  • Ran the 8-agent code-review skill in local mode on both diffs. First pass (storage-mode parametrization): zero findings. Second pass (operator API + Cargo.toml): 2 actionable findings, both addressed — a missing 404-unknown-provider negative-path assertion (added by extending the existing test) and a missing build-cost rationale comment on the Cargo.toml feature addition (added, matching the file's own convention).

🤖 Generated with Claude Code

…ory/LibSql

Storage-mode audit (docs/plans/2026-07-15-reborn-tier2-extension-plan.md
§1): result_read_continues_a_durable_result_byte_exactly reads a
byte-exact continuation slice back from the durable-preview seam, which
is backed by the group's real thread service — the same RootFilesystem
StorageMode selects — but the test rode the InMemory default only.
Parametrize it the backend_matrix.rs way so the byte-offset round trip
is proven against LibSql's real SQL storage too, not just InMemory's
Vec<u8> staging store.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 15, 2026 22:24

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The integration suite adds end-to-end operator LLM-provider CRUD coverage with API-key redaction assertions and parameterizes durable result continuation coverage across in-memory and LibSql storage modes.

Changes

Integration coverage

Layer / File(s) Summary
Operator LLM-provider lifecycle test
Cargo.toml, tests/integration/operator_llm_config.rs
Registers the operator configuration integration target, enables the required composition feature, builds the production-wired operator router, and verifies API-key redaction, provider deletion, and repeated-delete 404 behavior.
Durable result storage matrix
tests/integration/tool_call.rs
Uses rstest to execute byte-exact durable result continuation assertions with both StorageMode::InMemory and StorageMode::LibSql.

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

Sequence Diagram(s)

sequenceDiagram
  participant Test
  participant webui_v2_router
  participant RebornLlmConfigService
  Test->>webui_v2_router: Upsert provider with api_key
  webui_v2_router->>RebornLlmConfigService: Store provider
  RebornLlmConfigService-->>Test: Redacted provider response
  Test->>webui_v2_router: Fetch providers
  webui_v2_router->>RebornLlmConfigService: Read providers
  RebornLlmConfigService-->>Test: api_key_set provider view
  Test->>webui_v2_router: Delete provider
  webui_v2_router->>RebornLlmConfigService: Remove provider
  Test->>webui_v2_router: Delete provider again
  webui_v2_router-->>Test: 404 Not Found
Loading

Possibly related PRs

  • nearai/ironclaw#5381: Introduces the shared Reborn integration harness and tool-call testing framework used by the storage-mode coverage.
  • nearai/ironclaw#5392: Adds the StorageMode and rstest support used to parameterize the durable result test.
  • nearai/ironclaw#6059: Extends durable result_read persistence behavior covered by the tool-call integration tests.

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is detailed, but several required template sections are missing, including issue linkage and multiple checklist sections. Add the missing template sections: Change Type, Linked Issue, Security Impact, Trust-Boundary Checklist, Database Impact, Blast Radius, Rollback Plan, Review Follow-Through, and Review track.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed Conventional-commit style title accurately summarizes the two integration-test coverage additions in the PR.

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.

@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 parameterizes the result_read_continues_a_durable_result_byte_exactly integration test in tests/integration/tool_call.rs using rstest. The test is now executed against both StorageMode::InMemory and StorageMode::LibSql backends to verify that the byte-offset continuation behaves correctly across different storage implementations. There are no review comments, so I have no feedback to provide.

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.

@github-actions

github-actions Bot commented Jul 15, 2026 •

Copy link
Copy Markdown
Contributor

Coverage ratchet

Ratchet mode: ENFORCING

RATCHET PASS: global
  observed: 85.83% (305266 / 355677 lines)
  floor:    85.3% (tolerance 0.5pp -> effective floor 84.8%)
  denominator: 355677 lines now vs 320188 at floor capture (+35489 lines, +11.08%) — material change (>5%)

⚠️ 2 Reborn crate(s) have 0 int-tier coverage (target: 0) — ironclaw_prompt_envelope, ironclaw_scripts

Reborn integration-tier coverage

Line coverage (Reborn crates): 85.83% — 305266 / 355677 lines

Per-crate breakdown (63 crates, lowest-covered first)
Crate Line % Covered / Total
ironclaw_prompt_envelope 0% 0 / 88
ironclaw_scripts 0% 0 / 345
ironclaw_runtime_policy 31.75% 80 / 252
ironclaw_event_projections 43.31% 673 / 1554
ironclaw_run_state 53.07% 225 / 424
ironclaw_authorization 53.89% 464 / 861
ironclaw_observability 61.54% 16 / 26
ironclaw_webui_v2 62.98% 2684 / 4262
ironclaw_mcp 63.03% 578 / 917
ironclaw_triggers 65.44% 2142 / 3273
ironclaw_reborn_cli 66.18% 4488 / 6781
ironclaw_dispatcher 67.15% 92 / 137
ironclaw_filesystem 67.69% 3932 / 5809
ironclaw_memory 69.2% 773 / 1117
ironclaw_reborn_migration 71.57% 1551 / 2167
ironclaw_trust 72.88% 661 / 907
ironclaw_capabilities 74.39% 1685 / 2265
ironclaw_wasm_limiter 74.6% 47 / 63
ironclaw_reborn_event_store 74.67% 958 / 1283
ironclaw_extractors 74.72% 538 / 720
ironclaw_llm 78.53% 20372 / 25941
ironclaw_product_context 78.57% 11 / 14
ironclaw_first_party_extensions 78.81% 5576 / 7075
ironclaw_process_sandbox 80.65% 671 / 832
ironclaw_wasm_product_adapters 80.71% 1448 / 1794
ironclaw_memory_native 81.22% 3205 / 3946
ironclaw_secrets 82.79% 2794 / 3375
ironclaw_events 82.86% 1765 / 2130
ironclaw_reborn_identity 83.59% 433 / 518
ironclaw_wasm 83.97% 1011 / 1204
ironclaw_auth 83.99% 3147 / 3747
ironclaw_processes 84.44% 993 / 1176
ironclaw_reborn_config 84.85% 1831 / 2158
ironclaw_common 84.91% 1491 / 1756
ironclaw_turns 85.04% 13722 / 16136
ironclaw_host_api 85.13% 2663 / 3128
ironclaw_product_workflow 85.82% 10891 / 12691
ironclaw_projects 85.92% 659 / 767
ironclaw_network 86.12% 670 / 778
ironclaw_threads 86.7% 4594 / 5299
ironclaw_slack_v2_adapter 86.79% 1806 / 2081
ironclaw_product_adapters 87.18% 3265 / 3745
ironclaw_skills 87.58% 4470 / 5104
ironclaw_hooks 87.78% 9921 / 11302
ironclaw_product_adapter_registry 88.06% 531 / 603
ironclaw_reborn_traces 88.19% 11946 / 13546
ironclaw_host_runtime 88.53% 17437 / 19697
ironclaw_extensions 89.38% 2971 / 3324
ironclaw_approvals 89.41% 1587 / 1775
ironclaw_runner 89.5% 16989 / 18983
ironclaw_reborn_openai_compat 89.55% 3798 / 4241
ironclaw_reborn_composition 89.98% 81158 / 90197
ironclaw_conversations 90.39% 3123 / 3455
ironclaw_event_streams 90.82% 1009 / 1111
ironclaw_loop_host 92.24% 15043 / 16308
ironclaw_resources 92.69% 5134 / 5539
ironclaw_attachments 93.06% 630 / 677
ironclaw_reborn_webui_ingress 93.19% 2217 / 2379
ironclaw_telegram_v2_adapter 93.91% 2592 / 2760
ironclaw_agent_loop 94.8% 9200 / 9705
ironclaw_safety 95.04% 3677 / 3869
ironclaw_outbound 95.59% 3556 / 3720
ironclaw_first_party_extension_ports 95.62% 3672 / 3840

This table itself is informational and never gates the PR on its own — not the percentage, not the per-crate holes, not the 0-coverage callout. A separate coverage ratchet (dry-run until enforce=true; see tests/integration/coverage-floor.toml) can fail the build on specific configured floors.

Exemptions (3 entry/entries excluded from the accounting above)
Module / Crate Reason Issue
crate: ironclaw_embeddings v1-only: consumed only by root ironclaw (src/app.rs, src/tools/builtin/memory.rs, src/workspace/mod.rs, src/config/{mod,embeddings}.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_gateway v1-only: consumed only by root ironclaw (src/channels/web/platform/static_files.rs, src/channels/web/handlers/frontend.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_tui v1-only: consumed only by root ironclaw (src/main.rs, src/channels/tui.rs); no crates/* dependents. Crate's own doc comment confirms it bridges INTO v1, not Reborn. Covered by "Tests (Legacy)". #5657

@railway-app

railway-app Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

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

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 15, 2026 at 11:35 pm

Storage-mode audit plan (§5b): "Operator API has zero tier-2 coverage:
LLM-provider CRUD (including the api_key never echoed back redaction
invariant) ... no tests/integration/ file touches any of it." Adds a
dedicated new bin driving the real webui_v2 router + real
RebornLlmConfigService (not a stub) through upsert-with-key -> assert
no key value anywhere in the response + api_key_set flips true -> GET
re-fetch (redaction holds on read, not just write) -> delete -> assert
gone -> delete again -> assert 404 (the unknown-provider-id branch, not
covered by any existing crate-tier or contract-suite test).

Requires enabling `root-llm-provider` on the ironclaw_reborn_composition
dev-dependency (root Cargo.toml) so RebornRuntimeInput::with_boot_config
and the real LLM-config service exist in the int-tier build at all.
Dev-dependency only: the shipped ironclaw-reborn binary already carries
this feature via ironclaw_reborn_cli's own default, so this changes zero
production behavior — verified with a clean build and unchanged 21/21
webui_v2_product_api.rs pass before vs. after enabling it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 15, 2026 23:20
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6131 July 15, 2026 23:20 Destroyed

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added scope: dependencies Dependency updates size: S 10-49 changed lines risk: medium Business logic, config, or moderate-risk modules and removed size: XS < 10 changed lines (excluding docs) risk: low Changes to docs, tests, or low-risk modules labels Jul 15, 2026
@henrypark133 henrypark133 changed the title test(reborn): parametrize tier-2 durable-result continuation over InMemory/LibSql test(reborn): storage-mode audit + operator LLM-config tier-2 coverage Jul 15, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/integration/operator_llm_config.rs`:
- Around line 51-53: Keep the TempDir created in operator_router_with_llm_config
alive for the full HTTP scenario by returning it alongside the Router (or
otherwise transferring ownership) and updating every caller to retain it until
requests and provider writes complete. Apply the same lifetime fix to the
corresponding setup at the other referenced location, while preserving
production composition and the existing seam assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f660428b-ce1c-4c53-aa68-ca8c9003a4df

📥 Commits

Reviewing files that changed from the base of the PR and between 9403776 and 2bd4876.

📒 Files selected for processing (2)
  • Cargo.toml
  • tests/integration/operator_llm_config.rs

Comment on lines +51 to +53
async fn operator_router_with_llm_config() -> Router {
let root = tempdir().expect("runtime storage tempdir");
let storage_root = root.path().join("local-dev");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Keep the runtime TempDir alive through the HTTP scenario.

root drops when this helper returns, before provider writes begin. This leaves the router backed by deleted paths on Unix or failed cleanup on Windows.

Proposed fix
-async fn operator_router_with_llm_config() -> Router {
-    let root = tempdir().expect("runtime storage tempdir");
+async fn operator_router_with_llm_config(root: &tempfile::TempDir) -> Router {
     let storage_root = root.path().join("local-dev");
     let secret_key = "sk-test-should-never-appear-in-any-response";
-    let router = operator_router_with_llm_config().await;
+    let runtime_root = tempdir().expect("runtime storage tempdir");
+    let router = operator_router_with_llm_config(&runtime_root).await;

As per coding guidelines, production-wired behavior must use production composition and assert a meaningful seam.

Also applies to: 108-108

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/operator_llm_config.rs` around lines 51 - 53, Keep the
TempDir created in operator_router_with_llm_config alive for the full HTTP
scenario by returning it alongside the Router (or otherwise transferring
ownership) and updating every caller to retain it until requests and provider
writes complete. Apply the same lifetime fix to the corresponding setup at the
other referenced location, while preserving production composition and the
existing seam assertions.

Source: Coding guidelines

@henrypark133

Copy link
Copy Markdown
Collaborator Author

Closing as stale — no activity in over three weeks. The branch is untouched; reopen if this is still needed.

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-6131 — 2bd4876f Deployed Jul 15, 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 size: S 10-49 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants