Skip to content

id(currency_poc): preflight passes requests build_legs cannot build — fee_amount>0 with no fee_account, and transfer_ids count never checked (extra IDs silently dropped) #4664

Closed

Description

@dezren39

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:

  1. Fee with no fee account. preflight only rejects fee_account == Some(user_source) (:148) and only checks the fee account's ledger if let Some(fee_account) (:196-198). With fee_amount > 0 and fee_account: None it returns Ok; prepare then fails in build_legs at :115 ("fee_amount > 0 requires a fee_account").
  2. Too few transfer IDs. The duplicate check (:160-166) never counts. With one ID supplied for a three-leg conversion (T1 + fee + T3), preflight returns Ok; build_legs fails at :97 ("transfer_ids must cover every leg (T1, fee, T3)").
  3. Extra transfer IDs are silently dropped. build_legs consumes only the IDs the legs need (:92-97). With fee_amount == 0 and four IDs supplied, preflight returns Ok, 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 → preflight Ok, execute posts, 3 legs.
  • PROBE2: fee_amount=25, fee_account=None → preflight Ok; prepare Err "fee_amount > 0 requires a fee_account".
  • PROBE3: transfer_ids=[601] (3 legs needed) → preflight Ok; build_legs Err "transfer_ids must cover every leg (T1, fee, T3)".
  • PROBE4: fee_amount=0, transfer_ids=[601,602,603,604] → preflight Ok; 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

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

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/creatorFiled by the new-issue-creator job
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    effort/sSmall: expected under 2 hours of work
    on Nov 3, 2026
  2. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: filed

  3. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  4. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  5. 3 remaining items

  6. added
    queue/queuedHas a queued task in the Supabase agent queue
    status/readyTriaged and ready for queued implementation work
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    queue/queuedHas a queued task in the Supabase agent queue
    status/readyTriaged and ready for queued implementation work
    on Nov 3, 2026
  7. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  8. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)effort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions