Skip to main content

Relationship Bridge Architecture V2

Status: Proposed v2 (2026-05-05) Supersedes: the v1 primitive-first framing in this file from 2026-05-04 Scope: SECS runtime architecture, future deterministic kernel, host adapters Does not change: .secs scripting language, secs-roslyn compiler identity, scope model, modding contract, or the rule that SECS is not replaced by Unity DOTS / Flecs / any other ECS


Purpose

The first draft correctly identified two real pressures:

  1. SECS needs richer relationship and query semantics than one host callback named WalkScope.
  2. Unity DOTS integration cannot put Unity packages into the engine or force a managed boundary through every hot path.

The first draft then centered the design on the wrong object: a public low-level native primitive layer modeled as RawHashMap, PairId, ReachableCache, a Flecs-like query VM, and one giant HostBridge*.

That is backwards. Those are implementation tools. The architecture SECS needs is a deterministic SECS semantic kernel: a host-agnostic runtime substrate that owns SECS concepts directly — scopes, relations, collections, modifier bindings, query plans, channel dependencies, snapshots, command journals, diagnostics, and deterministic iteration. Native collections may implement that kernel, but they are not the architecture.

This v2 document reframes the bridge around that semantic kernel.


Decision Summary

Build a host-agnostic deterministic SECS Kernel between the SECS runtime coordinator and host adapters.

The kernel owns the semantic graph and deterministic indexes the runtime needs:

  • entity identity and lifetime tables
  • relation definitions and relation storage
  • scope-walk, reverse-walk, collection, ownership, and template IsA indexes
  • query plans and ordered query result materialization
  • modifier binding indexes and value-bucket preparation
  • channel dependency edges, invalidation, and snapshots
  • command journal recording and canonical apply order
  • save/load state sections and content-manifest hooks
  • host-agnostic diagnostics, tracing, and profiling markers

The kernel is pure netstandard2.1 C# with unsafe/blittable internals where needed. It has zero Unity package references. Unity DOTS is one adapter. The dev server is another adapter. Future hosts consume the same kernel.

The kernel may still live in an assembly named SECS.Native if that remains the product name, but the architectural concept is not "a raw native collection library." It is "the SECS semantic kernel."


Non-Negotiable Constraints

  • SECS scripting remains the authoring surface. Never frame this work as replacing SECS with Flecs, Bevy, Unity DOTS, or a generic ECS.
  • Engine and kernel assemblies have zero Unity package references.
  • Unity packages appear only in the Unity adapter.
  • Relationship storage is Bevy-style non-fragmenting: target is data, never archetype identity.
  • Determinism is required at the semantic API level from day one.
  • Hashmap iteration order and allocator free-list behavior must be deterministic from day one where those structures exist internally.
  • The kernel must not truncate SECS identities. SECS declaration ids are 64-bit FNV-1a hashes; entity handles are 64-bit today. Flecs's packed 31-bit relation / 32-bit entity target encoding is not a valid SECS identity model.
  • Instrumentation ABI slots must be host-agnostic. Do not put Unity ProfilerMarker fields in kernel structs.
  • The existing ISecsHostReads surface is a symptom of multiple responsibilities being collapsed into one interface. V2 splits the boundary by responsibility instead of reproducing the same shape as one giant function-pointer struct.

Corrected Layer Model

┌───────────────────────────────────────────────────────────┐
│ L1: SECS source (.secs) │
│ scopes, walks_to, modifiers, systems, events, │
│ saved scopes, mod operations │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│ L2: secs-roslyn output │
│ Generated behavior bodies + generated WorldSchema │
│ query plans, relation definitions, dependency metadata │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│ L3: SECS runtime coordinator │
│ registry, channel resolver, tick pipeline, events, │
│ activation, save/load, hot reload, diagnostics │
└───────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────┐
│ L4: SECS Kernel │
│ deterministic semantic graph and indexes │
│ relations, collections, query plans, modifier indexes,│
│ channel dependencies, snapshots, command journal │
└───────────────────────────────────────────────────────────┘

┌──────────────────┬──────────────────┬─────────────────────┐
│ L5a: SECS.Unity │ L5b: SECS.Server │ L5c: future hosts │
│ DOTS/Burst │ managed server │ Godot, MonoGame, │
│ adapter only │ adapter │ custom engines │
└──────────────────┴──────────────────┴─────────────────────┘

