Generated reference. This page mirrors
Code/Ownerships/README.md, this module's source-of-truth documentation (Standards/02_DOCUMENTATION_STANDARDS.md §1). Edit it there, not here -- this file is regenerated on every docs build and any local edit is silently overwritten.
Ownership¶
Purpose. One generic claim over an entity — who owns it, and who else may access it —
applying uniformly to doors, vehicles, and any other ownable world object, per
Legacy/04_ENTITIES_DOORS_PROPERTY.md
and 08_DATA_MODEL.md §5.
This module has no idea what a door is — that is World's job; it only tracks the claim.
Responsibilities.
- Ownership, OwnerRef, OwnerKind, AccessGrant, AccessLevel, OwnableId — the typed
replacement for the legacy _Owner table
(Legacy/04_ENTITIES_DOORS_PROPERTY.md §1)
and its three-different-runtime-types-in-one-field encoding
(D-16).
- IOwnershipService / OwnershipStore — LoadOrCreateAsync (an entity with no claim yet
loads as unowned, not missing), AssignOwnerAsync (also captures the OwnerDisplayName
snapshot at assignment time — see §5's note on why this isn't a live lookup), HasAccess
(now takes an AccessLevel, hierarchical — see §5), GrantAccessAsync (writes AccessList,
added by ADR-0009).
- Persistence under ownership/{entityId}
(08_DATA_MODEL.md §8).
Not responsible for.
- Resolving OwnerKind.Team/.Gang membership in HasAccess — the Jobs module (the
group/gang/team hierarchy) does not exist yet, so there is no membership to check against.
A Team- or Gang-owned entity is accessible today only through an explicit
per-character AccessGrant, never through kind-matching against a job the caller happens
to hold. This is a real gap, not a design decision — resolve it once Jobs lands
(ROADMAP.md Milestone 7).
- What kind of entity is ownable, or what owning one lets you do (open a door, drive a
vehicle) — that is each entity's own module (World, eventually Vehicles). Ownership
answers "who," never "what does that mean here."
- Revoking a grant — GrantAccessAsync (ADR-0009) replaces a character's existing grant with
a new one, but there is still no way to remove a character from AccessList entirely. Not
built because no consumer needs it yet; see "Future improvements."
Dependencies. Core (IServiceRegistry, IServiceResolver, IPersistenceBackend,
ISchemaRegistry, IEventBus, IGameLog), Character (CharacterId, used by AccessGrant
and to construct a Character-kind OwnerRef).
Public API.
- IOwnershipService — LoadOrCreateAsync(OwnableId), AssignOwnerAsync(OwnableId,
OwnerRef, string ownerDisplayName), HasAccess(Ownership, CharacterId, AccessLevel),
GrantAccessAsync(OwnableId, CharacterId, AccessLevel).
Events published. None yet — deferred until a consumer (a scoreboard, a "your access was revoked" notification) exists, following Inventory's README's and Economy's README's identical deferral.
Persistence. OwnershipDocument { EntityId, Owner, OwnerDisplayName, AccessList } under
ownership/{entityId}, schema version 1.
Future improvements.
- Team/Gang membership resolution in HasAccess, once Jobs exists.
- A RevokeAccessAsync to remove a character from AccessList entirely, once a consumer
needs it — GrantAccessAsync (ADR-0009) only ever replaces or adds, never removes.
- A Manage level (letting a non-owner grant others access) once a real consumer needs it —
Use/Passenger/Drive (ADR-0009) are ordered by vehicle privilege, not general-purpose.