Files
pixelheros/docs/registry/architecture.yaml
2026-05-15 14:52:29 +08:00

182 lines
8.1 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 0max_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