fix(machine): credit bills on stacked-confirmation, not stack command (#58) #77
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/escrow-credit-interlock"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem (root cause of #58)
Bill credit fired at stack-command time:
hal:stack-billissued the serial stack and immediately synthesizedhal:bill-inserted→BILL_INSERTED→fiatCentscredited. The validator's actual stacked-confirmation (billsValid, emitted by both the id003 and ebds drivers) was never subscribed anywhere. Both loss directions were live:BILL_INSERTEDarriving after the machine leftinsertingBills(done pressed during the escrow round-trip) was silently dropped by XState while the bill continued into the cashbox — stacked, never credited, no record.Verified against the legacy public-domain lamassu-machine tree (
c0b69d1, see the CLAUDE.md provenance correction on dev):brain.jscredits only in thebillsValidhandler (updateBillsScreen→Tx.billUpdate), holds abillsReadinterim state that makes "send coins" a no-op while a bill is in flight, and rejects bills read outside accepting states.Fix — the legacy interlock, ported
electron/hal-service.ts+ renderer fallbacksrc/services/hal.ts): escrow → in-flight tracking;onBillInserted(the credit callback) fires only onbillsValid.billsRejectedclears both markers — a failed stack was never credited.hal:stack-bill(main.ts) no longer synthesizes the credit.BILL_PENDINGevent +billPendingcontext field.FINISH_INSERTINGis guarded bycanFinishInserting(no bill in flight).BILL_INSERTEDrequires a matching pending bill;BILL_REJECTEDandconfirmAbandonentry clear it. Balance/rate gating moved to theBILL_PENDING(pre-stack) decision — once a bill physically stacked, credit is unconditional.insertingBillsor with unknown rate/balance is returned to the customer, closing the #35 gap at the point that physically takes money.Tests
confirmAbandon.Behavior notes for review
billsValidnever arrives (validator dies mid-stack),billPendingblocks "done" until the 3-min inactivity timeout routes toconfirmAbandon— self-recovering, and strictly better than crediting a phantom bill. A dedicated stack-timeout is possible follow-up work alongside the ERROR-event handling gap.pnpm testat the root fails on@bitSpire/hal("No test files found") — same hygiene family as #53.🤖 Generated with Claude Code