Repository navigation
Description
Problem
pkgs/id currency_poc: the recovery scanner decides "all legs posted" by counting per-leg lookup matches — matched == record.legs.len() — without ever checking that the legs are distinct or that there are any legs at all. A record with an empty leg list, or with the same transfer listed twice, is marked Posted / AlreadyPosted even though the ledger does not hold the conversion's legs.
Evidence (verified this run, main 11cb8966)
pkgs/id/src/currency_poc/recovery.rs:56-71— the scanner incrementspresent/matchedonce per entry inrecord.legsand treatsmatched == record.legs.len()as proof of posting. Forlegs == []that is0 == 0: unconditionally true. Forlegs == [t, t]a single posted transfertcounts twice.pkgs/id/src/currency_poc/intent.rs— neitherIntentStore::putnor theIntentRecordtype validates the leg list (non-empty, distinct IDs, IDs matchingtransfer_ids()/conversion), so a malformed record — hand-edited or foreign file-store JSON that still parses (cf. id(currency_poc): one corrupt or foreign .json file in the FileIntentStore directory aborts recovery for every pending conversion #4125), a buggy producer, a future store implementation — reaches the scanner as-is.- Laptop probe (verbatim currency_poc modules from main
11cb8966, md5-matched; probe~/git/fleet/probe-2026-11-01-laneA-dupids/on the laptop):- Record with
legs: [], stateRecorded,amount_in: 100:reconcile(Resubmit)→[(4242, AlreadyPosted)], stored state advanced toPosted, zero transfers in the ledger for the conversion. - Record with
legs: [t, t](the same transfer twice), stateSubmitted, withtposted exactly once:reconcile(Resubmit)→AlreadyPosted, statePosted, while only 1 distinct transfer exists.
- Record with
Why it matters
Posted is the scanner's terminal verdict: the record leaves the unresolved set and no one looks at it again. Declaring a conversion posted when its legs are absent or short is the failure the scanner exists to prevent — a conversion silently treated as settled when the money never (fully) moved. The executor's own records always have 2–3 distinct legs today, which is exactly why the guard belongs in the scanner/record validation rather than relying on every present and future producer being well-formed; the file store already admits, by design, whatever JSON parses into an IntentRecord.
Acceptance criteria
-
reconcilenever returnsAlreadyPostedfor a record with an empty leg list; such a record is reported (e.g.Inconsistent) and left unresolved, or rejected with an error — with a test pinning the chosen behaviour. - A record whose legs contain a duplicate transfer ID is not counted as fully posted on the strength of one distinct transfer; distinct-ID counting (or an equivalent leg-set validation) is used, with a test.
- Existing recovery tests pass, including
recovery_does_not_trust_transfer_id_existence_aloneand both crash-recovery scenarios.
Related: #2289 (parent PoC), #4125 (foreign/corrupt files in the same store directory — the plausible route by which a malformed-but-parseable record arrives).
Activity
dezren39 commentedon Nov 2, 2026
🤖 Agent note · filed
new-issue-creator-code-a)reconciledecides "all legs posted" by per-entry counting (matched == legs.len(), recovery.rs:56-71), so an intent record with an empty leg list (0 == 0) or the same transfer listed twice is markedPosted/AlreadyPostedwithout the conversion's legs being in the ledger. Verified this run on the laptop with verbatim currency_poc modules from main11cb8966(md5-matched): empty-legs record →AlreadyPosted, statePosted, 0 transfers; legs[t, t]withtposted once →AlreadyPosted, statePosted, 1 distinct transfer.~/git/fleet/probe-2026-11-01-laneA-dupids/(laptop); queue packet enqueued this run (repo-health-code-pilot).dezren39 commentedon Nov 2, 2026
🤖 Agent note · picked up
bc0afe2f5c642501a01823adb237ee6fc9298d32.12 remaining items
dezren39 commentedon Nov 2, 2026
agent-note:v1 — parked (window too short for 45-minute implementation)
dezren39 commentedon Nov 2, 2026
Pickup by repo queue worker lane H for task 6048 (small_fix for #4133). Fresh revalidation 2026-11-02T16:50Z: #4133 OPEN, no hard-stop labels (held / user/owned / do-not-merge / do-not-auto-edit all absent), no open PR or branch owns this fix. Implementing the recovery.rs leg validation (empty leg vector and duplicate leg IDs can no longer reach Posted/AlreadyPosted) plus the two regression tests in currency_poc/tests.rs, on branch queue/6048-4133-recovery-leg-validation.
dezren39 commentedon Nov 2, 2026
Implementation by repo queue worker lane H for task 6048: PR #4473 opened (branch
queue/6048-4133-recovery-leg-validation, commit 023ff40).recovery.rs: a record whose leg vector is empty or repeats a transfer ID is now reportedInconsistentand left unresolved, before any ledger lookup — it can no longer reachPosted/AlreadyPostedvacuously or off one distinct transfer.tests.rs: regression testsrecovery_rejects_empty_leg_vector(both policies) andrecovery_rejects_duplicate_leg_ids_backed_by_one_transfer.idlib cannot compile on main right now for the unrelated id(lib): references.rs does not compile — LocalIndex derives Default over a StoreId with no Default impl, and from_markdown breaks with a borrow of a loop-local String (PR #2756) #4454 breakage, so the verbatimcurrency_pocmodule from this branch was run as a probe crate on the laptop — 17 passed, 0 failed, 1 ignored, including all pre-existing recovery tests. Fullcargo test -p id --lib currency_pocre-run is owed once id(lib): references.rs does not compile — LocalIndex derives Default over a StoreId with no Default impl, and from_markdown breaks with a borrow of a loop-local String (PR #2756) #4454's fix (task 6359) lands; noted on the PR.Merge pull request #4473 from developing-today/queue/6048-4133-recove…
dezren39 commentedon Nov 2, 2026
Done by repo queue worker lane H (task 6048): PR #4473 merged (merge commit 4bfcf11) and #4133 is closed. Codex review on PR #4473 completed with no findings. Verification as recorded on the PR: verbatim
currency_pocmodule from the branch run as a laptop probe crate — 17 passed, 0 failed, 1 ignored, including the two new regression tests; the fullcargo test -p id --lib currency_pocre-run on main remains owed once the unrelated #4454 lib breakage is fixed (task 6359).