Skip to content

test: make coverage fast: optimize crypto deps in test builds, run capacity tests at test-scale caps - #69

Merged
senamakel merged 10 commits into
tinyhumansai:mainfrom
senamakel:fast-coverage
Nov 12, 2026
Merged

senamakel merged 10 commits into
tinyhumansai:mainfrom
senamakel:fast-coverage

Conversation

@senamakel

@senamakel senamakel commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Why

The v0.21.0 release spent 30 minutes in "Require 90% line coverage in every source file" (run 43181492534, 08:21→08:52), against 3.5 minutes for the plain cargo test step. Timing every test with cargo nextest found two kinds of cost, both multiplied by coverage instrumentation on a 4-core runner:

  1. Argon2id in debug builds. PasswordKey::derive runs the production parameters (64 MiB, 3 passes). Unoptimized, each derivation takes seconds. About 25 password and cipher tests paid that cost, up to 7.5 s each.
  2. Brute-force fills to production caps. Some tests proved a cap by making that many real calls: 960 grants per scope-row-cap test (3 tests, about 28 s each), 65,535 admits in the store-client test (15 s), and 1,024/1,026 begin/consume/record cycles in the creation-memo tests (4 s).

What

  • Crypto dependencies optimized in the dev profile. test and cargo llvm-cov inherit it. This covers argon2, blake2, aes, aes-gcm, ghash, polyval, chacha20, chacha20poly1305, poly1305, sha2, hmac, hkdf, curve25519-dalek, x25519-dalek and zeroize. Only these third-party crates are optimized: workspace code keeps debug assertions and coverage counters, and what each test checks is unchanged.
  • Test-scale caps, with production values pinned. Each cap is now one named constant that is small under cfg(test) and unchanged otherwise. The refusal at the boundary is the same comparison either way.
    • engine::MAX_SCOPE_ROWS replaces the 3 duplicate 960 constants (tool, flow-trust and import-trust paths). It is 8 under test. The pin test is the_production_scope_row_cap_is_960, plus compile-time asserts that it stays below the 1024-row load contract.
    • engine::MAX_PENDING_CREATIONS replaces a bare 1024 in memo_begin. It is 16 under test, pinned by the_production_creation_memo_cap_is_1024.
    • approval_callbacks::MAX_RUNTIME_SCOPES is MAX_APPROVAL_SCOPES2 outside tests and 16 under test, pinned by the_bus_approval_scope_cap_is_65536.
    • The affected tests fill to the constant, not a literal.

Results (local, nextest, --all-features)

before after
Sum of all test durations 258.7 s ~100 s
Tests over 1 s (total) 186.0 s ~15 s
Slowest test 28.2 s 4.2 s
tinysecurity-approval suite 28 s 0.5 s
Slowest password test 7.5 s 1.2 s

The rest is spread across 1,350 sub-second tests, plus a few production-strength Argon2id derivations. The frozen host fixtures need those exact parameters, so they stay.

