Repository navigation
Description
Problem
ConversionExecutor::preflight (pkgs/id/src/currency_poc/executor.rs:141, origin/main 0400795a8) is the §4 gate whose contract is that a request it passes can be built and submitted — the #4124/#4132 fixes added its same-account and duplicate-transfer-ID checks for exactly that reason. Two build requirements are still checked only inside build_legs, and one is checked nowhere, so preflight returns Ok for requests that can never execute, and silently discards caller-supplied transfer IDs:
- Fee with no fee account.
preflightonly rejectsfee_account == Some(user_source)(:148) and only checks the fee account's ledgerif let Some(fee_account)(:196-198). Withfee_amount > 0andfee_account: Noneit returnsOk;preparethen fails inbuild_legsat:115("fee_amount > 0 requires a fee_account"). - Too few transfer IDs. The duplicate check (
:160-166) never counts. With one ID supplied for a three-leg conversion (T1 + fee + T3),preflightreturnsOk;build_legsfails at:97("transfer_ids must cover every leg (T1, fee, T3)"). - Extra transfer IDs are silently dropped.
build_legsconsumes only the IDs the legs need (:92-97). Withfee_amount == 0and four IDs supplied,preflightreturnsOk, two legs are built, and the fourth pre-generated ID appears in no leg and in no persisted intent record — a caller that pre-generated and recorded that ID (the write-ahead discipline the module docs describe) is never told it went unused.
Evidence (verified this run)
Laptop probe probe-2026-11-02-laneB-preflight (verbatim currency_poc modules from origin/main 0400795a8, executor.rs md5 500df828; setup mirrors currency_poc/tests.rs funded ledger), cargo test: 4/4 pass, including the defect assertions —
- CONTROL: valid request →
preflightOk,executeposts, 3 legs. - PROBE2:
fee_amount=25, fee_account=None→preflightOk;prepareErr "fee_amount > 0 requires a fee_account". - PROBE3:
transfer_ids=[601](3 legs needed) →preflightOk;build_legsErr "transfer_ids must cover every leg (T1, fee, T3)". - PROBE4:
fee_amount=0, transfer_ids=[601,602,603,604]→preflightOk; 2 legs built; supplied ID 604 used by no leg.
Why it matters
preflight is a public, separately callable gate (the scenario tests call it as the §4 rejection surface). A gate that passes unbuildable requests pushes the failure into prepare, after the caller has been told the conversion is sound — the same false-pass shape #4124 and #4132 were filed and fixed for. The silently dropped extra ID is the worst case: nothing fails at all, so a pre-generated transfer ID can be reused or audited against a conversion that never carried it.
Acceptance criteria
preflightrejectsfee_amount > 0withfee_account: None, with a message naming the missing fee account.preflightrejects atransfer_idscount different from the leg count the request implies (2 without a fee, 3 with one): too few and too many.prepare/executebehaviour for valid requests is unchanged (existing scenario tests pass), and no request thatpreflightpasses can fail inbuild_legsfor these three reasons.- Regression tests in
pkgs/id/src/currency_poc/tests.rscover all three cases at thepreflightsurface (the id(currency_poc): conversion preflight never checks same-account legs — user==LP, fee==user, LP-dest==user-dest pass prepare, fail in submit, and strand a Submitted intent #4124/id(currency_poc): preflight never checks duplicate transfer_ids — a reused ID passes prepare, fails in submit, and strands a Submitted intent #4132 test pattern: fails preflight, no intent persisted).
Dedup: #4124 (same-account legs in preflight) and #4132 (duplicate transfer IDs in preflight) are closed/fixed and cover different checks; #4133 covers malformed leg vectors in persisted records (recovery side); #4578 covers FileIntentStore listing vs get. No open or closed issue covers the fee-account-presence or transfer-ID-count checks.
Activity
dezren39 commentedon Nov 3, 2026
🤖 Agent note · state: filed
dezren39 commentedon Nov 3, 2026
🤖 Agent note · picked up
3 remaining items
dezren39 commentedon Nov 3, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 3, 2026
🤖 Agent note · done
cargo test currency_pocin pkgs/id — exit 0, lib binary 33 passed / 1 ignored, all four new tests pass by name; Codex review completed with no findings; the unrelatedbasic: OpenCode metered-provider guardcheck was still queued at merge time (change verified directly on the laptop per merge authority)