You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
finima-api (crates/finima-api/) is a binary-only crate: Cargo.toml has no [lib] section, and src/main.rs declares its module tree directly (mod config; mod error_response; mod handlers; mod metrics; mod router; mod state; mod storage; mod ws;, main.rs:1-8). Nothing in this crate — AppState, the axum handlers, the router-building logic, the config loader — is importable from anywhere outside main.rs itself.
This has two independent, compounding costs, both confirmed concretely rather than assumed:
1. No integration test in the crate can exercise real production code
crates/finima-api/tests/common/mod.rs:8-10 already states the workaround plainly:
Because finima-api is a binary crate (no lib.rs), the integration tests reconstruct the router from the public library crates (finima-db, finima-auth, finima-core, etc.) rather than importing from finima-api.
All three existing integration test files (auth_test.rs, authorization_test.rs, tier2_flow_persistence_test.rs) follow this pattern: they hand-roll local reimplementations of the real axum handlers and a local TestAppState that mirrors — but is not — the real AppState.
This was proven to have real teeth during a recent adversarial review of #31/#32/#33's implementation (PR #100). Two production regressions were injected as a mutation-testing oracle:
AppState::set_metrics's entire body replaced with () (state.rs:544)
The whole "confirm" match arm deleted from the real handlers::flows::update_flow (flows.rs:298)
All existing tests in the crate — including the ones specifically written to cover this code — kept passing.cargo-mutants, scoped to exactly the changed files, reported 0/27 and 0/3 mutants caught respectively. Re-running the identical mutation-testing commands after a follow-up remediation pass (which genuinely fixed several other issues on the same review — see PR #100) showed zero improvement, because the fix couldn't touch the actual production handler code the tests can't reach; it could only make the test-local reimplementation more elaborate. The mutation score for AppState::set_metrics and update_flow's confirm branch is currently pinned at exactly 0 and will stay there regardless of how many more tests are added to this file, because no test in the crate can call either function.
2. Five separate [[bin]] targets already duplicate-include just to get config loading
Each of these bins declares #[path = "../config.rs"] mod config; to re-include src/config.rs as a second copy of the same module, because there's no crate to use finima_api::config from. bootstrap_tier2.rs and bootstrap_flows.rs additionally each hand-duplicate a build_embedder_for_bin function that's a near-verbatim copy of state.rs's build_embedder (bootstrap_tier2.rs:41-73, bootstrap_flows.rs:32-64, state.rs:~594-660) — three independent copies of the same backend-selection logic that have to be kept in sync by hand. (One already drifted: the two bootstrap copies used the panicking CandleEmbedder::new() after state.rs's copy was fixed to use the non-panicking CandleEmbedder::load() — caught and fixed separately, but exactly the kind of drift a shared lib.rs would make structurally impossible.)
What's requested
Extract finima-api into a proper lib.rs + thin main.rs binary, following the standard pattern for testable Rust web services:
Add crates/finima-api/src/lib.rs that declares the existing module tree (pub mod config; pub mod error_response; pub mod handlers; pub mod metrics; pub mod router; pub mod state; pub mod storage; pub mod ws; — or whatever subset needs to be pub vs. pub(crate)) and exposes whatever router/AppState-construction entry point(s) tests and other bins need (likely something like pub async fn build_app_state(config: AppConfig) -> Result<AppState, ...> and pub fn build_router(state: AppState) -> Router, mirroring what main.rs currently does inline).
Add a [lib] section to crates/finima-api/Cargo.toml (name = "finima_api" or similar).
Shrink main.rs to a thin entry point that calls into the new lib (config load → build_app_state → build_router → bind + serve), removing the mod declarations it currently owns directly.
Migrate the 6 [[bin]] targets (finima-api, merchant-audit, finima-normalize-directions, finima-redetect-recurring, bootstrap_flows, finima-generate-sample) plus the auto-discovered bootstrap_tier2 bin to use finima_api::config etc. instead of #[path = "../config.rs"], and to call the shared build_embedder/equivalent instead of maintaining their own copies.
Migrate tests/auth_test.rs, tests/authorization_test.rs, and tests/tier2_flow_persistence_test.rs to build their router/state via the real finima_api::build_router/finima_api::state::AppState instead of their local reimplementations, and delete the now-redundant hand-rolled handler/router code in tests/common/mod.rs. Re-run the same scoped cargo-mutants commands from PR feat(tier2): observability gauges, E2E persistence test, staging rollout enablement #100's review (cargo mutants --file crates/finima-api/src/state.rs --features sona -- --test tier2_flow_persistence_test and the equivalent for handlers/flows.rs's update_flow) to confirm the mutation score genuinely moves off 0 — that's the acceptance bar for this issue, not just "tests still pass."
Why this is its own issue, not bundled into anything else
The blast radius touches every existing integration test in the crate plus 6+ binary targets — it's a deliberate, scoped architectural change that deserves review on its own merits, not something to slip in as a side effect of an unrelated feature PR. It was explicitly scoped out of the #31/#32/#33 remediation (PR #100) for exactly this reason.
Acceptance criteria
crates/finima-api/src/lib.rs exists; main.rs is reduced to a thin entry point
The 5 bins currently using #[path = "../config.rs"] (plus bootstrap_tier2, which is auto-discovered) import finima_api::config normally instead
bootstrap_tier2.rs/bootstrap_flows.rs's duplicated build_embedder_for_bin functions are removed in favor of calling the shared finima_api implementation
auth_test.rs, authorization_test.rs, tier2_flow_persistence_test.rs call the real finima_api router/AppState construction instead of hand-rolled local reimplementations
cargo mutants --file crates/finima-api/src/state.rs --features sona -- --test tier2_flow_persistence_test and the equivalent scoped to handlers/flows.rs's update_flow show a mutation score above 0 (baseline: 0/27 and 0/3 as of PR feat(tier2): observability gauges, E2E persistence test, staging rollout enablement #100) — the actual proof this issue is closed, not just that the crate compiles and existing tests still pass
Full CI gate (cargo fmt, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace both default and --features sona) stays green throughout
References
PR feat(tier2): observability gauges, E2E persistence test, staging rollout enablement #100 (feat/tier2-observability-and-rollout) — the adversarial review (brutal-honesty-review + QE-Court: defense, 4 blind prosecutors, cross-vendor codex exec review, mutation-testing oracle, blind kill round, cross-vendor jury) that surfaced this gap, and its remediation commits (which fixed 5 of 6 MAJOR charges but explicitly could not fix this one without this extraction)
Background
finima-api(crates/finima-api/) is a binary-only crate:Cargo.tomlhas no[lib]section, andsrc/main.rsdeclares its module tree directly (mod config; mod error_response; mod handlers; mod metrics; mod router; mod state; mod storage; mod ws;,main.rs:1-8). Nothing in this crate —AppState, the axum handlers, the router-building logic, the config loader — is importable from anywhere outsidemain.rsitself.This has two independent, compounding costs, both confirmed concretely rather than assumed:
1. No integration test in the crate can exercise real production code
crates/finima-api/tests/common/mod.rs:8-10already states the workaround plainly:All three existing integration test files (
auth_test.rs,authorization_test.rs,tier2_flow_persistence_test.rs) follow this pattern: they hand-roll local reimplementations of the real axum handlers and a localTestAppStatethat mirrors — but is not — the realAppState.This was proven to have real teeth during a recent adversarial review of #31/#32/#33's implementation (PR #100). Two production regressions were injected as a mutation-testing oracle:
AppState::set_metrics's entire body replaced with()(state.rs:544)"confirm"match arm deleted from the realhandlers::flows::update_flow(flows.rs:298)All existing tests in the crate — including the ones specifically written to cover this code — kept passing.
cargo-mutants, scoped to exactly the changed files, reported 0/27 and 0/3 mutants caught respectively. Re-running the identical mutation-testing commands after a follow-up remediation pass (which genuinely fixed several other issues on the same review — see PR #100) showed zero improvement, because the fix couldn't touch the actual production handler code the tests can't reach; it could only make the test-local reimplementation more elaborate. The mutation score forAppState::set_metricsandupdate_flow's confirm branch is currently pinned at exactly 0 and will stay there regardless of how many more tests are added to this file, because no test in the crate can call either function.2. Five separate
[[bin]]targets already duplicate-include just to get config loadingEach of these bins declares
#[path = "../config.rs"] mod config;to re-includesrc/config.rsas a second copy of the same module, because there's no crate touse finima_api::configfrom.bootstrap_tier2.rsandbootstrap_flows.rsadditionally each hand-duplicate abuild_embedder_for_binfunction that's a near-verbatim copy ofstate.rs'sbuild_embedder(bootstrap_tier2.rs:41-73,bootstrap_flows.rs:32-64,state.rs:~594-660) — three independent copies of the same backend-selection logic that have to be kept in sync by hand. (One already drifted: the two bootstrap copies used the panickingCandleEmbedder::new()afterstate.rs's copy was fixed to use the non-panickingCandleEmbedder::load()— caught and fixed separately, but exactly the kind of drift a sharedlib.rswould make structurally impossible.)What's requested
Extract
finima-apiinto a properlib.rs+ thinmain.rsbinary, following the standard pattern for testable Rust web services:crates/finima-api/src/lib.rsthat declares the existing module tree (pub mod config; pub mod error_response; pub mod handlers; pub mod metrics; pub mod router; pub mod state; pub mod storage; pub mod ws;— or whatever subset needs to bepubvs.pub(crate)) and exposes whatever router/AppState-construction entry point(s) tests and other bins need (likely something likepub async fn build_app_state(config: AppConfig) -> Result<AppState, ...>andpub fn build_router(state: AppState) -> Router, mirroring whatmain.rscurrently does inline).[lib]section tocrates/finima-api/Cargo.toml(name = "finima_api"or similar).main.rsto a thin entry point that calls into the new lib (config load →build_app_state→build_router→ bind + serve), removing themoddeclarations it currently owns directly.[[bin]]targets (finima-api,merchant-audit,finima-normalize-directions,finima-redetect-recurring,bootstrap_flows,finima-generate-sample) plus the auto-discoveredbootstrap_tier2bin touse finima_api::configetc. instead of#[path = "../config.rs"], and to call the sharedbuild_embedder/equivalent instead of maintaining their own copies.tests/auth_test.rs,tests/authorization_test.rs, andtests/tier2_flow_persistence_test.rsto build their router/state via the realfinima_api::build_router/finima_api::state::AppStateinstead of their local reimplementations, and delete the now-redundant hand-rolled handler/router code intests/common/mod.rs. Re-run the same scopedcargo-mutantscommands from PR feat(tier2): observability gauges, E2E persistence test, staging rollout enablement #100's review (cargo mutants --file crates/finima-api/src/state.rs --features sona -- --test tier2_flow_persistence_testand the equivalent forhandlers/flows.rs'supdate_flow) to confirm the mutation score genuinely moves off 0 — that's the acceptance bar for this issue, not just "tests still pass."Why this is its own issue, not bundled into anything else
The blast radius touches every existing integration test in the crate plus 6+ binary targets — it's a deliberate, scoped architectural change that deserves review on its own merits, not something to slip in as a side effect of an unrelated feature PR. It was explicitly scoped out of the #31/#32/#33 remediation (PR #100) for exactly this reason.
Acceptance criteria
crates/finima-api/src/lib.rsexists;main.rsis reduced to a thin entry point#[path = "../config.rs"](plusbootstrap_tier2, which is auto-discovered) importfinima_api::confignormally insteadbootstrap_tier2.rs/bootstrap_flows.rs's duplicatedbuild_embedder_for_binfunctions are removed in favor of calling the sharedfinima_apiimplementationauth_test.rs,authorization_test.rs,tier2_flow_persistence_test.rscall the realfinima_apirouter/AppStateconstruction instead of hand-rolled local reimplementationscargo mutants --file crates/finima-api/src/state.rs --features sona -- --test tier2_flow_persistence_testand the equivalent scoped tohandlers/flows.rs'supdate_flowshow a mutation score above 0 (baseline: 0/27 and 0/3 as of PR feat(tier2): observability gauges, E2E persistence test, staging rollout enablement #100) — the actual proof this issue is closed, not just that the crate compiles and existing tests still passcargo fmt,cargo clippy --workspace --all-targets -- -D warnings,cargo test --workspaceboth default and--features sona) stays green throughoutReferences
feat/tier2-observability-and-rollout) — the adversarial review (brutal-honesty-review + QE-Court: defense, 4 blind prosecutors, cross-vendorcodex execreview, mutation-testing oracle, blind kill round, cross-vendor jury) that surfaced this gap, and its remediation commits (which fixed 5 of 6 MAJOR charges but explicitly could not fix this one without this extraction)crates/finima-api/tests/common/mod.rs:8-10— the existing, pre-PR-feat(tier2): observability gauges, E2E persistence test, staging rollout enablement #100 acknowledgment of this limitationcrates/finima-api/src/bin/bootstrap_tier2.rs:39-41— doc comment explaining why the embedder-construction logic is duplicated rather than shared