Skip to content

Cut dev→main: the money-path suite gets its own CI job (#276) — tag gate - #283

Merged
orveth merged 4 commits into
mainfrom
dev
Jul 30, 2026
Merged

Cut dev→main: the money-path suite gets its own CI job (#276) — tag gate#283
orveth merged 4 commits into
mainfrom
dev

Conversation

@orveth

@orveth orveth commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Carries #276 to main. This is a tag gate, not a convenience: v0.1.0 cannot be cut until main
itself has an unambiguous money-path row.

Payload — corrected after dev advanced under this PR

dev moved while this was open (6b79e131d51078), so the cut now carries two files, +167/-5, not
the one it opened with:

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 skipped while the job
went failure — so a single red row could not distinguish "the money suite failed" from "the money
suite 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 while Money-path tests went green
independently — 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 compiles acp and never spawns the ACP subprocesses whose
teardown 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.yml and the three
platform 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 independent money-path job green after this
merges.

🚨 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 without acp. An ok with a
zero numerator is not a pass, and it is more dangerous than red because it reads as success.
Take the
mobee-core unit-suite line: 639 passed; 2 ignored today, 641 once the seller lane's #282
lands, so the jump does not read as an anomaly.

Merge with --merge, not squash

main ⊆ dev currently holds and main is an ancestor of dev, verified — so this cut cannot revert
anything
, and in particular cannot revert #277: dev already carries that fix directly (SHIPPED_AS
present, zero stale mobee literals). Squashing would collapse the back-merge commit and break
main ⊆ dev by content as well as ancestry.

Not a release

release.yml has no branch trigger (push: tags: ['v*'] plus workflow_dispatch), and both publishing
jobs are gated github.event_name == 'push' && github.ref_type == 'tag'. Re-proven on the run that
immediately precedes this cut: dry-run #5 (30502160459, 2d7ce26b) passed 50 success / 6 skipped / 0
failures
with npm publish and GitHub Release both 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.rs completes in
2.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.

orveth and others added 2 commits July 29, 2026 17:13
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).
@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mobee Ready Ready Preview Jul 30, 2026 1:23am

Request Review

…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.
…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.
@orveth
orveth merged commit 9701ef1 into main Jul 30, 2026
5 of 6 checks passed
@orveth orveth added this to the v1 milestone Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant