Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
# Capability Spec: network-session
## Capability ID
`network-session`
## Status
PROPOSED
## Description
Logical session overlay on top of the tiered mesh network. Sessions provide player visibility scopes, nested hierarchies (free-roam → mission → phase), per-session host nomination, capacity enforcement, and seamless join/leave transitions.
## Interfaces
### `Session`
```typescript
interface Session {
readonly id: SessionId;
readonly parentId: SessionId | null;
readonly hostId: string;
readonly peers: ReadonlyArray<string>;
readonly capacity: number;
readonly rules: SessionRules;
readonly state: SessionState;
readonly depth: number;
}
```
### `SessionManager`
```typescript
interface SessionManager {
createSession(parentId: SessionId, config: SessionConfig): Session;
destroySession(sessionId: SessionId): void;
join(sessionId: SessionId, peerId: string): Promise<void>;
leave(sessionId: SessionId, peerId: string): Promise<void>;
move(peerId: string, fromSessionId: SessionId, toSessionId: SessionId): Promise<void>;
getSession(peerId: string): Session | undefined;
getSessionPath(sessionId: SessionId): ReadonlyArray<SessionId>;
}
```
### `SessionRouter`
```typescript
interface SessionRouter {
send(sessionId: SessionId, envelope: MessageEnvelope): void;
broadcast(sessionId: SessionId, envelope: MessageEnvelope): void;
sendToParent(sessionId: SessionId, envelope: MessageEnvelope): void;
}
```
### `SessionHostElection`
```typescript
interface SessionHostElection {
nominate(sessionId: SessionId): Promise<string>;
getHost(sessionId: SessionId): string | undefined;
}
```
## Behaviors
### NET-SESS-01 — Session tree
Sessions form a tree with exactly one root session per mesh. Each session has exactly one parent (except root). Cycles are impossible.
### NET-SESS-02 — Leaf membership
A peer belongs to exactly one leaf session at any time. The peer implicitly belongs to all ancestor sessions for parent-state-bridge purposes.
### NET-SESS-03 — Session-scoped routing
Messages sent within a session scope are delivered only to peers in that session or its descendants. Peers outside the scope do not receive the message.
### NET-SESS-04 — Upward routing
Messages with `scope: 'parent'` are delivered only to the parent session's host. This is used for child-to-parent state reporting (e.g., "mission complete").
### NET-SESS-05 — Broadcast within branch
Messages with `scope: 'broadcast'` are delivered to all peers in the target session and all descendant sessions.
### NET-SESS-06 — Per-session host election
Each session nominates its own host independently. The election uses the same scoring algorithm as mesh governance but scoped to session peers. A peer can host multiple sessions simultaneously.
### NET-SESS-07 — Host independence from mesh
The session host can be different from the mesh Tier 0 host. If the mesh host and session host are the same peer, that peer hosts both layers.
### NET-SESS-08 — Join with state snapshot
When a peer joins a session, the session host provides a state snapshot. The peer transitions through `requesting → syncing → active` before receiving live messages.
### NET-SESS-09 — Leave with cleanup
When a peer leaves a session, the session host cleans up peer state and notifies remaining peers. The leaving peer is moved to the parent session.
### NET-SESS-10 — Move with forwarding tunnel
When a peer moves from session A to session B, a temporary forwarding tunnel routes in-flight messages from A's host to B's host until the peer is fully synced.
### NET-SESS-11 — Capacity enforcement
`join()` is rejected when the session is at capacity. The rejection includes `session:capacity-exceeded` on the bus.
### NET-SESS-12 — Parent state bridge
Child sessions optionally receive read-only state from parent sessions (e.g., world time, weather). Child peers cannot send messages to parent.
## Error codes
- `NET_SESSION_NOT_FOUND` — Session does not exist
- `NET_SESSION_PEER_NOT_FOUND` — Peer not in session
- `NET_SESSION_CAPACITY_EXCEEDED` — Session at capacity
- `NET_SESSION_CYCLE_DETECTED` — Attempted to create session cycle
- `NET_SESSION_HOST_UNREACHABLE` — Session host not responding
- `NET_SESSION_TRANSITION_TIMEOUT` — Join/move/sync timed out
- `NET_SESSION_INVALID_SCOPE` — Unknown message scope
## Dependencies
- `@suaveplan/network`
- `@suaveplan/error`
- `@suaveplan/types`
- `@suaveplan/events`
- `@suaveplan/fsm`
- `@suaveplan/timing`
- `@opentelemetry/api`
- `zod`
## Notes
- Session depth should be bounded (suggested max: 4) to prevent routing overhead.
- Session state is in-memory only; persistence is deferred to `network-plugin-session-persistence`.
- The root session typically maps 1:1 with the mesh group.