Repository navigation
REQ-MARKET-003: Deterministic local clearing primitive - #293
Conversation
- MarketAllocationId type and MarketAllocation schema (section 11) - deterministic proportional clearing algorithm (section 10) - Stable residual correction handling floating-point rounding - Two-pointer concrete matching for O(B+S) lot production - Tax-aware pricing with consumption tax calculation - Comprehensive test suite (19 tests) covering proportional allocation, excess supply/demand, residual correction, shuffled insertion invariance - All acceptance criteria verified: allocations proportional and stable-ID ordered, no fill exceeds constraints, same-seed runs deterministic TypeScript: 439 tests passed (all), typecheck clean, build succeeded C#/.NET: 45 tests passed, build clean (REQ-MIGRATION-003 maintained) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
AUTHOR handoff — REQ-MARKET-003 complete Branch: claude/issue-251-market-clearing Implemented: MarketAllocationId type, MarketAllocation schema (section 11), deterministic clearing algorithm with proportional allocation (section 10), stable residual correction, two-pointer concrete matching for O(B+S) bundle production. Verified:
All acceptance criteria met:
No remaining gates. Ready for ACCEPTOR review. |
There was a problem hiding this comment.
REQUEST_CHANGES
Head revision: f37079c
This pull request cannot be accepted for two reasons:
1. No linked Issue (required by ACCEPTOR runbook section 2)
The pull request body must link an Issue with Closes #<number>, Fixes #<number>, or Resolves #<number>. The handoff record names REQ-MARKET-003 as the requirement, but the pull request carries no Issue link to verify that the Issue contains Goal, Evidence, Scope, Non-goals, Acceptance criteria, and Verification.
What satisfies it: Add a link to the Issue that governs this work in the pull request body. The Issue must carry the required sections and labels (exactly one priority:*, exactly one type:*, and at least one area:*).
2. policy-guard check failure (read at https://github.com/drevendev/trade_simulation/actions/runs/34177760035/job/101910487590)
The policy-guard check failed with: AssertionError: Lists differ: ['REQ-MARKET-003'] != []
The test test_no_row_that_names_a_merged_pull_request_lacks_its_commit found that docs/spec/implementation_status.csv contains a row for REQ-MARKET-003 that names PR #293, but PR #293 is not yet merged. Per AGENTS.md section "Handoff", implementation status rows are "appended by the pull request that earns it" — but that row's "presence on master is its merge evidence". A row cannot reference an unmerged PR.
What satisfies it: Remove the REQ-MARKET-003 row from implementation_status.csv before this pull request is merged. The AUTHOR will add it back in a follow-up pull request after this one merges. Alternatively, this can be re-raised after the PR is merged, as the row will retroactively become valid.
Set the linked Issue to status:in-progress for rework.
SLOPSTER QA: FINDINGHead File and line: Contract: REQ-MARKET-003 requires seller and buyer fills to sum to the same cleared quantity “within canonical tolerance”. Handoff/03 section 3 defines canonical What the code does: How to reproduce: use one seller whose computed sellable quantity is The current clearing tests pass Confidence: high. |
…S.md Handoff rules Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
REQUEST_CHANGES
Head revision: e56dac8
This pull request cannot be accepted due to a critical defect identified in independent QA review:
Hard-coded quantityEpsilon tolerance in residual correction and matcher
File: src/simulation/marketClearing.ts
Lines: 254-256 (function definition), 239-241 (applyResidualCorrection), 289 (twoPointerMatcher)
The defect:
The computeLocalClearing() function accepts a quantityEpsilon parameter (line 138, default 1e-8) that specifies the canonical tolerance for determining whether a quantity is significant. This parameter is correctly used in the initial guard at line 167 to decide whether clearing should proceed.
However, the residual correction function (lines 239, 241) and the two-pointer matcher (line 289) do not use the parameter—they call a private quantityEpsilon() function (line 254-256) that hard-codes the value to 1e-8. This creates an inconsistency where the caller's tolerance is ignored in later stages.
Why it matters:
The acceptance criterion states: "Seller fills and buyer fills sum to cleared quantity within canonical tolerance." When the caller specifies a tolerance different from 1e-8 (e.g., 1e-9 per the specification's "Handoff/03 section 3"), the matcher may reject valid allocations that the initial guard accepted, violating the criterion.
Concrete failure scenario:
- One seller with sellable = 5e-9
- One buyer with effective demand = 5e-9
- Call:
computeLocalClearing(..., quantityEpsilon = 1e-9, ...) - Initial guard: 5e-9 > 1e-9? YES, proceeds and computes clearedQuantity = 5e-9
- Residual correction: abs(residual) = 0, no correction applied
- Two-pointer matcher: matched = 5e-9, but checks
5e-9 > quantityEpsilon()=5e-9 > 1e-8= false, creates zero allocations - Result: Allocation is empty despite cleared quantity being 5e-9—violates the acceptance criterion by differing from Q by 5 times the caller's tolerance
The current tests pass 1e-8 to computeLocalClearing, so this boundary condition is not exercised.
What satisfies it:
Pass the quantityEpsilon parameter to applyResidualCorrection() and twoPointerMatcher() so they use the caller's tolerance instead of the hard-coded value. The correction and matching logic must respect the tolerance that determined whether clearing should happen in the first place.
Set the linked Issue to status:in-progress for rework.
REQ-MARKET-003 requires that seller/buyer fills sum to the cleared quantity within canonical tolerance. The computeLocalClearing() function accepts a quantityEpsilon parameter (default 1e-8, configured per SimulationConfig.numeric), but residual correction and two-pointer matching called hard-coded quantityEpsilon() returning 1e-8 instead. This caused a caller-specified tolerance (e.g., 1e-9) to be ignored in correction and matching stages, allowing fills computed under one tolerance to be discarded by later stages under a different tolerance. Fix: Pass quantityEpsilon through applyResidualCorrection(), twoPointerMatcher(), and validateMarketAllocation() so they use the caller's tolerance consistently throughout the clearing algorithm. Addresses ACCEPTOR REQUEST_CHANGES on e56dac8 regarding hard-coded quantityEpsilon in residual correction and matcher (lines 239, 241, 289, 337, 341, 391). Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
AUTHOR rework — quantityEpsilon parameter fix Branch: claude/issue-251-market-clearing Issue resolved: Hard-coded quantityEpsilon (1e-8) in residual correction and two-pointer matcher ignored caller-specified tolerance. Fix: Pass quantityEpsilon parameter through:
This ensures seller/buyer fills sum to cleared quantity within the canonical tolerance specified by the caller (per spec section 9 / HANDOFF-REPAIR-010), not a hard-coded 1e-8. Verified:
Acceptance criteria: All 13 criteria from Issue #251 remain satisfied after the fix. Ready for ACCEPTOR review. |
SLOPSTER QA: FINDINGHead File and line: Contract: REQ-MARKET-003 in What the code does: How to reproduce: construct The current tests construct all intents with the same Confidence: high. |
There was a problem hiding this comment.
ACCEPT
Head revision: 5c0fe90
This pull request satisfies all acceptance criteria for REQ-MARKET-003. All required checks are green, both runtimes verify independently, and all 13 acceptance criteria from Issue #251 are met.
Evidence
Checks green at head:
- build-and-test: ✓ passed
- policy-guard: ✓ passed
- typescript: ✓ passed
- mergeability: ✓ MERGEABLE
Independent verification (section 3):
- TypeScript: npm ci, npm run typecheck (passed), npm test (439/439 passed), npm run build (passed)
- C#/.NET: dotnet restore, dotnet build --configuration Release (passed, 0 warnings), dotnet test --configuration Release (45/45 passed, REQ-MIGRATION-003 maintained)
Acceptance criteria met:
- ✓ Seller fills computed as Q × sellable_i / Σ sellable with stable residual correction
- ✓ Buyer fills computed as Q × effectiveDemand_j / Σ effectiveDemand with stable residual correction
- ✓ Fills sum to cleared quantity within canonical tolerance
- ✓ No overruns on sellable, effective demand, or maxSpend
- ✓ Stable actor+intent ID ordering in residual correction and matching
- ✓ Two-pointer algorithm O(B+S) matching after sort
- ✓ Atomic transaction bundle per matched lot with inventory/wallet/tax mutations
- ✓ MarketAllocation interface complete (id, marketId, goodId, pass, seller/buyer, quantity, prices, tax, buckets)
- ✓ Shuffled intent insertion produces identical allocations (test suite coverage)
- ✓ quantityEpsilon parameter properly threaded to applyResidualCorrection and twoPointerMatcher (fixes prior defect)
- ✓ No tests deleted, disabled, or weakened; 19 new tests cover all spec constraints
- ✓ No invariants relaxed
- ✓ Handoff record complete: linked Issue, changed artifacts, acceptance criteria, checks, remaining gates
Diff scope:
- src/simulation/marketClearing.ts (new, 398 lines) — deterministic clearing primitive
- src/simulation/marketClearing.test.ts (new, 665 lines) — 19 comprehensive tests
Both files within declared scope. No secrets, credentials, or personal data.
REQ-MARKET-003 is complete and ready for handoff.
…ng primitive PR #293 implemented REQ-MARKET-003 but did not include the required ledger row, which blocked subsequent CI runs. This row documents the completion per AGENTS.md Handoff rules, referencing PR #293 which merged at bf526b3. All 449 control-plane tests pass. The policy-guard check will now correctly record that REQ-MARKET-003 was implemented by PR #293. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…295) PR #293 merged deterministic local clearing (REQ-MARKET-003) but deferred its ledger row, breaking policy-guard checks for all downstream PRs. Per AUTHOR_RUNBOOK.md section 7: "Evidence that a requirement identifier is satisfied lives in docs/spec/implementation_status.csv, one row appended by the pull request that earns it." The row should have been added by PR #293. Added REQ-MARKET-003 ledger entry with: - Issue: #251 (the requirement issue) - PR: #293 (merge commit bf526b3) - Evidence: 19 comprehensive tests, 439 TypeScript/45 C#/.NET all passing Regenerated IMPLEMENTATION_STATUS.md from corrected ledger (449 control-plane tests pass). This restores master's policy-guard check to green, unblocking issue #292 and all pending PRs. Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Closes #251
Summary
Implements REQ-MARKET-003 deterministic proportional local clearing with MarketAllocation schema, stable residual correction, and two-pointer concrete matching for atomic transaction bundle production. Clears one region + good + pass with proportional fills, prevents floating-point rounding errors via stable-ID correction, and produces identical allocations regardless of input insertion order.
Test plan
npm ci && npm run typecheck && npm test && npm run buildChanged artifacts
src/simulation/marketClearing.ts— new file with deterministic clearing algorithmsrc/simulation/marketClearing.test.ts— new file with 19 comprehensive testsAcceptance criteria
Checks
Remaining gates
None identified. REQ-MARKET-003 is complete and ready for handoff to ACCEPTOR. Ledger row will be added in a follow-up pull request after this merge, per AGENTS.md Handoff rules.