ADR 0013 — Canonical Pattern: Scope with State Channel plus Template Archetypes
Context
The Foundation Hardening's Wave 2b dispatch authored six
resolver-decision ADRs in parallel (R1, R2, R3, R5, R8, R9, recorded
as ad-0007 through ad-0012). Four of those six commit new gameplay
primitives that share an underlying shape:
./ad-0007-quest-thread-and-mission-scope-primitives.md
commits scope QuestThread plus LifecycleState plus
template<QuestThread>;
./ad-0008-pressure-to-front-emergence-scope-state-machine.md
commits scope ThreatSource and scope FrontCandidate plus
Severity and AggregatedSeverity channels (and the existing Front
scope already follows this pattern via its committed FrontStatus
channel);
./ad-0009-realm-scope-and-polity-rank-orthogonality.md
commits scope Realm plus PolityRank channel;
./ad-0010-act-progression-actstate-scope.md
commits scope ActState plus CurrentAct channel.
The pattern is repeated four times in parallel and is the implicit canonical shape for every new persistent gameplay primitive added by Foundation Hardening. Without an explicit pattern ADR, the pattern is discoverable only by reading all four ADRs together and inferring the shared shape. Future Foundation Hardening or post-Hardening waves under deadline pressure are likely to invent a fourth primitive shape (e.g., "state-as-Modifier-flag" or "state-as-host-field-only" or "state-as-tag-set") for the next new gameplay primitive, exactly the drift the no-fallback redesign-propagation rule forbids.
The pattern is workspace-internal Valenar authoring convention over
the existing SECS primitives (scope, channel, template, Modifier per
.claude/rules/secs-concepts.md). It is not a new SECS engine pattern
and does not belong in the workspace-root docs/decisions/ engine
ADR tree per
./ad-0004-lore-adr-folder.md.
Documenting it only as informal guidance in
.claude/rules/valenar-generation.md would not give it the load-bearing
authority it needs to prevent future drift; a rule file is not the
canonical decision record for a pattern this structurally
load-bearing.
Decision
Every new Valenar gameplay primitive added in Foundation Hardening (and post-Hardening waves that introduce a persistent gameplay primitive) uses the following canonical shape:
(a) Scope declaration. A scope X declaration carries the
persistent identity, the binding-propagation root for related scopes
that walk to it, and the row-instance lifecycle. The scope is the
queryable entity for events, Modifier attach / detach, dynamic quest
pressure binding, and Journal readback.
(b) State channel. One or more channels on the scope carry the
current lifecycle position. Names follow the pattern:
LifecycleState, Status, Rank, Phase, Severity, or another
domain-appropriate noun consistent with the existing FrontStatus
and OperationStatus precedent. The state channel uses a typed enum
where the lifecycle has discrete rungs (LifecycleState, PolityRank)
and uses a numeric channel where the lifecycle is continuous
(Severity). The channel is read via the 6-phase channel resolution
pipeline per .claude/rules/secs-concepts.md.
(c) Template archetypes. One or more template<X> archetypes
supply authored content rows: identity, narrative metadata, declared
relationships to other scopes, and the binding rules for how a scope
instance gets created from the archetype. The scope row references
the archetype via a DefinitionTemplateId field or equivalent typed
template id.
The three components together — scope identity, state channel, and template archetype — form the canonical Valenar primitive shape.
Instantiations of the pattern committed by parallel Wave 2b ADRs:
./ad-0007:scope QuestThreadplusLifecycleState(QuestThreadLifecycleState enum) plustemplate<QuestThread>. Alsoscope MissionplusLifecycleState(MissionLifecycleState enum) plustemplate<Mission>. Two pattern instantiations in one ADR../ad-0008:scope ThreatSourceplusSeveritychannel plustemplate<ThreatSource>(the archetype is implicit in the ThreatSource.Kind enum's per-kind authored data; the explicittemplate<ThreatSource>declaration follows the same shape).scope FrontCandidateplusAggregatedSeveritychannel; archetype is implicit at the FrontCandidate layer since FrontCandidates are generated from ThreatSource clusters rather than from an authored catalog. The existingscope Front(already committed in../../systems/gd-fronts.md) follows the pattern viaFrontStatusand the existing Front archetype shape../ad-0009:scope RealmplusPolityRankchannel. Archetype is implicit because Realm is a singleton and its initial state is authored as campaign-start data rather than as a per-instance template../ad-0010:scope ActStateplusCurrentActchannel. Archetype is implicit for the same singleton reason as Realm.
Two parallel Wave 2b ADRs deliberately do NOT instantiate the pattern, and the difference is documented as intentional:
./ad-0012: conditions and injuries are Modifier templates, not scopes. Modifiers are transient effect bundles per.claude/rules/secs-concepts.md; they describe mutable state on named characters that decay, refresh, or clear. The persistent identity is the named character (already a scope) and the condition / injury is a Modifier attached to that scope. This difference is intentional: the pattern committed in this ADR applies to persistent gameplay primitives that need their own identity (QuestThread, Mission, ThreatSource, FrontCandidate, Realm, ActState), not to transient effects attached to an existing identity../ad-0011: placeholder marker conventions are authoring policy, not a primitive shape. The True Harm placeholder convention applies to how deferred names are referenced in prose, header lines, and typed-id sketches; it does not introduce a new gameplay primitive and therefore does not instantiate the scope + state-channel + template-archetype pattern.
Alternatives Considered
Leave the pattern implicit across the four ADRs (no cross-cutting pattern ADR). Rejected because implicit-across-multiple-ADRs patterns cause future drift. Each later wave reading one of the four ADRs in isolation has to re-derive the pattern from a single example. Under deadline pressure, that re-derivation produces parallel shapes (state-as-tag, state-as-host-field, state-as-Modifier- flag) that violate the no-fallback redesign-propagation rule. An explicit pattern ADR turns the convention into a load-bearing authority a verifier can check.
Promote the pattern to a workspace-root ADR under
docs/decisions/. Rejected because the pattern is a Valenar coding
convention over existing SECS primitives, not a SECS engine pattern.
The split between Valenar-local ADRs and workspace-root engine ADRs
is committed at
./ad-0004-lore-adr-folder.md, and
this ADR fits the Valenar-local layer.
Document the pattern only in .claude/rules/valenar-generation.md (a
guidance rule file). Rejected because rule files are not the
canonical decision record for a load-bearing pattern. The four Wave
2b ADRs and any later pattern instantiations need a single citable
ADR to reference; valenar-generation.md may cross-reference this
ADR but does not replace it.
Tenets Applied
- "Future-proofed solutions only." A documented canonical pattern prevents future waves from inventing a fourth primitive shape under deadline pressure.
- "When you patch the same subsystem 3+ times, the original design is wrong" (inverted application). The pattern is repeated four times intentionally; documenting it explicitly is the redesign that prevents the next wave from patching with a fifth ad-hoc shape. Explicit-pattern-ADR is the architectural fix; implicit-pattern is the silent drift.
- "No hacks, no shortcuts, no workarounds." A shortcut here would be to invent a state-as-tag-set fallback the next time a primitive is added; this ADR pre-empts that shortcut by committing the canonical shape.
- "Research before designing." Documented-canonical-pattern records in shipped projects (Unity AddressableAsset pattern doc; Witcher 3 quest pipeline internal authoring conventions; CK3 trait / Modifier / Story cycle authoring conventions in Paradox's internal docs) all elevate repeated authoring patterns to citable authority. This ADR commits Valenar to the same discipline.
Runtime Backing Status
Status at this ADR's acceptance time: contract-only (the pattern itself is authoring guidance, not a runtime entity; individual instantiations carry their own runtime-backing status).
- Host/runtime owner: not applicable — the pattern documents existing SECS primitives (scope, channel, template) and does not introduce a new runtime entity. Each pattern instantiation (ad-0007 through ad-0010) carries its own host data classes per its own Runtime Backing Status section.
- Generated/.secs owner: not applicable for the pattern itself; each instantiation declares its own scope, channel, and template archetypes per its own ADR.
- Read-model/UI owner: not applicable; the pattern is authoring convention.
- Tests: any structural test that walks the lore ADR tree to verify the pattern is correctly applied is added during the Wave 5a runtime-backing wave's verifier pass.
- Known gaps: no runtime gap — the pattern is contract-only by its nature as a cross-cutting authoring convention.
- Illegal fallback behavior: any new Valenar persistent gameplay primitive committed after this ADR that uses a state-as-tag-set, state-as-host-field-only, state-as-Modifier-flag, or state-as-implicit-host-store shape — without superseding this ADR — is a tenet FAIL.
- Next closure wave: not applicable; the pattern stays contract-only permanently as authoring guidance.
Glossary Propagation
No new glossary terms are added by this ADR. The pattern documents
existing SECS vocabulary (scope, channel, template, Modifier) per
.claude/rules/secs-concepts.md and existing Valenar vocabulary
(LifecycleState, Status, Rank, FrontStatus, OperationStatus,
PolityRank, CurrentAct, Severity). Future glossary entries for
specific pattern instantiations are propagated by the instantiating
ADR (ad-0007 propagates QuestThread / Mission etc.; ad-0008
propagates ThreatSource / FrontCandidate etc.; ad-0009 propagates
Realm / PolityRank etc.; ad-0010 propagates ActState etc.).
Consequences
For Foundation Hardening waves that add new persistent gameplay primitives, the pattern is binding. Any new primitive must declare its scope, its state channel(s), and its template archetype(s) — or explicitly document why the pattern does not apply (e.g., transient effect bundles use Modifiers per ad-0012; authoring policy decisions use ADR text without a runtime shape per ad-0011).
For post-Hardening waves (Wave M content authoring; specific lane content for the seven cross-act lanes; later autonomous Crown-AI emergence; per-act gate-spec authoring), the pattern remains binding for any new persistent primitive. The pattern does not apply to content rows authored as template instances against an existing archetype — those are template-data per the "Templates are data" tenet and use the existing SECS template primitive.
For the verifier, any new ADR that commits a fifth primitive shape without explicitly superseding this ADR is a tenet FAIL. Any doc that introduces a new gameplay primitive outside the four pattern components (scope, state channel, template archetype, optional Modifier attachments per ad-0012) is also a FAIL.
For
./ad-0012-character-conditions-and-injuries-as-modifiers.md
and
./ad-0011-true-harm-placeholder-convention.md,
the explicit "NOT instantiated by" callout above is the binding
documentation that those two ADRs intentionally do not follow the
pattern. The shape difference is by design, not by oversight.
References
./ad-0004-lore-adr-folder.md./ad-0006-dynamic-quest-pressure-and-cross-act-lane-decisions.md./ad-0007-quest-thread-and-mission-scope-primitives.md./ad-0008-pressure-to-front-emergence-scope-state-machine.md./ad-0009-realm-scope-and-polity-rank-orthogonality.md./ad-0010-act-progression-actstate-scope.md./ad-0011-true-harm-placeholder-convention.md./ad-0012-character-conditions-and-injuries-as-modifiers.md../../systems/gd-fronts.md(existingFrontStatusprecedent).claude/rules/secs-concepts.md.claude/rules/valenar-contract-backing.md.claude/rules/orchestrator-mode.md § Source freshness and no-fallback redesign propagation