Previous production-readiness score: 6.6 / 10. CI is green; two fresh runtime probes fail.
Scope and verdict
TrustWeave SDK and reference-wallet assets at e0a4464fc6cafa339b94121fd56f33812c6601e4. SaaS is excluded. The code commit is 36fe0a2c; the later commit records evidence. Four pre-existing untracked files were preserved and excluded.
Fix lost revocations before relying on the database status provider under concurrent production writes. Custody and unsupported protocol features need an explicit experimental release boundary. This is not an assertion that unrelated modules are unsafe.
Scoring
Same six equally weighted categories as the prior production-readiness review. Mean 7.3333, rounded to 7.3. This measures readiness, not completion of an earlier findings list. Scores are judgement, not certification.
Category
/ 10
Reason
Security and access control
7.5
Federation and L3 fixes credited; lost revocations remain security-relevant.
Observability and diagnosability
6.5
Better guidance and safe route errors; raw Indy errors and deployment evidence remain.
Reliability and scale
6.5
Bounded stores and improved scans; reproduced concurrency and expansion defects remain.
Configuration and data
7.0
SPI/policy fixes hold; bitmap invariants and digest integration need repair.
Deployment and release
8.5
Green hosted gates and verified provenance; published-release qualification remains.
Testing and documentation
8.0
Broad executed baseline and clearer limits; modest branch coverage and new failing probes.
Validation evidence
Fresh tests: two targeted Kotlin/JUnit tests compiled and ran against the current implementation. Both failed correct-behavior assertions: concurrent revocations ended a=true, b=false; expansion expected 24 but returned 72. The JDBC wrapper only synchronizes reads, without modifying their data. See JUnit results, source and reproduction instructions. The temporary test was removed from the normal test tree. No production source was changed.
Fresh hosted checks: latest CI and documentation checks succeeded on the reviewed commit.
Retained baseline, not rerun here: 3,796 SDK unit/JVM tests (3,781 passed, 15 skipped), one live Indy integration test, 105 ABI checks, 24 executable examples, 80 web unit tests and 13 browser tests. Android app had two tests; shared JVM test task had no source. See validation evidence. The targeted run replaced that module's local XML; do not mix baseline and probe totals.
Coverage XML re-read: 27,024 / 47,930 lines (56.4%); 10,405 / 27,005 branches (38.5%). Prior successful provenance verification is credited. No new live custody, physical-device, penetration, load, vulnerability or release-publication test was performed.
Prior improvements credited
Current code and recorded evidence support the SPI registration fixes, corrected federation verification with pinned anchor keys, relative FileWallet paths, L3 audience/nonce checks, fail-closed constraints and green hosted gates. The uncommitted-code blocker is closed. These should not be reopened merely because new defects exist.
What prevents a perfect score
TW-FU-01 · High · Runtime confirmed
Concurrent revocations can erase each other
Status JSON is read on another connection before the allocation lock. Two writers read the same bitmap, then overwrite each other despite serialized allocation. Batch paths at lines 432 and 608 share the stale-snapshot pattern. The fresh H2 probe completed both calls but observed a=true, b=false. A previously revoked credential can become active.
Fix: Lock the list row before reading, using the same transaction for read, allocation and bitmap write across every mutation path.
Done when: Deterministic two-manager tests retain every committed revocation. Cover batch/single overlap, suspension, rollback and PostgreSQL.
TW-FU-02 · Medium · Runtime confirmed
Expansion uses BitSet capacity instead of declared size
A declared 16-entry list expanded by 8 becomes 72 because BitSet rounds storage to machine words. The fresh test expected 24 and got 72. Bitmap and metadata writes also use separate transactions; invalid growth and overflow are not explicitly rejected.
Fix: Use locked metadata size, validate positive growth and safe arithmetic, and update bitmap and metadata atomically.
Done when: Test non-word-aligned sizes, negative growth, overflow and injected failure between updates.
TW-FU-03 · Medium · Source confirmed
Batch updates bypass declared index bounds
BitSet.set accepts indices beyond the declared list size. This grows the bitmap without updating metadata; a very large index can allocate substantial memory. Remote exploitability depends on whether an application exposes these inputs. Purpose-incompatible updates are silently ignored.
Fix: Validate all indices and operation/purpose compatibility before any write; reject an invalid batch atomically.
Done when: Reject -1, size and Int.MAX_VALUE without mutation; mixed valid/invalid batches leave all bits unchanged.
TW-FU-04 · Medium · Source confirmed
Credential service cannot verify digest-mode anchors
Digest-mode clients intentionally return an envelope on read (AbstractBlockchainAnchorClient lines 75-83 and 314). CredentialAnchorService compares that envelope to the full credential, so a successful digest-mode write cannot round-trip through this verifier.
Fix: Verify envelopes using the anchor digest contract while retaining reference/evidence binding; retain full-payload equality for full mode.
Done when: Positive and tampering tests pass for both modes, includeProof choices, wrong references and altered envelope digests.
TW-FU-05 · Medium · Source confirmed
Shared anchor handlers convert cancellation into transaction failure
Write catches Exception and read does likewise at line 346. Provider-thrown CancellationException can become TransactionFailed; test mode can consult fallback storage. Parent-job cancellation may still propagate from withContext, so this is not a claim that all cancellation is suppressed.
Fix: Rethrow CancellationException before generic handlers on both shared paths.
Done when: A fake provider throwing cancellation preserves that exception type for read/write, including test mode; timeouts are not misclassified for retry.
TW-FU-06 · Medium · Source confirmed
Indy transport deadline and response limits are incomplete
timeoutMillis is unused. The owned client has a timeout, but injected clients need not. bodyAsText at line 89 consumes the entire response; errors embed raw provider bodies at lines 94 and 104. Endpoint configuration is trusted, which limits the threat boundary.
Public kid/typ arguments containing quotes or backslashes can produce malformed JSON or inject header members. Normal generated did:key inputs avoid the trigger. This is a helper correctness defect, not a demonstrated signature forgery.
Fix: Serialize the protected header with buildJsonObject.
Done when: Round-trip quotes, backslashes and Unicode; exactly one alg member remains EdDSA. Add shared-module tests.
TW-FU-08 · High · Qualification gap
Production custody is not yet an end-to-end qualified wallet
Documentation explicitly says managed authorization/persistence and passkey enrollment/recovery remain integration work; neither profile is wired into the reference UI. Virtual authenticators and local fixtures do not establish HSM, hosted IAM or physical-device recovery assurance. SUPPORTED_ONLY admits no wallet. This is a scope limitation, not evidence that adapters are insecure.
Fix: Keep the release explicitly experimental for these features, or complete service, UI, recovery and provider qualification before claiming production custody.
Done when: Use authorized managed-custody test resources for integration, key loss/rotation/recovery, tenant/key authorization and durable one-use authorization. Retain physical/provider evidence and promote only qualified capabilities.
TW-FU-09 · Medium · Capability gap
Autonomous checkout and stateful intent enforcement remain unavailable
Fail-closed line-item handling blocks autonomous checkout. Budget/recurrence require external state. Audience/nonce comparison is not an atomic consumed-challenge store. The previous fail-open bypass is closed; these are remaining capability limits.
Fix: Implement supported line-item matching and durable enforcement integration, or constrain advertised use cases.
Done when: Positive checkout vectors pass, mismatched items fail, and concurrent replay/cumulative-spend tests reject duplicate or over-budget operations.
TW-FU-10 · Medium · Assurance gap
Risk-based coverage and provider conformance need strengthening
Merged coverage is 56.4% lines and 38.5% branches. First-contract tests broaden module reach but did not cover concurrent revocation. Android shared compiled with no test source. This CI job generates reports without enforcing a repository-wide regression budget. Coverage alone is not security proof.
Fix: Add concurrent, negative, fault-injection and interoperability tests for high-risk paths; enforce reviewed module/regression gates and qualify supported providers.
Done when: Permanent regressions cover every defect, shared Android has meaningful tests, and real-provider conformance evidence exists for support claims.
TW-FU-11 · Medium · Assurance gap
Operational and final-release assurance remains incomplete
Guidance and safe status-list events exist; they do not establish an instrumented host, SLO/load or restore exercises. A verified manual-workflow artifact is not a newly published consumer release. CycloneDX is an inventory, not a vulnerability triage result.
Fix: Demonstrate a host telemetry integration, load/failure/recovery exercises, dependency triage and signed versioned publication for the intended release.
Done when: Verify safe coroutine correlation/metrics, bounded behavior under load, restore exercises and provenance of downloaded published artifacts.
Recommended sequence
Fix status-list transactions, size and index invariants, with PostgreSQL concurrency/rollback regressions.
Repair digest interoperability, cancellation, transport bounds and shared JWS serialization.
Define the supported release boundary and qualify custody/intent integrations before promotion.
Strengthen risk-based tests, operational exercises and published-release evidence; rerun full hosted gates on the fixes.
A perfect score requires no known material defects within a clearly stated support scope and strong evidence for that scope. It cannot promise bug-free software. Do not weaken fail-closed checks or relabel experimental providers to raise the score.