Repository navigation
REQ-CONFIG-004: population genesis reconciliation drops typed region identity #452
Description
Activity
- addedpriority:highImportant and time-sensitive; schedule ahead of normal workImportant and time-sensitive; schedule ahead of normal worktype:bugVerified behavior differs from the intended contractVerified behavior differs from the intended contractstatus:readySpecified and unblocked; safe for an agent to claimSpecified and unblocked; safe for an agent to claim
on Sep 13, 2026 - added a commit that references this issue
on Sep 14, 2026 - added a commit that references this issue
on Sep 14, 2026 - added a commit that references this issue
on Sep 14, 2026 - added a commit that references this issue
on Sep 14, 2026 - added a commit that references this issue
on Sep 14, 2026 AUTHOR claim
Role: AUTHOR
Selection path (AUTHOR_RUNBOOK.md §2):
- Item 1/2: no open pull requests at all (
gh pr list --state openis empty), so no changes-requested and no failing-check pull request of mine exists. - Item 3: the two
status:blockedIssues are not unblockable. REQ-MARKET-005: PR #414 still does not prove canonical-stock neutrality #416 is blocked on Add live WorldState wallet/inventory state and implement MarketSettlement.executeAllocation(world, ctx, allocation) #427 (still an openstatus:readyIssue, not landed); REQ-VISUALIZATION-006: M3 polished LocalMarket Pages experience #269 requiresREQ-MARKET-005 = IMPLEMENTEDindocs/spec/implementation_status.csv, which still readsPARTIAL. - Item 4: among
status:readyIssues,priority:highnon-policycandidates are REQ-CONFIG-004: preserve ProductionUnit GOOD_ENDOWMENT inventory-bucket identity #455, REQ-CONFIG-004: population genesis reconciliation drops typed region identity #452, REQ-VISUALIZATION-008: settlement guide conflates transfer conservation with later physical source/sink flows #447, REQ-VISUALIZATION-008: local-market guide misstates expectation causality and bootstrap boundary #446, REQ-VISUALIZATION-007: README still carries stale M2/M3 semantics after PR #381 #445, Add live WorldState wallet/inventory state and implement MarketSettlement.executeAllocation(world, ctx, allocation) #427, REQ-VISUALIZATION-005: PR #421 readability helper misses ancestor opacity #423.EXECUTION_ORDER.mdv5 requires the earliest milestone whose dependencies are satisfied;REQ-CONFIG-004is M1 and stillPARTIAL, which is earlier than the M3 rows. Of the two M1REQ-CONFIG-004Issues, this one is the older contract (2026-09-13 vs 2026-09-14), and REQ-CONFIG-004: preserve ProductionUnit GOOD_ENDOWMENT inventory-bucket identity #455 explicitly declares this Issue out of its own scope, so the two are meant to land separately. Taking this one; REQ-CONFIG-004: preserve ProductionUnit GOOD_ENDOWMENT inventory-bucket identity #455 stays available for a later run. - This Issue is not
policy, is unassigned, has no branch and no open pull request.
Intended scope: key cohort
POPULATION_ENDOWMENTgenesis reconciliation by canonical cohort owner plus typed Region identity insrc/simulation/genesisReconciliation.ts, deriving actual Region identity from canonical cohort state/seed rather thansourceSeedKeytext, keepingsourceSeedKeyas provenance only. Add a focused negative control proving that changing onlyPOPULATION_ENDOWMENT.regionIdfails reconciliation while owner, source key and aggregate population are unchanged. Update theREQ-CONFIG-004ledger row truthfully in the same pull request.Dependency check: acceptance criterion 4 requires sharing one canonical population-stock key with #448's cohort-owner repair. #448 landed as PR #459 (
11bd421);genesisReconciliation.tsalready keys population asPOP:${serializeOwner(...)}, so this repair extends that same key rather than introducing a parallel convention.Branch:
claude/issue-452-population-region-identityKnown blockers: none identified.
- Item 1/2: no open pull requests at all (
- addedstatus:in-progressClaimed work with an active branch or pull requestClaimed work with an active branch or pull requeststatus:needs-reviewImplementation complete, awaiting acceptanceImplementation complete, awaiting acceptanceand removedstatus:readySpecified and unblocked; safe for an agent to claimSpecified and unblocked; safe for an agent to claimstatus:in-progressClaimed work with an active branch or pull requestClaimed work with an active branch or pull request
on Sep 14, 2026 AUTHOR handoff
Branch:
claude/issue-452-population-region-identity
Pull request: #471
Tested revision:a8349336310508cbb6896d082893cb89f08923b4(branch head; all checks re-run at this revision after the ledger commit)What changed:
src/simulation/genesisReconciliation.tsnow keys cohort population byPOP:<cohort owner>:<region>on both sides instead of by owner alone. The expected side reads the record's own typedregionId; the actual side resolves the cohort's Region through the region registry fromCohortSeed.regionKey— the same canonical relation and the same lookup the goods projection already uses — sosourceSeedKeystays provenance only. This extends the single population key PR #459 introduced rather than adding a parallel convention (criterion 4).Negative control (criterion 2):
genesisReconciliation.test.ts→ "fails when a cohort's population record names another region while owner, source key and total are unchanged". It asserts the unmodified genesis reconciles, asserts the relabelled record's owner/sourceSeedKey/amount are identical and that total recorded population is unchanged, then asserts failure withcategory === "POPULATION". Proved sensitive by stashinggenesisReconciliation.tsback to itsmastercontent with the test in place: exactly that test fails (1 failed | 29 passed); restoring the repair returns 30/30.Checks:
npm cipassed;npm run typecheckpassed;npm testpassed (590/590, 40 files, 1 new);npm run buildpassed;dotnet restorepassed;dotnet build --configuration Release --no-restorepassed;dotnet test --configuration Release --no-buildpassed (45/45, REQ-MIGRATION-003 maintained);python scripts/implementation_status.py --checkpassed;python scripts/status_lint.py --self 471 --base masterpassed;python scripts/policy_guard.py --base masterpassed. The forge-run required checks had not reported when this was written — those outcomes are local runs at the tested revision, not a claim about CI.Ledger: the
REQ-CONFIG-004row is updated in place (ISSUE 452, PR 471,MERGE_COMMITleft empty forbackfill_merge_commits.py,EVIDENCEextended). STATUS deliberately staysPARTIALper criterion 5: sibling Issue #455 (ProductionUnitGOOD_ENDOWMENTINPUT/OUTPUT/INVESTMENT bucket identity, spec changelog HANDOFF-REPAIR-017) is still open, so the requirement is not yet provable at full typed-identity granularity.Decision recorded: Handoff/03 section 20 spells the owner+region reconciliation rule out explicitly for ProductionUnit-owned
GOOD_ENDOWMENTbut not separately forPOPULATION_ENDOWMENT. I read the typed-identity principle ("sourceSeedKeyis provenance only and must never substitute for typed stock identity") as general, consistent with how PRs #467 and #469 treated goods and resources, and with this Issue's own Evidence. If the researcher intends population to be deliberately Region-blind, the remedy is a spec question rather than a revert; no mirror file was read beyond registry, changelog, EXECUTION_ORDER and the single named domain document, and none was edited.No out-of-scope work was smuggled in: the diff is two source files plus the two ledger files. No new Issue was needed — no out-of-scope defect was discovered.
Remaining gate: none for this Issue. Setting
status:needs-review. This run does not approve and does not merge.ACCEPTOR: accepted and merged
PR #471 was reviewed at head
a8349336310508cbb6896d082893cb89f08923b4and merged as squash commitd3c354171db642ce28218cb3b108e9eeccd82f29(2026-09-14T21:24:36Z). Pull request state confirmedMERGEDbefore this note was written; this Issue closed automatically asCOMPLETEDviaCloses #452.Verdict: #471 (comment)
Evidence observed at the accepted revision
Required checks, read from the checks tab at
a834933:mergeabilitysuccess(measured aftermaster's then-headc2f1fd8; branch 0 commits behind, no conflict),typescriptsuccess,build-and-testsuccess,policy-guardsuccess. The one supersededpolicy-guardfailureearlier at the same head was ascope_guardrefusal of a placeholder body, cured by writing the handoff and re-running with no new commit — verified from run timestamps, not taken on the body's word.Independent re-execution of both runtimes at
a834933:npm cipassed,npm run typecheckpassed,npm testpassed (590/590 across 40 files),npm run buildpassed,dotnet build --configuration Releasepassed (0 warnings, 0 errors),dotnet test --configuration Releasepassed (45/45,REQ-MIGRATION-003maintained).All six acceptance criteria met. The key change: both sides of population reconciliation now key on
POP:${serializeOwner(...)}:${serializeRegion(...)}, with the actual side resolving the cohort's Region throughregionIdByRegionKeyfromCohortSeed.regionKeyrather than from seed-key text, sosourceSeedKeystays provenance only per Handoff/03 §20.The negative control's sensitivity was verified independently and more tightly than the pull request claimed: neutralizing only the region segment on both sides, changing nothing else, fails exactly one test — "fails when a cohort's population record names another region while owner, source key and total are unchanged" (
1 failed | 29 passedin that file). The control is sensitive to the region segment in isolation, closing the residual risk the AUTHOR had honestly flagged as unproven.Status of REQ-CONFIG-004
Deliberately still
PARTIALindocs/spec/implementation_status.csv, and correctly so. This Issue's typed-Region gap forPOPULATION_ENDOWMENTis closed, but sibling defect #455 (ProductionUnitGOOD_ENDOWMENTINPUT/OUTPUT/INVESTMENT bucket identity, spec changelog entry HANDOFF-REPAIR-017) remains open and is out of this Issue's scope by its own Non-goals. The requirement is not yet provable at full typed-identity granularity, and the ledger says so rather than overclaiming.The row's
MERGE_COMMITwas left empty by the authoring run because it is unknowable before merge;scripts/backfill_merge_commits.pyrecordsd3c3541for it, as it did for the preceding rows.Removing
status:needs-review: a closed Issue carries no activestatus:*label — the forge's closed state and itsCOMPLETEDreason are the durable resolution.- removedstatus:needs-reviewImplementation complete, awaiting acceptanceImplementation complete, awaiting acceptance
on Sep 14, 2026
Goal
Restore location-sensitive population opening-stock reconciliation without changing any population quantity, demographic mechanic, Clan relationship, or phase behavior.
Evidence
Canonical Handoff/03 defines
CohortSeed.regionKeyand recordsPOPULATION_ENDOWMENTwith a typedregionId; the world-generation contract also states that every cohort belongs to one Region and one Clan.REQ-CONFIG-004requires opening-stock reconciliation to prove the actual constructed stocks, not only aggregate totals.On current
master(25065757889f2db3513aa472c67d8e982761a6ae),src/domain/genesisLedger.tspreservesPOPULATION_ENDOWMENT.regionId, butsrc/simulation/genesisReconciliation.tsignores it. Expected population is keyed only bysourceSeedKey:Actual population is reconstructed from the cohort seed key:
Therefore a
POPULATION_ENDOWMENTwith the wrong typedregionIdcan still reconcile as long assourceSeedKeyand amount are unchanged. This is a distinct typed-location false positive from #448's cohort-owner defect: #448 repairs who owns the population stock; this finding repairs the Region identity carried by that stock record.Scope
Make the smallest CONFIG-004 repair:
COHORTownership (or an equivalent typed canonical key);sourceSeedKeytext;sourceSeedKeyas provenance/diagnostics only;POPULATION_ENDOWMENT.regionIdfails reconciliation while cohort owner, source key, and aggregate population remain unchanged;REQ-CONFIG-004implementation evidence/status truthfully after the repair lands.Non-goals
Acceptance criteria
POPULATION_ENDOWMENTreconciliation verifies canonical cohort owner and typed Region identity, not onlysourceSeedKey.docs/spec/implementation_status.csvdoes not claim CONFIG-004 is fully proved until both owner and Region identity gaps are repaired and evidenced.Verification
Run the focused genesis-reconciliation tests, including the wrong-region population negative control, then the repository-required TypeScript typecheck/test/build and retained .NET gates.