Module 15 · Dive 14.2
Entities, components & the law.
With storage settled, BCS is a discipline about shape, and it is short. A thing is an identity — a branded id, nothing embedded. Its state is data — plain property bundles, never behaviour modules, so even an archetype is just a bundle composed at read time. And a system is a process that owns its private state and obeys one rule at its boundary: only identities and messages about identities may cross. Reference by id, never embed. Watch what the rule buys, and what breaking it costs, below.
embed the list, then the group changes.Components are data
echo_data/bcs/archetypes.exBCS inherits the Entity-Component-System split — identity apart from data apart from behaviour — and sharpens it on the branded id. An entity is just a 14-byte id; it carries no record of its own. Its components are plain data, property bundles in the tables of the last dive, and crucially they are only data — there are no behaviour modules attached to an entity, no class hierarchy of code. This is what lets an archetype be data too: an archetype is an ARC entity whose value is a property bundle, optionally extending one parent via a single :extends link, and an instance carries its archetype’s id plus an overrides map. The composed view is not a class lookup; it is a fold computed at read time — base bundle first, each descendant merged after, the instance’s overrides merged last, right-most wins, at most one :extends deep. Inheritance becomes a `Map.merge` reduction over data, with the resolver taking a fetch function so the boundary stays wherever the definitions live. The payoff is that everything about an entity — its identity, its current state, its template lineage — is a value you can store in a table, ship in a message, and replay from a log. There is nothing else to serialize, because there is nothing else.
The law
mesh.8.1 · edge_store.exThe single rule that makes the whole thing compose is about boundaries. A system is a process that owns its private state, gated on a branded namespace, and the only values that cross its boundary are identities and messages about identities — never a copy of another system’s data. So a Broadcast does not hold the recipient list; it holds the RGP id and resolves the audience from the group that owns it. A relation like “portfolio holds asset” is not an id list embedded in the portfolio; it is a row keyed by the pair of names {subject, object} in an owning EdgeStore, which maintains its own forward and reverse indexes and exports neither. The figure shows why the rule is not pedantry: reference by id and there is exactly one copy of the audience, so an edit to the group is seen by everyone who holds its id, instantly and for free; embed a copy and you have created a second source of truth that goes stale the moment the original changes — the dual-write divergence of Chapter 12, reborn at the data-model layer. The law is the same instinct the whole platform runs on: a branded id is the unit that crosses every boundary — between runtimes (Chapter 10), between replicas (Chapter 12), and now between systems — and the data stays home with its owner. That is BCS, and it is the shape the durable floor was built to carry.
References & sources
- Echo records
- mesh.8.1.mdthe law — a system owns gated private state; only identities and messages about identities cross
- notifications.design.md§2 components-as-data; the RGP referenced by id, never embedded (the BCS law)
- echo_data/bcs/archetypes.exarchetypes are data; :extends; the read-time right-most-wins fold
- External
- Entity component systemidentity / data / behaviour separation
- Single source of truthwhy reference beats embed