Skip to content

Implement stable canonical entity/definition registries (REQ-CORE-003) - #73

Merged
drevendev merged 2 commits into
masterfrom
claude/issue-72-core-registries
Sep 5, 2026
Merged

drevendev merged 2 commits into
masterfrom
claude/issue-72-core-registries

Conversation

@drevendev

Copy link
Copy Markdown
Owner

Closes #72

Achieved outcome

Stable, ID-keyed canonical registries now exist for exactly the Milestone 1
registries bullet's entity list — Region, State, Currency, Clan,
PopulationCohort, ProductionUnit, LocalMarket, TransportLink — plus a
definitions registry, satisfying REQ-CORE-003. buildWorldRegistries
walks a ScenarioDefinition's seed lists in their own declared order and
allocates one REQ-CORE-001 typed ID per seed via the run's IdAllocator,
producing exactly the scenario-defined entity counts and IDs with no
duplicate/reused ID; a registry is legitimately empty when its seed list is
omitted or empty (e.g. no TransportLink yet, since transport is M5).
buildDefinitionRegistry is a typed read-only view over DefinitionPack's
existing goods/recipes/eventDefinitions/metricDefinitions fields,
matching CORE_SCHEMA_AND_LIFECYCLES.md section 6's DefinitionRegistry
shape exactly.

This pull request also reconciles docs/spec/IMPLEMENTATION_STATUS.md's
stale REQ-CONFIG-002 row (PR #70 merged as
005d0a553dbc685b8bf554ff0ae9d802a7ac04fd since that row was last written,
per AUTHOR_RUNBOOK.md section 1) and recomputes the coverage denominator
against the current 31-row REQUIREMENTS_REGISTRY.csv (previously stale at
25, carried forward from an earlier SPEC_CHANGELOG.md revision).

Tested revision

464f963e47ad276d75cfbd9f259fab609c11c66f (branch claude/issue-72-core-registries)

