182 lines
8.1 KiB
YAML
182 lines
8.1 KiB
YAML
# Architecture Decision Registry
|
||
#
|
||
# PURPOSE: Single source of truth for key architectural stances that all ADRs
|
||
# must agree on. Skills check this before writing new ADRs to detect conflicts
|
||
# at authoring time — before stories are created against contradictory decisions.
|
||
#
|
||
# RULES:
|
||
# - Register a stance when it constrains how OTHER systems must be built.
|
||
# An internal implementation detail that affects only one ADR does not need
|
||
# to be registered.
|
||
# - Never delete entries — set status: superseded_by: ADR-NNNN instead.
|
||
# - When a stance changes: update the entry, set revised: to today's date,
|
||
# add a comment with the old value, and run /architecture-review to check
|
||
# what ADRs are now invalidated.
|
||
# - adr: is the authoritative source. All other ADRs that depend on this
|
||
# stance list themselves in referenced_by.
|
||
#
|
||
# WRITTEN BY: /architecture-decision (Phase 5 — after ADR is approved)
|
||
# READ BY: /architecture-decision (Step 2 — before authoring begins)
|
||
# /architecture-review (Phase 4 — cross-ADR conflict baseline)
|
||
# /create-stories (to embed architectural constraints in stories)
|
||
# /dev-story (to check implementation against accepted stances)
|
||
#
|
||
# SEARCH PATTERNS (for skills using Grep):
|
||
# All state owners: Grep pattern="^ - state:" path="docs/registry/architecture.yaml"
|
||
# Who owns player_health: Grep pattern="state: player_health"
|
||
# All signal contracts: Grep pattern="pattern: signal"
|
||
# Budget for combat: Grep pattern="system: combat"
|
||
# All forbidden patterns: Grep pattern="^ - pattern:" (forbidden_patterns section)
|
||
# Superseded entries: Grep pattern="status: superseded"
|
||
|
||
version: 1
|
||
last_updated: ""
|
||
|
||
# ─── STATE OWNERSHIP ─────────────────────────────────────────────────────────
|
||
# Who is the authoritative owner of each piece of shared game state.
|
||
# Conflicts: two ADRs claiming to own the same state = data race / authority bug.
|
||
#
|
||
# Register state when it is READ or WRITTEN by more than one system.
|
||
# Internal-only state (never accessed by another system) does not need to be registered.
|
||
#
|
||
# Required fields: state, owner_system, adr, interface, referenced_by[], added
|
||
# interface: how other systems access this state (read-only property, method call,
|
||
# signal, shared resource, etc.) — this is the contract other ADRs depend on.
|
||
|
||
state_ownership: []
|
||
|
||
# Example:
|
||
#
|
||
# state_ownership:
|
||
# - state: player_health
|
||
# status: active # active | superseded_by: ADR-NNNN
|
||
# owner_system: health-system
|
||
# adr: docs/architecture/adr-0001-health-system.md
|
||
# interface: "HealthComponent.current_health (read-only float, range 0–max_health)"
|
||
# write_access: health-system-only # only owner can write; others read
|
||
# referenced_by:
|
||
# - docs/architecture/adr-0001-health-system.md
|
||
# - docs/architecture/adr-0003-combat-system.md # reads to apply damage
|
||
# - docs/architecture/adr-0007-ui-system.md # reads to display HUD
|
||
# added: 2026-03-26
|
||
# revised: ""
|
||
|
||
|
||
# ─── INTERFACE CONTRACTS ──────────────────────────────────────────────────────
|
||
# How systems are required to communicate with each other.
|
||
# Conflicts: one ADR expects signal, another expects direct call = integration bug.
|
||
#
|
||
# Register a contract when the communication pattern between two systems is
|
||
# explicitly decided in an ADR and other systems must follow the same pattern.
|
||
#
|
||
# pattern options: signal | direct_call | event_bus | shared_resource | rpc | none
|
||
|
||
interfaces: []
|
||
|
||
# Example:
|
||
#
|
||
# interfaces:
|
||
# - contract: damage_delivery
|
||
# status: active
|
||
# pattern: signal # how the producer notifies consumers
|
||
# producer: combat-system
|
||
# consumers:
|
||
# - health-system # receives damage_dealt signal, applies to health
|
||
# - ui-system # receives damage_dealt signal, shows damage number
|
||
# - audio-system # receives damage_dealt signal, plays SFX
|
||
# adr: docs/architecture/adr-0003-combat-system.md
|
||
# signal_signature: "damage_dealt(amount: float, target: Node, is_crit: bool)"
|
||
# referenced_by:
|
||
# - docs/architecture/adr-0003-combat-system.md
|
||
# - docs/architecture/adr-0001-health-system.md
|
||
# added: 2026-03-26
|
||
# revised: ""
|
||
|
||
|
||
# ─── PERFORMANCE BUDGETS ──────────────────────────────────────────────────────
|
||
# Frame time allocations per system, against a defined total frame budget.
|
||
# Conflicts: allocations that sum to more than the total budget = unshippable.
|
||
#
|
||
# Register a budget when an ADR explicitly claims a frame time allocation.
|
||
# The registry lets /architecture-review verify the total doesn't exceed the target.
|
||
|
||
performance_budgets: []
|
||
|
||
# Example:
|
||
#
|
||
# performance_budgets:
|
||
# - target_fps: 60
|
||
# total_frame_budget_ms: 16.6
|
||
# platform: PC # PC | Console | Mobile | All
|
||
# adr: docs/architecture/adr-0000-performance-targets.md
|
||
# added: 2026-03-26
|
||
# revised: ""
|
||
#
|
||
# - system: combat
|
||
# status: active
|
||
# budget_ms: 2.0
|
||
# adr: docs/architecture/adr-0003-combat-system.md
|
||
# notes: "Includes physics queries, hitbox evaluation, and damage calculation"
|
||
# referenced_by:
|
||
# - docs/architecture/adr-0003-combat-system.md
|
||
# added: 2026-03-26
|
||
# revised: ""
|
||
|
||
|
||
# ─── API DECISIONS ───────────────────────────────────────────────────────────
|
||
# Which engine APIs are chosen for which purpose across the project.
|
||
# Conflicts: two ADRs using different APIs for the same purpose = inconsistent
|
||
# implementation that breaks when one system expects the other's API.
|
||
#
|
||
# Register an API decision when the choice is non-obvious and other ADRs might
|
||
# make a different choice for the same purpose without knowing this was decided.
|
||
|
||
api_decisions: []
|
||
|
||
# Example:
|
||
#
|
||
# api_decisions:
|
||
# - purpose: physics_raycast
|
||
# status: active
|
||
# api: PhysicsServer3D.space_get_direct_state()
|
||
# not: RayCast3D node # explicitly banned for this purpose
|
||
# adr: docs/architecture/adr-0002-physics-architecture.md
|
||
# reason: "Direct server calls avoid per-frame node overhead; 3× faster in profiling"
|
||
# referenced_by:
|
||
# - docs/architecture/adr-0002-physics-architecture.md
|
||
# - docs/architecture/adr-0003-combat-system.md
|
||
# added: 2026-03-26
|
||
# revised: ""
|
||
|
||
|
||
# ─── FORBIDDEN PATTERNS ──────────────────────────────────────────────────────
|
||
# Architecture anti-patterns explicitly banned by accepted ADRs.
|
||
# When writing a new ADR, check this list — if the proposed approach matches
|
||
# a forbidden pattern, it must be reworked before the ADR can be Accepted.
|
||
#
|
||
# Register a pattern when an ADR explicitly bans it AND other ADRs might
|
||
# unknowingly use it (i.e., it's a tempting but wrong approach for this project).
|
||
|
||
forbidden_patterns: []
|
||
|
||
# Example:
|
||
#
|
||
# forbidden_patterns:
|
||
# - pattern: autoload_singleton_coupling
|
||
# status: active
|
||
# description: "Systems must not directly reference Autoload singletons by name.
|
||
# Use dependency injection or signals instead."
|
||
# why: "Tight coupling to Autoloads makes systems untestable in isolation and
|
||
# creates hidden dependencies that break when Autoload load order changes."
|
||
# adr: docs/architecture/adr-0001-health-system.md
|
||
# added: 2026-03-26
|
||
#
|
||
# - pattern: direct_cross_system_state_write
|
||
# status: active
|
||
# description: "A system must never write to state owned by another system.
|
||
# Use signals or method calls on the owner instead."
|
||
# why: "Direct state writes create race conditions and break the state
|
||
# ownership model. The owning system must be the sole writer."
|
||
# adr: docs/architecture/adr-0000-architecture-principles.md
|
||
# added: 2026-03-26
|