Model ownership
Canwu splits responsibility across three layers. The engine owns what must be deterministic, authoritative, and replayable. Optional extension crates own generic domain mechanics, such as movement or law, built on the public API. Your application owns period content and the decisions that give those mechanics meaning. Use this page to decide where a new rule belongs and which crate your code should depend on.
View diagram source
flowchart TB
App["Your application<br/>period content, scenarios,<br/>incidents, authority records"]
Ext["Extension crates<br/>canwu-movement, canwu-law,<br/>canwu-culture, canwu-society, …"]
Ref["Reference integrations<br/>canwu-reference-world and others<br/>replaceable examples"]
Api["canwu-api<br/>public API"]
Engine["Engine and mechanism crates<br/>canwu-core, canwu-event, canwu-sim,<br/>canwu-routing, canwu-transport, …"]
App --> Ext
App --> Api
Ext --> Api
Ref --> Api
Api --> Engine
Arrows point from a crate to what it depends on. Engine and mechanism crates never depend on extensions, reference integrations, or application code.
One ownership rule
Section titled “One ownership rule”Generic engine crates own deterministic simulation contracts: state, settlement, evidence, randomness, persistence, and replay. Extension crates and reference integrations own concrete world concepts, such as armies, governments, territories, people, and letters, together with the event payloads that describe them.
The rule also covers changes that span several plugins. When a maintenance operation must update records owned by different plugins, for example when a culture target retires while legal records still cite it, the kernel checks the participant set, the record versions, the work budgets, and that everything commits together or not at all. Each participant changes only records whose schema its own plugin owns, and the plugin that owns the target record must include an exact change to it. Plugins register as participants with register_owner_authorized_maintenance_participant or as dependency resolvers with register_maintenance_dependency_resolver. Both registrations are stored in the plugin descriptor, so a caller cannot leave a participant out.
Domain ownership
Section titled “Domain ownership”The table lists concerns that come up often and shows which crate owns the mechanism and what your application decides.
| Concern | Owned by | Your application decides |
|---|---|---|
| Person life and custody state, runtime person creation, withdrawing queued ingress | canwu-sim core state and directives |
When a person dies, is captured, is released, or appears; what to withdraw |
| Multi-owner conditional transitions | canwu-sim transition manifest, phase-10 staging, and phase-11 audit |
The participants, expected versions, and meaning of each transition |
| Rule-evaluation evidence | canwu-core record, canwu-sim boundary evidence, canwu-api viewer read |
Rule IDs and what their terms mean |
| Decision lineage and seat succession | canwu-decision ticket and controller binding |
Who holds a seat and when a successor takes over |
| Delegated resource access | canwu-resource access grant and Granted source policy |
Who may grant access to whom, and the authority evidence record |
| Movement lifecycle and capacity pools | canwu-movement runtime record and plugin; canwu-transport records and pure allocation |
Incidents, hazards, hostility, their random draws, and authority-basis records |
| Delegated carriers and carrier seizure | canwu-correspondence |
The relationship behind a delegation, and relaying news of a seizure to the sender |
| Authenticity findings | canwu-information interpretation |
How likely a forgery is to be detected |
| Weighted, unit-block, and advisory procedure stages | canwu-law compiled procedure |
Seat weights, blocks, and the tie-break rule |
| Culture boundary settlement | canwu-culture CultureBoundaryPlugin settles the lifecycle and produces deltas; canwu-society stays the only writer of canwu.society:state |
Exposure signals and the culture definition |
| Policy-pressure provenance and cohort headcount rebase | canwu-society |
The external stock record a rebase cites |
| External transmission sources | canwu-technology |
The cited content record and its declared reliability |
Two movement crates have similar names. canwu-reference-world includes a movement plugin that moves the example world’s armies and people with its order_movement_v1 command; it is replaceable example code. canwu-movement is the generic movement lifecycle extension for canwu-transport records and has no knowledge of the reference world.
Generic event contracts
Section titled “Generic event contracts”canwu-event holds only generic event contracts:
| Type | What it is |
|---|---|
SimEvent |
The event envelope: identity, time, affected entities, summary, cause, and correlation ID |
EventKind |
A type tag plus flattened structured fields. Domain crates define typed payloads and convert them with from_payload and decode_payload. |
CauseRef |
The cause of an event: a command, a parent event, a boundary, or a system |
EventAudience |
Who may see an event in actor-relative views; Private unless the plugin declares otherwise |
EventKindError |
The error returned when a payload cannot be encoded or decoded |
Typed payloads for movement, army arrival, person travel, letter delivery, report dispatch, knowledge, and debug fields live with the integrations that own them. The runtime keeps private compatibility payloads that validate the older event tags and fields strictly. A plugin event carries its plugin name and event type, which EventKind::plugin_identity returns. See the event system for how events are recorded and shown.
History: the retired canwu-world crate
Section titled “History: the retired canwu-world crate”Earlier versions shipped a canwu-world crate that put one example world into the engine’s dependency graph. Its twelve public types, MapPoint, Person, PersonTransitState, LetterStatus, LetterCargo, Government, Territory, Route, TransitState, Army, WorldSnapshot, and WorldDiff, now live in canwu-reference-world. That crate provides them through the public API, together with the example movement plugin, a detached projection, and the routing adapter planning_snapshot_from_world. canwu-routing plans over the generic PlanningSnapshot and does not depend on the example world.
canwu-sim still keeps its own copies of most of these types, re-exported by canwu-api, for the deprecated Canwu::world() projection and the legacy Command::OrderMovement path. New code should use canwu-reference-world or its own domain records. The per-type rationale is in the repository’s world and event ownership audit.