Verification

  • cargo fmt --check, cargo clippy --all-targets --all-features -D warnings, and cargo doc --no-deps --all-features with -D warnings are clean.
  • Full suite: 1379 passed.
  • cargo llvm-cov --workspace --all-targets --all-features passes. In a cold instrumented build, the test phase took 19 s on a 95-core box.
  • The native fixture script (run-native-master-cipher-coverage.sh) can't run on my box: its ancestor directories are group-writable, and the module loader refuses that. It's unchanged by this PR (examples don't build with cfg(test)); CI runs it. Without it, four files that the native fixtures exist to cover are under 90%. None of them is touched here.
  • Flake check: adapter::device::tests::unpublished_worker_plaintext_is_wiped_on_clock_read_failure_and_join_abort failed once in one full run. It relies on JoinHandle::abort landing at an await point. It then passed 20/20 alone, and 0 failures in 8 module-suite plus 6 full-workspace runs each on this branch and on upstream 740dafc. So it's a rare pre-existing race, not caused here.

Not changed, worth a follow-up

ApprovalStoreClient::admit scans a Vec with contains on every call, so filling it toward 65,536 subjects is quadratic in production too. A HashSet (or keeping the Vec for order and adding an index) would fix it.

Summary by CodeRabbit

  • Bug Fixes
    • Approval and flow-trust records now consistently enforce capacity limits. New entries are rejected when the available capacity is reached, while existing entries remain available.
    • New runtime approval scopes are limited to the configured capacity; duplicate scopes remain unaffected.
    • Pending creation requests are rejected once their limit is reached.

senamakel and others added 9 commits November 12, 2026 08:55
The 960-row scope cap was duplicated in the tool, flow-trust and import-trust grant modules. It now lives in one place, with a smaller value under test so filling a scope to its limit takes a handful of grants, and a test pins the production value.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Replace the hard-coded 960 row limit in the engine gap tests with a CAP
constant sourced from engine::MAX_SCOPE_ROWS, so the tests track the real
cap instead of silently drifting if it changes.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a test asserting that the production scope row limit stays at 960 and remains below the 1024 rows the scope load contract accepts, since unit tests only exercise the smaller test cap and would not catch a drift in the production value.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The upper bound on the production scope row cap and its relationship to the test cap are now checked by const assertions next to the constants instead of at runtime in a unit test, so a violation fails the build rather than a single test. The test keeps pinning the production value at 960.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Debug and test builds now compile the crypto crates at opt-level 3 so Argon2id key derivation no longer takes seconds per call under coverage instrumentation. Only third-party crypto crates are optimized, leaving the workspace's own debug assertions and coverage counters intact.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Raise the optimization level for the zeroize crate in dev builds so its
zeroing routines run at full speed during development, matching the
existing per-package overrides for other crypto dependencies.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Unit tests now fill the approval store client to its limit using a small
test-only cap instead of the production 65,536, so the bound check runs in a
handful of admits rather than tens of thousands. A new test pins the bus
constant's contract value, and a compile-time assertion keeps the test cap
from ever exceeding it.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The hard-coded 1024-entry cap on the creation retry memo is now a named constant that shrinks to 16 under cfg(test), mirroring the existing scope-row cap so tests can fill the memo without thousands of iterations. A compile-time assertion keeps the test cap at or below the production value, and a new test pins the production cap at 1024.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reformatted the approval engine and its gap tests to satisfy rustfmt, wrapping long conditionals and method chains and dropping stray blank lines. No behaviour changes.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@tinysweeper

tinysweeper Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Reviewed head: 5743dccf3832e7bb0c2c7b0305d63533865599a2

Verdict: Ready for maintainer review · Priority: none
Coverage: Reviewed 9 of 9 files.
Pull request purpose (title): test: make coverage…

Diagnostics and supporting details

Full summary

Pull request purpose (title): test: make coverage fast: optimize crypto deps in test builds, run capacity tests at test-scale caps. Tiny Sweeper completed its review; deterministic results follow.

Review snapshot

Change surface Files Review signal Count
Production 5 Active findings 0
Tests 3 Noted findings 0
Documentation 0 Resolved findings 0
Configuration 1 Pending checks/questions 0

Completeness: Complete
Test assessment: Test coverage is assessed from changed tests and lane evidence; execution is not claimed without trusted check data.

Features

  • Internal refactor — Shared scope row cap constant MAX_SCOPE_ROWS: Consolidates three duplicate 960 constants (tool, flow-trust, import-trust paths) into one shared constant that is 8 under test and 960 in production, with a compile-time assertion keeping it below the 1024-row load contract. (crates/tinysecurity-approval/src/engine.rs impl Engine {, crates/tinysecurity-approval/src/engine_flow_trust.rs impl Engine {, crates/tinysecurity-approval/src/engine_import_trust.rs impl Engine {, crates/tinysecurity-approval/src/engine_tool_trust.rs impl Engine {)
  • Internal refactor — Pending creation memo cap MAX_PENDING_CREATIONS: Replaces the bare 1024 in the creation memo refusal with a named constant that is 16 under test and 1024 in production, preserving the same comparison at the boundary. (crates/tinysecurity-approval/src/engine.rs impl Engine {, crates/tinysecurity-approval/src/engine.rs fn reusable_grant<'a>()
  • Internal refactor — Runtime scope cap MAX_RUNTIME_SCOPES: The store client's admit refusal uses a constant that is 16 under test and MAX_APPROVAL_SCOPES2 otherwise, with a compile-time assertion it stays within the bus cap. (crates/tinysecurity-module/src/approval_callbacks.rs impl ApprovalStoreClient {, crates/tinysecurity-module/src/approval_callbacks.rs use tinysecurity_bus::{)
  • Modified — Capacity tests fill to test-scale constants: Boundary tests now iterate to the named constants instead of literals, keeping the same refusal comparison under test while avoiding brute-force fills to production caps. (crates/tinysecurity-approval/src/engine_gaps_tests.rs async fn a_full_scope_takes_no_new_flow_trust_but_still_answers_for_a_live_one(), crates/tinysecurity-approval/src/engine_gaps_tests.rs async fn a_revoked_pair_cannot_cross_the_scope_row_cap_when_regranted() -> Resul, crates/tinysecurity-approval/src/engine_gaps_tests.rs async fn a_flow_identity_may_be_as_long_as_a_callers_but_a_tool_name_keeps_its_b, crates/tinysecurity-approval/src/engine_tests.rs async fn completed_executions_do_not_exhaust_the_creation_retry_window() -> Resu, crates/tinysecurity-approval/src/engine_tests.rs async fn indeterminate_creation_identities_survive_capacity_pressure_and_retry(), crates/tinysecurity-approval/src/engine_tests.rs async fn app_io_rows_cannot_supply_reusable_or_flow_authority() -> Result<()> {, crates/tinysecurity-module/src/approval_callbacks_tests.rs async fn store_client_admits_releases_and_bounds_runtime_subjects())
  • Added — Production cap value-pin tests: New tests assert the production cap values (960, 1024, 65,536) so silent drift of the non-test constants is caught. (crates/tinysecurity-approval/src/engine_tests.rs async fn completed_executions_do_not_exhaust_the_creation_retry_window() -> Resu, crates/tinysecurity-module/src/approval_callbacks_tests.rs async fn store_client_admits_releases_and_bounds_runtime_subjects())

Tests

  • unit — Fills a scope to the test-scale row cap, verifies the next new grant is refused, a re-issued existing grant is unchanged, and the scope still loads with the cap's worth of entries.: The tests lane reported the cap tests still exercise the refusal branch since they iterate the shared constant, and the value-pin tests guard against silent drift. (crates/tinysecurity-approval/src/engine_gaps_tests.rs async fn a_full_scope_takes_no_new_flow_trust_but_still_answers_for_a_live_one())
  • unit — Revokes a pair at the cap and confirms re-granting cannot cross the scope row cap.: The tests lane reported the behavioural comparison is identical under the test cap and the cap tests still exercise the refusal branch. (crates/tinysecurity-approval/src/engine_gaps_tests.rs async fn a_revoked_pair_cannot_cross_the_scope_row_cap_when_regranted() -> Resul)
  • unit — Exercises creation memo capacity and retry behavior at the test-scale cap.: The tests lane reported the cap tests still exercise the refusal branch and the pinned production value guards against drift. (crates/tinysecurity-approval/src/engine_tests.rs async fn completed_executions_do_not_exhaust_the_creation_retry_window() -> Resu, crates/tinysecurity-approval/src/engine_tests.rs async fn indeterminate_creation_identities_survive_capacity_pressure_and_retry())
  • unit — Fills the store client to the test-scale runtime scope cap and confirms the next new subject is refused while re-admitting a held one succeeds.: The tests lane reported the refusal is the same comparison either way and the description lane noted the test rewrites keep the same refusal comparison. (crates/tinysecurity-module/src/approval_callbacks_tests.rs async fn store_client_admits_releases_and_bounds_runtime_subjects())
  • unit — Pins production cap values: scope row cap 960 and creation memo cap 1024, with the bus approval scope cap pinned at 65,536.: The tests lane reported the value-pin tests fail if a production value regresses, guarding against silent drift. (crates/tinysecurity-approval/src/engine_tests.rs async fn indeterminate_creation_identities_survive_capacity_pressure_and_retry(), crates/tinysecurity-module/src/approval_callbacks_tests.rs async fn store_client_admits_releases_and_bounds_runtime_subjects())

Findings

No active actionable findings.

Before merge

None.

Agent review details

critique

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The critique lane reported reviewing 9 files with 0 findings.
  • Lane summary: Reviewed 9 files; 0 findings.

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The security lane reported reviewing 9 files with 0 findings.
  • Lane summary: Reviewed 9 files; 0 findings.

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The tests lane reported the behavioural comparison is identical either way, the cap tests iterate the shared constant so they still exercise the refusal branch, the new pins fail if a production value regresses, and it found no reportable defect.
  • Lane summary: The change replaces hard-coded 960/1024/65536 caps with shared constants that shrink under cfg!(test) so the cap tests run fast, and adds two pinning tests for the production values plus compile-time assertions tying the test caps to the production ones. The behavioural comparison is identical either way, the cap tests now iterate the shared constant so they still exercise the refusal branch, and the new pins fail if a production value regresses. No new error paths or uncovered branches appear, so no behavioural test is missing. The Cargo.toml profile change affects build speed only and cannot regress silently. I found no reportable defect.

commits

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The commits lane reported no sensitive content in committed files.
  • Lane summary: No sensitive content in committed files.

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The description lane reported the description matches the diff, naming the profile.dev.package crypto overrides, the three test-scale caps with production pins and the retuned tests, and noted the one trade-off (unit tests no longer exercise the 960/1024/65536 boundaries) is stated plainly in the body.
  • Lane summary: The description matches the diff: it names the profile.dev.package crypto overrides, the three test-scale caps with their production pins, and the retuned tests, and the diff does exactly that. The cap constants keep production values outside cfg(test), the refusal comparisons are unchanged, and the test loops fill to the constant rather than a literal. One point worth the author's attention is that unit tests no longer exercise the 960/1024/65536 boundaries, but that is a trade-off the body already states plainly, not a mismatch between the title/body and the code.
Evidence and run details
  • Models: ladder/vectors-oai3, deepseek-v4.1-flash
  • Spend: $0.007154
  • Tokens: 809843 input · 11386 output · 279808 cached · 559 embedding
  • Updated: 2026-11-12T09:16:23Z
Head State Pass summary
1d8f0b2ddffd ready for maintainer review 0 active finding(s), 0 resolved finding(s) (at 2026-11-12T09:13:29Z)
5743dccf3832 ready for maintainer review 0 active finding(s), 0 resolved finding(s) (at 2026-11-12T09:16:23Z)

tinysweeper 0.1.2

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T09:12:48.573634Z 1d8f0b2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Explain Change →

Warning

Review limit reached

  • Run on-demand review

This review includes 9 billable files and costs up to $2.25.

Or wait 54 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2beb6585-f9f1-4b7e-9530-706861cbd7a9
Commits

Reviewing files that changed from the base of the PR and between 1d8f0b2 and 5743dcc.

Files selected for processing: 9

  • Cargo.toml
  • crates/tinysecurity-approval/src/engine.rs
  • crates/tinysecurity-approval/src/engine_flow_trust.rs
  • crates/tinysecurity-approval/src/engine_gaps_tests.rs
  • crates/tinysecurity-approval/src/engine_import_trust.rs
  • crates/tinysecurity-approval/src/engine_tests.rs
  • crates/tinysecurity-approval/src/engine_tool_trust.rs
  • crates/tinysecurity-module/src/approval_callbacks.rs
  • crates/tinysecurity-module/src/approval_callbacks_tests.rs

No actionable comments were generated in the recent review.

Walkthrough

The development profile now optimizes selected cryptographic dependencies. The approval engine centralizes scope-row and creation-memo limits, and trust grant paths use the shared row limit. The runtime approval client applies a selected scope limit, with tests covering the configured capacities.

Changes: Cryptographic Development Profile

Layer / File(s) Summary
Development optimization settings
Cargo.toml
The development profile sets optimization level 3 for selected cryptographic and authentication dependencies. It does not add optimization settings for workspace code, debug assertions, or coverage instrumentation.

Approval Capacity Limits

Layer / File(s) Summary
Engine limits and creation memo checks
crates/tinysecurity-approval/src/engine.rs, crates/tinysecurity-approval/src/engine_tests.rs
The engine defines shared test and production limits for scope rows and pending creations. Creation memo checks and tests use the pending-creation limit. Tests assert the production limits are 960 rows and 1024 pending creations.
Scope-row checks for trust grants
crates/tinysecurity-approval/src/engine_flow_trust.rs, crates/tinysecurity-approval/src/engine_import_trust.rs, crates/tinysecurity-approval/src/engine_tool_trust.rs, crates/tinysecurity-approval/src/engine_gaps_tests.rs
Flow, import, and tool trust grant paths use the shared scope-row limit. Capacity tests check that additional grants fail with Error::Unavailable; revoking a grant does not free a row.
Runtime approval scope limit
crates/tinysecurity-module/src/approval_callbacks.rs, crates/tinysecurity-module/src/approval_callbacks_tests.rs
The runtime client uses a limit of 16 in test builds and the bus cap otherwise. Tests use the runtime limit and assert that the bus cap is 65,536.

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

Change: Other

Suggested reviewers: tinysweeper

Merge Risk: Minimal · previous review 1d8f0

This change speeds up test and coverage builds. It keeps the production approval capacity limits unchanged, and no merge-blocking risk was found.

Pre-merge checks: Passed 4

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names two parts of the change: optimizing crypto dependencies in test builds (Cargo.toml dev-profile opt-level for Argon2, AES, SHA-2, Curve25519 and related crates) and running capacity tes…
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.
Full details: Title check

Explanation

The title names two parts of the change: optimizing crypto dependencies in test builds (Cargo.toml dev-profile opt-level for Argon2, AES, SHA-2, Curve25519 and related crates) and running capacity tests at test-scale caps (cfg(test) limits of 8 and 16 in the approval engine and module, with tests now using MAX_SCOPE_ROWS, MAX_PENDING_CREATIONS and MAX_RUNTIME_SCOPES). Both match the raw summary and the PR objectives, which aim to cut coverage-test runtime. The title is specific and accurate, though it is a little long and uses a 'test:' prefix with two clauses.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit checks the limits in the code,
Then bounds each scope along its road.
The crypto builds with careful speed,
While tests confirm each cap they need.
Hop, hop—the changes pass review.

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a5b42f1f-626a-4f13-969b-19a1ad419042
Commits

Reviewing files that changed from the base of the PR and between 740dafc and 1d8f0b2.

Files selected for processing: 9

  • Cargo.toml
  • crates/tinysecurity-approval/src/engine.rs
  • crates/tinysecurity-approval/src/engine_flow_trust.rs
  • crates/tinysecurity-approval/src/engine_gaps_tests.rs
  • crates/tinysecurity-approval/src/engine_import_trust.rs
  • crates/tinysecurity-approval/src/engine_tests.rs
  • crates/tinysecurity-approval/src/engine_tool_trust.rs
  • crates/tinysecurity-module/src/approval_callbacks.rs
  • crates/tinysecurity-module/src/approval_callbacks_tests.rs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

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

tinysweeper found nothing blocking. Approving.

Diagnostics

Total spend: $0.0528

@senamakel
senamakel merged commit 9c8ba18 into tinyhumansai:main Nov 12, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant