The service layer wraps the core ECS engine with multi-world management, command governance, audit history, and storage lifecycle. The core layer has no knowledge of actors, roles, commands, or process-level orchestration.
For normative signatures, see Service Protocols.
archetype.app
ServiceContainer Wires everything
|
+-- StorageService Multiton storage pool
+-- CommandBroker Pure priority queue
+-- AuditLog Append-only audit rows
|
+-- WorldService World lifecycle, lookup, fork, destroy
+-- MutationService Entity, component, and processor mutations
+-- SimulationService Step, run, episode, rollout
+-- QueryService Internal storage-backed reads
|
+-- CommandService The gate: auth, audit, delegation
ServiceContainer¶
ServiceContainer is the lower-level composition root. Script users usually start with ArchetypeRuntime; host processes and tests use ServiceContainer when they need explicit service wiring.
from archetype.app.container import ServiceContainer
container = ServiceContainer()
Construction is synchronous. Storage backends are opened lazily on first use.
Dependency Graph¶
Services depend only on lower tiers:
iStorageService
↑ ↑ ↑
iWorldService iQueryService iAuditLog
↑ ↑ ↑
iMutationService iSimulationService |
↑ ↑ ↑ ↑
└───────────────┴──────────────┴──────────────┘
↑
iCommandBroker
↑
iCommandService
iCommandService is the only ActorCtx-aware service. It is also the only service the runtime calls.
StorageService¶
StorageService creates and pools async stores. It is a multiton keyed by effective storage configuration.
store = await container.storage_service.get_or_create_store(
storage_config,
cache_config,
)
See Stores for backend behavior.
WorldService¶
WorldService manages live world instances:
create_worldestablishes a new world identity.fork_worldsnapshots a source world into a new world identity.destroy_worldremoves the live in-memory world from the registry.- lookup methods return live
iWorldobjects for internal service callers.
External callers do not receive live iWorld objects. iCommandService downgrades lifecycle returns to WorldInfo.
World lifecycle details are normative in World Lifecycle.
MutationService¶
MutationService mutates world contents after the gate has authorized the operation:
- create and remove entities
- update existing components
- add and remove component types
- add and remove processors
It has no ActorCtx parameter. Authorization belongs to iCommandService.
SimulationService¶
SimulationService owns the execution hierarchy:
step: one tickrun: N steps, no termination, no forkrun_episode: step until termination or cap on the supplied worldrun_rollout: fork N worlds and run one episode in each
Rollout-internal forks use iWorldService directly. The gated run_rollout call is the audit unit, not each internal fork.
See Execution Hierarchy.
QueryService¶
QueryService is the internal storage-backed read path. It has no ActorCtx argument because it sits below the gate.
External reads go through iCommandService:
query_archetypelist_signaturesget_world_infoget_audit_historylist_processorslist_hookslist_resources
The viewer role is meaningful at the gate. See Command Gate.
CommandBroker¶
CommandBroker is a pure queue for tick-deferred commands. It stores, orders, dequeues, acknowledges, and clears commands.
It does not own RBAC, quota checks, or user-facing audit history. Those belong to iCommandService and iAuditLog.
See Command Broker.
AuditLog¶
AuditLog is append-only. It records accepted-and-applied gated operations and backs world.history(...) through iCommandService.get_audit_history(...).
Broker history is queue introspection; audit history is the durable record.
See Audit Log.
CommandService¶
CommandService is the policy enforcement point. Every external mutation, lifecycle operation, simulation control call, and read flows through it.
Each gated method follows the same shape:
guardrail_allow(command, ctx)
delegate to one underlying service
audit.record(row)
return downgraded/user-safe result
There are two paths through the gate:
- Direct calls apply now and return a result, such as
create_world,create_entity,run, andquery_archetype. - Tick-deferred calls use
submit,submit_batch, andsubmit_spawn;SimulationService.steplater callsdrain_and_apply.
Live objects do not escape the gate. create_world, fork_world, and get_world_info return WorldInfo; list methods return ProcessorInfo, HookInfo, and ResourceInfo.
How Services Connect to the API¶
The API Layer exposes the gate and selected queue/introspection endpoints through FastAPI. Route handlers translate HTTP into typed service calls and pass an ActorCtx from auth middleware.
The CLI is a thin HTTP client.
Source Reference¶
- Service container:
src/archetype/app/container.py - Service protocols:
src/archetype/app/interfaces.py - Command service:
src/archetype/app/command_service.py - Command broker:
src/archetype/app/broker.py - World service:
src/archetype/app/world_service.py - Mutation service:
src/archetype/app/mutation_service.py - Simulation service:
src/archetype/app/simulation_service.py - Query service:
src/archetype/app/query_service.py - Storage service:
src/archetype/app/storage_service.py