Repository navigation
refactor(insights): read reports, exports and audit provenance through an Insights facade - #1012
Conversation
|
Review of record: Codex PR #1012 reviewReviewed head No product defect found. One confirmed defect in the new architectural guard needs correction. FindingP2 · CONFIRMED · Concrete Infrastructure write calls escape the read-only guardLocation: The guard rejects write calls declared in Application or EF namespaces but accepts the same write through an existing concrete Infrastructure implementation. Failure scenario: A read method calls Evidence: Temporarily inserted that exact call at the start of the query in dotnet test tests/Cluckwork.Application.Tests --no-build --nologo \
--filter FullyQualifiedName~InsightsReadOnlyTestsAll 17 tests passed, including The namespace checks at lines 125–132 omit Product and architecture checks
Verification
The full integration suite and browser tests were not rerun for this review. NitsNone. Verdict: Request changes for the confirmed P2 guard gap; no product defect found. |
|
Addressed the confirmed Round 1 P2 in Infrastructure invocations are now rejected unless their implementation is in the source trees this guard scans. Local helpers remain permitted because their bodies are checked. No method-name denylist or production change was added. Mutation evidence:
Only |
|
Review of record: Codex PR #1012 round-two reviewReviewed only fix commit The original concrete FindingsP2 · CONFIRMED · The invocation-only walk misses method references and implicit callsLocation: The new Infrastructure check applies only to explicit invocation expressions, allowing persistence through a method group, delegate, constructor, getter, operator, or conversion. Failure scenario: Add these valid lines to Func<CancellationToken, Task<int>> save = db.SaveChangesAsync;
await save(ct);The method reference is never checked; the invocation resolves to Evidence: Delegate guard log, method-group guard log. A temporary integration probe staged an audit row, called the mutated The same missing-call problem applies to implicit execution. A temporary, compiled Infrastructure helper outside the scanned directory called _ = new InsightsWriteProbe(db, persist: true);
_ = new InsightsWriteProbe(db).Saved;
_ = (int)new InsightsWriteProbe(db);
_ = new InsightsWriteProbe(db) + 0;These were four separate mutations, not one combined execution. Logs: constructor, getter, conversion, operator. In contrast, explicitly invoking the same helper's Inspect symbol-bearing operations beyond invocations, including method references and implicit calls, before allowing execution outside the scanned implementations. Adding more invocation namespace cases does not address these bypasses. P2 · CONFIRMED · An external write helper in an unclassified namespace remains unrestrictedLocation: The external-implementation restriction applies only to the Failure scenario: A helper compiled into the Infrastructure project, but declared under public static int Save(AppDbContext db) => db.SaveChanges();Calling Evidence: The temporary helper compiled with zero warnings/errors. The real-tree guard passed, and the Postgres probe confirmed persistence. An equivalent explicitly invoked helper in Use an explicit policy for external calls, or inspect their implementations where available, rather than treating every unclassified namespace as read-only. This finding requires a newly introduced helper; finding 1 already works with the existing production types alone. Fix verification and controls
The rejected cases failed on the named operations, not invalid C#. The passing cases satisfied the guard's own semantic-compilation check. Dapper is not a current dependency; no Dapper bypass is claimed and no package was installed. The No new false positive was found on current read code or the local read-helper control. The scanned-tree exemption does catch direct writes in helper bodies; its remaining weakness is incomplete discovery of the operations those bodies can execute. Commands used: dotnet test tests/Cluckwork.Application.Tests --no-build --nologo \
--filter FullyQualifiedName~InsightsReadOnlyTests
dotnet test tests/Cluckwork.Application.Tests --no-build --nologo \
--filter FullyQualifiedName~ReadSession_UsesOnlyApprovedPersistenceOperations
sg docker -c 'dotnet test tests/Cluckwork.Api.IntegrationTests --nologo \
--filter FullyQualifiedName~InsightsReviewPersistenceProbe'The original-bypass result is in this log. All helper-based mutations, sources, and commands are in the reproduction script. Six separate Postgres mutation probes passed; the clean-source control failed at its persistence assertion as intended. Restored checkoutEvery mutation was reverted and every temporary source/test file removed. NitsNone. Verdict: Request changes for the two confirmed P2 guard gaps; the original UnitOfWork bypass is fixed, and no product defect was found. |
|
Addressed both Round 2 findings in 6ff3218, with one commit limited to
All temporary helpers and real-source mutations were reverted. The solution build has zero warnings/errors. All four test projects pass: Domain 495, Application 567, AppHost 10, Integration 1,873, with zero failures/skips. The original measured baseline was 2,922 tests; the final total is 2,945. CI is running on this head. The review loop was stopped deliberately by the owner after two consecutive rounds that found no product defect (rounds 1 and 2 found only guard gaps). No round 3 will be triggered. |
Change map: what this PR changes, before and afterPosted by the coordinator so this PR's structural change can be read at a glance. Reports, export files, audit history and routes are unchanged; only who calls whom changes. Ledger change (reads that were always there, now declared): New guard (tests only): After this PR and #1010 both merge:
|
|
Merged The three conflicts are resolved: The solution build has zero warnings or errors. All four test projects pass with no failures or skips: Domain 495, Application 593, AppHost 10, Integration 1,873 (total 2,971). The ImagePin guard also passes. |
What and why
Reports, exports, the audit viewer, and response provenance now read through
IInsightsModule.ReportQueries,ExportQueries, andAuditEventRepositorymove from Platform'sInfrastructure.Repositoriesinto the Insights-ownedInfrastructure.Insightsnamespace. Existing routes, authorization, results, streaming, and report concurrency behavior stay intact.One shared facade removes every direct audit repository injection. It aggregates the existing read ports, which remain internal composition dependencies so the concurrency decorator and provenance tests retain their behavior. A guard prevents endpoint use of those ports. Audit listing maps to a DTO after materialization; the append sink remains in Platform.
Six new
Rledger cells expose reads previously hidden by Platform's free hub. Insights reads Farm currency, Flock Management lifecycle and bird movements, Egg Operations production and grading, Commerce sales and payments, General Inventory exports, and Finance expenses. Explicit row types make the edges visible without changing SQL. The matrix is regenerated and both moved audit bypass entries are re-reviewed and re-keyed.Removing the audit mapper and response constructor changes the walk from 405 to 403 adapters on the original baseline. Non-empty rows remain 150 and Insights reaches remain 25, with no
Loosenablerows.ExpenseEndpointskeeps #1010'sIFinanceModuleandExpenseAuditEntityType; only its provenance dependency changes toIInsightsModule. The Finance contract and adapter-reach guards pass with the combined ledger.How it was verified
Verification on the original #856 baseline at
05d7e7a7and on this branch after mergingmainatb9f7f76b:dotnet build Cluckwork.slnpassed with zero warnings and errors. The baseline usedsg docker -c 'dotnet test Cluckwork.sln'; all four projects passed. The merged branch passed all four projects in one solution run with a local xUnitMaxParallelThreads=2runsettings file, zero failures or skips. No test timeout, assertion or repository configuration changed. The increase in Application tests includes #1010, now merged intomain. The ImagePin filter matched no Application tests and passed both Integration tests.Raw SQL literals are byte-identical; normalizing the namespace, explicit generic types, and DTO mapping reproduces all three original query files exactly. The export snapshot retains its separate non-retrying repeatable-read context. All five audit order clauses retain
Sequence. Existing backend behavioral assertions are unedited; three C# test files change imports only.The read-only guard rejects EF writes, SQL DML, unit-of-work and audit-write calls, direct endpoint use of query ports, and entity or
IQueryablecontract results. Real-source mutations failed onDbContext.SaveChangesAsyncand anIQueryable<AuditEventRead>leak, then were reverted. The existing seam guard also rejected the leak. Restoring one direct audit repository injection also failed the endpoint-port guard. The Round 1 concreteUnitOfWork.SaveChangesAsyncmutation now fails the real-tree assertion; the guard requires externalCluckwork.*targets to be approved reads, including calls made through method references, constructors, accessors, conversions and operators. Causal fixtures remain for the unit-of-work, delegate and constructor cases. Round 2 mutations all fail: both delegate forms, the external constructor/getter/conversion/operator, and the helper using a Domain namespace. Local read helpers remain green. The operation walk explicitly permits the existing read ports, contract DTO construction and getters, Domain-assembly data getters, and the snapshot/context read members. Dynamic calls and SQL method references without an inspectable literal fail closed. All mutations were reverted.The #1009 month-boundary fix from #1011 is now present through
main. This branch has no diff undertools/simulation/ui.CI on the merged head passed the build, all four backend test legs, web typecheck/tests/build, all three Playwright shards, CodeQL, dependency review and both language analyses. The arm64
imagecheck remains red under #1006: Trivy found two HIGH findings in the base image's OpenSSL packages (CVE-2026-84782) and no CRITICAL findings. The amd64 leg was canceled by the matrix and image publishing was skipped.Checklist
Closes #856