┌───────────────────────────────────────────────────────────┐
│ L6: Host runtime │
│ Unity DOTS / SignalR server / future host │
└───────────────────────────────────────────────────────────┘

What Changed From V1

V1 said "L4 is where Flecs's relationship semantics are reimplemented." V2 says: L4 is where SECS runtime semantics are represented in deterministic indexed form.

V1 exposed RawHashMap, PairId, and the query VM as the center of the public tier. V2 treats raw collections as internal kernel machinery unless an adapter use case proves a stable low-level API is necessary.

V1 put "one field per ISecsHostReads method" into a function-pointer bridge. V2 splits host integration into separate bridges because ISecsHostReads currently mixes unrelated jobs: host fields, scope walks, collections, template metadata, channel re-entry, template value resolution, generic scope queries, and prev-tick snapshots.


WorldSchema: The Compiler Output the Kernel Consumes

The compiler must eventually emit two kinds of output:

  1. Generated behavior bodies: formulas, triggers, systems, events, template methods, and contract callables.
  2. WorldSchema: a deterministic schema blob/table set describing the SECS world the kernel indexes.

WorldSchema is the missing architectural object from v1.

It contains:

  • scopes and declared walks_to edges
  • scope fields and their storage ids
  • typed scoped collections and their field-path ids
  • contracts, templates, tags, and template structural predicates
  • relation definitions and relation metadata
  • channel declarations, channel kinds, clamps, source fields, and track_prev
  • modifier declarations, effects, stacking, propagation, and mod attribution ids
  • query plans for generated query expressions
  • declared formula/channel dependencies where known
  • execution eligibility flags for generated bodies
  • content manifest names and hashes for save/load compatibility

The kernel must be initialized from this schema. It must not infer core SECS semantics by looking at arbitrary raw pairs.

Concrete Schema Shape

WorldSchema is not a serialization format decision. It is the logical table set the compiler/runtime agree on. It can be materialized from today's SecsRegistry during migration, then emitted directly by secs-roslyn later.

public readonly struct WorldSchema
{
public ulong SchemaId { get; init; }
public int Version { get; init; }

public ReadOnlyMemory<ScopeRow> Scopes { get; init; }
public ReadOnlyMemory<ScopeFieldRow> ScopeFields { get; init; }
public ReadOnlyMemory<CollectionRow> Collections { get; init; }
public ReadOnlyMemory<RelationDefinition> Relations { get; init; }

public ReadOnlyMemory<ContractRow> Contracts { get; init; }
public ReadOnlyMemory<TemplateRow> Templates { get; init; }
public ReadOnlyMemory<TagRow> Tags { get; init; }

public ReadOnlyMemory<ChannelRow> Channels { get; init; }
public ReadOnlyMemory<ModifierRow> Modifiers { get; init; }
public ReadOnlyMemory<QueryPlanRow> QueryPlans { get; init; }
public ReadOnlyMemory<ExecutionBodyRow> ExecutionBodies { get; init; }

public ContentManifest Manifest { get; init; }
}

The important rule: every row order is deterministic compiler output order. The kernel can derive dense internal indices from this order, but ids remain the 64-bit SECS ids. Schema order is also the default order for declaration iteration, diagnostics, save sections, and diff output.

Schema Rows That Matter First

The first implementation pass does not need every row above. The minimum useful schema is:

RowRequired fieldsPurpose
ScopeRowScopeId, Name, declared walk targetsBuilds scope legality table and walk relation definitions
ScopeFieldRowScopeId, FieldId, type, nameValidates host field bridge and channel source fields
CollectionRowparent scope, field id, kind, key type, element scopeBuilds collection relation definitions and iteration semantics
ContractRowcontract id, root scope, method idsBuilds contract entity sets and callable metadata
TemplateRowtemplate id, contract id, root scope, tagsBuilds structural predicates and template activation indexes
ChannelRowchannel id, kind, scalar type, source field, clamps, track_prevBuilds channel dependency and snapshot policy
ModifierRowmodifier id, effects, stacking, propagation, mod idBuilds modifier indexes and attribution
ExecutionBodyRowbody id, body kind, execution lane, dependency declarationLets runtime route generated bodies safely

Everything else can be added without changing the kernel concept.


Semantic Relation Model

