L2 — Collection lifecycle

L2 — Collection lifecycle

TL;DR. The OPTIONAL Collection-lifecycle service: named bundles of Terminals with an atomic-kill invariant. Servers MAY decline to mount L2; clients MAY decline to speak it. Wire discriminants are reserved but not yet allocated; L2 lands as a coherent unit in v0.2. The session vocabulary from earlier drafts is withdrawn.


1. L2 message catalog

A Collection is a named lifecycle bundle of Terminals (ADR-0015 §“L2”). A Terminal MAY belong to zero or one Collection. Killing a Collection MUST kill its member Terminals atomically. Detaching all clients from a Collection MUST leave the Collection and its Terminals alive.

L2 messages, reserved by ADR-0015 but not yet wire-allocated:

DirectionNameReferenceStatus
C → S (cmd)CREATE_COLLECTION§2TBD
C → S (cmd)ADD_TERMINAL_TO_COLLECTION§2TBD
C → S (cmd)REMOVE_TERMINAL_FROM_COLLECTION§2TBD
C → S (cmd)RENAME_COLLECTION§2TBD
C → S (cmd)KILL_COLLECTION§2TBD
C → S (cmd)LIST_COLLECTIONS§2TBD
S → CCOLLECTION_OPENED§1TBD
S → CCOLLECTION_CLOSED§1TBD
S → CCOLLECTION_RENAMED§1TBD
S → CCOLLECTION_MEMBERSHIP_CHANGED§1TBD

Discriminant bytes are allocated when L2 lands (target: v0.2). The earlier SESSION_OPENED / SESSION_CLOSED / SESSION_RENAMED messages at 0xA6 / 0xA7 / 0xA8 from 0.1.0-draft.6 are withdrawn: under ADR-0017 “session” is a TUI convention, not a wire concept. The bundle-as-named-lifecycle semantics it implied re-appear here as Collection, with the same atomic-kill invariant.


2. L2 commands

Reserved by ADR-0015. Wire discriminants TBD; allocated when L2 lands.

Command_L2 = tagged_union {
    CREATE_COLLECTION                { name: optional<str> },
    RENAME_COLLECTION                { collection_id: CollectionId, name: str },
    KILL_COLLECTION                  { collection_id: CollectionId },
    LIST_COLLECTIONS,
    ADD_TERMINAL_TO_COLLECTION       { collection_id: CollectionId, terminal_id: TerminalId },
    REMOVE_TERMINAL_FROM_COLLECTION  { collection_id: CollectionId, terminal_id: TerminalId },
}

CollectionId = tagged_union {
    LOCAL     { id: u32 },
    SATELLITE { host: str, id: u32 },
}

KILL_COLLECTION MUST kill the Collection’s member Terminals atomically: clients observe TERMINAL_CLOSED for every member, then COLLECTION_CLOSED. A partial-kill outcome is a protocol error.