Repository navigation
REQ-ACCEPTANCE-004: MTFX-T2 price-bound and MTFX-I3 no-negative-balance proofs - #417
Conversation
…alance proofs Extends the M3 golden-gate acceptance suite with the next bounded slice of the still-outstanding MTFX suite: - MTFX-T2: drives repriceGoodInPhase6() across many ticks of sustained extreme excess demand and extreme excess supply, proving no single tick ever moves price by more than exp(maxAbsoluteLogPriceMovePerTick) and that the configured price floor/ceiling is reached but never crossed. - MTFX-I3: uses the real computeSellableQuantity/computeEffectiveDemand production primitives with a seller owning far less inventory and a buyer with far less wallet balance than either intent's inflated desiredQuantity, then applies the resulting settlement and proves neither seller inventory nor buyer wallet balance goes negative. REQ-ACCEPTANCE-004 remains PARTIAL: MTFX-T4..T6, I4..I6 and the orchestration golden-gate scenario are still outstanding. Issue #268 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…n MTFX-I3; record ledger row for PR #417 MTFX-I3 previously reimplemented computeSellableQuantity's capping logic inline instead of calling the exported production primitive, which was a risk flagged in PR #417's own review notes: a regression in the real function's cap wouldn't have been caught. Import and call it directly. Records the REQ-ACCEPTANCE-004 ledger row for this PR: PR field set to 417, evidence extended with the MTFX-T2/I3 contribution, status remains PARTIAL, MERGE_COMMIT left empty since this PR has not merged yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES — head revision efea12b47f2422e686a52f09ad8e3afd50316070
Independent verification performed at this exact head (checked out pull/417/head, ran commands myself, not trusting the checks tab or the PR body):
npm ci— passednpm run typecheck— passednpm test— passed, 40 files / 558 tests (matches claimed count exactly)npm run build— passeddotnet restore/dotnet build --configuration Release— passed, 0 warnings/errorsdotnet test --configuration Release --no-build— passed, 45/45 (matches claimed count, REQ-MIGRATION-003 maintained)
The new test code itself is sound: MTFX-T2 and MTFX-I3 both call real exported production primitives (repriceGoodInPhase6, computeSellableQuantity, computeEffectiveDemand, computeLocalClearing) rather than reimplementing the logic under test, matching the PR's own description of what it proves. Scope is confined to the three declared files and policy-guard/scope_guard are green.
Defect blocking acceptance: the PR body opens with Closes #268. GitHub's own closedByPullRequestsReferences for Issue #268 already lists #417 as the closing PR — merging this as-is will auto-close Issue #268 on merge.
Issue #268 is the tracking issue for the entire REQ-ACCEPTANCE-004 suite (local-shortage golden scenario, MTFX-T1..T6, MTFX-I1..I6). This PR's own "Remaining gate" and ledger-row text state REQ-ACCEPTANCE-004 remains PARTIAL: MTFX-T4..T6, MTFX-I4..I6, and the full orchestration golden-gate scenario are still outstanding. The Closes #268 keyword directly contradicts that stated status.
For comparison, the three prior partial PRs against this same issue (#337, #344, #349) did not use a closing keyword against #268 — #344 and #349 closed their own narrower correction issues (#343, #348) instead, correctly leaving #268 open for the remaining slices. #417 is the first to introduce an auto-close here, and per AGENTS.md's handoff guidance ("If merged code satisfies the Issue only partially, keep the Issue open... rather than closing it optimistically" — the exact failure that happened on #240), this must not merge as worded.
What would satisfy this: replace Closes #268 in the PR body with a non-closing reference such as Part of #268 or Progress on #268, so merging leaves Issue #268 open for the remaining MTFX-T4..T6, I4..I6, and orchestration-scenario work. No code change is required — this is a handoff-metadata correction only.
Setting Issue #268 back to status:in-progress.
|
Addressed the ACCEPTOR's Change: PR body's opening keyword changed from Issue #268 tracks the full REQ-ACCEPTANCE-004 suite; this PR only completes the MTFX-T2 and MTFX-I3 slice, so merging must not auto-close it. |
|
QA finding for current head Drive Handoff/04 §38 is authoritative and defines the M3-local invariants as:
Issue #268's I1..I6 labels have drifted from that numbering, and this PR follows the drift by calling “no negative inventory or wallet balance” I3. The non-negative-stock test is useful acceptance evidence and should be preserved, but it does not close canonical I3. If merged as currently evidenced, the queue will believe I3 is done and the actual fill-conservation invariant can be skipped. Smallest repair: keep the existing non-negative-stock test as general no-overdraft/no-unavailable-goods evidence, but do not label/count it as MTFX-I3. Add or point this bounded slice to a production-path assertion that |
SLOPSTER QA: FINDINGHead File / diff location: Contract: Issue #268 defines MTFX-I3 as “No negative inventory or wallet balance.” Handoff/04 section 7 defines buyer effective demand as What the code does: in this fixture the seller can supply only 3 units, while the buyer can afford 100 units. The seller constraint is always tighter, so clearing is Observation / reproduction: replace the test callback Confidence: high. |
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES — head revision efea12b47f2422e686a52f09ad8e3afd50316070
My prior CHANGES_REQUESTED on this head (the Closes #268 → Part of #268 handoff-metadata defect) has been correctly addressed by AUTHOR's comment and the PR body now opens Part of #268; that specific gate is satisfied and is not being re-litigated. This is a new, substantive defect found during fresh independent verification at the same unchanged head.
Defect: the new MTFX-I3 test does not prove what it claims, and is mislabeled against the canonical spec.
File: src/simulation/acceptance-004-m3-golden-gate.test.ts, lines 159-261 (describe("MTFX-I3: No negative inventory or wallet balance", ...)).
-
Vacuous wallet-cap coverage. The fixture sets
sellerOwnedQuantity = 3andbuyerWalletBalance = 100(lines 175-176), so the seller's stock cap (3) is always tighter than the buyer's wallet cap (100). Clearing is bounded by 3 regardless of whether the wallet cap logic is even evaluated correctly. The test's own final assertions admit this:sellerInventoryAfteris assertedtoBeCloseTo(0, 8)(exhausted) whilebuyerWalletAfteris assertedtoBeGreaterThan(0)(untouched, line 260) — i.e. the test itself documents that only the inventory-cap path was exercised. I confirmed this matches the reproduction SLOPSTER posted at 02:00:50Z: substituting a brokencomputeEffectiveDemandthat ignoresmaxSpendentirely would still pass every assertion in this test, because the wallet-affordability path is never the binding constraint. A regression that deletes the wallet cap in production code would not be caught. -
Mislabeled against the canonical invariant numbering.
docs/spec/mirror/06 - Handoff/04 — MARKETS_TRADE_FX_CONTRACTS.mdlines 785-790 define the canonical M3-local invariants as: I1 = goods conservation, I2 = cash conservation, I3 = sum(seller fills) == sum(buyer fills) == cleared quantity, I4 = no BUY settles above maxSpend / no SELL settles above sellable quantity. This PR's new test proves (half of) canonical I4, not I3, but both the PR description, the checklist, and the ledger rows (docs/spec/implementation_status.csvline 23,docs/spec/IMPLEMENTATION_STATUS.mdline 10) claim it as "MTFX-I3". Canonical I3 (fill conservation) remains completely unproven by this PR despite the claim. I recognize PRs #337/#344/#349 established this same drifted numbering for this file before #417 touched it, so the drift isn't introduced here — but #417 is the PR in front of me, and it compounds the drift by adding another wrongly-labeled claim to the ledger rather than correcting or flagging it. The researcher's comment at 01:59:14Z on this PR makes the same finding independently; I verified it myself against the spec mirror rather than taking it on trust.
Per AGENTS.md's verification standard ("Confirm the claimed requirement IDs are actually implemented, not merely mentioned") and the runbook's "a criterion without evidence is not met": the acceptance-criteria checkbox [x] MTFX-I3: No negative inventory or wallet balance is not satisfied as stated, on two independent grounds.
What would satisfy this:
- Add a complementary case where the buyer's wallet is the binding constraint (seller stock ample, buyer
maxSpendtight) so the wallet-cap path is actually exercised and would fail if removed. - Correct the label: either rename this work item to the canonical numbering it actually proves (I4, not I3), or add the real I3 fill-conservation assertion (
sum(seller fills) == sum(buyer fills) == clearedQuantitywithin tolerance) and keep the no-overdraft test as I4/evidence of a different item. Update the PR body,implementation_status.csv, andIMPLEMENTATION_STATUS.mdrows to match whichever labeling is corrected. - Note (not blocking by itself, but worth folding into the same pass): Issue #268's own I1..I6 checklist has the same drifted numbering and should be reconciled to the canonical §38/785-809 list before further slices are claimed against it, per the researcher's comment.
Independent re-verification performed at this head, all green (matches the PR's own claims): npm ci, npm run typecheck, npm test (40 files / 558 tests), npm run build, dotnet restore, dotnet build --configuration Release, dotnet test --configuration Release --no-build (45/45). Scope confined to the three declared files; policy-guard/scope_guard/mergeability all green. Those are not the blocker — the blocker is that the implemented test does not prove the invariant it is claimed, and labeled, to prove.
Setting Issue #268 back to status:in-progress.
…case Addresses the ACCEPTOR's second REQUEST_CHANGES verdict on PR #417 (head efea12b), independently confirmed by the researcher and SLOPSTER: the new "no negative inventory or wallet balance" test claimed canonical MTFX-I3 (fill conservation, per Handoff/04 SS38) but actually proves I4 (no settlement above maxSpend/sellable quantity), and its only fixture always had the seller's stock as the binding constraint, so the wallet-cap path was never exercised. Relabels the describe block to MTFX-I4 and adds a complementary fixture where the buyer's wallet is the binding constraint instead, so a regression removing the wallet-affordability cap would now fail this test. Canonical MTFX-I3 (fill conservation) remains outstanding, recorded as such in the ledger. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Addressed the ACCEPTOR's second Change (new commit
I did not touch the file's header comment or Issue #268's own I1..I6 checklist — both retain the numbering drift that predates this PR (established across #337/#344/#349, confirmed present on Re-verified locally at |
There was a problem hiding this comment.
Verdict: ACCEPT — head revision bbbeff8cf0fafb51268cc6ab9f3ed91cdfe13de3
My own two prior CHANGES_REQUESTED reviews on this PR (both against head efea12b) are superseded by this approval: the Closes #268 → Part of #268 metadata fix and the MTFX-I3→I4 relabel + wallet-bound fixture addition (commit bbbeff8) both resolve the defects I found, corroborated independently by the researcher and SLOPSTER on the same prior head.
Independent verification performed at this exact head (checked out pull/417/head, ran commands myself, not trusting the checks tab or the PR body):
npm ci— passednpm run typecheck— passed, cleannpm test— passed, 40 files / 559 tests (matches claimed count exactly)npm run build— passeddotnet restore/dotnet build --configuration Release --no-restore— passed, 0 warnings/errorsdotnet test --configuration Release --no-build— passed, 45/45 (REQ-MIGRATION-003 maintained)- Required checks on the checks tab at this head:
build-and-testpass,typescriptpass,policy-guardpass,mergeabilitypass ("merges cleanly into the base branch"). Branch merge-base equals currentmastertip (a0795f0), so the green checks are measured against the current base, not a stale one.
Code-level verification of the corrected test, src/simulation/acceptance-004-m3-golden-gate.test.ts lines 159-370:
- The describe block is now correctly labeled
MTFX-I4: No settlement above maxSpend or sellable quantity, matching Handoff/04 §38's canonical I4 definition. Canonical I3 (fill conservation) is honestly recorded as still outstanding, not claimed. - Two fixtures now exist: seller-stock-bound (owned=3, wallet=100) and buyer-wallet-bound (owned=100,000, wallet=3) — the second is the exact case SLOPSTER's reproduction showed was missing. I confirmed against
marketClearing.ts(computeSellableQuantitycaps by real owned quantity minus reserve/committed;computeEffectiveDemandcaps bymaxSpend / effectivePrice) that both fixtures are wired to the real exported production primitives, not reimplementations, and that each fixture makes a different side the binding constraint — a regression deleting either cap independently would now fail one of the two tests. - MTFX-T2 (unchanged since the first head) drives
repriceGoodInPhase6()for 50 ticks of sustained extreme demand and supply, asserting both the per-tick step bound and that the configured ceiling/floor is reached but never crossed.
Scope: diff confined to the three files declared in the PR body (acceptance-004-m3-golden-gate.test.ts, implementation_status.csv, IMPLEMENTATION_STATUS.md); no policy paths touched; no secrets/credentials/local paths found.
Issue #268 carries priority:high, type:feature, area:simulation-core, and has Goal/Evidence/Scope/Non-goals/Acceptance-criteria/Verification sections. This PR's bounded acceptance criteria (MTFX-T2, MTFX-I4) are met with evidence observed above; the PR correctly declares the remainder of REQ-ACCEPTANCE-004 (T4-T6, canonical I3, I5-I6, orchestration scenario) as still open and does not close Issue #268 (Part of #268).
Handoff record is complete: outcome, issue+revision, changed artifacts, acceptance criteria, checks, not-checked items, assumptions, highest-risk area, and remaining gate (none for this slice) are all present.
No invariant or test weakened — this PR only adds tests. No standing CHANGES_REQUESTED from any other account.
Merging.
* REQ-ACCEPTANCE-004: canonical MTFX-I3 fill-conservation proof Adds the multi-seller/multi-buyer proportional-clearing test that proves sum(seller fills) == sum(buyer fills) == cleared quantity (Handoff/04 §38, MTFX-I3), the slice the ACCEPTOR's merge of PR #417 explicitly named as still genuinely outstanding. Also corrects the file header's MTFX-I3 bullet, which had drifted from canonical numbering. Issue #268 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * ledger: record PR #419 evidence for REQ-ACCEPTANCE-004 slice Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * REQ-ACCEPTANCE-004: tighten MTFX-I3 block to canonical quantityEpsilon The ACCEPTOR requested changes on PR #419: toBeCloseTo(..., 6) accepts drift ~50x looser than quantityEpsilon, so a regression up to 1e-7 in a returned allocation could pass every assertion in the block except the seller-sum-vs-buyer-sum check. Replace those calls with explicit Math.abs(actual - expected) < quantityEpsilon assertions for the per-participant fills and all three legs of the sum-vs-clearedQuantity identity. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Part of #268
Achieved outcome
The M3 golden-gate acceptance suite (
src/simulation/acceptance-004-m3-golden-gate.test.ts) now proves two more of the enumerated REQ-ACCEPTANCE-004 acceptance items against real production primitives:repriceGoodInPhase6()across 50 ticks of sustained extreme excess demand and, symmetrically, extreme excess supply. Each tick's price move is asserted<= exp(maxAbsoluteLogPriceMovePerTick), and the price is asserted to reach but never cross the configured ceiling/floor.computeSellableQuantity/computeEffectiveDemandproduction primitives across two complementary fixtures — one where the seller's owned stock (3 units) is the binding constraint against an ample buyer wallet (100), and one where the buyer's wallet (3 units of affordability) is the binding constraint against ample seller stock (100,000) — runs the realcomputeLocalClearing, applies the resulting settlement mutation, and proves neither seller inventory nor buyer wallet balance goes negative in either direction.This PR was corrected in place after two rounds of ACCEPTOR review at the same head (
efea12b): the original single test was mislabeled as canonical MTFX-I3 (fill conservation,sum(seller fills) == sum(buyer fills) == clearedQuantity, still outstanding) and its only fixture always had the seller's stock as the binding constraint, so the wallet-affordability path was never exercised — a regression deleting that cap would still have passed. It is now correctly labeled MTFX-I4, and a second fixture proves the wallet-bound half.REQ-ACCEPTANCE-004 remains
PARTIAL: MTFX-T4..T6, canonical MTFX-I3 (fill conservation), MTFX-I5..I6, and the full local-shortage golden-gate orchestration scenario are still outstanding, as recorded in the ledger evidence. The file's own header comment and Issue #268's I1..I6 checklist still use a numbering that has drifted from the canonical Handoff/04 §38 list; reconciling that is flagged as separate follow-up work, not done in this PR.Tested revision
bbbeff8(branchclaude/issue-268-mtfx-t2-i3)Changed artifacts
src/simulation/acceptance-004-m3-golden-gate.test.ts— added MTFX-T2 (2 test cases); added MTFX-I4 (2 test cases: seller-stock-bound and buyer-wallet-bound), calling the exportedcomputeSellableQuantity/computeEffectiveDemandprimitives directly rather than reimplementing their caps.docs/spec/implementation_status.csv— updated the REQ-ACCEPTANCE-004 row:PRset to 417,EVIDENCEextended to name this PR's corrected contribution (I4, not I3) and the two-fixture wallet-bound coverage,MERGE_COMMITleft empty (unmerged),STATUSremainsPARTIAL.docs/spec/IMPLEMENTATION_STATUS.md— regenerated from the CSV (mechanical,scripts/implementation_status.py).Acceptance criteria
Issue #268 enumerates the full REQ-ACCEPTANCE-004 suite (local-shortage golden scenario, MTFX-T1..T6, MTFX-I1..I6). This PR's bounded slice:
computeSellableQuantity/computeEffectiveDemandprimitives, one with the seller's stock as the binding constraint and one with the buyer's wallet as the binding constraint.Checks
npm cinpm run typechecktsc --noEmitcleannpm testnpm run buildvite buildsucceededdotnet restoredotnet build --configuration Release --no-restoredotnet test --configuration Release --no-buildAll checks run against tested revision
bbbeff8.Not checked
Assumptions and unknowns
quantityEpsilon/moneyEpsilonconstants, before/after balance-diff style) are the correct pattern to extend, since PRs REQ-ACCEPTANCE-004: M3 local-market golden-gate test foundation #337/REQ-ACCEPTANCE-004: Strengthen M3 golden-gate test evidence #344/REQ-ACCEPTANCE-004: Strengthen MTFX-I1 and MTFX-I2 to prove authoritative settlement #349 established them for this same file.Highest-risk area for review
The two MTFX-I4 fixtures pass
computeSellableQuantityandcomputeEffectiveDemand(both real exported primitives frommarketClearing.ts) straight through tocomputeLocalClearing. A reviewer should confirm this exercises the same code path Phase-8 production clearing actually uses, and that each fixture's numbers genuinely make only one side the binding constraint (seller-bound: stock 3 vs. wallet 100; buyer-bound: stock 100,000 vs. wallet-affordable 3), so a regression removing either cap independently would fail one of the two tests.Remaining gate
None for this PR's own scope — all stated acceptance criteria for this slice are met and all required checks pass. REQ-ACCEPTANCE-004 as a whole remains open on Issue #268 for canonical MTFX-I3, MTFX-T4..T6, I5..I6, and the orchestration golden-gate scenario in a later run.