The kernel stores relations, but relations are not anonymous Flecs pairs. Every relation is declared metadata.

public readonly struct RelationDefinition
{
public ulong RelationId { get; init; }
public ulong SourceScopeId { get; init; }
public ulong TargetScopeId { get; init; }
public RelationKind Kind { get; init; }
public RelationCardinality Cardinality { get; init; }
public RelationOrdering Ordering { get; init; }
public RelationLifecycle Lifecycle { get; init; }
public RelationMutationPolicy MutationPolicy { get; init; }
public RelationSavePolicy SavePolicy { get; init; }
public bool MaintainReverseIndex { get; init; }
public bool Acyclic { get; init; }
public bool HostBacked { get; init; }
}

Required relation kinds include:

KindPurpose
ScopeWalkDeclared walks_to edge used by @Scope / WalkScope semantics
CollectionMembershipParent field-path collection to child entity
OwnershipLifetime ownership for bindings and spawned children
TemplateIsATemplate inheritance / structural IsA once semantics are committed
ModifierBindingOwnerBinding owner to target linkage
SavedScopeDispatch-frame saved entity references and future saved lists
HostReferenceHost-exposed relation that is indexed by SECS but stored by the host

The same physical storage may support multiple relation kinds, but the semantic metadata decides invalidation, traversal, save/load, diagnostics, and query planning.

Required Relation Enums

public enum RelationCardinality : byte
{
OneToOne,
OneToMany,
ManyToOne,
ManyToMany,
}

public enum RelationOrdering : byte
{
None,
AscendingTargetId,
SourceInsertionOrder,
ExplicitListOrder,
KeyOrder,
}

public enum RelationLifecycle : byte
{
None,
RemoveOnSourceDestroy,
RemoveOnTargetDestroy,
RemoveOnEitherDestroy,
CascadeDestroyTarget,
}

public enum RelationMutationPolicy : byte
{
RuntimeOwned,
HostMirrored,
HostAuthoritative,
SchemaOnly,
}

public enum RelationSavePolicy : byte
{
RuntimeState,
RebuildFromHost,
RebuildFromSchema,
Transient,
}

The exact enum names can change. The axes cannot. Cardinality, ordering, lifecycle, mutation, and save policy are semantic properties, so they belong in schema rather than in ad hoc storage code.

Initial Relation Definitions

RelationCardinalityOrderingMutationSave policyNotes
self ScopeWalkone-to-onenoneschema/runtime-ownedrebuild from schemaEvery entity can walk to itself for its root scope
parent ScopeWalkmany-to-oneascending target idhost mirrored or runtime ownedrebuild from host/runtime stateScalar WalkScope requires at most one target for a scope id
collection membershipone-to-many from collection scopeexplicit list or key orderruntime ownedruntime stateScopedList and ScopedDictionary differ by ordering/key policy
ownershipone-to-manyascending target idruntime ownedruntime stateDrives lifetime cleanup and spawned-child teardown
modifier binding ownerone-to-manysource insertion orderruntime ownedruntime stateDrives remove-all-by-owner
saved scopeframe-local many-to-onesource insertion orderruntime ownedtransientSaved lists become ordered relation sets
template IsAmany-to-many or DAGschema orderschema onlyrebuild from schemaDeferred until inheritance semantics are committed

This table is deliberately semantic. It should exist before choosing any internal storage container.

Storage Rule

Relationship storage is non-fragmenting:

  • No archetype-per-pair model.
  • No unique (Relation, Target) archetype identity.
  • A relation table stores targets as values and maintains forward/reverse indexes as required by RelationDefinition.

This keeps the Bevy-style advantage from v1 while avoiding the mistake of importing Flecs's packed pair identity model.


Identity Model

V1's PairId packed a 31-bit relationship hash and 32-bit target index into one ulong. That is invalid for SECS.

SECS already uses 64-bit ids:

  • declaration ids are FNV-1a-64 ulong
  • TemplateId wraps ulong
  • current EntityHandle wraps long

V2 therefore uses explicit composite keys:

public readonly struct EntityRef
{
public readonly long Value;
}

public readonly struct RelationKey
{
public readonly EntityRef Source;
public readonly ulong RelationId;
}

public readonly struct RelationEdge
{
public readonly EntityRef Source;
public readonly ulong RelationId;
public readonly EntityRef Target;
}

