Core Package Architecture and Decision Traceability Map¶
Scope of this document. This document specifies and visualizes the package hierarchy, structural decoupling boundaries, and decision traceability hypergraph for rtp-core. It models the module's 4-tier Directed Acyclic Graph (DAG), diagrams the decoupled seams that eliminate cyclic package tangles, and specifies the closed hypergraph connecting implementation classes to governing ADRs, absolute prohibition requirements (S-001..S-007), and automated verification tests.
Companion architectural decisions and references:
- ADR-000: Development Workflow and D-005 Guard Rail.
- ADR-001: Archimedean Spiral 1D Mapping.
- ADR-008: MemoryTracker as Active Task GC.
- ADR-015: Stale-Chunk Guard for Count-Bound Pipes.
- ADR-016: Anvil Read-Only Subsystem.
- ADR-094: Quality-Engineering Gates and ArchUnit Enforcement.
- ADR-110: Purpose-Gated Live Loads.
- ADR-112: Per-Region Work Division on Folia.
- ADR-114: Cost-Governed On-Demand Chunk Reads.
- ADR-115: Package DAG Disentanglement and Finite Decision-Preservation Hypergraph (Authoritative Decision).
- docs/dev/REQUIREMENTS.md: Absolute Prohibition Requirements (S-001 through S-007).
- docs/dev/TRACEABILITY.md: Requirements to Code and Test Traceability Matrix.
Executive Overview (Package DAG & Decision Hypergraph)¶
The rtp-core module implements the platform-neutral coordinate math, memory tracking, multi-tier chunk resolution, and teleport execution pipelines. The architecture is structured around two governing models:
-
Acyclic Package Layering (0.0% SonarQube Package Tangles): The packages in
rtp-coreare organized into a 4-tier Directed Acyclic Graph (DAG). Dependencies flow strictly downward (Tier 4 $\to$ Tier 3 $\to$ Tier 2 $\to$ Tier 1). Elimination of cyclic package tangles ensures that domain algorithms (such asMemoryTrackerandLocationGenerator) operate as isolated, self-contained components without coupling to the plugin composition root or presentation layers. -
Finite Decision Hypergraph (Code $\longleftrightarrow$ ADR $\longleftrightarrow$ Requirement $\longleftrightarrow$ Test): Implementation invariants (including Archimedean spiral indexing, Anvil pre-filter deduplication equations, and weak-reference garbage collection sweeps) link directly to their governing design records. Classes declare their governing ADRs, prohibition requirements, and operational invariants in structured Javadoc headers, establishing a closed, traceable graph from requirement to automated verification.
flowchart TD
subgraph TargetDAG ["rtp-core 4-Tier Directed Acyclic Graph (DAG)"]
direction TB
T4["Tier 4: Orchestration & Presentation<br/>(common.RTP, commands.*, web editor, menus)<br/>Leaf entry points; zero inbound dependencies"]
--> T3["Tier 3: Execution Pipelines & Coordination<br/>(tasks.teleport, pregen, cache refiller, action engine)<br/>Depends on T2 and T1"]
--> T2["Tier 2: Domain Engines & Memory<br/>(selection math, MemoryTracker, shapes, database)<br/>Pure algorithms; depends on T1"]
--> T1["Tier 1: Foundation & Contracts<br/>(configuration schema, SPIs, models, enums)<br/>0 outgoing core dependencies"]
end
classDef dag fill:#d1e7dd,stroke:#0f5132,stroke-width:2px,color:#0f5132;
class TargetDAG,T4,T3,T2,T1 dag;
1. The 4-Tier Package Hierarchy¶
Dependencies flow strictly downward: Tier 4 $\to$ Tier 3 $\to$ Tier 2 $\to$ Tier 1. Higher tiers consume lower tiers; upward or circular dependencies are prohibited.
flowchart TD
subgraph T4 [Tier 4: Orchestration, Ingress & Presentation]
direction TB
T4_RTP["io.github.dailystruggle.rtp.common (RTP Composition Root)"]
T4_CmdTree["io.github.dailystruggle.rtp.common.commands (Command Tree)"]
T4_CmdSub["io.github.dailystruggle.rtp.common.commands.* (Subcommands)"]
T4_Menu["io.github.dailystruggle.rtp.common.commands.menu.*"]
T4_Editor["io.github.dailystruggle.rtp.common.commands.editor.*"]
T4_Events["io.github.dailystruggle.rtp.common.event"]
end
subgraph T3 [Tier 3: Execution Pipelines & Runtime Coordination]
direction TB
T3_Teleport["io.github.dailystruggle.rtp.common.tasks.teleport (TeleportPipelineTask)"]
T3_Tasks["io.github.dailystruggle.rtp.common.tasks (TaskPipes, ScanTask)"]
T3_Tick["io.github.dailystruggle.rtp.common.tasks.tick (Processing loops)"]
T3_Action["io.github.dailystruggle.rtp.common.action (ActionManager)"]
T3_Network["io.github.dailystruggle.rtp.common.network (Protocol dispatch)"]
T3_Importer["io.github.dailystruggle.rtp.common.importer"]
end
subgraph T2 [Tier 2: Domain Engines, Math & Storage]
direction TB
T2_Selection["io.github.dailystruggle.rtp.common.selection.region (Regions, Queues)"]
T2_Shapes["io.github.dailystruggle.rtp.common.selection.region.selectors.*"]
T2_Tools["io.github.dailystruggle.rtp.common.tools (MemoryTracker, ChunkSafety)"]
T2_Database["io.github.dailystruggle.rtp.common.database (Accessors, Factory)"]
T2_Metrics["io.github.dailystruggle.rtp.common.metrics (Governors, Profiles)"]
T2_PlayerData["io.github.dailystruggle.rtp.common.playerData (Limits, Cache)"]
end
subgraph T1 [Tier 1: Foundation, Schemas & Primitives]
direction TB
T1_Config["io.github.dailystruggle.rtp.common.configuration.schema (Immutable specs)"]
T1_Enums["io.github.dailystruggle.rtp.common.configuration.enums"]
T1_Math["io.github.dailystruggle.rtp.common.selection.region.selectors.memory.table"]
T1_Pool["io.github.dailystruggle.rtp.common.database.pool"]
T1_Contracts["io.github.dailystruggle.rtp.common.tools.contracts (TrackableTask, TicketHolder)"]
T1_Text["io.github.dailystruggle.rtp.common.text"]
end
T4 --> T3
T4 --> T2
T4 --> T1
T3 --> T2
T3 --> T1
T2 --> T1
classDef t4 fill:#e2d9f3,stroke:#59359a,stroke-width:1px,color:#261447;
classDef t3 fill:#cfe2ff,stroke:#1f4e8a,stroke-width:1px,color:#0b1f3a;
classDef t2 fill:#d1e7dd,stroke:#0f5132,stroke-width:1px,color:#0f5132;
classDef t1 fill:#f8f9fa,stroke:#495057,stroke-width:1px,color:#212529;
class T4,T4_RTP,T4_CmdTree,T4_CmdSub,T4_Menu,T4_Editor,T4_Events t4;
class T3,T3_Teleport,T3_Tasks,T3_Tick,T3_Action,T3_Network,T3_Importer t3;
class T2,T2_Selection,T2_Shapes,T2_Tools,T2_Database,T2_Metrics,T2_PlayerData t2;
class T1,T1_Config,T1_Enums,T1_Math,T1_Pool,T1_Contracts,T1_Text t1;
Tier Specifications¶
- Tier 1 (Foundation & Schemas):
Contains pure data schemas, configuration records, domain enums, primitive spatial math tables, and lifecycle contracts. Classes in Tier 1 shall have zero dependencies on other
rtp-corepackages. - Tier 2 (Domain Engines & Storage):
Contains core mathematical engines and state managers: Archimedean spiral and Hilbert spatial memory (
MemoryShape), resource tracking (MemoryTracker), database accessors (DatabaseAccessorFactory), and concurrency governors (ImmediateLoadGovernor). Classes in Tier 2 depend strictly on Tier 1 contracts and schemas; they shall contain no references to command execution, player messaging, or presentation layers. - Tier 3 (Execution Pipelines & Coordination):
Contains runtime task orchestrators and asynchronous pipelines: player teleport pipelines (
TeleportPipelineTask), background queue pre-generation (PregenTask), scan crawlers (ScanTask), scripted action execution (ActionManager), and network synchronization. Depends on Tier 2 domain engines and Tier 1 foundation contracts. - Tier 4 (Orchestration & Ingress):
Contains user-facing and external entry points: command dispatch trees, interactive book menus, web editor channels, event bridges, and the plugin composition root (
RTP.java). Depends downward on Tiers 3, 2, and 1. Zero core packages shall depend on Tier 4.
2. Structural Seam Decoupling Patterns¶
The 4-tier DAG resolves cyclic dependencies across packages by decoupling four critical structural seams:
1. Task Execution vs. Resource Safety (tasks.teleport $\longleftrightarrow$ tools)¶
Pattern: Interface Extraction.
- tools.MemoryTracker manages resource lifecycles and garbage collection sweeps without coupling to the concrete execution details of TeleportPipelineTask.
- tools.contracts.TrackableTask defines the lifecycle contract (UUID id(), isCompleted(), getReservations(), cancel()).
- TeleportPipelineTask implements TrackableTask. MemoryTracker interacts strictly through the contract, isolating Tier 2 from runtime execution in Tier 3.
flowchart LR
TeleportTask["tasks.teleport.TeleportPipelineTask<br/>(Tier 3: Execution)"]
--> Trackable["tools.contracts.TrackableTask<br/>(Tier 1: Contract)"]
Tracker["tools.MemoryTracker<br/>(Tier 2: Safety Sweep)"]
--> Trackable
TeleportTask --> Tracker
classDef c1 fill:#cfe2ff,stroke:#1f4e8a,stroke-width:1px,color:#0b1f3a;
classDef c2 fill:#d1e7dd,stroke:#0f5132,stroke-width:1px,color:#0f5132;
classDef c3 fill:#f8f9fa,stroke:#495057,stroke-width:1px,color:#212529;
class TeleportTask c1;
class Tracker c2;
class Trackable c3;
2. Command Tree Inversion (commands $\longleftrightarrow$ commands.*)¶
Pattern: Shared Base & Provider Registration.
- Root command infrastructure (BaseRTPCmd, parameter parsers) resides in commands.base (or leverages commands-api).
- Concrete subcommands (commands.admin.AdminCmd, commands.config.ConfigCmd) depend downward on commands.base.
- Subcommands register into the tree dynamically or via provider collections, ensuring child subcommands do not import the parent composition builder.
3. Domain Models vs. Runtime Pipelines (selection.region $\longleftrightarrow$ tasks)¶
Pattern: Separation of Schema & Pipeline Coordination.
- Region functions as a calculation manifold operating on immutable configuration schemas (RegionConfigRecord) defined in Tier 1.
- Teleport execution pipelines are dispatched by Tier 3 coordinators (QueueRefillCoordinator), avoiding direct task invocation inside domain calculation classes.
4. Composition Root vs. Global State (common.RTP)¶
Pattern: Context Encapsulation & Constructor Injection.
- RTP.java operates strictly as a Tier 4 Composition Root: it instantiates and wires subsystems during startup, and tears them down during shutdown.
- Internal domain classes receive required SPI services (RTPScheduler, RTPServerAccessor, MemoryTracker) via constructor parameters or a scoped RTPContext.
- Classes in Tiers 1, 2, and 3 shall contain no static references to RTP.java.
3. Decision and Requirement Traceability Hypergraph¶
The relationship between implementation, requirements, and design rationale forms a closed hypergraph: $$\mathcal{H} = (V, \mathcal{E}), \quad V = \mathcal{REQ} \cup \mathcal{ADR} \cup \mathcal{S} \cup \mathcal{C} \cup \mathcal{T}$$
Every safety-critical class links directly to its governing requirements, design records, and automated test suites:
graph LR
subgraph CodeLayer ["1. Implementation (In-Code Javadoc)"]
ClassFile["ImmediateLoadGovernor.java<br/>@governedBy ADR-114<br/>@trace REQ-RTP-S-005<br/>@invariant S-005<br/>@prohibition No semaphore bypass"]
end
subgraph DocLayer ["2. Design Rationale (ADR & Requirements)"]
ADR["ADR-114 (Cost-Governed Reads)<br/>ADR-110 (Purpose-Gated Loads)<br/>REQ-RTP-S-005 (Async Chunk I/O)"]
end
subgraph TestLayer ["3. Verification (Automated Test)"]
TestFile["ImmediateLoadGovernorTest.java<br/>(Validates Concurrency Permits)"]
end
ClassFile -->|Inspect Header| ADR
ClassFile -->|Verify Edits| TestFile
ADR -->|Defines Invariant| TestFile
classDef code fill:#cfe2ff,stroke:#1f4e8a,stroke-width:1px,color:#0b1f3a;
classDef doc fill:#fff3cd,stroke:#664d03,stroke-width:1px,color:#664d03;
classDef test fill:#d1e7dd,stroke:#0f5132,stroke-width:1px,color:#0f5132;
class ClassFile code;
class ADR doc;
class TestFile test;
Standard Class Invariant Header Format¶
Safety-critical classes declare their governing constraints using standardized Javadoc tags:
/**
* Enforces per-region and global concurrency bounds on native chunk generation
* during on-demand (LoadPurpose.IMMEDIATE) teleport execution.
*
* @governedBy ADR-110 (Purpose-Gated Live Loads)
* @governedBy ADR-114 (Cost-Governed On-Demand Chunk Reads)
* @trace REQ-RTP-S-004
* @trace REQ-RTP-S-005
* @invariant S-005: Zero synchronous chunk loading or blocking calls on the main/tick thread.
* @invariant Concurrency-Cap: Maximum 1 concurrent generation permit per region, 2 server-wide.
* @invariant Fail-Visibility: Requests timing out after 1200ms shall complete with msgBusy (S-004, S-007).
* @prohibition DO NOT remove semaphores to "speed up" concurrent player teleports; unbound
* live chunk generation causes severe main-thread tick stalls and watchdog crashes.
*/
public final class ImmediateLoadGovernor {
// ...
}
Tag Invariant Definitions¶
@governedBy ADR-NNN: Declares the authoritative architectural decision record defining the engineering trade-offs and rationale.@trace REQ-MODULE-FAMILY-NNN: Declares the functional or non-functional requirement satisfied by the component.@invariant S-00x: Declares compliance with non-negotiable absolute prohibition requirements (S-001 through S-007).@invariant <Name>: Declares mathematical, operational, or concurrency invariants (e.g., concurrency bounds, non-mutating reads).@prohibition: Declares explicit negative constraints defining operations that refactoring shall not introduce.
4. ArchUnit Verification Guardrails¶
Package acyclicity and tier separation are verified mechanically during the build by RTPArchitectureTest (rtp-core/src/test/java/.../RTPArchitectureTest.java):
public class RTPArchitectureTest {
@ArchTest
static final ArchRule packages_must_be_free_of_cycles =
slices().matching("io.github.dailystruggle.rtp.common.(*)..")
.should().beFreeOfCycles()
.because("Package tangles break modularity and prevent isolated component testing.");
@ArchTest
static final ArchRule domain_engines_must_not_depend_on_orchestration =
noClasses().that().resideInAnyPackage("..selection..", "..tools..", "..database..")
.should().dependOnClassesThat().resideInAnyPackage("..commands..", "io.github.dailystruggle.rtp.common")
.because("Domain engines in Tier 2 shall not have upward dependencies on Tier 4 orchestration.");
@ArchTest
static final ArchRule foundation_must_have_zero_outgoing_core_dependencies =
classes().that().resideInAPackage("..configuration.schema..")
.should().onlyDependOnClassesThat().resideInAnyPackage("..configuration.schema..", "..configuration.enums..", "java..")
.because("Tier 1 Foundation schemas shall be completely free of domain and runtime dependencies.");
}
5. Component Tier Taxonomy¶
Components in rtp-core map to the 4-tier hierarchy according to functional domain and dependency characteristics:
| Component Category | Target Package | Tier | Exemplar Classes |
|---|---|---|---|
| Immutable schema, DTO, or enum | common.configuration.schema or common.configuration.enums |
Tier 1 | RegionConfigRecord, ShapeType |
| Foundation contract or lifecycle SPI | common.tools.contracts |
Tier 1 | TrackableTask, ChunkTicketHolder |
| Math curve, spatial memory, shape | common.selection.region.selectors.* |
Tier 2 | CircleOptimizedDualLayer, CurveHash |
| Storage, memory tracking, governor | common.tools, common.database, common.metrics |
Tier 2 | MemoryTracker, ImmediateLoadGovernor |
| Pipeline task, async scheduler | common.tasks.teleport, common.tasks |
Tier 3 | TeleportPipelineTask, PregenTask |
| Command, menu, web editor, UI, composition root | common.commands.*, common.commands.menu.*, common |
Tier 4 | AdminCmd, EditorChannelWiring, RTP |