Changed artifacts

  • src/domain/worldRegistries.ts — WorldRegistries, RegistryEntry, buildWorldRegistries. ID-keyed registry construction with no economic behavior.
  • src/domain/worldRegistries.test.ts — exact scenario-defined counts; legitimate empty registries; correct id-kind prefix and no duplicate ID within/across registries; field-equivalent repeated genesis with a fresh allocator.
  • src/domain/definitionRegistry.ts — DefinitionRegistry, buildDefinitionRegistry.
  • src/domain/definitionRegistry.test.ts — definitions pass through unchanged, including the empty case.
  • src/domain/index.ts — barrel-exports the new registry types/functions; updated module-area doc comment.
  • docs/spec/IMPLEMENTATION_STATUS.md — flips REQ-CONFIG-002 to IMPLEMENTED (merge commit 005d0a553dbc685b8bf554ff0ae9d802a7ac04fd, from already-merged PR Implement keyed deterministic RNG service (REQ-CONFIG-002) #70); adds a new REQ-CORE-003 row as IN_PROGRESS naming this Issue/branch and the proving tests; recomputes the denominator to 31 and the summary line to "9 of 31 requirements implemented; 1 in progress".

No TradeCraftSimulation/** or TradeCraftSimulation.Tests/** file was touched.

Acceptance criteria

  • Stable, ID-keyed registries exist for Region, State, Currency, Clan, PopulationCohort, ProductionUnit, LocalMarket, TransportLink, and definitions.
  • A registry may be legitimately empty/non-active where the specification permits, without that being a validation failure — see "leaves a registry legitimately empty when the scenario omits or empties its seed list" in src/domain/worldRegistries.test.ts.
  • A regression test proves baseline genesis creates exactly the scenario-defined entity counts and IDs (not merely non-zero/approximate counts) — see "creates exactly the scenario-defined entity counts" and the id-kind-prefix/no-duplicate-ID assertions in src/domain/worldRegistries.test.ts.
  • npm run typecheck, npm test, and npm run build pass.
  • docs/spec/IMPLEMENTATION_STATUS.md gains a REQ-CORE-003 row (added here as IN_PROGRESS; becomes IMPLEMENTED only once this or a follow-up reconciliation pull request merges, per the legend).

Checks

Check Outcome Evidence
npm ci passed 43 packages installed, 0 vulnerabilities, at 464f963e47ad276d75cfbd9f259fab609c11c66f
npm run typecheck passed tsc --noEmit clean
npm test passed 16 files / 79 tests passed, including the 9 new tests across src/domain/worldRegistries.test.ts and src/domain/definitionRegistry.test.ts
npm run build passed vite build succeeded
python3 -m unittest discover -s scripts/tests passed 61/61
python3 scripts/policy_guard.py --base master passed policy-guard: passed over 6 changed file(s)
dotnet build --configuration Release not_run No TradeCraftSimulation/** or TradeCraftSimulation.Tests/** file changed; residual risk: none — this change cannot affect the legacy build.
dotnet test --configuration Release not_run Same reason as above; residual risk: none.

Not checked

  • The concrete per-entity schema fields from CORE_SCHEMA_AND_LIFECYCLES.md section 5 (e.g. RegionState.controllerStateId, StateState.treasury) are not populated: ScenarioDefinition's *Seed types are still empty placeholder interfaces pending REQ-CONFIG-003 (baseline definition pack / scenario construction), which is an explicit Non-goal of Issue Implement stable canonical entity/definition registries (REQ-CORE-003) #72. Each registry entry today carries only its allocated ID plus whatever fields its seed type already declares (currently none); buildRegistry's { ...seed, id } spread means no registry-building code needs to change once seed fields land.
  • No WorldGenesisLedger or opening-stock reconciliation (REQ-CONFIG-004) and no RNG-driven bounded variation (REQ-CONFIG-002/003) — both explicit Non-goals.
  • MonetaryAuthority, Bond, Shipment and EventInstance registries are intentionally not built here: neither Issue Implement stable canonical entity/definition registries (REQ-CORE-003) #72's Scope nor document 11's Milestone 1 registries bullet lists them, even though CORE_SCHEMA_AND_LIFECYCLES.md section 5.8 defines MonetaryAuthorityState. Building them was judged out of this bounded unit's scope rather than an oversight.

Assumptions and unknowns

  • Assumption: per Issue Implement stable canonical entity/definition registries (REQ-CORE-003) #72's own recorded open question, AUTHOR_RUNBOOK.md section 4's "at most one directly listed dependency document" permits opening CORE_SCHEMA_AND_LIFECYCLES.md (document 01) alongside the FILE-named document 11, because document 11 itself directly names it ("Implement typed IDs and primitive value/domain types required by CORE_SCHEMA_AND_LIFECYCLES") under the Milestone 1 Implementation bullets — i.e. the requirement's own primary document names the dependency document, rather than the registry row's DEPENDS_ON column (which names requirement IDs, not documents). I did not open any further document.
  • Assumption: since *Seed types are empty ({}) placeholders, the array index within each scenario seed list is the only available per-entity identity signal before REQ-CONFIG-003 defines concrete seed fields; I used ${entityKind}:${index} as the ID allocator's creationKey. This is scaffolding-only — no future requirement is bound to this exact creation-key string, since callers only ever observe the resulting allocated ID, not the creation key.
  • Fact, not inference: docs/spec/mirror/REQUIREMENTS_REGISTRY.csv's REQ-CORE-003 row has STATUS=READY, PRIORITY=P0, DEPENDS_ON=REQ-CORE-001,REQ-CONFIG-001, both already IMPLEMENTED (PR Implement canonical persistent typed IDs (REQ-CORE-001) #48 / 58a0b49..., PR Implement the canonical configuration hierarchy (REQ-CONFIG-001) #67 / 493da16e...).
  • Fact, not inference: no other open Issue or pull request currently names REQ-CORE-003 or touches src/domain/worldRegistries.ts / src/domain/definitionRegistry.ts (checked via gh issue list / gh pr list and git branch -a before claiming).

Highest-risk area for review

The ${entityKind}:${index} creation-key scheme in buildRegistry (src/domain/worldRegistries.ts) is the one judgment call the specification does not spell out mechanically, since *Seed types carry no identity field yet — see Assumptions above. A reviewer should confirm that deferring all concrete per-entity schema fields to REQ-CONFIG-003 (rather than trying to shape this registry's entries around CORE_SCHEMA_AND_LIFECYCLES.md's full RegionState/StateState/etc. interfaces now) is the correct scope boundary, since REQ-CONFIG-003 and REQ-CONFIG-004 build directly on these registries.

Remaining gate

None for this pull request's own scope. REQ-CORE-003 becomes IMPLEMENTED in IMPLEMENTATION_STATUS.md only once this merges. Populating concrete per-entity schema fields (REQ-CONFIG-003), opening-stock reconciliation (REQ-CONFIG-004), and wiring the keyed RNG service into any bounded scenario variation remain separate, already-scoped requirements, consistent with Issue #72's Non-goals.

Closes #72

Reconciles the stale REQ-CONFIG-002 row in IMPLEMENTATION_STATUS.md now
that PR #70 has merged, and recomputes the requirement-count denominator
against the current 31-row REQUIREMENTS_REGISTRY.csv.
@drevendev

Copy link
Copy Markdown
Owner Author

Verdict: REQUEST_CHANGES

(Posted as a comment, not a formal review: GitHub refuses a same-account review on this PR.)

Independent verification at head 464f963e47ad276d75cfbd9f259fab609c11c66f:

  • npm ci, npm run typecheck, npm test (79/79), npm run build, python3 scripts/policy_guard.py --base master all reproduce as claimed — confirmed green.
  • Required checks (build-and-test, typescript, policy-guard) are green at this head.
  • src/domain/worldRegistries.ts / definitionRegistry.ts and their tests genuinely prove exact scenario-defined counts, correct id-kind prefixes, no duplicate IDs within/across registries, legitimate emptiness for omitted seed lists, and field-equivalent repeated genesis — the Issue Implement stable canonical entity/definition registries (REQ-CORE-003) #72 acceptance criteria for the registries themselves are met.
  • Diff is confined to declared scope; no workflow/AGENTS.md/docs/zendev policy files touched; no secrets/credentials found; no test weakened.

Defect

docs/spec/IMPLEMENTATION_STATUS.md lines 28 and 45: the PR recomputes the coverage denominator and states it as fact — "31 as of SPEC_CHANGELOG.md revision HANDOFF-REPAIR-003" and "9 of 31 requirements implemented ... The other 21 requirement identifiers ... are not yet mapped."

This is incorrect. I counted docs/spec/mirror/REQUIREMENTS_REGISTRY.csv directly (unchanged by this PR, verified byte-identical to master's copy): it has 32 distinct REQ_ID data rows, not 31 (verified via awk 'END{print NR}' minus the header row, and independently via cut -d, -f1 | sort -u | wc -l). The correct summary should read "9 of 32 requirements implemented; 1 in progress," with 22 unmapped identifiers, not 21.

Why it matters: IMPLEMENTATION_STATUS.md is the durable ledger later runs trust for requirement coverage (per AGENTS.md, "state lives in the forge, not in a conversation"). An off-by-one here, introduced while explicitly fixing a different staleness (the REQ-CONFIG-002 row, which is correctly reconciled — verified against merged PR #70), compounds error rather than removing it: a future run reconciling this file again from a stale "31" would need to re-derive the true count from scratch instead of trusting the ledger.

What would satisfy it: recompute the denominator directly from REQUIREMENTS_REGISTRY.csv's actual row count (32) at the PR's head revision, and correct both the "Coverage" paragraph and the "Summary" line (including the "other N requirement identifiers" count) to match.

No other defect found. The registry/definition code, its tests, and the REQ-CONFIG-002 reconciliation are solid and can proceed once this single count is corrected.

REQUIREMENTS_REGISTRY.csv has 32 distinct REQ_ID data rows, not 31, per
ACCEPTOR verdict on PR #73.

Addresses REQUEST_CHANGES verdict:
#73 (comment)
@drevendev

Copy link
Copy Markdown
Owner Author

Verdict: ACCEPT

Independent verification at head d23fd08a0292d65d0d2c1b48d401332c4aea73c0 (branch claude/issue-72-core-registries), which supersedes the prior REQUEST_CHANGES at 464f963e with a single new commit ("Fix IMPLEMENTATION_STATUS.md requirement-count denominator (31→32)").

  1. Checks green at this head: build-and-test, policy-guard, typescript all pass per gh pr checks 73 at d23fd08.
  2. Acceptance criteria (Issue Implement stable canonical entity/definition registries (REQ-CORE-003) #72), each with evidence observed:
    • ID-keyed registries for Region, State, Currency, Clan, PopulationCohort, ProductionUnit, LocalMarket, TransportLink, and definitions — src/domain/worldRegistries.ts, src/domain/definitionRegistry.ts.
    • Legitimate emptiness without validation failure — worldRegistries.test.ts "leaves a registry legitimately empty when the scenario omits or empties its seed list" (transportLinks, markets).
    • Regression test proves exact scenario-defined entity counts and IDs, no duplicates — worldRegistries.test.ts "creates exactly the scenario-defined entity counts" and the id-kind-prefix/no-duplicate-ID tests.
    • npm run typecheck, npm test, npm run build all reproduce green at this head (checked out locally): typecheck clean, 16 files/79 tests passed, build succeeded. python3 scripts/policy_guard.py --base master also passed (6 changed files).
    • docs/spec/IMPLEMENTATION_STATUS.md gains a REQ-CORE-003 row (IN_PROGRESS).
  3. Scope confined: diff touches exactly docs/spec/IMPLEMENTATION_STATUS.md, src/domain/{worldRegistries,definitionRegistry}.{ts,test.ts}, src/domain/index.ts — matches Issue Implement stable canonical entity/definition registries (REQ-CORE-003) #72's declared Scope plus the explicitly-permitted IMPLEMENTATION_STATUS.md write (AGENTS.md authority table, Issue AC5). No .github/workflows/**, AGENTS.md, or docs/zendev/** touched.
  4. No invariant or test weakened; no test deleted or disabled.
  5. No secret, credential, or personal data found in the diff.
  6. Handoff record complete in the PR body (outcome, Issue/revision, artifacts, acceptance criteria, checks table, not-checked items, assumptions, risk area).

Prior defect, now fixed

The prior verdict's sole defect — IMPLEMENTATION_STATUS.md claiming a 31-row denominator — is corrected. I independently counted docs/spec/mirror/REQUIREMENTS_REGISTRY.csv at current master (awk 'END{print NR-1}' and cut -d1 | sort -u | wc -l, both 32). The new text reads "9 of 32 requirements implemented; 1 in progress" with 22 unmapped identifiers (32 − 9 − 1 = 22), which is arithmetically correct. I also independently confirmed the REQ-CONFIG-002 row's cited merge commit 005d0a553dbc685b8bf554ff0ae9d802a7ac04fd is in fact PR #70's merge commit.

No other defect found. Merging.

@drevendev
drevendev merged commit 3b6f2eb into master Sep 5, 2026
3 checks passed
@drevendev
drevendev deleted the claude/issue-72-core-registries branch September 5, 2026 03:12
drevendev added a commit that referenced this pull request Sep 5, 2026
…005) (#76)

Adds assertValidRunOptions and assertValidScenarioDefinitionShape,
covering the fail-fast, non-coercing slice of section 21's validation
rules that is realizable today: RunOptions's own fields, and
ScenarioDefinition's required top-level field shapes. Additive
alongside assertNoBehavioralOverrides, which proves key-membership
only. Sub-config bound checks and seed-content validation remain out
of scope pending REQ-CONFIG-003 and the M3-M10 requirements that will
give those placeholder types concrete fields.

Also reconciles IMPLEMENTATION_STATUS.md's stale REQ-CORE-003 row: PR
#73 (closing Issue #72) merged as 3b6f2eb since that row was written.

Closes #74

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement stable canonical entity/definition registries (REQ-CORE-003)

1 participant