If a future backend wants packed keys for performance, it can build internal fingerprints or dense table indices after schema load. That optimization must never become the semantic identity contract.


Kernel API Surface

The kernel API should be narrow and semantic. A representative shape:

public interface ISecsKernel
{
KernelSchemaHandle LoadSchema(WorldSchema schema);

EntitySetView EntitiesByContract(ulong contractId);
EntitySetView EntitiesByScope(EntityRef scopeTarget);

bool TryWalkScope(EntityRef source, ulong scopeId, out EntityRef target);
RelationTargetView Targets(EntityRef source, ulong relationId);
RelationSourceView Sources(EntityRef target, ulong relationId);

void Record(CommandOp op);
ApplySummary ApplyRecordedCommands(KernelApplyPhase phase);

QueryResultView ExecuteQuery(QueryPlanId queryId, QueryArgs args, KernelScratch scratch);

ModifierView ActiveModifiers(EntityRef target);
ChannelDependencyToken BeginResolve(EntityRef target, ulong channelId);
void EndResolve(ChannelDependencyToken token);
void MarkFieldWritten(EntityRef target, ulong scopeId, ulong fieldId);
void MarkRelationChanged(RelationEdge edge);

bool TryReadPrevTick(EntityRef target, ulong channelId, out KernelScalar value);
void SnapshotTrackedChannels(IChannelValueReader reader);
}

This is not final API syntax. It states the boundary:

  • callers ask for SECS concepts
  • relation/query/channel operations go through semantic ids
  • command application is explicit
  • invalidation is semantic
  • no Unity type appears
  • no raw collection is required at the public layer

Views, Not Collections

Kernel methods return views such as EntitySetView, RelationTargetView, ModifierView, and QueryResultView. These views define:

  • count
  • indexed access
  • deterministic iteration order
  • lifetime/ownership rules
  • whether the view survives mutation or only the current phase

They may be backed by arrays, raw lists, spans, slices, or adapter-native wrappers. The view contract is the API. The backing container is not.


Host Boundary Split

The old ISecsHostReads shape should not be converted one-to-one into function pointers. It currently combines too many responsibilities.

V2 splits the boundary:

BoundaryOwnsNative eligibility
HostFieldBridgeRead/write host scalar/entity fields by (entity, scopeId, fieldId)Native/Burst eligible when implemented by adapter
HostCommandSinkApply host side effects and command buffers at canonical apply pointsAdapter-specific
HostCallableBridgeDeclared scope methods / contract callables implemented by host codeManaged by default; native only when declared eligible
HostEntityBridgeEntity creation, destruction, id allocation, and host entity mappingAdapter-specific
TraceBridgediagnostics, walk trace, modifier trace, query traceHost-agnostic callback ids
InstrumentationBridgeprofiling scopes/timers/countersOpaque marker ids, not Unity types

The runtime coordinator owns template metadata lookup, channel re-entry, template value resolution, saved-scope frames, and prev-tick snapshot reads. Those are SECS runtime services, not host services.

This split lets the Unity adapter provide Burst-safe function pointers for field reads and structural indexes without pretending every generated body is Burst-compatible.

Bridge Ownership Rules

Current ISecsHostReads member familyV2 owner
ReadInt/Long/Float/Double/Bool/EntityHostFieldBridge
host field writesHostFieldBridge plus command apply phase
WalkScopekernel relation index; host may mirror authoritative edges
GetChildren, GetChildByTemplate, WalkChildrenkernel collection relation index
LookupTemplateruntime coordinator / registry
CallScopeQuery<TArgs,TResult>HostCallableBridge when host-implemented; generated callable dispatch otherwise
ResolveChannel*runtime coordinator / channel resolver
ResolveTemplateValue*runtime coordinator / template-value resolver
ReadPrevTick*kernel snapshot service

This table is the migration map. Anything on the right side that says runtime/kernel should not be added to a host function-pointer struct.


Execution Lanes

Generated behavior must declare its execution lane. Without this, the architecture cannot honestly support both Unity Burst and rich managed SECS behavior.

LaneAllowedExamples
NativeEligibleBlittable args, no managed allocation, no generic dispatch, no managed host callable, no unplanned channel re-entrysimple formulas, structural predicates, pure field reads
KernelEligibleUses kernel services such as query plans, relation walks, modifier indexes, and channel dependencies, but no host-managed callablemost future query/channel paths
ManagedOnlyUses managed callbacks, template metadata objects, generic scope queries, or behavior the compiler cannot prove native-safecomplex contract queries, structured feature-placement records, some validation paths

