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
4 changes: 2 additions & 2 deletions docs/spec/IMPLEMENTATION_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ that fact; this file does not.
| REQ-PRODUCTION-001 | `READY` | `IMPLEMENTED` | #558 | #559, `96ed4198e3f3220916e9ce78455befe37ff971f3` | PR #559 implements the M4 persistent ProductionUnit state boundary: live installedCapital is the sole mutable capacity stock; ProductionSignalState and lastLifecycleReviewTick are materialized at genesis; INPUT/OUTPUT/INVESTMENT inventories remain distinct physical maps; deriveNameplateCapacity derives batches per tick strictly as installedCapital × RecipeDefinition.batchesPerCapitalUnit without a serialized capacity authority; validateProductionUnitPersistentState rejects non-finite or negative capital/inventory, inventory aliasing, out-of-range or non-finite signals, invalid counters and review ticks; genesis reconciliation reads live installedCapital and its capital-removal negative control mutates the live authority. Focused proof: src/simulation/productionUnitState.test.ts (8 tests) plus the updated genesisReconciliation capital-removal negative control. Exact-head CI run 35306469114 on b2dabe251952dd6dd79b15e4cdc384398b3f8155 passed TypeScript typecheck/tests/build, retained .NET build/test, policy-guard and mergeability. PR #559 then squash-merged as 96ed4198e3f3220916e9ce78455befe37ff971f3; no Phase-2 planning, production execution, investment execution, lifecycle transition behavior, M5+, or mirror change is claimed. |
| REQ-PRODUCTION-002 | `READY` | `IMPLEMENTED` | #570 | #571, `219ae9a4e9422071af984118b18114123fca466e` | PR #567 established the deterministic ACTIVE-unit Phase-2 production/labor/INPUT planner and canonical INPUT budget commitments. PR #571 completes the repaired REQ-PRODUCTION-002 boundary from HANDOFF-REPAIR-M4-004 / Handoff/05 sections 19-20: ordinary investment review runs only on tick > 0 cadence multiples; demand, margin and sales pressure use the fixed equal one-third weights; workingCapitalTarget protects mandatoryKnownCash + grossWageCashEnvelope + desiredInputCost + operatingLiquidityBuffer before investment; investmentBudget is bounded from excess opening home cash; desired capital growth is capped by maxCapitalGrowthPerReview; existing INVESTMENT inventory is subtracted; material desired purchases require finite positive prior-close gross INVESTMENT prices; goods and IDs are stable-good ordered; canonical BUY/INVESTMENT intents keep sourcePlanId=ProductionPlan.planId, inventoryBucket=INVESTMENT and commit maxSpend through a distinct `${planId}:INVESTMENT` budget-ledger envelope. Focused regressions in src/simulation/productionPlanning.test.ts prove due-cadence pressure/budget/intents, genesis/off-cadence suppression, price-evidence fail-fast, distinct INPUT versus INVESTMENT commitments with duplicate-overcommit rejection, insertion-order determinism, same-tick transaction/market context non-financing, and no planning-time installedCapital or investmentInventory mutation. Phase-3 labor allocation, Phase-5 execution/output sale, Phase-12 capital formation/depreciation, lifecycle transitions, MOTHBALLED reactivation eligibility and M5+ remain owned by their separate requirements and are not claimed here. |
| REQ-POPULATION-001 | `READY` | `NOT_STARTED` | — | — | — |
| REQ-POPULATION-002 | `READY` | `NOT_STARTED` | — | — | — |
| REQ-POPULATION-002 | `READY` | `IMPLEMENTED` | #575 | #576 | PR #576 implements the complete M4 Population-owned Phase-2 LaborSupplyPlan boundary from HANDOFF-REPAIR-M4-005 / Handoff/06 section 8: only positive-population WORKING cohorts emit normal supply; participation uses the Population-owned stratum baseline multiplied by the exact linear health and prior-close opportunity factors with neutral M4 workingEligibility/lawParticipationFactor and configured min/max clamps; available worker-equivalents are bounded to cohort population; IDs and enumeration are stable by persistent cohortId; plans are ephemeral TickContext state with no RNG, WorldState mutation or employer linkage. Focused regressions in src/simulation/laborSupplyPlanning.test.ts prove factor endpoints/clamping, CHILD/ELDER and zero-population exclusion, tiny-positive supply, invalid/non-finite evidence rejection, missing-stratum rejection, insertion-order equivalence and no cohort-state mutation. Substantive code head fe2782e77e208c9b002516aaa3e12aa658faf580 passed CI run 35411625919 with TypeScript typecheck/tests/build, retained .NET build/test and policy-guard; final evidence-only head reruns required gates before SLOPSTER judgement. Phase-3 allocation/wage settlement, household consumption, persistent employer stock, Phase-13 demography/migration, M6 institutions and M5+ remain separate requirements. |
| REQ-PRODUCTION-003 | `READY` | `NOT_STARTED` | — | — | — |
| REQ-PRODUCTION-004 | `READY` | `NOT_STARTED` | — | — | — |
| REQ-PRODUCTION-005 | `READY` | `NOT_STARTED` | — | — | — |
Expand All @@ -107,7 +107,7 @@ that fact; this file does not.
| REQ-ACCEPTANCE-005 | `READY` | `NOT_STARTED` | — | — | — |
| REQ-VISUALIZATION-009 | `READY` | `NOT_STARTED` | — | — | — |

