Summary
writePurchaseAuditRecord (introduced in #1609) logs a warning and continues
when common.WriteAuditRecord fails mid-run, on both the main pipeline
(executePurchasePipeline) and the --input-csv path (processPurchaseLoop).
CheckAuditLogWritable only proves the log was writable at the start of the
run; a failure partway through (disk full, permissions changed, the file
deleted out from under the process) leaves that recommendation's purchase
attempted with no durable record, and the run continues purchasing more
recommendations regardless.
Location
cmd/multi_service.go, writePurchaseAuditRecord (shared helper) and its
two callers: executePurchasePipeline and processPurchaseLoop.
Failure scenario
A --purchase run (either entry point) purchases recommendation 1 for real,
then the disk fills up or the audit-log file becomes unwritable before
recommendation 2 is processed. WriteAuditRecord for recommendation 1's
result fails; writePurchaseAuditRecord logs Warning: failed to write audit record: ... and the loop proceeds to purchase recommendation 2, 3, etc. Every
purchase after the first failure moves real money with no audit trail at all,
and the operator has no way to reconcile which recommendations were bought
without one.
Suggested fix
When common.WriteAuditRecord fails on a real purchase (not a dry run), stop
processing further recommendations in that loop rather than logging a warning
and continuing, on both executePurchasePipeline and processPurchaseLoop.
The already-attempted purchase's PurchaseResult should still be returned to
the caller so it is reflected in the CSV report, but no further purchase
should be attempted once the audit trail can no longer be trusted to capture
it. A dry run may continue (nothing is bought, so the audit log matters less
for reconciliation), matching the fail-closed-on-purchase-only pattern
already used for the duplicate check (#1941) and --target-coverage sizing
(#1942).
Found while implementing #1609 and reviewing the failure-visibility of
writePurchaseAuditRecord's two call sites.
Summary
writePurchaseAuditRecord(introduced in #1609) logs a warning and continueswhen
common.WriteAuditRecordfails mid-run, on both the main pipeline(
executePurchasePipeline) and the--input-csvpath (processPurchaseLoop).CheckAuditLogWritableonly proves the log was writable at the start of therun; a failure partway through (disk full, permissions changed, the file
deleted out from under the process) leaves that recommendation's purchase
attempted with no durable record, and the run continues purchasing more
recommendations regardless.
Location
cmd/multi_service.go,writePurchaseAuditRecord(shared helper) and itstwo callers:
executePurchasePipelineandprocessPurchaseLoop.Failure scenario
A
--purchaserun (either entry point) purchases recommendation 1 for real,then the disk fills up or the audit-log file becomes unwritable before
recommendation 2 is processed.
WriteAuditRecordfor recommendation 1'sresult fails;
writePurchaseAuditRecordlogsWarning: failed to write audit record: ...and the loop proceeds to purchase recommendation 2, 3, etc. Everypurchase after the first failure moves real money with no audit trail at all,
and the operator has no way to reconcile which recommendations were bought
without one.
Suggested fix
When
common.WriteAuditRecordfails on a real purchase (not a dry run), stopprocessing further recommendations in that loop rather than logging a warning
and continuing, on both
executePurchasePipelineandprocessPurchaseLoop.The already-attempted purchase's
PurchaseResultshould still be returned tothe caller so it is reflected in the CSV report, but no further purchase
should be attempted once the audit trail can no longer be trusted to capture
it. A dry run may continue (nothing is bought, so the audit log matters less
for reconciliation), matching the fail-closed-on-purchase-only pattern
already used for the duplicate check (#1941) and
--target-coveragesizing(#1942).
Found while implementing #1609 and reviewing the failure-visibility of
writePurchaseAuditRecord's two call sites.