A formula that calls ResolveChannelInt is not automatically invalid, but it is not automatically Burst-safe either. The compiler/runtime must classify it.

This replaces v1's ambiguous "function-pointer bridge means Burst-compatible" assumption.


Query Model

The query engine is a SECS query planner, not a generic Flecs query VM first.

The compiler lowers source constructs to query plans over kernel relations and indexes:

  • every X in Collection
  • ordered X in Collection order_by Channel desc limit N
  • first / random / count
  • saved-scope iteration and future saved-scope lists
  • multi-hop predicates through declared scope relations
  • structural predicates: has_tag, has_template, has_contract
  • future descendants(Type) only after transitive traversal semantics are committed

The kernel decides whether a plan can execute through a simple indexed scan, ordered materialization, or a small backtracking join. A full Flecs-style backtracking VM is an implementation option, not the first architectural commitment.

All query result iteration order is part of the semantic contract. It cannot depend on hash bucket order.

Initial QueryPlan Shape

The first query IR can be small:

public readonly struct QueryPlanRow
{
public ulong QueryId { get; init; }
public QueryResultShape ResultShape { get; init; }
public QueryOrdering Ordering { get; init; }
public ReadOnlyMemory<QueryOp> Ops { get; init; }
}

public readonly struct QueryOp
{
public QueryOpCode OpCode { get; init; }
public int A { get; init; }
public int B { get; init; }
public ulong Id { get; init; }
}

Initial opcodes:

OpMeaning
ScanContractStart from entities registered under a contract
ScanRelationTargetsExpand (source, relation) -> targets
ScanRelationSourcesExpand (target, relation) -> sources
FilterHasTemplateStructural template predicate
FilterHasContractStructural contract predicate
FilterHasTagStructural tag predicate
FilterScalarCompareField/channel comparison via runtime reader
SortByChannelOrdered iteration by resolved channel
LimitTake first N after current ordering
ProjectEntityEmit entity result

That covers the v1 pressure points without prematurely committing to a full variable-join VM. Add BindVariable / JoinVariable when there is a concrete lowering that needs them.


Channel, Modifier, and Dependency Integration

The six-phase channel pipeline remains the SECS value model:

Base -> Additive -> Multiplicative -> HardOverride -> Clamp -> Return

The kernel does not replace the channel resolver. It provides deterministic indexes and dependency edges the resolver needs:

  • active modifier bindings by target
  • active modifier bindings by owner
  • bindings by affected channel/field
  • propagation source to virtual binding mapping
  • per-target prepared modifier buckets
  • channel dependency edges discovered during resolution
  • field-write, relation-change, membership-change, and binding-change invalidation
  • prev-tick snapshot storage for tracked channels

ModifierEntry.ModId / mod attribution is reserved from day one as a host-agnostic integer id. The content manifest maps it to names and packages.


Determinism Contract

Determinism is not "the hashmap happens to iterate stably." Determinism is a semantic API guarantee.

Every kernel iterator must document its order:

  • entity sets: ascending entity id unless a declaration says source order
  • declaration tables: compiler output order
  • collections: collection ordering semantics (ScopedList order, ScopedDictionary key order, or explicit relation order)
  • query results: declared query order, explicit order_by, or stable fallback order
  • command journal apply: tick step order, system registration order, command sequence number, then entity id where batching is required
  • save/load sections: schema order, then stable key order

Internal hashmaps must still use deterministic hashing/iteration and allocators must use deterministic free-list behavior. Those are necessary implementation constraints. They are not sufficient by themselves.

Required Iterator Orders

IteratorOrder
all entitiesascending entity id
entities by contractactivation order unless query explicitly requests id order
entities by scopeactivation order within that scope unless query requests id order
relation targetsrelation Ordering
relation sourcesascending source id unless relation declares insertion/list order
ScopedList childrenexplicit list order
ScopedDictionary childrenascending key order
active modifiers on targetbinding application order, with prepared buckets preserving phase order
command journaltick step, system registration order, sequence number
save sectionsschema row order, then semantic key order

This table can be changed only by explicit design decision. No implementation may expose hash bucket order through these iterators.