**Summary: 34 of 49 requirement identifiers implemented.**
**Summary: 35 of 49 requirement identifiers implemented.**
The denominator is the data-row count of the mirrored registry at generation time; it is never carried forward from an earlier revision. Work that is claimed but not yet merged is a `status:in-progress` label on its Issue, not a row here.

<!-- coverage:generated:end -->
Expand Down
1 change: 1 addition & 0 deletions docs/spec/implementation_status.csv
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ REQ-CONFIG-006,IMPLEMENTED,527,546,cd12a1cd8bffd298ca237378687312da47c91355,"Com
REQ-CONFIG-007,IMPLEMENTED,549,550,cd6e685be439ac5ab2b5f3e5cb4661d9798f3385,"Composite completion: PR #532 declared and validated the M4 PopulationConfig and need-category configuration surface while Q-002 remained open; HANDOFF-REPAIR-M4-003 resolved Q-002; PR #550 lands the complete twenty-control canonical baseline and ownership rules without pulling M8 or population behavior forward. Implemented slice, PR #532: the twenty M4-subset controls section 33 of 06 - Handoff/06 - POPULATION_DEMOGRAPHY_CLANS_CONTRACTS.md names - liquidity floor (section 4), participation bounds and the health-participation and weak-opportunity clamps (section 8), the wage signal (section 9), the four welfare EMA alphas and the real-income scale (section 10) and the health-stock controls (section 11) - are declared on PopulationConfig in src/config/simulationConfig.ts; NeedCategoryDefinition and BASELINE_NEED_CATEGORY_IDS land on DefinitionPack in src/config/definitionPack.ts as an optional needCategories key, because Handoff/03 section 8 says need quantities and substitute groups belong to definitions and not to global config; validatePopulationConfig() and the need-category rules are in src/config/validation.ts, the latter called from validateDefinitionPack() because the goodId cross-reference needs the declared-goods set; and validateWorldGenesis() in src/simulation/worldState.ts runs validatePopulationConfig() beside the two REQ-CONFIG-006 calls, so an out-of-range control fails at genesis rather than at the first tick that reads it. Four controls carry a stated value: minHealthParticipationFactor 0.75 and maxHealthParticipationFactor 1.02 from section 8 of Handoff/06 itself (""Recommended healthParticipationFactor range [0.75,1.02]""), and wageSignalAdjustmentSpeed 0.20 and prosperityAlpha 0.15 mapped from section 8 of Handoff/03 wageSignalAlpha and prosperityEmaAlpha. Both mappings are forced rather than chosen - the section 9 update wageSignal x exp(speed x ln(target/wageSignal)) is algebraically a geometric EMA with that smoothing factor, and neither document declares a competing wage-signal or prosperity smoothing control - and both are recorded as inferences in the pull request body and the Decision comment on Issue #531. Three further divergences were refused on the Q-001 maxLogWageStep precedent, because mapping them would invent a semantic: liquidityFloorShare versus precautionaryCashFloorMonths 0.25 (a share versus a number of months, and section 4's floor needs both of its own parameters), per-category priceSensitivity_c versus the single global needSubstitutionElasticity 0.60 (section 5 requires ESSENTIAL_FOOD and COMFORT to differ, which one global contradicts), and healthEmaAlpha 0.20, which has no counterpart at all. Deliberately not declared, each with the sentence that places it elsewhere: workerEpsilon (section 9), because workers are measured in worker-equivalents, a quantity, and NumericConfig.quantityEpsilon owns that tolerance - the HANDOFF-REPAIR-010 precedent #528 applied to laborEpsilon; and the section 10 P_raw weights, because section 33 does not list them among what PopulationConfig centralizes, they must sum to 1.0, and section 33's ""Scenario files may override values but may not introduce new bespoke formulas without schema version change"" is what a scenario-tunable weight vector would defeat. Tests that fail without the change, in src/config/validation.test.ts: the four stated defaults pinned against their spec sentence; the population block deterministic across calls and accepted by its own validator; one absence test per unvalued control, so filling one in without answering Q-002 fails the build; twenty absence tests covering the deferred M8 demography/migration/mobility controls, so pulling M8 forward fails the build; a test asserting the full M4-subset field list is declared; non-finite, out-of-range, inverted-participation-bound and inverted health/opportunity-clamp rejection, plus entry-by-entry validation of baseParticipationByStratum; need categories validated as a set (exactly the four baseline ids accepted, an unknown id rejected, a missing baseline id rejected, a key/id mismatch rejected, an empty substitutionGoods list rejected because section 5 normalizes share_g = weight_g / sum(weight) and an empty list makes every share 0/0, a repeated goodId rejected because it would double-count its own weight in that same normalization, a non-positive basePreference or qualityFactor rejected, and a goodId the pack does not declare rejected - the REQ-CONFIG-005 negative control from #512 and #516 applied to the new reference); a negative control asserting no PopulationConfig key duplicates a LaborConfig, MarketConfig, ProductionConfig or NumericConfig key, checked over all twenty declared controls and, at the type level, over the declared sibling surfaces too, because both sides leave controls undefaulted and Object.keys() of the runtime defaults saw only four of the twenty; assertNoBehavioralOverrides still refusing a scenario carrying population; the seven remaining sibling placeholders still empty; and six existing numeric/markets/production/labor values pinned unchanged. Ten further tests in the new src/simulation/genesisPopulationConfig.test.ts run the enforcement end to end through buildInitialWorld() on the baseline scenario: the canonical defaults accepted, a non-finite control, an out-of-range control, an inverted participation clamp and an out-of-range per-stratum rate each rejected before construction, a pack declaring no needCategories accepted (the baseline pack declares none, and household demand is REQ-POPULATION-001's to run), and a need category naming an undeclared good rejected; and, after researcher QA on head d6c99db, three tests proving a valid non-empty four-category pack survives buildInitialWorld() unchanged into world.definitionRegistry.needCategories, field for field, with absence preserved as absence. The negative control was run: with the validatePopulationConfig() call commented out of validateWorldGenesis() and the tests in place, exactly the four config-bound regressions fail and the other three pass (4 failed | 3 passed of 7); restoring the call returns 7/7. The DefinitionPack -> DefinitionRegistry -> WorldState boundary is closed in the same pull request: needCategories was validated at genesis and then discarded, because src/domain/definitionRegistry.ts projected only goods/recipes/eventDefinitions/metricDefinitions and DefinitionPack is not reachable from WorldState, so REQ-POPULATION-001..003 would have had no canonical source for the categories this row declares; needCategories is now in the DefinitionRegistry Pick and in buildDefinitionRegistry(), with a test in src/domain/definitionRegistry.test.ts that derives the expected projection from the pack rather than naming fields by hand, so the next definitions field added and forgotten fails instead of disappearing. Negative control run: reverting the projection fails exactly those four tests and no others. At the branch head the TypeScript suite passed 840/840 (50 files, up from 827/49 on master), typecheck and build passed, and legacy .NET passed 45/45 (REQ-MIGRATION-003 maintained). Completion slice, PR #550: src/config/m4PopulationDefaults.ts materializes the complete twenty-control HANDOFF-REPAIR-M4-003 baseline; createDefaultSimulationConfig().population uses createDefaultPopulationConfig(); focused regressions pin the exact values including Math.log(1.05), validator acceptance, per-call reference isolation, stale-alias exclusion and M8 exclusion; src/config/validation.test.ts replaces the obsolete undefined-default assertions with materialization/ownership checks; docs/spec/OPEN_QUESTIONS.md records Q-002 ANSWERED; the existing needCategories DefinitionPack -> DefinitionRegistry -> WorldState projection remains intact. Exact-head CI run 35280031062 on 68a911a8e558e9e0a829da61191c2a21d30e4955 passed TypeScript typecheck/tests/build, retained .NET build-and-test, policy-guard (including handoff, generated-status and ledger-honesty checks) and mergeability. PR #550 then merged as cd6e685be439ac5ab2b5f3e5cb4661d9798f3385; M4 population behavior remains owned by REQ-POPULATION-001..003 and no such behavior is claimed here."
REQ-PRODUCTION-001,IMPLEMENTED,558,559,96ed4198e3f3220916e9ce78455befe37ff971f3,"PR #559 implements the M4 persistent ProductionUnit state boundary: live installedCapital is the sole mutable capacity stock; ProductionSignalState and lastLifecycleReviewTick are materialized at genesis; INPUT/OUTPUT/INVESTMENT inventories remain distinct physical maps; deriveNameplateCapacity derives batches per tick strictly as installedCapital × RecipeDefinition.batchesPerCapitalUnit without a serialized capacity authority; validateProductionUnitPersistentState rejects non-finite or negative capital/inventory, inventory aliasing, out-of-range or non-finite signals, invalid counters and review ticks; genesis reconciliation reads live installedCapital and its capital-removal negative control mutates the live authority. Focused proof: src/simulation/productionUnitState.test.ts (8 tests) plus the updated genesisReconciliation capital-removal negative control. Exact-head CI run 35306469114 on b2dabe251952dd6dd79b15e4cdc384398b3f8155 passed TypeScript typecheck/tests/build, retained .NET build/test, policy-guard and mergeability. PR #559 then squash-merged as 96ed4198e3f3220916e9ce78455befe37ff971f3; no Phase-2 planning, production execution, investment execution, lifecycle transition behavior, M5+, or mirror change is claimed."
REQ-PRODUCTION-002,IMPLEMENTED,570,571,219ae9a4e9422071af984118b18114123fca466e,"PR #567 established the deterministic ACTIVE-unit Phase-2 production/labor/INPUT planner and canonical INPUT budget commitments. PR #571 completes the repaired REQ-PRODUCTION-002 boundary from HANDOFF-REPAIR-M4-004 / Handoff/05 sections 19-20: ordinary investment review runs only on tick > 0 cadence multiples; demand, margin and sales pressure use the fixed equal one-third weights; workingCapitalTarget protects mandatoryKnownCash + grossWageCashEnvelope + desiredInputCost + operatingLiquidityBuffer before investment; investmentBudget is bounded from excess opening home cash; desired capital growth is capped by maxCapitalGrowthPerReview; existing INVESTMENT inventory is subtracted; material desired purchases require finite positive prior-close gross INVESTMENT prices; goods and IDs are stable-good ordered; canonical BUY/INVESTMENT intents keep sourcePlanId=ProductionPlan.planId, inventoryBucket=INVESTMENT and commit maxSpend through a distinct `${planId}:INVESTMENT` budget-ledger envelope. Focused regressions in src/simulation/productionPlanning.test.ts prove due-cadence pressure/budget/intents, genesis/off-cadence suppression, price-evidence fail-fast, distinct INPUT versus INVESTMENT commitments with duplicate-overcommit rejection, insertion-order determinism, same-tick transaction/market context non-financing, and no planning-time installedCapital or investmentInventory mutation. Phase-3 labor allocation, Phase-5 execution/output sale, Phase-12 capital formation/depreciation, lifecycle transitions, MOTHBALLED reactivation eligibility and M5+ remain owned by their separate requirements and are not claimed here."
REQ-POPULATION-002,IMPLEMENTED,575,576,,"PR #576 implements the complete M4 Population-owned Phase-2 LaborSupplyPlan boundary from HANDOFF-REPAIR-M4-005 / Handoff/06 section 8: only positive-population WORKING cohorts emit normal supply; participation uses the Population-owned stratum baseline multiplied by the exact linear health and prior-close opportunity factors with neutral M4 workingEligibility/lawParticipationFactor and configured min/max clamps; available worker-equivalents are bounded to cohort population; IDs and enumeration are stable by persistent cohortId; plans are ephemeral TickContext state with no RNG, WorldState mutation or employer linkage. Focused regressions in src/simulation/laborSupplyPlanning.test.ts prove factor endpoints/clamping, CHILD/ELDER and zero-population exclusion, tiny-positive supply, invalid/non-finite evidence rejection, missing-stratum rejection, insertion-order equivalence and no cohort-state mutation. Substantive code head fe2782e77e208c9b002516aaa3e12aa658faf580 passed CI run 35411625919 with TypeScript typecheck/tests/build, retained .NET build/test and policy-guard; final evidence-only head reruns required gates before SLOPSTER judgement. Phase-3 allocation/wage settlement, household consumption, persistent employer stock, Phase-13 demography/migration, M6 institutions and M5+ remain separate requirements."
7 changes: 7 additions & 0 deletions src/simulation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ export {
type ProductionPlanningResult,
} from "./productionPlanning";

export {
createPhase2LaborSupplyPlanningHandler,
generateLaborSupplyPlansPhase2,
planCohortLaborSupplyPhase2,
type LaborSupplyPlan,
} from "./laborSupplyPlanning";

export {
TOTAL_PHASES,
PHASE_NAMES,
Expand Down
Loading
Loading