Conversation
Decouples the money-path suite from the acp job so a cancelled acp step no longer skips (and masks) money-path CI. Gated: diff workflow-only +24/-4; money-path cargo invocation byte-identical vs dev HEAD; new job well-formed, no needs:, workflow parses+dispatches (all 4 jobs live); Money-path tests row GREEN with 641 tests run / 639 passed (non-zero — real execution, not a vacuous ok); no required status check pins the old display name (dev rules=[], main ruleset no required_status). acp FAILURE on this PR = the out-of-scope #271 flake and is itself live proof of the decouple (money ran while acp died).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…279, #282) Tests-only (+143/-1, seller_node/run.rs mod tests). Leg 1: fresh award id for a Delivered job is recorded (Awarded::New) but never re-executed — the composition of record layer + state guard. Leg 2 (#279): a passing TRIPWIRE pinning the known mid-flight hole — a second award mid-flight is admitted for execution because neither dedup layer (event-id record / job-state guard) refuses and there is no per-job in-flight lock; kept as a tripwire (not #[ignore]) so it auto-reddens when the lock lands, at which point invert + close #279. Also corrects an existing test's message that overclaimed a duplicate-award check it never exercised. Gated: money-path row 641 passed / 2 ignored (639+2, count moved exactly), both new fn names present by log — genuinely ran, non-vacuous.
This was referenced Jul 30, 2026
…230, #287) Pre-existing test-only flake, not a #282 regression and not a production defect. The overspend race test re-awarded a hardcoded presumed winner (format!({:064x},0)); when scheduling left agent 0 among the two refused, that call was a fresh 30-sat reserve against 10 available and reserve() correctly refused it — read as an idempotency failure when the guard did the right thing. The aggregate asserts above the panic (winners.len()==3, reserved==90) were passing throughout. Fix: capture the actual race winners and re-award winners[0], making the idempotent-re-award leg deterministic. Test-only +17/-8, all in mod tests. Gated: money-path row green 641/0/2 by structural max-N+presence rule on the live head; seller-orch red-proved the panic byte-for-byte (requested:30/available:10/bound:Wallet) by pointing the re-award at a never-awarded id. Landed by seller-orch per buyer-orch(#230 owner)+lead ruling, buyer-orch reviews post-hoc.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Carries #276 to
main. This is a tag gate, not a convenience:v0.1.0cannot be cut untilmainitself has an unambiguous money-path row.
Payload — corrected after
devadvanced under this PRdevmoved while this was open (6b79e13→1d51078), so the cut now carries two files, +167/-5, notthe one it opened with:
.github/workflows/ci.yml— +24/-4. The money-path suite moves out of the acp job into its own job(own runner, no
needs:). This is ci: run the money-path suite in its own job (#271) #276, the reason for the cut.crates/mobee-core/src/seller_node/run.rs— +143/-1, and entirely test code. test(seller): pin the award-dedup contract on two distinct award events (#279) #282's award-dedupcontract tests. Verified rather than taken from the description:
#[cfg(test)]sits at line 2796 andmod tests {at 2797, and both hunks land at offsets 3705 and 3721 — inside that module. So itdoes not ship; the release artifact is byte-unaffected.
⇒ No shippable code changes in this cut, which is what the "no dry-run" argument below rests on. I
would have described this PR wrongly had I not re-measured after the head moved.
What it fixes, stated as the ambiguity it removes
The acp job dies intermittently. When it died, the money-path step was marked
skippedwhile the jobwent
failure— so a single red row could not distinguish "the money suite failed" from "the moneysuite never ran." Our doctrine makes full-suite-green an independent precondition for shipping money
code, and that shape cannot satisfy an independent precondition: a skipped row looks exactly like a
passing one from a distance.
Tagging on that shape would have shipped money code on a tree whose money suite had not demonstrably run.
Field-proven before it got here
On its own PR run (
30501469514),Build & test (acp)FAILED whileMoney-path testswent greenindependently — 639 passed, 0 failed. The exact scenario it exists for, exercised by the real flake on
the first attempt. That is a control, not an argument.
It also cannot inherit the flake: the money-path job builds with
--no-default-features --features gateway,git-delivery,wallet, so it never compilesacpand never spawns the ACP subprocesses whoseteardown is what the kill is locked to.
How this gets verified — and why no dry-run
No release dry-run is spent on this, deliberately. A dry-run exercises
release.ymland the threeplatform builds; #276 touches neither, so a dry-run has no access to the property being changed. A
green dry-run here would verify something adjacent to the change and reassure about nothing.
The instrument with access is
main's own CI: the independentmoney-pathjob green after thismerges.
🚨 Read that row by the named count, not the last line. The job's log ends with
running 0 tests/test result: ok. 0 passed— integration binaries that compile to nothing withoutacp. Anokwith azero numerator is not a pass, and it is more dangerous than red because it reads as success. Take the
mobee-coreunit-suite line:639 passed; 2 ignoredtoday,641once the seller lane's #282lands, so the jump does not read as an anomaly.
Merge with
--merge, not squashmain ⊆ devcurrently holds andmainis an ancestor ofdev, verified — so this cut cannot revertanything, and in particular cannot revert #277:
devalready carries that fix directly (SHIPPED_ASpresent, zero stale
mobeeliterals). Squashing would collapse the back-merge commit and breakmain ⊆ devby content as well as ancestry.Not a release
release.ymlhas no branch trigger (push: tags: ['v*']plusworkflow_dispatch), and both publishingjobs are gated
github.event_name == 'push' && github.ref_type == 'tag'. Re-proven on the run thatimmediately precedes this cut: dry-run #5 (
30502160459,2d7ce26b) passed 50 success / 6 skipped / 0failures with
npm publishandGitHub Releaseboth skipped.Still open, and deliberately not blocking
The acp flake itself (#271) is not fixed by this and stays with the seller lane. It is non-required and
by design cannot block a tag. Newly measured there: a passing run of
acp_concurrency.rscompletes in2.012s and the kill arrives at 2.032s — a 20ms margin, so the test has already finished its work
and the defect is in teardown, not in the test's logic or deadlines.