Observability and ABI Reservations

The v1 instinct to reserve observability from day one is correct. The Unity-specific shape is not.

Kernel structs reserve host-agnostic fields and callback slots:

  • uint ModId on modifier binding / prepared modifier entries
  • TraceBridge.OnWalkTrace
  • TraceBridge.OnQueryTrace
  • TraceBridge.OnModifierTrace
  • opaque PerfMarkerId fields or marker ids in hot kernel components

The Unity adapter maps PerfMarkerId to Unity.Profiling.ProfilerMarker. The server adapter maps it to counters/log scopes. The kernel never references Unity profiling types.

Trace Payload Families

Trace payloads must be blittable or trivially serializable:

TraceRequired fields
walk tracesource entity, scope id, result entity, relation id, success/failure code
query tracequery id, op index, input count, output count, elapsed marker id
modifier tracetarget entity, modifier id, mod id, effect id, bucket, active/skipped reason
invalidation traceinvalidated entity/channel/relation, reason, generation before/after
diagnosticcode, severity, entity id, declaration id, optional payload token

Strings are resolved by tools through the content manifest and registry name tables. Hot kernel paths emit ids, not strings.


Save/Load and Hot Reload

The kernel state is saveable because it is semantic:

  • entity table
  • relation tables
  • modifier bindings
  • channel cache entries that are save-worthy
  • prev-tick snapshots
  • command journal if saving mid-tick is supported
  • content manifest: active content package, declaration names, ids, schema hash, mod attribution ids

Save/load format remains an open decision, but the content manifest is not optional. The manifest is the only way to survive modifier/template/channel renames across versions without silent loss.

Hot reload operates by comparing old and new WorldSchema instances and applying a controlled commit at a tick boundary. Pure data changes can patch declarations and invalidate affected caches. Structural changes rebuild affected relation/query/channel indexes.


Migration Strategy

Do not build a 15K LOC native primitive library in isolation and hope it matches SECS later.

V2 migration is contract-first:

  1. Define WorldSchema from the current registry/declaration tables.
  2. Define kernel semantic APIs and deterministic iteration contracts.
  3. Build a managed reference kernel for correctness tests if useful.
  4. Implement unsafe/native-backed kernel internals behind the same semantic APIs.
  5. Move scope walks and collection membership behind kernel relation indexes.
  6. Move InstanceStore entity/contract/scope indexes behind deterministic kernel tables.
  7. Move modifier binding indexes and propagation mappings behind kernel tables.
  8. Move channel dependency invalidation and prev-tick snapshots behind kernel tables.
  9. Add query-plan execution for generated stand-ins.
  10. Split generated execution lanes and replace generated signatures in one planned compatibility break.

The ISecsHostReads signature flip is still a major event for generated code, but the runtime can prepare for it by introducing compatibility facades before the final generated-output switch.

Validation Gates

No kernel implementation should be considered architecture-complete without:

  • differential tests against the current managed stores for InstanceStore, modifier bindings, channel cache invalidation, and prev-tick snapshots
  • property tests for relation add/remove/destroy invalidation
  • deterministic replay tests for command journal apply order
  • save/load round-trip tests with renamed modifier/template ids through the content manifest
  • query result order tests for every declared iterator order
  • adapter boundary tests proving engine/kernel assemblies have no Unity package references

The managed reference kernel, if built, exists to make these tests precise before unsafe storage enters the picture.


What We Explicitly Do Not Build

V2 does not build:

  • a general ECS replacement for SECS
  • Flecs systems, observers, modules, timers, or script parser
  • Unity DOTS as the canonical storage layer
  • a public raw collection library as the primary product surface
  • packed Flecs pair ids as the SECS identity model
  • author-facing query syntax before the semantic kernel can execute it

Open Decisions Deferred to the Companion Doc

The companion document relationship-bridge-open-questions.md tracks the decisions still required under this v2 framing:

  • exact kernel public API and assembly naming
  • entity handle layout and generation policy
  • relation metadata fields and lifecycle rules
  • command journal apply semantics
  • scope-walk cache invalidation model
  • query-plan IR shape
  • execution lane classification rules
  • host bridge split details
  • save/load format
  • hot reload commit policy
  • migration checkpoints

The key architectural decision in this document is already made: the bridge is a deterministic SECS semantic kernel, not a primitive-first Flecs clone.