Membrane visibility routing
Membrane routing is an alpha interface for controlling who may read and emit ordinary generated tokens. “Membrane” is a routing metaphor: it is not Half, encryption, a security boundary, or a hidden latent chain-of-thought channel.
The two streams
Section titled “The two streams”assistant_public tokens remain in model context and may be emitted. assistant_inner tokens also remain ordinary context tokens, but are removed from user-facing emission and can be hidden from non-assistant viewers by an explicit visibility matrix.
import torchfrom arti import ( MEMBRANE_STREAM_ASSISTANT_INNER, MEMBRANE_STREAM_ASSISTANT_PUBLIC, MembraneRoutingConfig, MembraneVisibilityRouter, build_membrane_visibility, membrane_emit_tokens,)
ASSISTANT, USER = 0, 1router = MembraneVisibilityRouter(MembraneRoutingConfig(hidden_dim=8))
hidden = torch.randn(1, 3, 8) # [B, T, D]targets = torch.tensor([[0, 1, 0]]) # [B, T], supervised routesrouted = router(hidden, stream_ids=targets)assert routed.stream_logits.shape == (1, 3, 2)
token_ids = torch.tensor([[101, 202, 303]]) # [B, T]assert membrane_emit_tokens(token_ids, routed.stream_ids) == [[101, 303]]
readable_by = torch.zeros(2, 2, dtype=torch.bool) # [participant, stream]readable_by[:, MEMBRANE_STREAM_ASSISTANT_PUBLIC] = Truereadable_by[ASSISTANT, MEMBRANE_STREAM_ASSISTANT_INNER] = True
visibility = build_membrane_visibility( routed.stream_ids, torch.tensor([USER]), readable_by)assert visibility.shape == (1, 3, 3) # [B, query, source]When stream_ids is supplied, the router uses those routes for supervised or curriculum training. When omitted, it chooses argmax over its learned two-way logits. The router does not generate token IDs.
hidden [B,T,D] → Linear(D,2) → stream logits/probabilities [B,T,2] ↓ route IDs [B,T]token IDs [B,T] ─────────→ public emission mask [B,T]route IDs + viewer policy ─→ visibility [B,T,T]Context and emission are separate
Section titled “Context and emission are separate”membrane_emit_tokens filters the public decode result; it does not delete inner tokens from model context. append_membrane_tokens appends token IDs together with stream metadata and, when supplied, participant and phase IDs. Pass the visibility returned above to an ARTI layer to enforce the read contract.
Treat the runtime as four independent planes:
| Plane | Input → output | Responsibility |
|---|---|---|
| Router | hidden → stream logits / IDs | Learned public-vs-inner assignment |
| Visibility | viewer + stream policy → [B,T,T] |
Which sources each query may read |
| Model context | token + stream metadata → next context | Retain both configured streams |
| User emit | token IDs + stream IDs → public IDs | Filter the external decode result |
Collapsing model-context append and user emission into one filter would delete the inner feedback path. Conversely, keeping a token in model context does not authorize emitting it.
Training and inference responsibility
Section titled “Training and inference responsibility”During training, provide target stream_ids and optimize the two-way stream_logits alongside the normal token objective. During inference, omit stream_ids so the trained router selects a stream; append all generated tokens to model-side context, then emit only the configured public streams. The API supplies this routing contract, but it does not mean an untrained base model already knows when an inner stream is useful.
Boundaries
Section titled “Boundaries”- The API enforces tensor routing invariants; it does not prove a language model has learned when to use inner speech.
- Hidden tokens are not secret against code with access to model memory, tensors, logs, or checkpoints.
- Applications must keep user emission filtering and model-context updates separate.
- This surface remains alpha in ARTI 1.7.0; validate it on the target model and task.