Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/spec/IMPLEMENTATION_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ that fact; this file does not.
| REQ-VISUALIZATION-002 | `FROZEN` | `NOT_STARTED` | — | — | — |
| REQ-VISUALIZATION-003 | `READY` | `IMPLEMENTED` | #42 | #45, `d27a94e63580a2d7d0da005a245ae36fec5560fd` | `src/diagnostics/m0Preview.test.ts` — asserts `docs/m0-preview.json`'s legacy baseline seed/turns/hash match `docs/spec/LEGACY_BASELINE.md` exactly, its canonical-scaffolding flag matches the real `toolchainStatus()` in `src/index.ts`, and `docs/index.html` fetches the static artifact without referencing any canonical or legacy runtime module path. Manual build/render smoke check (headless-Chromium screenshots at 1280×1000, 360×900, and a full-page 1100×1900 capture) against a local static server, described in `docs/spec/M0_PREVIEW.md`; 7 files / 16 tests passed and both runtime suites green at merge commit `d27a94e63580a2d7d0da005a245ae36fec5560fd`. Actual production GitHub Pages deployment was explicitly out of AUTHOR scope in #45 and has not been independently re-verified by this reconciliation, which is bounded to `gh pr list` and the merged pull request's own body per `AUTHOR_RUNBOOK.md` section 1. |
| REQ-VISUALIZATION-004 | `READY` | `IMPLEMENTED` | #160 | #220, `f199c8677e99256c4b9ca46d68772b80ef7aa1b3` | M1 Milestone Preview (REQ-VISUALIZATION-004): deterministic JSON snapshot of canonical world-gen overview without exposing mutable domain objects. src/diagnostics/m1Preview.ts generates typed M1Preview interface exposing scenario ID/seed/configVersion, world topology counts (stateCount, regionCount, currencyCount, etc.), and arrays of State/Currency/Region/Clan details. src/diagnostics/m1Preview.test.ts (12 tests) generates docs/m1-preview.json from baseline-multistate-v1 scenario and seed 42; asserts M1Preview schema completeness, non-zero entity counts, deterministic generation invariance, and that docs/index.html references m1-preview.json without runtime imports. Smoke test: generated artifact is deterministically serializable, contains 4 states (State Alpha/Beta/Gamma/Delta), 24 regions, 4 currencies, 8 clans, 216 cohorts, 172 production units. All acceptance criteria met: M1 preview JSON generated deterministically from baseline scenario; GitHub Pages displays world-gen topology via static artifact (no mutable WorldState exposure); one-way read-only diagnostic output; TypeScript 231/231 tests passed, typecheck clean, build succeeded; C# 45/45 tests passed, build clean (REQ-MIGRATION-003 maintained). |
| REQ-VISUALIZATION-005 | `READY` | `IMPLEMENTED` | #411 | #421, `02bd6a8fbc592561d301a86dd9b3fc16ed91149d` | M2 Milestone Preview (REQ-VISUALIZATION-005): deterministic JSON snapshot of canonical M2 tick orchestration and zero-flow reconciliation without exposing mutable domain objects. src/diagnostics/m2Preview.ts generates typed M2Preview interface exposing scenario ID/seed/configVersion, world topology counts, phase trace (0-15 proof with no phase 16), tick counter (firstTick/lastTick/ticksExecuted = 1/101/101), and reconciliation health (passedTicks=101/failedTicks=0/tolerance=1e-9). src/diagnostics/m2Preview.test.ts (13 tests) generates docs/m2-preview.json from baseline-multistate-v1 scenario and seed 42 executing 101 no-op ticks; asserts M2Preview schema completeness, phase trace exactly 0-15 (no phase 16), tick counter preservation, reconciliation passes (all 101 ticks pass with zero unmatched deltas within tolerance 1e-9), deterministic generation invariance, and that docs/index.html references m2-preview.json without runtime imports. GitHub Pages displays tick/phase/reconciliation health via static artifact (no mutable WorldState exposure); one-way read-only diagnostic output. PR #244 (merged 5777e08957350dc610790f7e8cd59a0e5a70476d) delivered the M2Preview generator and JSON artifact. PR #368 (Issue #359, merged a89a8becd7aba073918a317a24b0341e482a6300) added a Pages render smoke test, but Issue #402 (SLOPSTER/researcher finding) showed those tests only fetched and inspected the JSON artifacts directly and never executed docs/index.html or observed a rendered DOM, so a broken DOM-population callback would leave every assertion green. PR #407 (Issue #402, merged 39c2c168388f44a6dff5cccbeefdd52763f92362) rewrote src/diagnostics/m1m2-pages-render.test.ts to load the real docs/index.html into jsdom with runScripts:'dangerously', bind window.fetch to the existing local static server, and assert on the actual rendered #m1-preview-body/#m2-preview-body DOM text after the preview fetches resolve; added desktop (1280px) and narrow (360px) viewport smoke cases and a DOM-population negative control per milestone. Issue #411 (QA/researcher finding) showed that PR #407's viewport smoke cases only checked getComputedStyle(...).display !== 'none' and textContent in jsdom, which has no box-model layout: a visibility:hidden or clipping (overflow:hidden + max-height:0) CSS rule on the populated preview body would leave every assertion green even though the content is not actually visible/readable. PR #421 (this PR, Issue #411) replaces those two viewport tests with real Chromium navigation via Playwright and asserts locator.isVisible(), which reflects an actual non-empty bounding box and non-hidden computed style; adds a Playwright devDependency and a pretest script (playwright install chromium) so npm test self-installs the browser; adds two negative-control tests proving a visibility:hidden regression on #m1-preview-body and a zero-height clipping regression on #m2-preview-body are each caught while DOM population/JSON fetch still succeed; preserves PR #407's DOM-population negative controls unchanged. ACCEPTOR review on PR #421's first head (independently confirming a SLOPSTER finding) showed Playwright's isVisible() does not check opacity, so an opacity:0 regression on a populated preview body would pass every positive assertion added by this PR. PR #421 (same branch, second head) added an isReadable() helper combining isVisible() with an explicit computed-opacity!=='0' check, used it for the two positive viewport tests' body assertions, and added a third negative-control test proving an opacity:0 regression on #m1-preview-body is caught while DOM population/JSON fetch still succeed. Verification: TypeScript 563/563 tests passed (40 files; 560 pre-existing + 3 net new: 2 viewport tests rewritten in place, 3 negative-control tests added), typecheck clean, build succeeded; C#/.NET 45/45 tests passed, build clean (REQ-MIGRATION-003 maintained). |
| REQ-VISUALIZATION-005 | `READY` | `IMPLEMENTED` | #411 | #479 | M2 Milestone Preview (REQ-VISUALIZATION-005): deterministic JSON snapshot of canonical M2 tick orchestration and zero-flow reconciliation without exposing mutable domain objects. src/diagnostics/m2Preview.ts generates typed M2Preview interface exposing scenario ID/seed/configVersion, world topology counts, phase trace (0-15 proof with no phase 16), tick counter (firstTick/lastTick/ticksExecuted = 1/101/101), and reconciliation health (passedTicks=101/failedTicks=0/tolerance=1e-9). src/diagnostics/m2Preview.test.ts (13 tests) generates docs/m2-preview.json from baseline-multistate-v1 scenario and seed 42 executing 101 no-op ticks; asserts M2Preview schema completeness, phase trace exactly 0-15 (no phase 16), tick counter preservation, reconciliation passes (all 101 ticks pass with zero unmatched deltas within tolerance 1e-9), deterministic generation invariance, and that docs/index.html references m2-preview.json without runtime imports. GitHub Pages displays tick/phase/reconciliation health via static artifact (no mutable WorldState exposure); one-way read-only diagnostic output. PR #244 (merged 5777e08957350dc610790f7e8cd59a0e5a70476d) delivered the M2Preview generator and JSON artifact. PR #368 (Issue #359, merged a89a8becd7aba073918a317a24b0341e482a6300) added a Pages render smoke test, but Issue #402 (SLOPSTER/researcher finding) showed those tests only fetched and inspected the JSON artifacts directly and never executed docs/index.html or observed a rendered DOM, so a broken DOM-population callback would leave every assertion green. PR #407 (Issue #402, merged 39c2c168388f44a6dff5cccbeefdd52763f92362) rewrote src/diagnostics/m1m2-pages-render.test.ts to load the real docs/index.html into jsdom with runScripts:'dangerously', bind window.fetch to the existing local static server, and assert on the actual rendered #m1-preview-body/#m2-preview-body DOM text after the preview fetches resolve; added desktop (1280px) and narrow (360px) viewport smoke cases and a DOM-population negative control per milestone. Issue #411 (QA/researcher finding) showed that PR #407's viewport smoke cases only checked getComputedStyle(...).display !== 'none' and textContent in jsdom, which has no box-model layout: a visibility:hidden or clipping (overflow:hidden + max-height:0) CSS rule on the populated preview body would leave every assertion green even though the content is not actually visible/readable. PR #421 (this PR, Issue #411) replaces those two viewport tests with real Chromium navigation via Playwright and asserts locator.isVisible(), which reflects an actual non-empty bounding box and non-hidden computed style; adds a Playwright devDependency and a pretest script (playwright install chromium) so npm test self-installs the browser; adds two negative-control tests proving a visibility:hidden regression on #m1-preview-body and a zero-height clipping regression on #m2-preview-body are each caught while DOM population/JSON fetch still succeed; preserves PR #407's DOM-population negative controls unchanged. ACCEPTOR review on PR #421's first head (independently confirming a SLOPSTER finding) showed Playwright's isVisible() does not check opacity, so an opacity:0 regression on a populated preview body would pass every positive assertion added by this PR. PR #421 (same branch, second head) added an isReadable() helper combining isVisible() with an explicit computed-opacity!=='0' check, used it for the two positive viewport tests' body assertions, and added a third negative-control test proving an opacity:0 regression on #m1-preview-body is caught while DOM population/JSON fetch still succeed. Verification: TypeScript 563/563 tests passed (40 files; 560 pre-existing + 3 net new: 2 viewport tests rewritten in place, 3 negative-control tests added), typecheck clean, build succeeded; C#/.NET 45/45 tests passed, build clean (REQ-MIGRATION-003 maintained). Issue #423 (researcher/QA finding on PR #421's merged head) showed the remaining false-positive path in that isReadable() helper: CSS opacity applies to an element and all of its contents but is not inherited, so a transparent ancestor composites the populated body away while the body's own computed opacity stays '1' and its bounding box stays non-empty. Injecting #m1-preview { opacity: 0; } therefore left isReadable(#m1-preview-body) returning true on a fully invisible preview. PR #479 (Issue #423) replaces the single-node opacity read with effectiveOpacity(locator), which multiplies each computed opacity along the ancestor chain from the target element to the document root inside the browser via locator.evaluate; isReadable() now gates on effectiveOpacity(...) > 0. It adds one negative-control test that injects #m1-preview { opacity: 0; } after navigation - leaving the JSON artifact, fetch URL and render callback untouched - and asserts that DOM population still succeeded, that isVisible() is still true and the body's own computed opacity is still exactly '1' (so the previous helper would have returned true), that isReadable() now returns false, and that the untouched M2 panel stays readable. The direct-opacity, visibility:hidden, clipping and DOM-population negative controls from PR #407 and PR #421 are preserved unchanged and still pass, and the normal 1280px/360px viewport cases still prove the populated bodies readable, so no actual normal-view failure was exposed and the row stays IMPLEMENTED per the researcher's 2026-09-11 triage on #423. Mutation-proved: with isReadable() reverted to its previous single-node form the new control fails with 'expected true to be false' (19 passed / 1 failed); with the fix all 20 pass. Gate is > 0, i.e. full transparency only - no perceptibility threshold was invented, and non-opacity mechanisms (filter, occlusion, clip-path, contrast) remain out of scope per #423's non-goals. Contributing pull requests for REQ-VISUALIZATION-005: #244, #368, #407, #421 and #479. Verification on PR #479's head: TypeScript 609/609 tests passed (41 files; 1 net new test), typecheck clean, build succeeded; C#/.NET 45/45 tests passed, build clean, 0 warnings (REQ-MIGRATION-003 maintained). |
| REQ-MARKET-001 | `READY` | `IMPLEMENTED` | #246 | #248, `6c4dafba8a3cc65055ffc540f9bf69b8ac0e9a7a` | Ephemeral MarketIntent contract and budget commitment ledger for M3 local market procurement (sections 5-6 of MARKETS_TRADE_FX_CONTRACTS.md). src/simulation/marketIntent.ts defines: MarketIntent interface (id, actor, regionId, goodId, side, purpose, quantities/budgets, inventory buckets); comprehensive validation covering all specification constraints (non-negative/finite quantities, BUY maxSpend, SELL minimumReserveQuantity, ProductionUnit bucket routing [INPUT/OUTPUT/INVESTMENT for specific purposes], actor ownership validation); BudgetCommitmentLedger interface tracking actor+currency+envelope commitments with commitment tracking, overcommitment prevention, and reusable-envelope release. src/simulation/marketIntent.test.ts: 35 comprehensive tests covering valid MarketIntent creation for all actor types (Clan, State, ProductionUnit) and purposes (CONSUMPTION, INPUT, INVESTMENT, PUBLIC_PROCUREMENT, INVENTORY_REBALANCE); validation rejection of non-finite/negative values; budget ledger operations (creation, commitment accumulation, envelope isolation, overcommitment prevention, partial/full release, reusability handling); ProductionUnit-specific bucket routing and validation. src/simulation/tickOrchestrator.ts extended: TickContext now includes budgetLedger field (initialized empty per tick); phase handlers in M3+ can manage budget commitments through the ephemeral ledger without mutation of persistent WorldState. All acceptance criteria met: MarketIntent schema fully defined with all required/optional fields; validation rejects non-finite/negative quantities and invalid constraints; BUY maxSpend and SELL minimumReserveQuantity validated; budget ledger prevents overcommitment within envelope limits; ProductionUnit intents use explicit INPUT/OUTPUT/INVESTMENT buckets; static-fixture test suite covers all constraint classes with 35 tests. TypeScript verification: 322 tests passed (28 files), typecheck clean, build succeeded. C#/.NET: 45 tests passed, build clean (REQ-MIGRATION-003 maintained). |
| REQ-MARKET-002 | `READY` | `IMPLEMENTED` | #270 | #316, `e3b747ef310957b99904977ad88ae5035ed5ef25` | Foundation (PR #250): Phase-6 price formation with persistent market expectations (Handoff/04 section 9): repriceGoodInPhase6() bounded log-space repricing formula, updateMarketExpectations() EMA updates. Specification ownership: Handoff/03 section 4 defines canonical market baseline values. PR #250 implemented formula and EMA mechanics correctly but used non-canonical defaults. Fix (PR #316, Issue #270): Corrected five market configuration defaults in src/config/simulationConfig.ts to match Handoff/03 section 4: shortageSignalWeight (0.5 → 0.65), inventorySignalWeight (0.5 → 0.35), basePriceAdjustmentSpeed (0.1 → 0.12), maxAbsoluteLogPriceMovePerTick (0.1 → 0.18), expectationAlpha (0.2 → 0.25). Added six regression tests in src/config/validation.test.ts verifying each default matches specification. All acceptance criteria met: Phase-6 repricing formula unchanged, all five defaults now match specification exactly, canonical baseline targetInventoryCoverageTicks (1.0) preserved. Verification: TypeScript 481 tests passed (including new canonical-market-defaults suite), typecheck clean, build succeeded; C#/.NET 45 tests passed, build clean (REQ-MIGRATION-003 maintained). |
| REQ-MARKET-003 | `READY` | `IMPLEMENTED` | #251 | #293, `bf526b33abcd7caf6188237dad4756273850266e` | Deterministic proportional local clearing primitive with MarketAllocation schema, stable residual correction, and two-pointer concrete matching for atomic transaction bundle production. src/simulation/marketClearing.ts implements proportional clearing for one region+good+pass, preventing floating-point rounding errors via stable-ID correction, and produces identical allocations regardless of input insertion order. src/simulation/marketClearing.test.ts: 19 comprehensive tests covering proportional splits, excess supply/demand, zero-flow edge cases, shuffled-insertion determinism, tax-aware pricing validation, and stable ID ordering. Acceptance criteria verified: seller/buyer fills sum to cleared quantity within tolerance; no fill exceeds constraints; residual correction stable-ID ordered; shuffled intent insertion produces identical normalized allocations; all specification constraints verified. TypeScript: 439 tests passed, typecheck clean, build succeeded. C#/.NET: 45 tests passed, build clean (REQ-MIGRATION-003 maintained). REQ-MARKET-003 ready for M3 market-phase integration. |
Expand Down
Loading
Loading