Repository navigation
Issue #427: settle Phase-8's realized MAIN allocations onto authoritative actor stock - #477
Conversation
Wires the remaining half of Issue #427 acceptance criterion 2. Phase-8 already produced realized MAIN-pass `MarketAllocation`s and PR #475 added the live actor stock plus `executeAllocation(world, ctx, allocation)`; nothing joined them, so no production path could move authoritative stock. Two things blocked that join, and both are fixed here. First, the allocations Phase-8 produced were not settleable. The handler assumed a `cur:reserve` market currency no actor holds and assessed consumption tax with `destinationStateId: null`, which `executeAllocation` refuses outright because tax debited from a buyer and credited to nobody destroys money inside a transfer. Both are now read from the canonical `RegionState`: the region's settlement currency, and its controller as the treasury the tax lands in. An uncontrolled region assesses zero consumption tax (HANDOFF-REPAIR-006), and the one rate feeds both the affordability calculation and the recorded gross price. Second, the M3 Phase-8 fixtures traded `CLAN` against `CLAN` on a `GENERAL` bucket. R235 calls that implementation drift: a Clan owns a treasury and no physical goods, so the allocation names a stock endpoint that does not exist. They now trade a `PRODUCTION_UNIT` seller debiting `OUTPUT` against a `COHORT` buyer crediting its single household inventory. `applyMarketSettlementTransition(world, context)` is the settlement boundary itself, folding `executeAllocation` over the MAIN-pass allocations in the section-36 stable order clearing already emitted them in. It sits beside `applyMarketStateTransition` rather than inside `createPhase8Handler` because a `PhaseHandler` returns a `TickContext` and `executeTick()` holds one `WorldState` immutable across all sixteen phases (REQ-CORE-004), so a phase handler has no way to hand a mutated world back. Section 35 asks for exactly this split: planning returns deltas, mutation belongs in an explicit settlement function. Three regressions cover it, against a real `buildInitialWorld()` world rather than a test-local map: money and goods conservation across every actor that holds either (criteria 2-3); identical post-settlement wallets, inventories, treasuries, markets and ledger with telemetry on and off (criterion 4, the gap Issue #416 could not close before the boundary existed); and a negative control perturbing one settled wallet to prove that comparison can fail while the allocations still compare equal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The canonical-stock-neutrality clause is proved at a real settlement boundary for the first time. R235 named the condition -- "REQ-MARKET-005 remains PARTIAL until the real Phase-8 settlement and telemetry-neutrality evidence merges" -- and this pull request is that evidence. MERGE_COMMIT is cleared because the row now names a pull request that has not merged; backfill_merge_commits.py fills it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Verdict: ACCEPT — head
|
| Check | Conclusion at da2a46e |
|---|---|
build-and-test |
success |
typescript |
success |
policy-guard |
success |
write-mergeability-status |
success |
mergeability (commit status) |
success — "merges cleanly into the base branch (clean)" |
Nothing pending, skipped, neutral or unknown. mergeable: MERGEABLE,
mergeStateStatus: CLEAN.
On the one red run at this SHA. commits/da2a46e/check-runs lists four policy-guard
runs; the earliest (23:23:45Z, run 34908651599) is a failure and the three after it
(23:25:20Z, 23:25:56Z, 23:27:32Z) are successes. I ordered them by completed_at
rather than take the body's word: the failure is the earlier one, the latest run is green,
and the body's account of why — scope-guard refusing the placeholder body the pull request
was opened with, repaired by editing the body — is consistent with a re-run at an unchanged
commit. Nothing was promoted from failed to passed; both are recorded honestly.
The branch is not behind. git merge-base --is-ancestor origin/master da2a46e succeeds
against master = f5e666c776a3bd7a7b41ae8f559378bbda359791, re-checked immediately before
this verdict. The green checks were measured against the base that will actually be merged
into.
Independent re-execution at da2a46e, checked out locally, both runtimes:
npm ci— passednpm run typecheck— passed (tsc --noEmit, no diagnostics)npm test— passed, 611 tests / 41 filesnpm run build— passed (vite build)dotnet restore— passeddotnet build --configuration Release --no-restore— passeddotnet test --configuration Release --no-build— passed, 45/45python scripts/implementation_status.py --check— passed, 29 ledger rows over 49 registry rowspython scripts/status_lint.py --repo drevendev/trade_simulation --self 477— passed
REQ-MIGRATION-003 holds: the canonical TypeScript change leaves the legacy .NET build and
suite green. 611 is 608 (the count I measured on #475) plus the three new tests, so the
body's arithmetic is what I observed.
2. Acceptance criteria of Issue #427, judged one by one
Criteria 1, 3 and 5 and the existence/dispatch/refusal half of 2 were measured and accepted
on PR #475; I am not re-litigating them. The two this pull request addresses:
-
2, wiring half — met, and not literally. This is the one real decision in the review,
so the reasoning is here rather than implied. The criterion and the Issue's Scope both say
phase8MainMarketClearing.tscallsexecuteAllocation. It does not;
applyMarketSettlementTransition(world, context)
(src/simulation/marketSettlementTransition.ts:447) does, foldingexecuteAllocationover
every MAIN-pass entry ofcontext.marketAllocations.I checked the structural argument rather than accept it.
PhaseHandlerreally is
(world, context, pendingTransitions) => TickContext(phase8MainMarketClearing.ts:44,
phase6MarketPriceFormation.ts:79), andexecuteTick()holds oneWorldStateacross the
tick per REQ-CORE-004, so a handler has no return channel for a settled world: the literal
wording cannot be satisfied without either discarding the settled world (settling nothing
while reading as wired) or rewriting REQ-CORE-004's contract. The precedent is real too —
applyMarketStateTransition(marketStateTransition.ts:32) has exactly this shape, is
likewise called only from tests, is described in this repository's own suite as "the real
production boundary", and was accepted on PR REQ-ACCEPTANCE-004: persist Phase-6 price and post-MAIN expectation into WorldState #441. The Handoff/04 quote is verbatim at
06 - Handoff/04 — MARKETS_TRADE_FX_CONTRACTS.md:748. A criterion whose literal reading
requires breaking a higher-order requirement is one I read for its substance, and the
substance — realized MAIN allocations reaching canonically-owned stock — is delivered.What decides it for me is that the deviation was not absorbed quietly: it is in the pull
request body's own criterion-2 box, in a Decision comment on Add live WorldState wallet/inventory state and implement MarketSettlement.executeAllocation(world, ctx, allocation) #427
(comment 5672204313), in the function's doc comment, and in the AUTHOR claim posted
before the implementation. The handoff says plainly thatREQUEST_CHANGESis correct if
I read the criterion literally. I do not, and this is the record of why.Evidence: "criteria 2-3: every realized MAIN-pass allocation reaches the canonically-owned
wallet and inventory…" drivesexecuteTick()and asserts, per allocation, that the
resolved endpoints arePRODUCTION_UNIT/OUTPUTandCOHORT/GENERAL, and that
marketCurrencyIdanddestinationStateIdare the region's own. -
3, at the production boundary — met. Same test. Buyer gross debit equals seller net
receipt plus collected tax; the seller'sOUTPUTdecrease equals the buyer's household
increase; and world-wide totals of that currency (clan treasuries, cohort wallets,
production-unit wallets, state treasuries) and of that good (household, INPUT/OUTPUT/
INVESTMENT, public) are unchanged across a realbuildInitialWorld()world. Two details
make it non-vacuous:expect(collectedTax).toBeGreaterThan(0)means the tax leg is
actually exercised, andexpect(settled).not.toBe(world)plus a re-read of the input
world's wallet proves the settlement happened on a new world and the input is untouched. -
4 — met. "criterion 4: telemetry on and off produce an identical post-settlement
WorldState" settles both runs and comparesclans,cohorts,productionUnits,
states,marketsandcontext.currentLedger. It first asserts the settled cohorts
differ from the pristine ones, so the comparison is over mutated stock rather than two
untouched copies — that assertion is what stops this being a test that passes by doing
nothing. The negative control perturbs one settled wallet by one unit and confirms the
comparison fails while the allocations still compare equal.
REQ-MARKET-005 → IMPLEMENTED is earned. The registry clause has three limbs. Stocks:
the new settlement comparison above. Allocations: marketAllocations deep-equality, at
acceptance-req-market-005-phase8-integration.test.ts:929 as well as the pre-existing
assertion. Replay hash: computeTickHash on/off comparison, lines 221 and 245, retained
unchanged. All three now have evidence at a boundary that mutates canonical stock, which is
the condition R235 named.
3. The diff is confined to the declared scope
Five files, every one named in the handoff (scope_guard inside policy-guard decides that
half and passed; I read the diff for the rest). All five sit inside the Issue's Scope: the
Phase-8 wiring, the settlement boundary, the M3 Phase-8 fixtures, and the ledger row plus its
generated document.
I checked the one item that could have been a Non-goals breach. Non-goals forbid "any change
to … tax semantics", and phase8MainMarketClearing.ts:138 now assesses zero rate when the
region has no controller. That is not a new tax rule: SPEC_CHANGELOG.md:30 (HANDOFF-REPAIR-006)
states "An uncontrolled Region collects zero State consumption tax" in terms, and
executeAllocation already refuses positive collected tax with a null destinationStateId
because it would destroy money inside a transfer. The previous constant pair — "cur:reserve",
which no baseline actor holds, and a positive rate with a null destination — was the defect
that made Phase-8's own allocations unsettleable. Conformance repair, in scope.
4. No invariant and no test was weakened
The eight pre-existing it( blocks in the converted acceptance file are all still present;
three are added, and the suite count rises 608 → 611. No expect line is removed anywhere in
the diff — the deletions are fixture-construction blocks only, replaced by
canonicalCounterparties() reads of the real baseline world, which throws rather than
degrading if the endowment assumption stops holding. No it.skip, no deleted file.
I checked the one place a behaviour change could have quietly hollowed out a retained
assertion. acceptance-004-m3-golden-gate.test.ts is untouched, and its fixtures use
synthetic regions absent from world.regions, so they now assess zero tax where they
assessed 0.1. Its two createPhase8Handler sites (lines 2250, 2388) assert on
sellerNetUnitPrice and bounded repricing, never on gross price or tax, and its tax
assertions (lines 861-917) inject their own getTaxationInfo with an explicit
destinationStateId, so they never reach the changed code path. Nothing was made vacuous.
The body flagged this as the highest-risk area; it was, and it holds.
The invariants moved the right way: money conservation, goods conservation and
non-negative stock now have assertions against a real mutated WorldState where before they
had them only against test-local maps.
One thing I verified rather than assumed, because the doc comment claims it: settlement is
genuinely all-or-nothing. executeAllocation refuses before rebuilding any world, and since
each call returns a new world rather than writing through, a mid-loop
SettlementRefusedError leaves the caller holding the world it passed in, not a half-applied
one. The comment is accurate.
5. No secret, credential, or personal data
policy-guard decides this and passed. Reading the diff independently for everything else, I
saw no token, credential or local machine path.
6. The handoff record is complete
All nine elements are present, and the evidence separates what was measured from what was
assumed rather than blurring them: the criterion-2 deviation is argued and offered up for
refusal, the ledger cell's reference to the earlier a681fe2 is explained inline instead of
being silently restated as da2a46e, and three residual risks (no production driver calls
the boundary, no multi-market coverage, computeTickHash still not covering canonical stock)
are named with their reasons. The acceptance-004-m3-golden-gate.test.ts CLAN+GENERAL
fixtures were filed as #478 rather than fixed in this branch — the right call.
Follow-ups, not blockers
- REQ-MARKET-005: PR #414 still does not prove canonical-stock neutrality #416. The body asks whether its criteria 1-3 are now met and declines to decide. They
read as met to me for the same reasons criteria 3 and 4 above are met, but REQ-MARKET-005: PR #414 still does not prove canonical-stock neutrality #416 is not this
pull request's unit of work and I will not close an Issue on a review that did not examine
it. It stays open for a run that claims it. - R235: golden-gate Phase-6/Phase-8 dispatch fixtures still trade CLAN against CLAN on a GENERAL bucket #478 stays as filed.
- No production driver calls
applyMarketSettlementTransition. True, and true of
applyMarketStateTransitionsince PR REQ-ACCEPTANCE-004: persist Phase-6 price and post-MAIN expectation into WorldState #441, because no per-tick driver loop exists in this
repository at all. When one is written it must call both, or the settlement it skips is
invisible. That hazard is recorded in ADR 0007; it is not a defect this pull request
introduced.
Merging with --squash --delete-branch. Issue #427 has nothing left under the reading above,
so Closes #427 is correct and I will confirm it closed.
…tween canonical stock owners (#506) * REQ-ACCEPTANCE-004: trade the M3 dispatch fixtures between canonical stock owners R235 (`ANSWERS_TO_IMPLEMENTER.md`, `CODE_RUNTIME_QA_M3_16`) calls a `CLAN`+`GENERAL` M3 settlement endpoint implementation drift: a Clan owns a treasury and no physical goods at all (Handoff/01 §§5.3/5.4/7), so `resolveGoodsEndpoint()` refuses such an allocation rather than inventing a container. PR #477 converted the seven Phase-8 fixtures in `acceptance-req-market-005-phase8-integration.test.ts` and deliberately left the two Phase-6/Phase-8 *dispatch* fixtures in the golden gate alone: they never settle, so they did not throw. They still named endpoints no production path could produce, on a synthetic region that was not in `world.regions`. Both now draw their counterparties and their region from a real `buildInitialWorld(baselineScenario, ...)` world via a new `canonicalDispatchCounterparties()` helper: a `PRODUCTION_UNIT` seller offering from the `OUTPUT` inventory that actually holds its food, against a funded `COHORT` buyer whose single household inventory owns consumed food, in a region whose `RegionState.controllerStateId` is non-null — so the settlement currency and consumption-tax destination Phase 8 reads off the canonical `RegionState` both resolve, as they would in production. This is a fixture-identity change only. Every assertion about once-per-tick dispatch, Phase-6/Phase-8 price sharing, bounded repricing and the persistence boundary is unchanged in meaning and still passes. Closes #478 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * ledger: record PR #506 against REQ-ACCEPTANCE-004 The requirement stays IMPLEMENTED -- this pull request repairs the identity of two of its fixtures, it does not add acceptance coverage. ISSUE/PR now name the work that last touched the row (#478 / #506); the prior pair (#268 / #441) and every earlier contributing pull request stay named in EVIDENCE. MERGE_COMMIT is left empty for scripts/backfill_merge_commits.py, which cannot run until this pull request has a squash commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Closes #427
Achieved outcome
Phase-8's realized MAIN-pass allocations now reach authoritative actor stock. PR #475 left
two halves that nothing joined: Phase-8 produced
MarketAllocations, andexecuteAllocation(world, ctx, allocation)could apply one to live wallets and inventories,but no path carried an allocation from the first to the second, and the allocations Phase-8
produced were not settleable in any case — they named a currency no actor holds and assessed
consumption tax with no treasury to receive it, either of which
executeAllocationrefusesoutright.
applyMarketSettlementTransition(world, context)is that path; the currency andtax destination now come from the canonical
RegionState; and the M3 Phase-8 fixtures tradecanonical owners instead of the
CLAN+GENERALpairing R235 calls implementation drift.Money conservation, goods conservation and telemetry on/off canonical-stock neutrality are
proven against a real
buildInitialWorld()world at the production boundary rather than ona test-local map, which promotes
REQ-MARKET-005toIMPLEMENTED.Tested revision
da2a46e67e9b463b483849045bb95e82140d84cb— every check in the table below was measuredagainst this exact revision, the branch head.
(The
REQ-MARKET-005evidence cell names the earliera681fe2for the five build/testsuites, with the reason stated inline: that cell was written before the ledger commit
existed. The results are identical, because the only delta from
a681fe2toda2a46eisthis CSV and the document generated from it, which none of the five suites reads. Both
numbers are honest;
da2a46eis the one a reviewer should re-measure.)Changed artifacts
src/simulation/phase8MainMarketClearing.ts— resolves the market currency and the taxdestination from the canonical
RegionStateinstead of assuming them.marketCurrencyIdwas the constant
"cur:reserve", which no actor in the baseline scenario holds; taxationreturned
destinationStateId: nullwhile still assessing a positive rate, so the tax wasdebited from the buyer and credited to nobody. An uncontrolled region now assesses zero
consumption tax (HANDOFF-REPAIR-006), and the one rate feeds both the affordability
calculation and the recorded gross price, so the two cannot drift apart.
src/simulation/marketSettlementTransition.ts— addsapplyMarketSettlementTransition(world, context), which foldsexecuteAllocationoverevery MAIN-pass allocation in
context.marketAllocationsand returns the settled world.No change to
executeAllocationitself.src/simulation/acceptance-req-market-005-phase8-integration.test.ts— converts all sevenPhase-8 fixtures from
CLAN-against-CLANon aGENERALbucket to aPRODUCTION_UNITseller debiting
OUTPUTagainst aCOHORTbuyer crediting its single householdinventory, via one
canonicalCounterparties()helper that picks them out of the realbaseline world; adds three settlement regressions; and rewrites the file header, which
still asserted that live wallets, inventories and
executeAllocationdo not exist.docs/spec/implementation_status.csv—REQ-MARKET-005row updated:PARTIAL→IMPLEMENTED,PR→ 477,MERGE_COMMITcleared (the row now names an unmerged pullrequest;
backfill_merge_commits.pyfills it), evidence extended.docs/spec/IMPLEMENTATION_STATUS.md— regenerated byscripts/implementation_status.py;not hand-edited.
Acceptance criteria
Issue #427's criteria 1, 3 and 5 and the existence/dispatch/refusal half of criterion 2 were
delivered by PR #475 and are not re-litigated here. This pull request addresses the two the
ACCEPTOR's record on #427 left open.
executeAllocationis called for every realizedMAIN-pass
MarketAllocation.applyMarketSettlementTransition()iteratescontext.marketAllocations, skips any non-MAIN pass, and callsexecuteAllocationfor each, in the section-36 stable order
computeLocalClearing()already emitted themin (it sorts sellers and buyers by
actorKey|intentIdbefore matching, so re-sortinghere would invent a second ordering rule that could disagree with the one clearing
used). Proven by
criteria 2-3: every realized MAIN-pass allocation reaches the canonically-owned wallet and inventory…, which drivesexecuteTick()and assertseach allocation's resolved endpoints, currency and tax destination.
Read the deviation below before accepting this box.
WorldState.Same test: buyer gross debit equals seller net receipt plus collected tax; the seller's
OUTPUTdecrease equals the buyer's household increase; and the world-wide totals ofthat currency (across every clan treasury, cohort wallet, production-unit wallet and
state treasury) and of that good (across every household, INPUT/OUTPUT/INVESTMENT and
public inventory) are unchanged. PR Issue #427: add live actor stock and MarketSettlement.executeAllocation #475 proved this for a hand-built allocation; it is
now proven for allocations a real Phase-8 run produced.
WorldState.criterion 4: telemetry on and off produce an identical post-settlement WorldStatesettles both runs and compares
clans,cohorts,productionUnits,states,marketsandcontext.currentLedger. It first asserts the settled cohorts differ fromthe pristine ones, so the comparison is over mutated stock rather than two copies of an
untouched world.
criterion 4 negative controlperturbs one settled wallet by a singleunit and confirms the comparison fails while the allocations still compare equal —
exactly the divergence shape Issue REQ-MARKET-005: PR #414 still does not prove canonical-stock neutrality #416 asked for.
Deviation from criterion 2's literal wording
Criterion 2 says
executeAllocationis "called by Phase-8", and the ACCEPTOR's record on#427 says
phase8MainMarketClearing.tsmust call it. It does not; the settlement boundarydoes, applied to Phase-8's output. The reason is structural, not stylistic:
PhaseHandleris(world, context, pendingTransitions) => TickContext, andexecuteTick()holds oneWorldStateimmutable across all sixteen phases (REQ-CORE-004), so a phase handler has noway to hand a mutated world back. The three alternatives are worse — calling
executeAllocationinside the handler and discarding its result settles nothing; putting aworld on
TickContextcollapses the ephemeral/authoritative split; makingexecuteTick()return a settled world rewrites REQ-CORE-004's contract for one requirement. Handoff/04
section 35 asks for exactly this split ("Pure planning/allocation functions should return
plans/deltas. Mutation belongs in explicit settlement/delivery functions"), ADR 0007 already
fixed
executeAllocationas world-in/world-out for the same reason, andapplyMarketStateTransition()— accepted on PR #441 as the real production boundary for theother half of persistent truth — is the precedent this follows. If the ACCEPTOR reads
criterion 2 as literal, this box is not met and the correct verdict is
REQUEST_CHANGES;recorded as a Decision comment on #427 rather than decided quietly here.
Checks
npm cinpm run typechecktsc --noEmit, no diagnostics, atda2a46enpm testmaster), atda2a46enpm run buildvite build, atda2a46edotnet restoredotnet build --configuration Releaseda2a46edotnet test --configuration ReleaseREQ-MIGRATION-003maintained, atda2a46epython scripts/implementation_status.py --checkpython scripts/status_lint.py --repo drevendev/trade_simulation --self 477typescript/build-and-test/policy-guard/mergeability(the forge's own)da2a46eOutcome is exactly one of
passed,failed,not_run,unavailable.Not checked
typescript,build-and-test,policy-guardandmergeabilityallpassedatda2a46e(run 34908821610).
The two earlier
policy-guardfailures on this branch werescope-guardrefusing theplaceholder body this pull request was opened with, before the body below existed; editing
the body re-ran the check without a new commit, which is the documented repair. Nothing was
promoted: those runs are recorded as failed and these as passed.
applyMarketSettlementTransition(), because no per-tickproduction driver loop exists in this repository yet; it is exercised by tests, exactly as
applyMarketStateTransition()has been since PR REQ-ACCEPTANCE-004: persist Phase-6 price and post-MAIN expectation into WorldState #441. Residual risk: a future driver coulddrop the returned world and silently drop the settlement. That hazard is named in ADR 0007
and is unchanged by this pull request.
one region. Residual risk: an ordering defect that only appears across markets. Low — the
boundary does not itself order anything, it preserves the order clearing produced.
Assumptions and unknowns
executeAllocationrefuses aCLANgoods endpoint and refuses positivecollected tax with a null
destinationStateId; both are read directly frommarketSettlementTransition.tsand covered by PR Issue #427: add live actor stock and MarketSettlement.executeAllocation #475's refusal regressions. The baselinescenario's production units hold
good:foodinOUTPUTand its cohorts hold the region'ssettlement currency; read from a real
buildInitialWorld()world, andcanonicalCounterparties()throws rather than silently degrading if that stops being true.REQ-MARKET-005is now fully satisfied ratherthan still
PARTIAL. The registry acceptance has two halves: telemetry emission fromactual clearing, proved since PR REQ-MARKET-005: Complete Phase-8 telemetry golden-gate acceptance #387/REQ-MARKET-005: stop telemetry toggle from short-circuiting Phase-8 clearing #414, and "turning telemetry on/off does not change
canonical stocks, allocations or replay hash", which had never been proved for the stocks
clause because no settlement boundary existed. R235 stated the condition — "REQ-MARKET-005
remains PARTIAL until the real Phase-8 settlement and telemetry-neutrality evidence merges"
— and this is that evidence. The judgement is that the boundary above counts as "the real
Phase-8 settlement". See the deviation section; this is the same call.
met to me: its regression executes a real settlement boundary, compares canonical wallets,
inventories and ledger, and has a controlled-divergence negative control. I have not
claimed or closed REQ-MARKET-005: PR #414 still does not prove canonical-stock neutrality #416 — it was not this run's unit of work — and have left a comment
there pointing at this pull request. That call is the ACCEPTOR's.
computeTickHash()should cover canonical stock. It still hashes onlytick, config version, scenario, seed, a constant phase trace and transaction count. The
neutrality proof here no longer leans on it, so this is not a gap in this requirement, but
it remains a weak replay hash. Not filed — it may already be intended for a later milestone.
Highest-risk area for review
phase8MainMarketClearing.ts. ChangingmarketCurrencyIdanddestinationStateIdfromconstants to canonical lookups changes what every Phase-8 allocation records, including in
acceptance-004-m3-golden-gate.test.ts, whose fixtures use synthetic regions that are not inworld.regions. Those now resolve to no controller, so they assess zero consumption taxwhere they previously assessed 0.1 — the gross price equals the net price for them. That
suite passes unchanged (its assertions are on
sellerNetUnitPriceand on bounded repricing,and its buyers' budgets were never binding), but it is behaviour a reviewer should confirm is
intended rather than absorbed. The alternative reading — that an unknown region should keep
charging tax to a null treasury — is the defect this fixes, so the fallback is deliberate.
Remaining gate
No mandatory work remains for this pull request. Two follow-ups, both filed, neither smuggled
into this branch:
the deviation section, and the ACCEPTOR decides that. If the reading is accepted, Add live WorldState wallet/inventory state and implement MarketSettlement.executeAllocation(world, ctx, allocation) #427 has
nothing left and can close.
acceptance-004-m3-golden-gate.test.tsPhase-6/Phase-8 dispatch fixtures still tradeCLANagainstCLANon aGENERALbucket. They never settle, so they do not throw, butR235 calls that pairing implementation drift. Filed as R235: golden-gate Phase-6/Phase-8 dispatch fixtures still trade CLAN against CLAN on a GENERAL bucket #478 (
status:needs-triage) rather thanconverted here.
🤖 Generated with Claude Code