Code Sync Audit
Status: governance reference — populated incrementally by waves. Wave D
fills the Valenar-docs and SECS-design-docs sections. Other artifact
sections are deferred to future waves and are marked explicitly. Status
vocabulary in this doc follows
pr-status-and-sync-policy.md.
Active Migration: Location → Territory Rename + Force Model (Wave D Docs)
The Location → Territory rename is the active cross-cutting migration. It is
governed by
docs/adr/ad-0005-territory-rename-and-force-model.md.
This Wave D pass covers docs only. No Location alias, compatibility shim, or
transitional synonym is preserved in any live design doc — per the
no-backwards-compatibility tenet, every live artifact class must reflect
Territory once its corresponding wave completes.
Doc files renamed by this Wave D:
examples/valenar/docs/systems/gd-locations-features-sites.md→examples/valenar/docs/systems/gd-territories-features-sites.mdexamples/valenar/docs/ux/gd-territory-dossier.md→examples/valenar/docs/ux/gd-territory-dossier.mdexamples/valenar/docs/generation/gd-territory-generation-contract.md→examples/valenar/docs/generation/gd-territory-generation-contract.mdexamples/valenar/docs/generation/gd-start-location-contract.md→examples/valenar/docs/generation/gd-start-territory-contract.md
Doc files created by this Wave D:
examples/valenar/docs/systems/gd-forces.mdexamples/valenar/docs/systems/gd-operations.mdexamples/valenar/docs/systems/gd-defense-zones.mdexamples/valenar/docs/systems/gd-fronts.mddocs/adr/ad-0005-territory-rename-and-force-model.md
Subsequent waves (deferred):
- Wave S —
.secssource rename inContent/territories/→Content/territories/; newContent/forces/,Content/characters/skills/fieldcraft.secs; updates toscope Characterfor the four position fields and to activity definitions for theTechniqueReftyped arg. - Wave G —
Generated/Territories/→Generated/Territories/; new compiler-owned generated output for Force, Operation, DefenseZone, Front, Fieldcraft, TechniqueRef; renameTerritoryKnowledgeTypes.cs→TerritoryKnowledgeTypes.csandLocationContentState→TerritoryContentState. - Wave M —
Host/andServer/rename:LocationData→TerritoryData,LocationDossierReadModel→TerritoryDossierReadModel,GameWorld.CoreLocationId→GameWorld.CoreTerritoryId, all internal field/parameter/variable names; SignalR DTOs and ReadModel projections. - Wave C —
Client/rename:LocationContextPanel.tsx→TerritoryContextPanel.tsx,LocationPlanningBoard.tsx→TerritoryPlanningBoard.tsx,useLocationDossier.ts→useTerritoryDossier.ts; capture scenarios; Zustand store keys; Force/Operation/DefenseZone/Front UI surfaces. - Wave T — Test file rename and new tests for Territory, Force, Operation, DefenseZone, Front, Fieldcraft, and TechniqueRef dispatch.
The behavior-vocabulary baseline at Wave D start was 158. Wave D is docs-only and does not change that baseline. The baseline is updated by the wave that fixes the underlying offending lines, not by docs touches.
Wave M Out-of-Scope Forwards (Generated/ residue, deferred to Wave G2)
Wave M (Host/ + Server/ rename) deliberately did not touch any file
under examples/valenar/Generated/, because the Generated tree is owned
by Wave G and its follow-ups, not by Wave M. As a result, four
identifiers in examples/valenar/Generated/Territories/FeaturePlacement/FeaturePlacementTypes.cs
still carry the pre-rename Location form and must be renamed in a
follow-up Wave G2 micro-edit before Wave Final closes the
migration. The deferred identifiers are:
WorldMapFacts.Locations(line 150) — should becomeWorldMapFacts.Territories.WorldMapFacts.StartingLocationId(line 152) — should becomeWorldMapFacts.StartingTerritoryId.TerritoryFacts.LocationId(line 113) — should becomeTerritoryFacts.TerritoryId.FeaturePlacementResult.LocationId(line 168) — should becomeFeaturePlacementResult.TerritoryId.
All four will be renamed in a single Wave G2 micro-edit before Wave Final. Until that micro-edit lands, the consumer callsites continue to read the pre-rename names by design:
examples/valenar/Host/Bridge/HostBridge.cs:749readsworld.MapFacts.Locations.TryGetValue(...)(a comment on the preceding line already flags the deferred rename).examples/valenar/Generated/Systems/World/MapGenerationSystem.cs:150readsplacement.LocationId(and again at lines 259, 301, 304 in the same file) when ordering and bindingFeaturePlacementResultrows to territories.
These callsites stay temporarily — they are not Wave M regressions and must not be patched as part of Wave M cleanup. They will be updated in the same Wave G2 micro-edit that renames the four field names above.
Wave M Git-History Note — LocationFoundingReadModel D+A
The Wave M rename of examples/valenar/Host/ReadModels/LocationFoundingReadModel.cs
to examples/valenar/Host/ReadModels/TerritoryFoundingReadModel.cs
landed in the working tree as a git delete + add rather than as a
detected rename, because the post-rename file's content similarity to
the pre-rename file falls below git's default 50% rename-detection
threshold. With the explicit lower threshold,
git diff --find-renames=10% --name-status HEAD -- examples/valenar/Host/ReadModels/ confirms the pair as R045 (45%
similarity), which is below the 50% auto-detect cutoff but above the
10% floor — so the rename is real, just not auto-detected.
The two sibling renames in the same Wave M dispatch DID auto-detect:
LocationDossierReadModel.cs → TerritoryDossierReadModel.cs shows as
R070 at the default threshold. That confirms the FoundingReadModel
below-threshold case is content-driven (the file is small and most of
the body changed during the rename), not the result of a Write-vs-git mv process error.
The lost line-by-line history is recoverable via:
git log --follow --find-renames=10% -- \
examples/valenar/Host/ReadModels/TerritoryFoundingReadModel.cs
No remediation is required. The file's content is correct; the git provenance is suboptimal but inspectable.
Wave D Out-of-Scope Forwards
The following items reference the old Location vocabulary and would
become stale after specific later waves complete; they are recorded here
as forward-pointers, not as Wave D edits:
examples/valenar/docs/captures.mdreferences the pre-renameLocationContextPanelandLocationPlanningBoardidentifiers. These will be updated when Wave C renames the React components and the capture scenarios are refreshed. Wave D does not editcaptures.md. At Wave D close,captures.mdretains 10 capital-Locationmentions at lines 52, 92, 96, 101, 103, 115, 124, 130, 132, and 142. The hits reference the React componentsLocationContextPanelandLocationPlanningBoard, the dev-only bridge symbolswindow.__valenarCapture.getLocationCanvasPosandgetMcLocationId, thelocation-*capture-scenario id family, and the lower-caselocationUX terms used in the rail-tab and dossier-inner-tab copy. All 10 hits will be updated in Wave C alongside the React component renames, the capture-scenario id renames, and the dev-only bridge symbol renames; alocation-*->territory-*capture scenario id migration is part of that same Wave C scope. Wave D intentionally does not touch any of these.examples/valenar/docs/lore/adr/ad-0002-lore-docs-migration.mdreferencesexamples/valenar/Content/territories/scopes.secsandGenerated/Territories/TerritoryKnowledgeTypes.csas historical-record citations of the docs tree at the time of that ADR. After Wave S and Wave G complete, a post-migration note may be added at the bottom of that ADR. Wave D does not edit lore ADRs.examples/valenar/docs/implementation/pr-status-and-sync-policy.mdreferences the pre-renameLocationDataidentifier in a status policy example. Wave M will carry the rename-related sync update for that file.- The Wave D-renamed doc paths are reflected in
.claude/rules/valenar-generation.mdpaths:glob; theLocationData.cs→TerritoryData.csrename target reference points at a path that does not yet exist (Wave M will land it). This forward-reference is intentional and acceptable per the rule-glob convention used elsewhere.
Wave S Outcome — Generated Provenance Tests Blocked Until Wave G
Wave S completed the Content/locations/ → Content/territories/ directory
rename, the bare_location → bare_territory template rename, the
Location → Territory scope/contract/channel renames in .secs source,
the new Content/forces/ files (Force, Operation, DefenseZone, Front
scopes/contracts/channels), the new
Content/characters/skills/fieldcraft.secs skill template, the four
new Character position fields, the WorldData JSON-schema rename
(starting_location → starting_territory,
location_cell_id → territory_cell_id,
valenar:template/location/bare_location →
valenar:template/territory/bare_territory, and the top-level JSON array
key "locations" → "territories") in both the Python generator
(Content/maps/generate_dummy_worlddata.py) and the committed fixture
(Content/WorldData/world-42.json).
After Wave S close, 20 of 41 GeneratedProvenanceTests fail because
examples/valenar/Generated/Locations/ still emits // Source: Content/locations/... headers and the cross-checked scope,
contract, and channel declarations still reference the old
Location / Feature / Site Generated-side names. This is
expected behavior pending Wave G and is recorded here as an
explicit blocker, not as a Wave S regression. The 20 failing tests at
Wave S close are:
EveryGeneratedFileDeclaresSourceOwnedProvenanceGeneratedAggregateFilesDeclareLockedSecsSourcesGeneratedDeclarationsChannelsMirrorSecsSourcesGeneratedDeclarationsCollectionsMirrorSecsSourcesGeneratedDeclarationsContractMethodsMirrorSecsSourcesGeneratedDeclarationsContractRootScopesMirrorSecsSourcesGeneratedDeclarationsModifiersMirrorSecsSourcesGeneratedDeclarationsRecordFieldsMirrorSecsSourcesGeneratedDeclarationsScopeFieldsMirrorSecsSourcesGeneratedDeclarationsScopeMethodsMirrorSecsSourcesGeneratedDeclarationsScopesAndContractsMirrorSecsSourcesGeneratedDeclarationsTemplateFieldsMirrorSecsSourcesGeneratedMapGenerationCreateEntityCallsMirrorSecsSystemMethodGeneratedTemplateChannelSourcesMirrorSecsTemplateBodiesGeneratedTemplateCommandMethodsMirrorSecsTemplateBodiesGeneratedTemplateCreateEntityCallsMirrorSecsTemplateMethodsGeneratedTemplateEntriesHaveMatchingSecsTemplateDeclarationsGeneratedTemplateFieldAssignmentsMirrorSecsTemplateBodiesGeneratedTemplateTagsMirrorSecsTemplateBodiesGeneratedVocabularyDeclarationsMirrorSecsSources
The historical remediation path was Wave G: rename
Generated/Locations/ → Generated/Territories/, rewrite all // Source: Content/locations/... headers to // Source: Content/territories/...,
rename Location / Feature / Site Generated scope/contract/channel
declarations to their Territory counterparts, regenerate the FNV-1a-64
hash constants in compiler-owned generated output, and add emitted rows/helpers
for the new Force / Operation / DefenseZone / Front / Fieldcraft
constructs. Wave G must run after Wave S commits to clear all 20
provenance failures; until then dotnet test tests/Valenar.Host.Tests/ will report exactly these 20 failures and a
verifier pass over the post-Wave-S state should treat them as
acknowledged blockers, not Wave S regressions.
The Wave S WorldData JSON rename also breaks runtime deserialization in
examples/valenar/WorldData/ValenarWorldDocument.cs, where the C# DTOs
still declare Locations / LocationCellId (snake-cased to JSON
locations / location_cell_id). Renaming those C# DTO members and
the ValenarWorldLocation / ValenarWorldLocationFacts records to
ValenarWorldTerritory / ValenarWorldTerritoryFacts /
TerritoryCellId / Territories belongs to Wave M (Host/Server
rename). Until Wave M runs, loading world-42.json at runtime will
deserialize an empty Territories array and the world import system
will fail to populate territories. dotnet build SECS.sln still
passes after the Wave S round-2 fixture edits because compilation does
not read the JSON.
Known Blockers At Wave Start
This section enumerates dirty-tree drift that existed in the working copy at the moment Wave D began, so future verifier passes can distinguish between Wave-D-introduced changes and inherited drift. The items here are explicitly out of Wave D scope (Wave D is docs-only per the wave matrix) and are recorded so that a subsequent verifier does not re-flag them as Wave D regressions. The Wave 0 explorer report enumerated these files in its "Repo state" section; this subsection is the audit-trail home for that enumeration.
Pre-Existing Build Break — Engine Resolver Rename Migration
A prior recovery wave began renaming the engine's primary stat-channel
resolver type but did not propagate the rename to the consumer
projects. As a result, dotnet build SECS.sln fails at the working-tree
state Wave D inherited.
- Wave that introduced the drift: prior recovery wave (not Wave D).
- Build-failure sites (8 errors at conversation start):
benchmarks/SECS.Benchmarks/ScenarioBuilder.cs:69benchmarks/SECS.Benchmarks/BenchmarkHost.cs:38(×2)benchmarks/SECS.Benchmarks/BenchmarkHost.cs:41benchmarks/SECS.Benchmarks/HierarchicalScenario.cs:103examples/character-trainer/Host/Bridge/HostBridge.cs:16examples/character-trainer/Host/GameRuntime.cs:11examples/character-trainer/Host/GameRuntime.cs:28(×2)
- Drift shape (per
pr-status-and-sync-policy.mdvocabulary): drift between current (consumer projects reference the prior engine resolver type name) and target (engine type was renamed). The fix is mechanical — update the eight call sites to the new type name — but it is a code change, not a docs change. - Wave D scope decision: NOT fixed in Wave D. Wave D is docs-only per the wave brief; touching benchmark or character-trainer source is outside the Wave D patch envelope.
- Where the fix belongs: a future engine/runtime wave (Wave C in
the recovery matrix, or a dedicated build-fix wave). Until that wave
runs,
dotnet build SECS.slnis expected to fail with these eight errors and verifier passes should treat the build break as a known blocker rather than a Wave D regression. - Reference for migration context:
docs/copilot-stat-channel-migration.md:454documents the rename history. - Assigned wave: Wave 0-Build (see
pr-wave-roadmap.md § Wave 0-Build). - Resolved by: Wave 0-Build. All 11 StatResolver -> ChannelResolver consumer occurrences across 5 files were renamed. dotnet build SECS.sln returns 0 errors after this change. Status: CLOSED.
Pre-Existing Staged Drift In Companion Rule Files
The git status at the start of Wave D's session showed a set of files already in modified state in the working tree, before any Wave D edit ran. These modifications are content-correct (they update vocabulary in companion governance files) but predate Wave D and are not attributable to it.
.claude/rules/behavior-vocabulary.md— staged before Wave D began. Wave D's companion vocabulary edit went todocs/design/behavior-vocabulary.md, a different file. The pre-existing modification of the.claude/rules/mirror is permitted under the meta-fix exception in.claude/rules/orchestrator-mode.md("Edits that only change CLAUDE.md,.claude/rules/, settings, hooks, or auto-memory files are small and self-contained. The orchestrator may execute these inline rather than dispatching."), so no fix wave is required. The note exists to prevent future verifier passes from re-flagging the modification as a Wave D change.- Benchmark consumer files participating in the resolver-rename
build break above:
benchmarks/SECS.Benchmarks/AllocationBenchmarks.csbenchmarks/SECS.Benchmarks/BenchmarkHost.csbenchmarks/SECS.Benchmarks/CachedHierarchicalBenchmarks.csbenchmarks/SECS.Benchmarks/CommandProcessBenchmarks.csbenchmarks/SECS.Benchmarks/HierarchicalBenchmarks.csbenchmarks/SECS.Benchmarks/HierarchicalScenario.csbenchmarks/SECS.Benchmarks/QueryBenchmarks.csbenchmarks/SECS.Benchmarks/ScenarioBuilder.csbenchmarks/SECS.Benchmarks/StatResolutionBenchmarks.cs
- Character-trainer consumer files participating in the same build
break:
examples/character-trainer/Host/Bridge/HostBridge.csexamples/character-trainer/Host/GameRuntime.cs
- Fix wave: the benchmark and character-trainer files share the
same fix wave as the build break above (future engine/runtime wave).
The
.claude/rules/behavior-vocabulary.mdmodification needs no separate fix wave.
Purpose
This document tracks where committed Valenar docs, Content/,
Generated/, Host/, Server/, Client/, src/SECS.*, tests/, and
scripts/ diverge from each other or from the design contract. It is
populated by waves; each wave fills the artifact-class sections it
audits. It is the machine-readable record of drift between current
implementation and target design — per-doc status blocks summarize, this
doc enumerates.
When a wave audits a section, it appends a wave-labeled subsection rather than overwriting prior wave findings. Closed drift items (where the implementation is brought up to the target) are kept in the audit trail so that future readers can see what was wrong, what was fixed, and which wave fixed it.
How To Use This Document
Readers looking for the authoritative design use the doc tree (the
systems/, generation/, acts/, catalogs/, and ux/ directories).
Readers looking for known drift between design and implementation use
this doc. Each artifact class has a top-level section; each section has
one or more Wave <Letter/Number> subsections for the wave that
audited it. Empty subsections say (deferred to Wave <ID>) using the
wave-id convention from the wave brief. Open questions raised by an
audit but not resolvable at audit time go in
pr-open-questions.md, with this doc cross-linking
to them.
Valenar Docs
Wave D
Wave D applied 10 patch-target edits to the Valenar docs tree to remove
the deprecated behavior-noun and planning-noun vocabulary as live
nouns and to fix two Territory-scale parentheticals that misled readers
about Territory geometry. The deprecated terms are documented in
docs/design/behavior-vocabulary.md;
the audit below describes the rewrites without re-quoting them inline.
-
examples/valenar/docs/systems/objectives-clues-missions.md— H1 rewritten to "Objectives, Clues, Missions, and Activities" (the prior H1 ended with the deprecated planning-noun). Core Terms, Relationship Between The Layers, and Design Rules sections rewritten to remove the deprecated planning-noun as a live planning category and to introduceroutine activityandcomposite activityas planning-layer sub-forms ofactivity(per the ADR-aligned behavior vocabulary indocs/design/behavior-vocabulary.md). -
examples/valenar/docs/ux/current-plan.md— three substitutions removing the deprecated planning-noun and replacing it with composed-activity language at lines describing the active mission rollup, the active composed-activity context bullet, and the traceability rule. -
examples/valenar/docs/ux/objectives-screen.md— three substitutions removing the deprecated planning-noun from the "approach" wording, the "activenoun" listing wording, and the "Do not letnounreplace" guidance line, all replaced with composed-activity phrasing. -
examples/valenar/docs/systems/camp.md— one substitution rewriting "can surface asdeprecated planning-noun" to "can surface as routine activity shapes". -
examples/valenar/docs/glossary.md— Technique definition rewritten to remove the deprecated capitalized behavior-noun and planning-noun pair and to useactivities,missions, andassignmentsinstead. -
examples/valenar/docs/systems/character-skills.md— two substitutions removing the deprecated capitalized behavior-noun and planning-noun pair from the "noun-list, Missions, or Assignments" enumeration and from the "Techniques,noun-list, Missions, and Assignments" enumeration, replaced with the activities/missions/assignments wording. -
examples/valenar/docs/ux/combat-dungeon-screen.md— six substitutions: round-log row label rewritten so the fired noun isactivityinstead of the deprecated behavior-noun; behavior-branch field name updated toactivity_ref(the field previously used the deprecated behavior-reference field name); resolver wording rewritten so a resolveractivitytakes a behavior reference (the prior wording used the deprecated resolver behavior-noun); the paired sentence about the resolver invoking the highest-weighted branch's behavior rewritten toactivity; the "the resolver is itself adeprecated noun" paragraph rewritten to useactivityandactivity call path; and the cross-link line previously referring to the deprecated behavior-primitive wording rewritten toactivity primitive. The proposal-doc nature of this file is unchanged; the substitutions are vocabulary fixes inside the proposal. -
examples/valenar/docs/README.md— index entry forgd-realm-ranks-and-polity.mdrewritten from "realm creation, rank, founding tier, and crown-scale capabilities" to "polity ladder above settlements, founding tier, and crown-scale capabilities" to remove the "realm creation" wording that contradicted the canonical line that there is no single Realm birth moment. Index entry forgd-objectives-clues-missions.mdrewritten to match the new H1. -
examples/valenar/docs/generation/territory-generation-contract.md(formerlylocation-generation-contract.mdprior to Wave D Territory rename) — the(~50 km × 50 km)parenthetical at the Territory Scale description rewritten to(an irregular Voronoi polygon at this scale). The fix preserves the 250–500 km² area but removes the square-cell implication. -
examples/valenar/docs/generation/world-generation-contract.md— the matching(a ~50 km × 50 km strategic cell)parenthetical rewritten to(an irregular Voronoi cell at this scale).
Wave D also created six new Valenar docs:
implementation/status-and-sync-policy.md,
implementation/code-sync-audit.md (this
file), implementation/open-questions.md,
systems/tags-and-classification.md,
catalogs/tag-catalog.md, and
systems/state-axes-and-thresholds.md.
Inbound links from examples/valenar/docs/README.md were added in a
single pass.
Wave D-Journal Readback Drift
Wave D's Journal owner-doc pass now anchors durable narrative readback in
gd-journal.md and sharpens the ownership split with
gd-current-plan.md,
gd-territory-dossier.md,
gd-objectives-screen.md,
gd-objectives-clues-missions.md,
gd-quest-and-lore-design.md,
gd-canon.md, and gd-glossary.md.
The accepted Journal code slice now ships the baseline runtime/client alignment
that this owner-doc pass was pointing at: a dedicated Journal
query/version/client path exists, Journal-class narrative memory no longer
depends on a raw flat log surface, and Chronicle remains the separate
combat-only chronology lane. The remaining drift is narrower and stays below the
full contract in the following deferred areas:
-
Journal target vs raw-log surfaces — baseline implemented; single-authored Journal retained.
gd-journal.mddefines Journal prose as the only authored narrative lane. The dedicated Journal path now owns Journal-class narrative memory, so raw-log or event-log wording is no longer the target surface. What remains deferred is richer structure, annotation, and linking around that single surface, not a second prose lane. -
Journal vs Chronicle separation — baseline implemented.
gd-journal.md,gd-canon.md, andgd-quest-and-lore-design.mdkeep Journal for durable day-based narrative memory and Chronicle for combat chronology only. That boundary is now present in the accepted runtime/client slice. Remaining follow-through is richer cross-surface context, not any merger of Chronicle back into Journal. -
Annotations and player notes.
gd-journal.mddefines annotation layering as part of the target contract, but player-authored notes and richer annotation affordance remain deferred. -
Deeper Current Plan linking.
gd-current-plan.mdandgd-journal.mddescribe a tighter Journal-to-plan readback loop than the accepted baseline currently ships. Deeper Current Plan linking remains deferred. -
Richer site / lore-artefact / faction metadata.
gd-journal.mdallows broader metadata and link depth than the accepted baseline currently exposes. Richer site, lore-artefact, and faction metadata remain deferred. -
Core / camp / settlement / realm progression wording — shipped; no longer a broad deferred cleanup slice. The accepted runtime/client slice now separates these states explicitly: Core establishment creates the anchor and nearby reveal only; it does not create the first settlement or a Realm-birth moment. The first settlement is a later camp-gated step at the established Core location, and settlement, realm/governance, and construction surfaces stay locked until that first settlement exists.
gd-core.md,gd-canon.md, andgd-glossary.mdremain correct that the Core is distinct from settlement or realm birth. The residual in this area is no longer broad wording cleanup; only genuine Journal follow-through or any truly still-open Journal-only raw-log phrasing remains deferred.
The remaining Journal follow-through is tracked in
pr-wave-roadmap.md. Wave J should now be treated as a
follow-through wave for these deferred Journal items, not as first delivery of
the dedicated Journal path or the Journal/Chronicle split, and not as the owner
of the already-shipped Core -> camp-gated first-settlement ->
settlement-gated realm/governance/construction wording slice.
Rollout-sequencing decisions live in pr-open-questions.md.
Wave D-Story-Authoring Pipeline Follow-Through
This follow-through wave did not change lore truth, design truth, runtime
surfaces, or story prose. It aligned docs/process surfaces around the already
committed story layer from
ad-0003-story-content-layer-and-agent-audit.md.
-
examples/valenar/docs/implementation/pr-llm-story-authoring-pipeline.md— new thin process doc that points local LLM agents to the committed story README, entry template, indexes, and ADR instead of re-embedding those rules; records theAGENTS.md/CLAUDE.mdvs skills vs subagents split; marks story-specific skills and story-specific subagent files as future required rather than currently committed; and records the read-only auditor policy plus the current manual verification commands. -
examples/valenar/docs/README.md— added a Story section linking the story README, entry template, all five indexes, and the new pipeline doc; also added the pipeline doc to the implementation-doc index so readers can reach the process surface from the main docs hub.
pr-open-questions.md remained unchanged because this follow-through wave did
not surface a new decision that needs user input or a separate ADR. The lore
prefix convention file also remained unchanged because ADR 0003 already
established that the story layer sits outside the lore-tree prefix scheme.
Future required state remains deferred: dedicated story-specific skills, story-specific subagent files, and dedicated validators are not yet committed. This subsection records the governance scaffold so later waves can add those assets without collapsing the story/non-canon boundary.
Wave Q — Dynamic Quest Pressure and Cross-Act Lane Architecture
Status: SHIPPED (docs-only).
Wave Q shipped the docs-only contract for state-driven quest pressure
and the seven cross-act Quest Thread lanes that feed the Saga Arc. The
four user decisions Q1–Q4 are formalized in
ad-0006-dynamic-quest-pressure-and-cross-act-lane-decisions.md.
The runtime contract for the DynamicQuestPressureGenerator is the
binding generation surface; runtime implementation is deferred to
Waves QP / QL / QF / QR planned in
pr-wave-roadmap.md.
Wave Q changes to the Valenar docs tree:
- Created
../systems/gd-dynamic-quest-pressure-model.mdas the planning-layer generation contract. The five Generator Contract Rules (causal source fact, player-actionable contract, consequence-if-ignored, consequence-if-resolved, Journal readback hook) are normative for every generated planning-layer artifact. The Feature-Transition Trigger Table and the First Proof Slice are the binding runtime targets for Wave QP and Wave QF. - Created 7 cross-act Quest Thread lane owner docs under
examples/valenar/docs/quest-threads/: Core/Truth, Survival/Settlement, Pressure/Corruption, People/Retinue, Faction/Polity, Rune/Crafting/True Harm, Reclamation/Crown. Each carriesact_scope: cross-actper the Q3 decision. - Patched the Quest Thread taxonomy line in
../systems/gd-quest-and-lore-design.mdto acknowledge that some campaign-spanning lanes (Core/Truth, Reclamation/Crown) run the full Saga Arc, without promoting them to a new vocabulary tier. - Removed the
Interactingstate from the 10-state Feature ladder in../generation/gd-feature-generation-contract.mdand from the matching ladder in../generation/gd-territory-generation-contract.md. Both docs now carry the 9-state ladder that matches the committed runtimeFeaturePlacementTypes.csenum. - Closed the
Interactingdrift note in../systems/gd-state-axes-and-thresholds.mdas "Not adopted." - Added Quest Hooks sections to
../systems/gd-world-pressure-nexus.md,../systems/gd-corruption-reclamation.md,../systems/gd-fronts.md, and../systems/gd-operations.mdenumerating which world-state facts the generator binds to. - Added Dynamic Objective Sources and Dynamic Pressure Ranking sections
to
../systems/gd-objectives-clues-missions.mdand../ux/gd-current-plan.mdsurfacing the generator-driven artifact contract. - Extended the Journal
Entry Classesenumeration in../ux/gd-journal.mdwith a paragraph describing dynamic-event readback entries; no new Journal lane was introduced. - Added two bullets to the Planning And Behavior Canon section of
../gd-canon.mdrecording the structural decisions (lane model, failure-forward rule). No competing player premise was authored; the../README.mdpremise remains the sole player-fantasy surface per the Q2 decision.
Wave Q did not touch any .secs, Generated/, Host/, Server/,
Client/, src/SECS.*, or tests/ file. Runtime implementation is
deferred to Waves QP, QL, QF, and QR.
SECS Design Docs
Wave D-Behavior Vocabulary
docs/design/behavior-vocabulary.md — the Wave 3 cleanup note was
inaccurate: it claimed Wave 3 had removed the Valenar player-doc
carve-out for the deprecated capitalized behavior-noun and
planning-noun, when the actual doc cleanup happened in Wave D. Wave
D updated that line to reference Wave D and to enumerate the
player-facing Valenar docs cleaned by this wave.
The Group A allowlist section was extended with a normative bullet
clarifying that Routine Activity and Composite Activity are
planning-layer sub-forms of activity — not SECS keywords, not
runtime nouns, and not separate behavior kinds. Routine Activity
describes a reusable composed pattern; Composite Activity describes a
one-time composed approach for a mission or complex operation. Both
lower to sequences of atomic activity queue entries at execution
time.
Content/
Wave S
- 13 .secs system/event files: bare slot syntax replaced with assignment
form (
phase = Phases.X;,frequency = Cadence.Y;). The bare form (phase X;,frequency Y;) was an early prototype convention; the assignment form is canonical per the SECS design docs and matches what the future compiler will emit. - 6 .secs files: bare TemplateId strings (
TemplateId.Create("Name")) replaced with canonical colon-slash format (TemplateId.Create("valenar:template/resource/name")). The bare form was a pre-Wave-5 convention; canonical ids are required perdocs/design/01-world-shape.md § Canonical id string formatand enforced by the CI guardscripts/check-secs-source-contract.sh. - 18+ .secs files: comment hygiene pass — removed Wave labels,
v1/v2version tags, temporary-output status adjectives, and future-compiler commentary from live source, per.claude/rules/secs-source-hygiene.md. Displaced historical context is recorded here and inpr-open-questions.md. map_generation.secs: removed the barefrequency once;slot, addedphase = Phases.Production;in assignment form. One-shot cadence is deferred to a future compiler keyword; the file records the Production phase commit without a frequency slot until that keyword lands.
Generated/
Wave G
- Historical checked-in hash table: added canonical
_Templatehash constants for 5 resources (Iron, Coal, Copper, ManaCrystal, DragonBone) and 4 recipes (WheatFarmRecipe, LumberRecipe, IronMineRecipe, CoalMineRecipe, CopperMineRecipe). Added FNV provenance comments to Wheat and WheatFarmRecipe. Replaced stale Wave-5/5b inline comments with current canonical-format descriptions per the Wave-5b dual-use naming convention. - Template files: updated
Idreferences from bare-name or unsuffixed constants to_Templatehash constants (Iron, Coal, Copper, ManaCrystal, DragonBone, LumberRecipe, IronMineRecipe, CoalMineRecipe, CopperMineRecipe). - Building templates: updated
MineandLumberyardActiveRecipeIdfields from bare-name template ids to_Templatehash constants. - Historical checked-in module: added
RegisterTemplateIdentifiercalls for canonical ids (valenar:template/resource/iron, etc.) replacing bare-name registrations for the 5 resources and 4 recipes that now use_Templatehashes. GeneratedProvenanceTests: added 9 canonical-id overrides for_Templatehashes (Iron_Template, Coal_Template, Copper_Template, ManaCrystal_Template, DragonBone_Template, LumberRecipe_Template, IronMineRecipe_Template, CoalMineRecipe_Template, CopperMineRecipe_Template). FixedBuildingProductionSystemTestsreference fromH.IrontoH.Iron_Template.
Host/
Core Grounds — Runtime String Drift At GameRuntime.cs:356
The runtime journal string "The Core is established here and already anchors the first settlement." at examples/valenar/Host/GameRuntime.cs:356
conflates the Core layer (MC's personal anchor at the Nexus/Wardheart) with
the Settlement layer (the population-bearing layer that begins at the first
Outpost in Act 2). The docs commit Core and Settlement as distinct layers
and commit Core Grounds as the preferred physical-area term for the Core's
anchor compound; the runtime string predates that wording and is now
player-visible drift.
- Drift shape: runtime string lags the committed Core-vs-Settlement
scale boundary recorded in
gd-canon.md"Core Distinctions",gd-core.md, andgd-glossary.md"Core" entry. The string implies Core establishment also births the Settlement, which the docs explicitly reject. - Scope of fix: rewrite the journal string so Core establishment does
not imply Settlement birth. Candidate wording such as
"The Core is established here. The Settlement layer remains a separate Act 2 step."is illustrative; the runtime wave will finalize the exact string when it ships. - Wave assignment: out of scope for the Core Grounds docs wave (this
task was docs + .secs comment only). Belongs to a future runtime / Host
wave or to
Wave L(Host and Server vocabulary audit) perpr-wave-roadmap.md. Status: OPEN.
Server/
(deferred to Wave L)
Client/
(deferred to Wave Cl)
src/SECS.*
(deferred to Wave S)
tests/
Wave T
Wave T is the additive cross-cutting audit that combines (a) the original
pr-wave-roadmap.md § Wave T charter — audit
tests/**/*.cs and scripts/check-behavior-vocabulary.sh for live
deprecated-vocabulary tokens — with (b) the CI / test / validation
consolidation slice that fell out of the Activity Detail / Nested Surface
Alignment task. Both halves are docs-only edits to this audit doc and to
pr-wave-roadmap.md; Wave T does not edit test
code, scripts, baselines, workflows, or .secs content.
Canonical Validation Command Set
The following commands, in the order shown, are the canonical validation surface a verifier or contributor should run after any Activity Detail, nested surface, founding step, or behavior-vocabulary touching change. Wave T did not introduce or modify any of these commands; this subsection records the ordered set so future waves do not re-derive it from scratch.
dotnet build SECS.slndotnet test tests/SECS.Engine.Tests/SECS.Engine.Tests.csprojdotnet test tests/Valenar.Host.Tests/Valenar.Host.Tests.csprojdotnet test tests/Valenar.Server.Tests/Valenar.Server.Tests.csprojcd examples/valenar/Client && npx tsc --noEmitbash scripts/check-behavior-vocabulary.sh --checkbash scripts/check-readonly-boundary.sh --checkbash scripts/check-secs-source-contract.sh --checkbash scripts/check-tag-contract.sh --checkbash scripts/check-save-load-contract.sh --checkbash scripts/check-activity-provenance-contract.shbash scripts/check-valenar-story-forbidden-terms.shbash scripts/validate-valenar-story-docs.shpython3 tests/valenar_story_audit/test_validate_story_docs.pygit status --porcelain(no unintended modifications)
The Python story audit at step 14 is included per the orchestrator-committed
Q4 decision: it is a canonical validator that should run alongside the C#
test projects and the shell guard scripts, not as an isolated audit. It is
not yet wired into a top-level dotnet test umbrella because it is a
non-.NET runner; Wave T does not introduce that wiring.
Wave T — Known Pre-Existing Test State
The Wave T explorer's brief originally framed
tests/Valenar.Host.Tests/GeneratedProvenanceTests.cs:1773
GeneratedTemplateFieldAssignmentsMirrorSecsTemplateBodies as a
pre-existing failure caused by a mismatch between
examples/valenar/Generated/Templates/Resources/Mine.cs /
Lumberyard.cs field assignment rows and the corresponding
examples/valenar/Content/.../mine.secs / lumberyard.secs field
bodies. Wave T re-ran
dotnet test tests/Valenar.Host.Tests/Valenar.Host.Tests.csproj at the
working-tree state Wave T inherited and observed all 219 tests passing,
including GeneratedTemplateFieldAssignmentsMirrorSecsTemplateBodies.
The drift surface the explorer flagged either:
- has already been resolved by an intervening commit between the explorer's snapshot and the implementer's snapshot, or
- was a false positive in the explorer's grep-based inference (the explorer did not actually run the test before writing the brief).
Wave T does not invent a .secs fix, rewrite Generated/ content, or
edit the test. If a future regression re-introduces the same shape, the
correct fix is to align the .secs source field declarations with the
compiler-owned C# field assignment rows emitted under
examples/valenar-v2/Generated/obj/**/SecsGenerated/*.g.cs. For Valenar
v2, .secs source plus compiler-owned SecsGenerated output is the
authoritative generated shape; checked-in examples/valenar-v2/Generated/
contains only Valenar.V2.Generated.csproj and host-owned
ValenarHostIds.cs. Do not fabricate .secs content to satisfy the test.
Wave T — blockedReason Vocabulary Clarification
The strings 'Loading founding state.' at
examples/valenar/Client/src/components/modes/territory/stage0TerritoryModel.ts:115
and :123 are NOT fabricated activity-availability blockedReason
values. They are client-owned TerritoryFoundingStepSnapshot.blockedReason
loading-state placeholders for a different snapshot type
(TerritoryFoundingStepSnapshot, not ActivityAvailabilitySnapshot or
QueueItemSnapshot). They exist precisely because the founding step
read-model carries its own blockedReason field that the React surface
must populate before the SignalR snapshot arrives. Any future grep guard
targeting fabricated activity-availability blockedReason fallbacks must
exclude these two lines via a type-aware allow-list or a precise regex
keyed on TerritoryFoundingStepSnapshot rather than on the literal string
Loading founding state.. Wave T does not add such a guard.
scripts/
Wave T
Wave T — Behavior-Vocabulary Baseline State
scripts/check-behavior-vocabulary.sh --check reports OK at 158 hits
against the recorded floor of 158 in scripts/.behavior-vocabulary-baseline.
The script exits 0; the target floor described by
.claude/rules/behavior-vocabulary.md
"Target end state is 0 hits" remains aspirational.
The pre-Wave-T history of the baseline file:
- The historical floor was 153 (set before the engine refactor commit
e26c541"engine: replace mutable Activity/Policy contexts with structural read-only types"). - Commit
e26c541bumped the floor to 158 in the same change that introducedActivityQueryContext,EventQueryContext,PolicyQueryContext,CandidateBuilderContext,ReadOnlyTickContext, andIReadOnlySlotStore. The +5 absorbed by that rebaseline is pre-Wave-T drift unrelated to any Wave T edit.
Wave T does NOT rebaseline. Per the orchestrator-committed Wave T scope
and .claude/rules/behavior-vocabulary.md "each cleanup wave should
lower the recorded baseline rather than letting it drift upward", the
correct fix is a downstream cleanup wave (Wave Z per
pr-wave-roadmap.md § Wave Z) that brings the
actual hit count down toward 0 and then re-runs --baseline against the
lower floor. Until that wave runs, the 158 floor stays.
Wave T — Excess Hits Identified (158 - 153 = 5)
The +5 drift between the historical 153 floor and the current 158 floor
breaks down by guard-script group as follows. Wave T captured these via
bash scripts/check-behavior-vocabulary.sh --check (against a
temporarily-zeroed baseline) and via worktree comparison against the
pre-e26c541 commit e022571. To avoid Wave T's audit table itself
adding hits to the guard (the table would otherwise quote each banned
token literally), the table below describes each hit by file path,
guard group letter, and structural shape — the verbatim hit strings are
visible in the script's --check output and are intentionally NOT
re-quoted here.
| File:line | Token group | Structural shape | Context |
|---|---|---|---|
.claude/rules/secs-source-hygiene.md:22 | A (deprecated behavior-noun family — see .claude/rules/behavior-vocabulary.md § Removed) | Negative-context table row enumerating forbidden old-keyword compatibility notes | The rule cites the banned token literally in order to forbid it. |
.claude/rules/secs-source-hygiene.md:22 | B (deprecated planning-noun family — same § Removed) | Same row, separately matched by the Group B regex on the literal banned planning-noun | Hit attributable to the second banned token sitting on the same line. |
.claude/rules/secs-source-hygiene.md:59 | A (deprecated behavior-noun family) | Inline contrast wording naming the banned behavior token to demonstrate which forms are illegal in live source | Negative-context normative example. |
.claude/rules/secs-source-hygiene.md:60 | B (deprecated planning-noun family) | Inline contrast wording naming the banned planning token to demonstrate which forms are illegal | Negative-context normative example, paired with the line above. |
examples/valenar/Generated/Activities/Character/Site/CharacterSiteActivities.cs:640 | D (content-row identifier in the Activity_<ContentName> shape — see .claude/rules/behavior-vocabulary.md § Generic-mechanic vs content-row) | Generated registration row for a one-off activity identifier emitted during a recent rename pass | Structurally similar to the existing Group D content-row family that the cleanup wave must either allowlist (if it becomes a generic-mechanic family) or fold into a typed-args generic-mechanic activity. |
The first four hits are structurally one cluster: a single
.claude/rules/secs-source-hygiene.md edit added two table cells and
one inline paragraph that quote the two banned deprecated tokens in
negative context. The fifth hit is the residual from a Group D rename
pass (the rename ended +5 new identifier sites and -6 removed, net -1
inside Group D but the table only enumerates one representative new
site to give the cleanup wave a concrete anchor).
Wave T — Suggested Fix Shape For The Downstream Cleanup Wave
Wave T does not fix the excess; documenting the actionable shape is the
deliverable. The cleanup wave (Wave Z per
pr-wave-roadmap.md § Wave Z) should:
- Either extend
GLOBAL_EXEMPT_FILESinscripts/check-behavior-vocabulary.shto include.claude/rules/secs-source-hygiene.md(matching the existing exemption for.claude/rules/behavior-vocabulary.mdanddocs/design/behavior-vocabulary.md, which are likewise normative-rule docs that necessarily quote the deny list), OR rewrite the four hygiene-rule cells/lines to describe the banned vocabulary structurally without naming the tokens (e.g. "deprecated planning noun" / "deprecated behavior noun" rather than the literal forbidden words). Wave T's recommendation is the exemption: the rule's stated purpose is to forbid the tokens, so it must be allowed to name them. - For the Group D hit in
CharacterSiteActivities.cs:640, evaluate whether the new one-off identifier should be allowlisted (if it has become a generic-mechanic family) per the.claude/rules/behavior-vocabulary.md § "CI guard"allowlist extension procedure, or whether it stays a one-off activity that simply contributes to the baseline floor until a future content refactor folds it into a typed-args generic-mechanic activity. - For this audit doc itself: extend
GLOBAL_EXEMPT_FILESto includeexamples/valenar/docs/implementation/pr-code-sync-audit.mdso that future drift audits can quote banned-token shapes verbatim without adding to the floor — mirroring the existing exemption fordocs/design/behavior-vocabulary.md. Wave T avoided this by writing the audit table structurally (see the table above), but a sibling exemption would let later audits be more concrete. - After steps 1, 2, and 3 land, re-run
bash scripts/check-behavior-vocabulary.sh --baselineagainst the newly-clean tree to lock the lower floor. Per.claude/rules/behavior-vocabulary.md, the cleanup-wave baseline re-run is the only legitimate path that lowers the floor.
Wave T — Pre-Existing CI Workflow Out Of Scope
.github/workflows/wave-t-validation.yml exists in the working tree at
Wave T start as pre-session drift. Per the orchestrator-committed Wave T
scope guidance, Wave T does not edit, validate, dispatch, or remove that
workflow. The validator and any future cleanup wave should treat the
workflow file as inherited surface rather than a Wave T artifact.
Wave T — GROUP_E_FILES / scan_exact_files Question
The original pr-wave-roadmap.md § Wave T § Open Questions
asked whether the GROUP_E_FILES / scan_exact_files() expansion
attempted in Wave D iter-1 warrants a separate ADR-gated governance wave.
Wave T's audit finding is: defer. The current Group E (stat -> channel
migration) scan in check-behavior-vocabulary.sh uses
gather_stat_channel_doc_files and gather_stat_channel_code_files,
which are bespoke gatherers for that specific migration. They are
zero-tolerance, currently report 0 hits, and serve their purpose. No
generalized GROUP_E_FILES mechanism is required today; a future
migration that needs the same shape can copy the pattern.
Activity Detail / Nested Surface Alignment
This top-level section records the M/B/C/T/D-Detail wave outcomes for the
Activity Detail / Nested Surface Alignment task. The four task waves
disambiguate from the unrelated story-layer waves of similar letter
names by carrying the (Activity Detail) task suffix in their roadmap
entries. Wave T's CI/validation consolidation subsections continue to
live under ## tests/ and ## scripts/; this section cross-references
that work without duplicating it.
Wave M (Activity Detail) — UX Owner Docs
Status: SHIPPED.
Wave M (Activity Detail) shipped the 7 UX owner docs that anchor the Activity Detail / Nested Surface design contract:
gd-shell-screen-model.mdgd-queue-screen.mdgd-territory-dossier.mdgd-current-plan.mdgd-objectives-screen.mdgd-journal.mdgd-activity-catalog.md
Each doc carries an ## Implementation status section using the
pr-status-and-sync-policy.md
vocabulary. Wave M (Activity Detail) deliberately did not lock
backend DTO field names in these docs; the abstract phrasing
("the parent-run / child-run reference Wave B (Activity Detail) exposes
— Wave B-owned, pending sync") was intentional because Wave B
(Activity Detail) had not yet committed names at the time of authoring.
Remaining drift (deferred): all 7 owner docs still use the abstract
phrasing for parent-run / child-run / blocked-reason references. Now
that Wave B (Activity Detail) has committed concrete names
(ActivityRunSnapshot.ParentRunId, ActivityRunSnapshot.ChildRunId,
QueueItemSnapshot.BlockedReason, TypeScript parentRunId, childRunId,
blockedReason), a field-name sync pass is needed. Wave D-Detail
deferred this pass to a dedicated Wave B-sync (Activity Detail) entry
in pr-wave-roadmap.md rather than touching
Wave M's territory in a Wave D-Detail docs-only scope. The open question
is recorded in
pr-open-questions.md § Wave B Field-Name Sync in gd-* Docs.
Wave B (Activity Detail) — Backend Fields, Scout Retirement, Demo Mods, Tests
Status: SHIPPED (engine wave committed, field names committed, tests at 219/219 PASS).
Wave B (Activity Detail) shipped engine parent/child run linkage, server-truthful blocked-reason projection, Scout lead retirement, demo mod retargeting, and two new test files:
ActivityRunSnapshotrecord atServer/Services/GameSnapshot.cs:121–122addedParentRunId : long?andChildRunId : long?. SHIPPED.QueueItemSnapshotrecord atGameSnapshot.cs:224addedBlockedReason : string?. SHIPPED.PlayerActivityQueueItemReadModelatHost/ReadModels/PlayerActivityQueueReadModel.cs:57addedBlockedReason : string?. SHIPPED.- TypeScript types at
Client/src/api/types.ts:663–664addedparentRunId?: number | nullandchildRunId?: number | nullonActivityRunSnapshot. SHIPPED. - ScoutApproach activity WireId
"scout-approach"atGenerated/Activities/Character/Site/CharacterSiteActivities.cs:640is committed and live; the legacy Scout lead identifier is retired. SHIPPED. - Demo mods retargeted:
Generated/Mods/CompatScoutActivityMod.csandExtendedScoutActivityMod.csboth target the ScoutApproach activity hash constant in theH.Activity_<ContentName>shape (seeGenerated/Activities/Character/Site/CharacterSiteActivities.cs:640for the canonical declaration; the literal hash identifier is the same Group D content-row token Wave T described structurally to avoid adding to the behavior-vocabulary baseline). SHIPPED. - Engine commit
e26c541introducedActivityRun.Origin,ActivityRun.ParentRunId,ActivityRun.ChildRunId, andActivityExecutor.StartAt(ActivityRequest, TickContext, int). The "PASS-conditional on engine-wave commit" gate that Wave B (Activity Detail) carried at brief time is now resolved; the engine APIs are in HEAD. - Two new test files cover the projected fields:
tests/Valenar.Host.Tests/ActivityRunNestingProjectionTests.cs(2 tests covering host-side parent/child null projection and the host reverse-lookup round trip) andtests/Valenar.Host.Tests/QueueProjectionBlockedReasonTests.cs(2 tests covering null and non-nullBlockedReasonon queue rows). Both pass as part of the 219/219 PASS recorded by Wave T.
The locked Wave B (Activity Detail) field-name set is exactly
parentRunId, childRunId, and blockedReason; no other fields were
exposed by this wave.
Wave C (Activity Detail) — Shared Activity Detail Host, Openers, Client Cleanup
Status: SHIPPED with 2 openers deferred.
Wave C (Activity Detail) shipped the shared Activity Detail host component, the new mode, the depth/cycle guards, and the wired openers:
-
New
activity-detail/directory atClient/src/components/activity-detail/carryingActivityDetailHost.tsx,ActivityDetailHost.module.css,activityDetailRequest.ts, anduseActivityDetailViewModel.ts. SHIPPED. -
Mode
mc/activity-detailwithhiddenFromRail: trueatClient/src/components/shell/modes.tsx:268,272. SHIPPED. -
hiddenFromRail?: booleanfield onModeDefatClient/src/components/shell/modeDef.ts:118. SHIPPED. -
Depth guard
ACTIVITY_DETAIL_MAX_DEPTH = 16atClient/src/components/activity-detail/activityDetailRequest.ts:84. SHIPPED. -
7 logical openers across 9 caller sites:
- Activities (catalog) —
ActivitiesSummary.tsx, source'catalog'. - Activities (here/dossier) —
ActivitiesSummary.tsx, source'dossier'. - Queue / QueueSummary —
QueueSummary.tsx, source'queue'. - Queue / QueueNavigator —
QueueNavigator.tsx, source'queue'. - Queue / QueueExpansion —
QueueExpansion.tsx, source'queue'. - Territory Dossier rows —
Stage0ActivityRows.tsx, source'dossier'. - BottomQueueSlots —
BottomQueueSlots.tsx, source'bottom-queue-slots'. - Journal entries —
MissionsExpansion.tsx, source'journal'. - Objectives entries —
MissionsExpansion.tsx, source'objectives'.
The brief framed this as "7 openers SHIPPED" by collapsing ActivitiesSummary's two source variants into a single "Activities" opener and Queue's three caller sites into a single "Queue" opener, yielding 7 logical openers. The audit records both counts to avoid ambiguity in future waves.
- Activities (catalog) —
-
Stage0ActivityPresentation.tsfallback cleanup at lines 33, 72, 98. The?? undefinedpatterns are legitimate display deferrals (undefinedhides the row) and not fabricated engine-data fallbacks. Cross-reference: Wave T —blockedReasonVocabulary Clarification under## tests/for the related distinction between activity availability andTerritoryFoundingStepSnapshot.blockedReasonloading- state strings. SHIPPED. -
FocusedQueueItemreplaced — zero references remain in the client source tree. SHIPPED. -
ActivitiesExpansion.{tsx,module.css}deleted — only a comment reference remains inActivityDetailHost.module.css:4. SHIPPED. -
queueStore.mapQueueItematClient/src/stores/queueStore.ts:197propagatesblockedReason. SHIPPED.
Deferred openers (2):
- TerritoryContextPanel name tap (
source: 'context-panel'). TheActivityDetailOpenerSourceunion atClient/src/components/activity-detail/activityDetailRequest.ts:29already declares the'context-panel'source value, but noTerritoryContextPanelcaller invokesopen('left', ACTIVITY_DETAIL_MODE_ID, ...). Wave D-Detail does not ship the wiring; the deferral is tracked inpr-open-questions.md § Activity Detail — Deferred Opener Decisionsand asWave TerritoryContextPanel (Activity Detail)inpr-wave-roadmap.md. - Current Plan / Situations opener (
source: 'plan'). The same union at line 27 already declares the'plan'source value, but no plan/situations surface caller invokes the opener. Wave D-Detail does not ship the wiring; the deferral is tracked in the samepr-open-questions.mdsection and asWave Plan (Activity Detail)inpr-wave-roadmap.md.
Wave T (Activity Detail) — CI / Validation Consolidation (cross-reference)
Wave T's Activity Detail-additive scope (canonical 15-step validation
command list, pre-existing 153 -> 158 baseline drift documentation,
blockedReason vocabulary clarification, and the 219/219 host-test
state) already lives under ## tests/ § Wave T and
## scripts/ § Wave T. The Wave T entry is recorded once
there and not duplicated here. Status: SHIPPED (docs-only).
Pre-Existing Drift Resolution Summary
Two pre-existing drift items called out by the Wave T audit had already resolved themselves at the current tree state Wave D-Detail inherited:
GeneratedTemplateFieldAssignmentsMirrorSecsTemplateBodiestest state: documented in Wave T as a 218/219 host-test snapshot mismatch at the explorer's grep-snapshot moment; resolved at the implementer's snapshot. The current run is 219/219 PASS. See## tests/ § Wave T § Wave T — Known Pre-Existing Test State.- Behavior-vocabulary baseline drift between the historical 153 floor
and the 158 floor introduced by engine commit
e26c541: documented by Wave T; current state is 158/158 OK with the baseline file at 158. Wave Z is the future cleanup wave that lowers the floor toward 0. See## scripts/ § Wave T § Wave T — Behavior-Vocabulary Baseline State.
Wave D (Activity Detail) — Implementation / Process Docs / Backlog Alignment
Status: SHIPPED (docs-only).
Wave D-Detail aligned the implementation / process docs and the backlog to record the M/B/C/T (Activity Detail) outcomes:
- This section in
pr-code-sync-audit.mdadded. - 5 new wave entries added to
pr-wave-roadmap.md:Wave M (Activity Detail),Wave B (Activity Detail),Wave C (Activity Detail),Wave TerritoryContextPanel (Activity Detail),Wave Plan (Activity Detail), plus theWave B-sync (Activity Detail)field-name sync entry andWave Vitesttest-runner setup entry. - 3 new sections added to
pr-open-questions.md: the deferred opener decisions, the Wave B field-name sync question, and the Vitest / JS test setup framework choice question. pr-roadmap.mdupdated with the shared Activity Detail host runtime surface and the field-name sync near-term consumer.
Wave D-Detail did not touch the 7 gd-* owner docs; the field-name
sync work is deferred per the open question and the scheduled
Wave B-sync (Activity Detail) entry.
Open Drift Items
The following drift items are surfaced by Wave D for tracking but are not closed by Wave D. They live here as anchors and are cross-linked from the relevant design docs.
-
Territory knowledge axis: prototype vs target ladder. CLOSED by Wave R-1 (2026-05-10). The
int Exploredbinary onTerritoryDatawas replaced by the eight-stepTerritoryKnowledgeStateenum (Unknown -> Sighted -> Scouted -> Surveyed -> Secured -> Claimed -> Cleansed -> Developed) plus a forward-compatint KnowledgeIntensitynuance field. The enum lives inexamples/valenar/Generated/Territories/TerritoryKnowledgeTypes.cs; the scope-field row pair is registered throughH.KnowledgeState/H.KnowledgeIntensityin the compiler-emitted hash table plus the compiler-emitted declaration rows. Numeric intensity thresholds remain TBD persystems/state-axes-and-thresholds.md"Territory Knowledge Axis". -
Site numeric intensity field. CLOSED by Wave R-2 (2026-05-10).
int StateIntensitywas added toSiteDatawith a verified FNV-1a-64 hash constant (H.StateIntensity = 0x2BD07323BBB9FC07UL), aScopeFieldDeclarationrow inGenerated/Declarations.cs, and read/write paths through the Site branch ofHostBridge.Content/territories/sites/scopes.secsis in sync. The field tracks intensity on theState(progress ladder) axis, not onDiscoveryState. Default 0; numeric thresholds within each ladder label remain TBD per a future balance wave. Wire projection (SiteSnapshot) is deferred to a future Server wave. Resolved by: Wave R-2. Status: CLOSED. -
Feature numeric intensity field. CLOSED for the field foundation by Wave R-3 (2026-05-10).
int DiscoveryIntensitywas added toFeatureDatawith a verified FNV-1a-64 hash constant (H.DiscoveryIntensity = 0x6B8E15B1072C893AUL), aScopeFieldDeclarationrow inGenerated/Declarations.cs, and read/write paths through the Feature branch ofHostBridge.Content/territories/features/scopes.secsis in sync. The field tracks intensity on theDiscoveryStateladder. Default 0; bare integer per the unified convention established by R-1'sKnowledgeIntensityand R-2'sStateIntensity. Wire projection (FeatureSnapshot.discoveryIntensity) is deferred to a future Server wave, mirroring R-2'sSiteSnapshotdeferral. Resolved by: Wave R-3. Status: CLOSED for the field foundation. -
Feature numeric intensity thresholds. The 0–100 intensity ranges per
FeatureDiscoveryStatelabel are design intent but not committed values per the authority doc's explicit balance-pass deferral. Wave R-3 shipped the field foundation only (int DiscoveryIntensity); threshold commitments remain open. Closing this drift requires a future balance-pass wave to commit per-label intensity ranges. Status: OPEN for thresholds. -
Feature placement formula and ownership. CLOSED by Wave R-4 (2026-05-10) for the algorithm rewrite and the host-system retirement. The additive
ScoreCandidate(suitability * 2 - avoidance + noise / 2) was replaced by the multiplicative score formula authored ingd-feature-generation-contract.md"Placement Formula":score = hardGate * suitability * rarityModifier * seededNoise * spacingPenalty * storyBias. Static factors (hardGate, suitability, seededNoise, storyBias = 1.0 stub) are computed byGenerated/Territories/FeaturePlacement/FeaturePlacementQuery.Evaluate; dynamic factors (rarityModifier =clamp(1 - used/budget, 0, 1), spacingPenalty =clamp(distance / minSpacing, 0, 1)) are applied by the newFeaturePlacementSelectorstatic helper at selection time.FeatureFamilywas expanded to 14 values matching the contract's family list; stub families (Water, Food, Forest, Travel, Shelter, Corruption, Nexus) carry no committed templates yet and read-model switches default-case to the Landmark / generic visual until templates land.AvoidanceWeightswas folded intoSuitabilityWeightsas negated entries on every profile so each profile carries one self-consistent weight set;H.AvoidanceWeightswas retired from the hash table and the field row was dropped fromGenerated/Declarations.cs.FeaturePlacementSystemwas deleted and its logic moved to the staticGenerated/Territories/FeaturePlacement/FeaturePlacementSelector.cs, whichMapGenerationSystem.Executecalls afterCreateForcedFeaturesso ordinary Features are placed in the Generated entry-point system, not in a Host-side ITickSystem.TerritoryFactsgained anIsWaterfield (1 = water, 0 = land) so the hardGate factor blocks Land-family Features from spawning on water Territories. Resolved by: Wave R-4. Status: CLOSED for the algorithm and ownership refactor. -
Feature placement balance pass. The
MinScorethresholds on each profile (130–165) were tuned for the additive formula's score distribution. Wave R-4 changed the formula scale to a fixed-point integer in [0, 1000], so the existing thresholds are now permissive rather than restrictive at the static-score gate. Profile budget values (MinPerWorld,MaxPerWorld,DensityDivisor,MinSpacingRank, etc.) are also untuned for the new formula's distribution. Closing this drift requires a future balance-pass wave to recommit threshold values against the multiplicative formula. Status: OPEN for thresholds. -
Feature stub-family templates. Seven of the 14 Feature families expanded by Wave R-4 (Water, Food, Forest, Travel, Shelter, Corruption, Nexus) carry no committed templates today. The Nexus family is occupied semantically by
DormantNexusbut that template remains in the Story family pending the contract's Nexus-promotion decision; the other six families have no templates at all. Closing this drift requires future content waves to author templates per the example list ingd-feature-generation-contract.md"Feature Families". Status: OPEN. -
FeatureSnapshot wire shape. The
FeatureSnapshotprojection surfaced to the React client does not yet expose the placement intensity, score, or family fields beyond what was committed before Wave R-3. Wave R-4 deliberately did not extend the wire surface (parity with R-2 / R-3 deferral). Closing this drift requires a future Server wave. Status: OPEN. -
Planned terrain tags. 19 terrain-derived tags listed in
gd-territory-generation-contract.md"Derived Classes And Tags" are not yet committed toContent/common/tags.secs. Seecatalogs/tag-catalog.md"Planned Tags (Not Yet Committed)" section. -
gd-dynamic-quest-pressure-model.mddoc-runtime gap. Wave Q shipped the docs-only generation contract at../systems/gd-dynamic-quest-pressure-model.mdwith five binding Generator Contract Rules (causal source fact, player-actionable contract, consequence-if-ignored, consequence-if-resolved, Journal readback hook), the Feature-Transition Trigger Table, the Urgency Signal Contract, and the First Proof Slice walkthroughs. NoDynamicQuestPressureGeneratorC# class, no read-model field for source-fact / urgency-rank / lane-name, and no test exists inexamples/valenar/Host/,examples/valenar/Server/,examples/valenar/Client/,examples/valenar/Generated/, ortests/Valenar.Host.Tests/. The contract is binding but no runtime consumes it. Resolved by: Wave QP (generator runtime) + Wave QR (read-model extensions). Status: OPEN. -
Cross-act lane owner docs doc-runtime gap. The 7 lane owner docs under
examples/valenar/docs/quest-threads/(Core/Truth, Survival/Settlement, Pressure/Corruption, People/Retinue, Faction/Polity, Rune/Crafting/True Harm, Reclamation/Crown) exist and carry lane-scope metadata. No Quest Thread runtime object, no lane-key enum, and no lane-association field exist in any C# type underexamples/valenar/Host/,examples/valenar/Server/,examples/valenar/Client/, orexamples/valenar/Generated/. The authored lanes are binding for content authoring (Wave QL) but no runtime artifact references them today. Resolved by: Wave QP (generator emits lane-declared artifacts) + Wave QL (mission ladders authored per lane). Status: OPEN. -
Interactingremoval — CLOSED. TheInteractingstate was removed from both../generation/gd-feature-generation-contract.md(10→9 state ladder) and../generation/gd-territory-generation-contract.mdby Wave Q. The runtime 9-state enum inexamples/valenar/Generated/Territories/FeaturePlacement/FeaturePlacementTypes.cswas not changed; the doc ladder now matches the committed runtime enum. The drift note at../systems/gd-state-axes-and-thresholds.mdline 96 records the resolution. NoInteractingalias, default, or transitional synonym is preserved in any live doc per the no-fallback redesign propagation rule. Resolved by: Wave Q. Status: CLOSED.
Pending Runtime Backing — Foundation Hardening
The following contract surfaces were authored as design / ADR commitments
by the Foundation Hardening (Waves 2a / 2b / 3a / 3b) but have
no live runtime backing today. Each row is a contract-only runtime-
backing status per
.claude/rules/valenar-contract-backing.md.
The named owner files do NOT yet exist on disk; the next closure wave
column names the Foundation Hardening wave that lands them.
| Contract surface | Authority | Pending runtime owner(s) | Closure wave | Status |
|---|---|---|---|---|
| QuestThread scope + Mission scope + lifecycle channels | gd-quest-thread-and-mission-state-machine.md, ad-0007 | legacy/v1/examples/valenar/Host/Systems/QuestThreadSystem.cs (does not exist), legacy/v1/examples/valenar/Host/Systems/MissionSystem.cs (does not exist), matching Host/Data types | Wave 5a (source / Generated) + Wave 6 (runtime backing) | contract-only |
| ThreatSource scope + FrontCandidate scope + emergence state machine | gd-front-emergence.md, ad-0008 | Host data + Host system for ThreatSource and FrontCandidate (do not exist) | Wave 5a + Wave 6 | contract-only |
| Realm scope + PolityRank channel + ladder | gd-realm-ranks-and-polity.md, ad-0009 | legacy/v1/examples/valenar/Host/Data/RealmData.cs (does not exist), legacy/v1/examples/valenar/Host/Systems/RealmRankSystem.cs (does not exist) | Wave 5a + Wave 6 | contract-only |
| ActState scope + ActProgressionSystem | gd-act-progression.md, ad-0010 | legacy/v1/examples/valenar/Host/Data/ActStateData.cs (does not exist), legacy/v1/examples/valenar/Host/Systems/ActProgressionSystem.cs (does not exist) | Wave 5a + Wave 6 | contract-only |
| ProvinceDefensePlan.PlanState channel | gd-defense-zones.md (PlanState section), Foundation Hardening resolver R4 (2026-05-17) | New PlanState channel added to existing legacy/v1/examples/valenar/Host/Data/ProvinceDefensePlanData.cs (file exists; PlanState channel does not) | Wave 5a + Wave 6 | partial (host data file exists, channel does not) |
MC Conditions / Injuries Modifier templates + apply/tend/clear Activities | gd-character-conditions-and-injuries.md, ad-0012 | Modifier templates plus the apply / tend / clear Condition Activity templates (do not exist); ActivityExecutor extensions | Wave 5a (Modifier + Activity templates) + Wave 6 (execution paths) | contract-only |
| Labor and Capacity Settlement-scope and Province-scope channels | gd-labor-and-capacity.md | Settlement-scope and Province-scope Labor / Capacity channels (do not exist); channel resolution paths through HostBridge | Wave 5a + Wave 6 | contract-only |
| ContactEngagement scope | gd-combat-rules.md (ContactEngagement section) | ContactEngagement host data + scope read/write paths through HostBridge (do not exist) | Wave 5a + Wave 6 | contract-only |
| ValidationReport host type | gd-generation-validation.md | ValidationReport host type populated by the generation pipeline (does not exist) | Wave 5a + Wave 6 | contract-only |
| storyBias placeholder | gd-feature-generation-contract.md, Foundation Hardening resolver R17 (2026-05-17) | FeaturePlacementQuery.cs:190 currently returns => 1.0 as a silent stub. Per R17 this becomes throw new NotImplementedException in Wave 5a, and the authored formula lands in Wave 5a / Wave 6 when source-fact dependencies resolve. | Wave 5a (replace stub with NotImplementedException) + Wave 6 (author formula) | stubbed (illegal silent-default fallback; closing requires the R17 sequence) |