Status: draft Type: standards-track Applies-To: TernaryOS network subsystem, driver/runtime boundary, user-facing network identity and tooling Created: 2026-03-26 Updated: 2026-03-26 Author: @t81dev Discussion: initial scope draft
This RFC proposes a standards-compatible TCP/IP stack for TernaryOS with a T81-native identity, representation, and observability layer.
The stack remains conventional on the wire:
The T81-specific layer appears above and around the wire protocol surface:
This RFC does not yet freeze a syscall ABI, socket API, or packet-capture file format. It establishes the architectural direction and the boundaries that future implementation work must preserve.
Concrete base-81 endpoint and evidence encodings are included as illustrative examples in Appendix A. Those examples are not yet normative, but they show the intended direction for user-facing notation and trace artifacts.
TernaryOS needs a networking story that is both practical and native to the rest of the system.
Purely conventional TCP/IP integration would provide interoperability, but it would also leave networking as an outlier subsystem with foreign naming, foreign diagnostics, and weak integration with T81 identity and audit primitives.
A fully custom “base-81 network stack” would move too far in the other direction. It would sacrifice interoperability and blur the contract being implemented. If the system claims to provide TCP/IP, then TCP/IP wire semantics must remain recognizable and standards-compatible.
The middle path is therefore:
That split preserves interoperability while making networking feel like part of the T81 system rather than a bolted-on compatibility module.
The network stack defined by this RFC is a TCP/IP implementation, not a translation layer for a distinct T81 wire protocol.
That means:
Any T81-native identity or naming layer must resolve onto standard protocol, address, and port tuples before transmission.
Base-81 is permitted and encouraged in the following roles:
Base-81 is not part of the normative binary wire format for TCP/IP itself.
This RFC distinguishes between:
The stack may be required to behave deterministically when driven by the same recorded sequence of:
This RFC does not require the external network to produce deterministic inputs, and it does not promise replay-stable outcomes against arbitrary peers.
The intended property is:
The initial protocol scope for the stack is:
These layers are responsible for:
The initial transport scope is:
UDP should provide the simplest end-to-end standards-compatible datagram path. TCP should provide a stream transport with standard connection setup, ordered delivery, retransmission, and teardown semantics.
Above the raw endpoint layer, TernaryOS should provide a T81-native resolution surface that maps:
onto:
This allows T81 tools to operate on native names while preserving standard network interoperability underneath.
The current architectural bias is toward immutable CanonFS-backed service descriptors and resolution manifests rather than a mutable runtime-first registry.
That bias is motivated by:
A runtime registry is not forbidden, but if introduced later it should be treated as an explicitly governed dynamic layer above the canonical manifest surface rather than the primary source of truth.
The preferred v1 resolution input is a CanonFS-backed immutable service descriptor manifest.
This RFC defines a first concrete descriptor contract named
t81.net.service-descriptor.v1.
The initial authoring and interchange format should be UTF-8 JSON with an
explicit top-level schema field, consistent with other versioned tool-facing
surfaces in the repository.
Each descriptor should identify:
Required logical fields:
schema: t81.net.service-descriptor.v1
service_id: <base81-service-id>
host_id: <base81-host-id>
transport: tcp | udp
address_family: ipv4
address: <standard textual IP literal>
port: <uint16>
manifest_ref: <canonfs object reference>
Optional logical fields:
interface_id: <optional base81-interface-id>
route_label: <optional base81-route-label>
policy_profile: <optional policy/profile ref>
trust_profile: <optional trust/profile ref>
labels: <optional array of base81 labels>
Descriptor rules:
service_id and host_id are the primary T81-facing identities.transport, address_family, address, and port are the standard
networking coordinates used for actual packet transmission.manifest_ref is the stable CanonFS identity of the descriptor artifact
used during resolution and should appear in audit and replay records.service_id, but selection rules
must be deterministic for a fixed manifest set and policy state.The likely design direction is that a resolver consumes one or more CanonFS
descriptors, applies deterministic filtering and policy, and produces a single
resolved endpoint tuple plus the manifest_ref lineage required for evidence.
Illustrative t81.net.service-descriptor.v1 JSON document:
{
"schema": "t81.net.service-descriptor.v1",
"service_id": "B6nP4",
"host_id": "Q2xA8",
"transport": "tcp",
"address_family": "ipv4",
"address": "192.0.2.14",
"port": 25,
"interface_id": "if:7Lm",
"route_label": "rt:primary",
"policy_profile": "default-egress",
"trust_profile": "tier1-peer",
"manifest_ref": "canonfs:K81A2M4...",
"labels": ["mail", "internal"]
}
The serialization format may evolve later, but any alternative encoding should preserve the same field semantics and schema versioning boundary.
schema
t81.net.service-descriptor.v1service_id
host_id
transport
tcp, udpaddress_family
ipv4address
port
1..65535manifest_ref
interface_id
route_label
policy_profile
trust_profile
labels
A descriptor must be rejected if:
schema is missing or unknowntransport is not one of the declared allowed valuesaddress_family is not supported by the implementationaddress is invalid for the declared familyport is outside the allowed rangemanifest_ref is not a valid CanonFS referenceA descriptor may be rejected if:
policy_profile or trust_profile names an unknown local policy surfaceinterface_id names an interface that does not exist in the current runtimeRejecting a malformed or unsupported descriptor is preferred over silently coercing it into a weaker interpretation.
Given a fixed set of CanonFS service descriptors and a fixed policy state, resolution should be deterministic.
For a request such as:
Q2xA8B6nP4tcpthe resolver should:
The tie-break rules are not yet frozen, but the RFC direction is:
This matters because connection setup evidence must be explainable after the fact. If a service identity resolves to one address in one replay and another in the next, the system loses one of the main benefits of a governed network subsystem.
The current v1 preference is:
service_idhost_id if one was suppliedtransport if one was suppliedhost_idservice_idtransportaddress_familyaddressportmanifest_refThat ordering is intentionally simple. It can be revised later, but any future revision must remain deterministic and auditable.
The stack should emit canonical network evidence records for:
These records should be sufficient to support:
The preferred direction is to integrate these records with existing Axion evidence conventions rather than invent a parallel observability system for networking.
At minimum, the replay/evidence model should be able to capture:
The design target is not just readable logs. The design target is a canonical event stream rich enough that the same recorded network inputs can reproduce the same stack-level behavior and evidence output on replay.
The following surfaces are explicitly in scope for base-81 enhancement:
The following areas should not be base-81-specialized in v1:
Those are transport and protocol mechanics, not representation or identity surfaces.
This initial draft intentionally leaves several decisions open:
These questions should be resolved before the RFC advances beyond draft.
This RFC adopts a layered API direction rather than choosing exclusively between a BSD-socket-like surface and a T81-native networking surface.
The intended architecture is:
This gives TernaryOS:
The lower user-facing boundary should expose conventional networking concepts such as:
This does not require a byte-for-byte POSIX socket API clone in the first implementation, but it does require that the transport-facing boundary remain clearly legible in standard networking terms.
The transport surface should operate on resolved endpoint coordinates such as:
This surface exists for:
Above the transport surface, TernaryOS should provide a native API that works in terms of:
service_idhost_idThis native layer should:
Illustrative operations in this layer:
net resolve B6nP4net connect B6nP4net connect Q2xA8:B6nP4net session show flow:9Qm2LxThese examples are non-normative, but they show the intended direction:
operators and T81-native tools should not need to work directly with raw
ip:port tuples unless they explicitly choose to.
The T81-native networking surface should lower into the conventional transport-facing surface rather than bypassing it with a separate transport implementation model.
That means:
This is important because it preserves both explainability and compatibility. A session should be auditable as:
B6nP4 on host Q2xA8”tcp, 192.0.2.14, port 25, manifest canonfs:...”not merely as a raw transport event divorced from the T81 naming layer.
This RFC does not freeze concrete syscall numbers, CLI syntax, or library function signatures for the networking API.
It does freeze the architectural expectation that:
The layered API should preserve enough detail that failures can be reported in both T81-native and transport-native terms.
Examples:
service_idThis matters because a governed networking surface should let operators answer two different questions:
The reporting model should make a hard distinction between:
Illustrative distinction:
net connect Q2xA8:B6nP4trust_profile=tier1-peernet connect Q2xA8:B6nP4tcp 192.0.2.14:25 via canonfs:K81A2M4...This distinction should also appear in evidence records so that audits can differentiate:
This RFC adopts a staged deployment strategy.
The preferred initial implementation target is virtual or internal networking first, followed by external NIC-backed networking later.
The first implementation should prioritize network paths where both endpoints and most event sources are inside the TernaryOS-controlled environment.
Examples include:
This phase is preferred because it allows the project to validate:
without immediately taking on the full nondeterminism and device complexity of external networks.
External networking should follow after the internal model is stable.
This phase extends the same architectural contract to:
The purpose of delaying this phase is not to avoid external networking. The purpose is to avoid coupling the first architectural validation of the stack to all external hardware and network variability at once.
The internal-first deployment strategy must not create a throwaway architecture.
Phase 1 and Phase 2 should share:
The difference between phases should primarily be the device and peer boundary, not the meaning of service identity or connection lifecycle.
An internal-first strategy is the most defensible path for this project specifically because TernaryOS places unusual weight on:
Those properties are easier to establish in a controlled virtual environment before extending them across uncontrolled external networks.
The main risk of an internal-first strategy is overfitting to simulated or well-behaved environments.
To limit that risk, the project should ensure that Phase 1 tests include:
That keeps the initial stack honest without forcing full hardware bring-up on day one.
This RFC is designed to maximize interoperability by preserving conventional TCP/IP wire semantics.
The T81-specific layer is additive:
not a replacement for standard networking behavior.
This direction adds complexity relative to a minimal host-socket wrapper because it requires:
That cost is justified only if TernaryOS intends networking to be a native subsystem rather than a thin compatibility shim.
This RFC will eventually require:
Rejected as the sole architecture.
It provides quick utility but gives TernaryOS little control over evidence, traceability, or T81-native identity. It is acceptable as a bootstrap aid, not as the architectural endpoint.
Rejected for the TCP/IP RFC.
That would be a different protocol family, not TCP/IP. If pursued, it should be specified later as an overlay or adjacent transport above standard networking.
Rejected.
External networks are inherently nondeterministic. The correct contract is deterministic internal stack execution under a recorded event/timer trace, not a promise that real-world peer interactions always replay identically.
Before this RFC should move from draft to proposed, follow-on work should
settle:
This appendix is non-normative. It exists to make the intended user-facing benefits concrete before the exact encoding is frozen.
Conventional endpoint:
192.0.2.1:443/tcp
Illustrative T81-facing rendering:
tcp://3Kp8N.7f:tls
Where:
3Kp8N is an illustrative base-81 host identifier7f is an illustrative compact rendered address fragmenttls is a service alias that resolves to port 443The exact split between rendered address material and service alias remains open for later drafts.
The likely rendering goals are:
The precise base-81 alphabet and rendering grammar remain open. This RFC only commits to the need for a canonical rendering, not yet the final character set.
The rendering grammar should optimize for:
Illustrative sketch:
endpoint := transport "://" host "." service
endpoint_raw := transport "://" host ":" port
flow_ref := "flow:" flow_id
packet_ref := "pkt:" packet_id
This sketch is non-normative. It exists to clarify the shape of the intended surface, not to freeze the exact grammar.
Illustrative CanonFS-backed resolution descriptor:
schema = "t81.net.service-descriptor.v1"
service_id = "B6nP4"
host_id = "Q2xA8"
transport = "tcp"
address_family = "ipv4"
ipv4 = "192.0.2.14"
port = 25
interface_id = "if:7Lm"
route_label = "rt:primary"
policy_profile = "default-egress"
trust_profile = "tier1-peer"
manifest_ref = "canonfs:K81A2M4..."
The key idea is that operators interact with the base-81 identity surfaces, while the resolver deterministically maps those identities to standard transport coordinates.
Illustrative flow reference:
flow:9Qm2Lx
Illustrative packet evidence reference:
pkt:5fA1zK
Illustrative replay bundle reference:
replay:net:2Mx81T
These identifiers are intended to be:
Illustrative raw-port fallback:
tcp://Q2xA8:25
Illustrative service-alias form:
tcp://Q2xA8.mail
Illustrative longer host/service identities:
udp://A8kLm2Z.sync
The intended rule is that service-alias rendering should be preferred when the alias is unambiguous in the current resolution context, while raw-port fallback must remain available for debugging, low-level tooling, and unresolved alias cases.
Illustrative operator flow:
$ net resolve Q2xA8:B6nP4
resolved service=B6nP4 host=Q2xA8 transport=tcp address=192.0.2.14 port=25 manifest=canonfs:K81A2M4...
$ net connect Q2xA8:B6nP4
session opened flow:9Qm2Lx endpoint=tcp://Q2xA8.mail
$ net session show flow:9Qm2Lx
flow:9Qm2Lx
request: Q2xA8:B6nP4
resolved: tcp 192.0.2.14:25
manifest: canonfs:K81A2M4...
policy: allowed
state: established
Illustrative policy-denied flow:
$ net connect Q2xA8:B6nP4
connect denied service=B6nP4 host=Q2xA8 policy=trust_profile:tier1-peer reason=peer-not-allowed
Illustrative transport-failure flow:
$ net connect Q2xA8:B6nP4
connect failed service=B6nP4 host=Q2xA8 resolved=tcp 192.0.2.14:25 error=tcp-timeout
These examples are still non-normative. They exist to show the intended user experience: