MultiverseSocial.com
Contents

Channels manual · Web 4

The > Web 4 < Channel Paradigm

Web 4 is solid: your data, your choice.

A Channel is a small program with one job and a numbered place in a fixed table. Sixteen core channels make up the machine. The first, Channel 0, is NetXecChannel: it is the System. As the conductor it starts all sixteen cores (itself included), gives each its own thread and its own slice of a shared bus, and tells them when to wake. Everything else plugs in beside them as sidecars and sub-channels.

The idea that goes with it is older than the code: the person who owns the data owns the machine that holds it. The source tree says it in one line in channels6-review/channel_data.h:4: “> Web 4 < Channel Paradigm is controlled by your Solid Pod.” Your solid pod holds your identity, your records and your choices. You can carry it, bind it to a server or a device when you need one, and unbind it again. Nothing is taken from the pod without your say.

Your data, your choice. Consent starts off. People-recognition starts off. Raw camera frames stay in your pod. Section 6 lists every default and where it comes from.

Go to section 6: privacy and ownership

At a glance

ItemValueSource
Core channels16 (ids 0–15)defines.h:19, 73-88
Sub-channel cells256 flat ids = core × 16 + sub; 93 carry a nameNetXecChannel.c:82-115
GPUChannel, the Blitter Bus (crossbar)512 slots × 16 KiB = 8,388,608 bytes; 36-byte slot header, 16,348 bytes of payload. These are NetXecChannel’s block today; GPUChannel is not connected to it yet planneddefines.h:50-59
Tick16 ms (about 60 per second)defines.h:28-32
Sidecar ids100 and above (Main 110, ContainerDisplay 111, SQL 112, config ids 100–104)MainChannel.h:28, ChannelConfig.h:25-29
Node ids64-bit, 0 is invalid; records are big-endian and mostly fixed sizeNODE-RECORD.md
Capability bitsIPV6 1, RELAY 2, DHT 4, AI 8, ALL 15meshrec.h:27

This page replaces the older “Channels · ContainerDisplayChannel roster & joins” page. The interactive join chart is still at /dev/channels/joins/.

How to read this manual

Every statement about the code is taken from the source files and carries a file:line reference. Where the sources do not say something, this page says planned or leaves it out. Each channel and each sub-channel wears one of these labels:

builtReal behaviour exists in the source (it may still be small). stubThe channel opens and holds state or settings, but there is no real device, codec or network behind it. name onlyThe name is reserved in the sub-channel table. No code is behind it. stagedWritten and tested offline, but not wired into the running system. plannedA design or a roadmap item. Nothing runs today.

“Opened at boot” is a separate question from “built”. Several sidecars have working code that nothing in NetXecChannel.c opens automatically; those are marked not opened at boot.

All numbers use decimal unless written 0x…. Offsets count from byte 0. “BE” means big-endian, the wire order of every pod record.

Part 1

NetXecChannel: the System, core Channel 0

built NetXecChannel.c (1,608 lines) is the “Web4 microkernel bootstrap and main loop” (NetXecChannel.c:1-15). It is the program that builds as solidpod.exe. NetXecChannel is the System: core Channel 0, one of the sixteen cores. In the current source, core 0 is named “System” in the name tables and there is no separate SystemChannel.c; this file holds its code. As core 0 it creates the sixteen cores (itself included), executes them and routes between them. Its job in four parts:

  1. Create the 16 core channels (its own System slot, channel 0, among them), each with a name, a lock, a run-state record and a thread (BootstrapChannels, NetXecChannel.c:466-556).
  2. Allocate the crossbar, the shared 8 MiB block that is meant to carry data between cores (NetXecChannel.c:481).
  3. Route wake-ups: when one channel has something for another, it sets a bit; the per-core threads (one per core, core 0 included) see it and run the matching handler from a 512-entry dispatch table (NetXecChannel.c:600-756).
  4. Run the main loop: poll the window system, tick STDIO and Container, run a watchdog, and shut everything down in a safe order (NetXecChannel.c:1301-1565).

The structures it owns

StructureBytesWhat it is
NetXecChannel336The record that holds core 0’s tables and the other cores: channel_base[16] (core 0 itself is channel_base[0], a Channel), buffer_block (the crossbar), threads[16], thread parameters, the event channel, the container, bridge and STDIO pointers, flags.
Channel488One channel: id, name, ch_input / ch_output crossbar slots, ch_event_flags, an I/O request queue of 16, a lock, runtime, run-info, thread, ch_listeners[16], ch_sub_channel[16], listener mask, QoS class (channels.h:277-297).
Runtime920The function table of a channel: init, start, run, paint, expunge, join, merge, leave, read, write, halt, pause, quit, open, close, plus 16 × 2 tables of lock, unlock and callback pointers.
RunInfo160Run state (RT_* 0–27), wait time, iteration count, timestamps.
HyperLock32A mutex plus a condition variable and a name, one per channel.
ChannelData80The typed-data header; see ChannelData flags.
EventChannel592Event ring owner; see System.

Sizes are compile-time asserts at channels.h:456-498. Also asserted there: IORequest 64, NetXecThread 64, ThreadParams 32, SPSCRing 32, Field 112, Object 312, MemoryHandle 64, ArbitrationChannel 2,128.

Boot sequence

OpenNetXecChannel (NetXecChannel.c:152-460) opens things in this order. Memory comes first because everyone allocates through it; it is closed last.

StepWhat happensLine
1Open Memory. Every other channel allocates from it, so it comes first and closes last.158
2Open Thread (the thread pool).166
3Allocate the NetXecChannel struct.174
4BootstrapChannels: allocate the crossbar and the 16 channel structs with their runtimes and run-infos.184
5Create a HyperLock for each channel.191
6Fill the thread parameters.220
7InitDispatchTable: 512 entries, all harmless defaults except one real handler.234
8GetChannelThreads: one thread per core.239
9Open Event (the OS-event ring).242
10Open Container (windows and display).251
11Open STDIO; join it to Event and to the Signal core (270-283).262
11bOpen MainChannel early (the session owner). Its joins wait until step 17.294
12 / 12b / 12cOpen URL, then Image, then Code (the Code Share front).308, 312, 316
13Open Server.320
14Open Font.324
15Open Media.328
16Open Clock and seat it in its core slot (ClockJoinCore: it sets the id, name and NetXec pointer and stores Clock in channel_base[6]; it makes no ChannelJoin call).341
17MainJoinHub joins MainChannel to every live core; the optional stubs that CHANNELS7_OPEN_* variables ask for are opened.365

The environment variables are read at NetXecChannel.c:289, 370-380, 398-454:

VariableDefaultEffect
CHANNELS7_OPEN_MAINon=0 skips MainChannel. The older name CHANNELS7_OPEN_USER=1 still forces it on.
CHANNELS7_OPEN_CONTAINER_DISPLAYoff=1 opens ContainerDisplayChannel (sidecar 111).
CHANNELS7_OPEN_SQLoff=1 opens SQLChannel (sidecar 112, a stub).
CHANNELS7_OPEN_NIMOSINIoff=1 opens the Nimosini placeholder (NetXecChannel.c:433). See channel 15.

Threads, wake-up flags and the dispatch table

Every core channel has its own thread (CoreChannelThread, NetXecChannel.c:600-695). The thread sleeps on the channel’s HyperLock condition, waking at least every 16 ms (ri_wait_time), or earlier when another channel pokes it.

The poke is one bit. Each channel owns a 64-bit ch_event_flags word. It is cut into 16 nibbles, one per possible sender (defines.h:34-44):

bit 0READbit 1WRITEbit 2JOINbit 3reserved

The woken thread reads and clears the word (NetXecChannel.c:662), then for each non-zero nibble n it looks up dispatch_table[IO_PERMUTATION_INDEX(n, self, dir)] and calls the handler (NetXecChannel.c:675-686). The index is (src<<5) | (tgt<<1) | dir with DIR_READ 0 and DIR_WRITE 1 (defines.h:55-62). Sixteen sources × sixteen targets × two directions = 512 entries.

Honest status. All 512 table entries are no-op defaults except one: SystemReadFromSignal (Signal → System), installed at NetXecChannel.c:755. The fabric is complete; the handlers for the other 511 cells are not written yet. planned

Known issue in the wake bits. The READ and WRITE macros build their mask by shifting a plain 32-bit int by ch × 4 (defines.h:41-44; the JOIN and RESERVED macros on lines 43-44 shift the same way). For senders 8–15 that shift reaches past bit 31, so those wakes are unreliable (the MASK macro already uses a 64-bit constant). The Signal sender, nibble 4, which the one live handler uses, is not affected. A fix that widens the constants to 64 bits has been proposed and is not applied. planned

Example flow: a key press reaches System

  1. The main loop polls the window system and turns each event into a 64-bit code with EncodeEvent (NetXecChannel.c:797-822). Key down is 0x05010000 | scancode<<8, key up 0x05020000…, mouse button down, button up and motion use 0x0601…, 0x0602… and 0x0603…. Motion packs x and y; button down and up pack the button number and x only (NetXecChannel.c:805-816). Quit is 0xFF010000.
  2. HandEventToEventChannel pushes the code on the EventChannel ring (NetXecChannel.c:1175-1216).
  3. WakeSystemForSignal sets the READ bit in System’s nibble 4 (NetXecChannel.c:853-863).
  4. System’s thread wakes and runs SystemReadFromSignal, which pops 8-byte codes from the ring into the crossbar slot [System][Signal][READ] (NetXecChannel.c:713-744).
  5. STDIO, joined to Event and Signal at boot, reads the same events from the Event ring through its own cursor (EventChannelPopSTDIO, STDIOChannel.c:525-540), not from the crossbar slot, for the command line (channel 12).

The sub-channel table

SubChannelAllocatedNames[256] (NetXecChannel.c:82-115) is the master list of names. A flat id is core × 16 + sub, so Memory’s “registry” (core 2, sub 4) is flat id 36. Unused cells hold the string “null”. Names are not code: the right-hand column of each channel card below says what, if anything, stands behind each name. The table below is generated straight from the source by a small C program, so it cannot drift.

Core channelFlat idsNamed sub-channels (sub index, name, flat id)
0 System0–150 stdin (0) 1 stdout (1) 2 stderr (2) 3 event (3)
1 Device16–310 gpu (16) 1 usb (17) 2 rs232 (18)
2 Memory32–470 heap (32) 1 stack (33) 2 shared (34) 3 cloud (35) 4 registry (36) 5 device (37) 6 page (38) 7 buffer (39)
3 Thread48–630 arbitration (48)
4 Signal64–79none — every cell is “null”
5 Media80–950 audio (80) 1 image (81) 2 video (82) 3 vlc (83) 4 tv (84) 5 audiowav (85) 6 player (86)
6 Clock96–1110 timer (96)
7 Container112–1270 menu (112) 1 screen (113) 2 twitter (114) 3 solid (115)
8 URL128–1430 ftp (128) 1 telnet (129) 2 gopher (130) 3 file (131) 4 chat (132) 5 irc (133)
9 Server144–1590 socket (144) 1 ftp (145) 2 apache (146) 3 mysql (147) 4 bml (148) 5 bql (149) 6 blockc (150) 7 debug (151) 8 portserver (152)
10 Process0160–1750 encryption (160) 1 statistics (161) 2 transform (162) 3 smc (163) 4 js0 (164) 5 js1 (165) 6 c (166) 7 fortran (167) 8 color (168) 9 antlr (169) 10 bitcoin (170) 11 wallet (171) 12 piet (172) 13 compression (173)
11 Process1176–1910 gps (176) 1 gprs (177) 2 bml (178) 3 bql (179) 4 html (180) 5 sql (181) 6 emscripten (182) 7 solid (183) 8 xml (184) 9 state (185) 10 shopping (186) 11 stock (187) 12 code (188)
12 STDIO192–2070 cli (192)
13 Compiler208–2230 x64 (208) 1 arm8 (209) 2 c (210) 3 fortran (211) 4 java (212) 5 emscripten (213) 6 js (214) 7 julia (215)
14 Debug224–2390 gdb (224) 1 vc (225)
15 Nimosini240–2550 neural0 (240) 1 neural1 (241) 2 neural2 (242) 3 neural3 (243) 4 neural4 (244) 5 neural5 (245) 6 neural6 (246) 7 neural7 (247) 8 grok (248) 9 bert (249) 10 chatgpt (250) 11 neuralnet (251)

Process1 “code” (flat id 188) is present in the source but was missing from the earlier version of this page. It is the Code Share front (docs/CODECHANNEL.md). Container’s header also defines a fifth sub, CC_SUB_CONFIG 4 (ContainerChannel.h:42), that the name table does not list.

The CoreChannelNames table (NetXecChannel.c:66-71) gives the display names; CoreChannelClearNames (:74-79) gives the STDIO prefixes such as SystemChannel (core 0, NetXecChannel) or ContainerChannel.

Main loop, watchdog and shutdown

  • Main loop (RunMainLoop, NetXecChannel.c:1301-1350): poll events; tick STDIO; run the watchdog; tick Container every 16 ms. The window is 1280×960, twice HyperView’s 640×480 (NetXecChannel.c:1226).
  • Watchdog (NetXecChannel.c:828-847): for each core that is sleeping on its wait condition (RT_WAITCOND) and has waited longer than its wait time plus 10 ms (100 ms if none is set), sets bit 0x1 and signals it, so an idle waiter always wakes.
  • Diagnostic menu: Esc opens a menu of keys r (print channel diagnostics), e, x, c, u, s, t; q quits (NetXecChannel.c:1059-1173).
  • Shutdown (NetXecChannel.c:1373-1565) follows the HyperView rule: mark every runtime RT_STOPPING then RT_SHUTDOWN, wake all threads, join every thread, wait up to 1 s for each runtime to reach RT_ZOMBIE or RT_STOPPED (then force RT_STOPPED), and only then close Server, Clock, Container, Image, Code, URL, Bridge, STDIO, Font, Media and Event, free the channels and the crossbar, and close Memory last.
  • main prints “NetXec: 16 core channels online” once boot completes (NetXecChannel.c:1571-1608).

Part 2

The sixteen core channels

Ids are CHANNEL_SYSTEM 0 to CHANNEL_NIMOSINI 15 (defines.h:73-88). Channel 0, System, is NetXecChannel (part 1); the other fifteen follow it. Each card gives: the id and status, what the channel is for, what reading and writing mean for it, its sub-channels, what it may be joined to, and an example flow. “Links” come from the draft join chart (docs/channel-joins.md); the binary does not enforce that chart yet (see Joins and the policy chart).

Reading a card: “read” and “write” are the two directions of the crossbar pair. A channel reads from the slot [self][peer][READ] and writes to [self][peer][WRITE] (channel_io.c:112-140). Core slot versus core id: bootstrap makes a plain Channel in every channel_base[n] (NetXecChannel.c:507-547). Only Clock replaces its slot (ClockJoinCore, ClockChannel.c:137). Container, URL, Media, Server and STDIO open their own channel object that carries the core id but leave the slot as bootstrap made it (ContainerChannel.c:4, 214, URLChannel.c:883, MediaChannel.c:41, ServerChannel.c:40, STDIOChannel.c:167). (Some source comments call these objects “sidecar”; this manual keeps “sidecar” for channels that are not the core’s own object.)

0 System (NetXecChannel) built code in NetXecChannel.c

Purpose
System is NetXecChannel, core Channel 0 (part 1). The root of the machine: standard streams, OS events, and the authority to start, stop and pause other channels. In the source it is the channel_base[0] slot with its own thread; there is no separate SystemChannel.c: its code is NetXecChannel.c. The EventChannel (the OS-event ring) reports itself as System’s sink: ch_id = CHANNEL_SYSTEM, name “Event” (EventChannel.c, “event sink rides on System”).
Read / write
Read from Signal: the one real dispatch handler in the whole table pops 8-byte event codes from the EventChannel ring into the crossbar (NetXecChannel.c:713-744, 755). Write: no handler yet. Design intent for the kill switch: System sets RT_STOPPING or RT_PAUSED on channel 15 and that always wins (Nimosini spec §2, planned).
Sub-channels
0 stdin (0)1 stdout (1)2 stderr (2)3 event (3) name only except event, which is the EventChannel ring: 64 KiB of 8-byte codes (8,192 events), single producer, lock-free flags, plus a second read cursor for STDIO (EventChannel.c).
Links
Chart allows Device, Memory, Thread, Signal, Media, Clock, Container, URL, Server, STDIO, Compiler, Debug, Nimosini. It denies Process0 and Process1.
Example
Key press → EncodeEvent → Event ring → SystemReadFromSignal → crossbar slot (no code consumes that slot yet, only debug prints peek at it: NetXecChannel.c:1003-1011, 1087-1093). STDIO reads the Event ring itself, through its own cursor, for the command line (see the walk-through).

1 Device stub

Purpose
Hardware: graphics, USB, serial. The planned home for cameras and microphones and for seeing a pod drive when it is plugged in.
Read / write
None yet. Nothing in the source opens these three channels at boot.
Sub-channels
0 gpu (16) stub GPUChannel, the Blitter Bus (crossbar), is the crossbar of the Web 4 Channel Paradigm (see part 3). Source channels7/GPUChannel.c (153 lines): a query-name call only, no device; never opened at boot and called by no other file. There is no CHANNEL_GPU: gpu is Device sub-channel 0 (flat id 16), and the stub sets its channel id to Device (GPUChannel.c:90), so it has no slot in the crossbar. The separate channels7-read/GPUChannel.c (1,838 lines) is a different file, described in part 3. 1 usb (17) stub DeviceUSBChannel.c: a vendor/product filter; enumerate returns 0 and open returns −2 (no libusb). 2 rs232 (18) stub DeviceRS232Channel.c: configure only; open-port returns −2.
Also homed here
GPSChannel.c and GPRSChannel.c set ch_id = CHANNEL_DEVICE (GPSChannel.c:90), although the name table lists “gps” and “gprs” under Process1. See Process1.
Links
Chart allows only System, Memory, Thread, Signal; every other pair is denied. Devices hand data to Memory, they do not talk to the network.
Planned
Camera and microphone frames delivered into Memory rings for channel 15 (Nimosini spec §2). USB volume detection for the portable pod (see bind on demand). planned

2 Memory built

Purpose
Every allocation in the system goes through Memory. It is opened first and closed last. The 8 MiB crossbar itself is allocated here as shared (IPC) memory (NetXecChannel.c:481).
Read / write
AllocMem / FreeMem take a request: size, name, RAM type, data type, dimension, flags (memory.h). A header (MemoryHandle, 64 bytes) and an IPC prefix sit in front of the memory you receive. Memory types (defines.h:376-383): HEAP 0, STACK 1, IPC 2, GPU 3, CLOUD 4, REGISTRY 5, PAGE 6.
What is real
IPC (POSIX shm / Win32 mapping, MemoryChannel.c:179, 219-232) and PAGE (mmap / VirtualAlloc, MemoryChannel.c:297-303) are real. HEAP and STACK are plain calloc (MemoryChannel.c:114-133). GPU, CLOUD and REGISTRY currently fall back to plain calloc. In the source: // TODO: SDL_GPUBuffer path and // TODO: remote pod-backed storage (MemoryChannel.c:262, 275). That second TODO is the hook where the pod will plug in; see Take your pod with you. planned
Sub-channels
0 heap (32)1 stack (33)2 shared (34)3 cloud (35)4 registry (36)5 device (37)6 page (38)7 buffer (39)
Code behind them: shared = SharedMemoryChannel.c, a named mapping built; buffer = BufferChannel.c over MemoryBuffers.h, a Java-NIO-style Buffer (position, limit, capacity, mark; flags READONLY, DIRECT, BIG_ENDIAN, MAPPED) built; registry = RegistryChannel.c, a thin preferences get/put front built; heap, stack, cloud, device, page = allocator types or names with no separate channel file.
Typed data
Memory also carries ChannelData (an 80-byte typed header: 32 data types in 4 dimensions) and Objects made of named Fields, saved as NAME.chd (defines.h:410-452, channel_data.h). Flags are tabled in ChannelData flags.
Links
Chart allows Memory to join all fifteen other cores; it is the shared floor.

3 Thread built

Purpose
The thread pool and the thread records. GetNetXecThread hands out threads (up to MAX_CPU_THREADS 64), each pointing at its owner channel’s RunInfo and HyperLock (ThreadChannel.c:186-187, defines.h:19-32).
Portable threads
PodThread (256 bytes, thread.h:53-66) is a thread you can sign and send: name[80], id u64, owner WebID[64], signature[64], entry hash u64, data bytes u64, memory type, flags, priority, stack size. PodThreadFromLocal, PodThreadSign (Ed25519) and PodThreadVerify work. PodThreadToLocal — turning a received pod thread back into a running one — is a TODO that returns −1 (ThreadChannel.c:359-366). planned
Sub-channels
0 arbitration (48) not opened at boot ArbitrationChannel.c is a sidecar lock-request queue (256 requests, 4 workers, channels.h:370-387). Nothing in the NetXec bootstrap opens it, and the arbitration pointer in NetXecChannel is never set.
Links
Chart allows System, Device, Memory, Signal, Clock, Container, Process0, Process1, STDIO, Nimosini. It denies Media, URL, Server, Compiler, Debug.
Example
Every core channel’s own thread is started at boot by GetChannelThreads (step 8).

4 Signal built small

Purpose
Soft signals and the path events take into the system. SignalChannel is a software latch: SignalArm, SignalDisarm, SignalRaise, SignalPoll, SignalClear, a queue of 16 (SignalChannel.h). It installs no OS signal handlers.
Read / write
As a core slot, Signal is the source side of the one real handler: System reads “from Signal”. STDIO is joined to the Signal core at boot (NetXecChannel.c:277-283). The sidecar OpenSignalChannel is not called by the bootstrap. not opened at boot
Sub-channels
None — all sixteen cells (flat 64–79) are “null”.
Links
Chart allows Signal with every core except Compiler.
Planned
Nimosini spec: Signal carries mail, news and peer-up / peer-down events to channel 15. planned

5 Media built mostly stubs

Purpose
Pictures, sound and video. A MediaChannel is opened at boot step 15, carries core id 5, and groups three sub-slots: VIDEO 0, AUDIO 1, TELECONFER 2 (MediaChannel.h:17-19). It does not replace the core slot channel_base[5].
Sub-channels
1 image (81) built ImageChannel.c: URL-driven, non-blocking (rides the curl pool), interlaced fill so a picture appears progressively, observers are notified; opened at boot step 12b.
0 audio (80) stub AudioChannel.c: a PCM queue with play/stop flags; no audio device.
5 audiowav (85) stub AudioWavChannel.c: parses WAV into a buffer; play is a stub.
2 video (82) stub VideoChannel.c: stubs, no ffmpeg; aware of the video pod flags.
3 vlc (83) stub VLCChannel.c: reads a path from preferences only.
6 player (86) stub PlayerChannel.c: path and transport state only.
4 tv (84) name only.
Calls
The phone records (see Phone records) say who rings whom; the sound and picture of a call belong to Media. Constants for audio and video rings, codecs (OPUS 1, AV1 2, H264 3, VP9 4) and media states are in defines.h:581-604. Nimosini never touches call media (spec §2). The real media engine is planned.
Links
Chart allows System, Memory, Signal, Clock, Container, STDIO.

6 Clock stub

Purpose
Time and ticks for everyone else. ClockChannel.c is described in its own source comment as a “thin compile-clean skeleton” (ClockChannel.c:3): it opens, counts iterations and stamps the time; its status string reads “Clock open stub”. It is opened at boot (step 16) and seated in its core slot by ClockJoinCore (ClockChannel.c:131-138): the call sets its id, name and NetXec pointer and stores it in channel_base[6]. It makes no ChannelJoin call, so at boot nothing joins Clock to a peer except the one join MainJoinHub adds; the draft join chart below says which links are meant. Its wait time is 40 ms.
Sub-channels
0 timer (96) name only
Links
Chart allows System, Memory, Thread, Signal, Media, Container, STDIO.
Planned
Rate-limit windows and the scheduler tick for Nimosini (spec §2). The draft join chart, however, denies Clock↔Nimosini, so this needs reconciling (see the open questions). planned

7 Container built

Purpose
The screen: windows, gadgets, graphic objects (gobs), menus. ContainerChannel is the HyperView-parity UI catalog. Limits: 64 containers, 16 windows, 256 members, 64 gobs; the view is 640×480 (ContainerChannel.h). It is ticked every 16 ms by the main loop and is closed before Image at shutdown.
Read / write
Anything that can be seen is a Container “kind” (CC_KIND_* 0–18: file, archive, window, container, channel, solid, gob, gadget, animated gob, text pane, super-bitmap, file pop-up, prefs pane, title bar, memory window, server config, pup catalog, scroll bar). Each frame is drawn in the HyperView order: animate → composite → status → present (ContainerChannel.h, display tick).
Sub-channels
0 menu (112)1 screen (113)2 twitter (114)3 solid (115) — ids 0–3 are CC_SUB_MENU/SCREEN/TWITTER/SOLID. screen is backed by ScreenChannel.c (display query) built; solid by SolidChannel (see Process1); menu and twitter are names.
Sidecars
BridgeChannel gives Container a main()-like entry (argc/argv) and a console sink. FontChannel (SDL3_ttf optional). ContainerDisplayChannel (id 111) is a display-name layer over Container; the core id stays 7 (opened only when CHANNELS7_OPEN_CONTAINER_DISPLAY=1). ChannelConfig is the Container “config board” with 16 user-defined channel slots and LINK / SET_RT operations (ChannelConfig.h:20-35).
Links
Chart allows System, Memory, Thread, Signal, Media, Clock, URL, STDIO, Nimosini.
Planned
The owner’s setup and consent screen for Nimosini is drawn by Container (spec §2). planned

8 URL built

Purpose
Fetching things by address. URLChannel is a singleton (ch_id 8, URLChannel.c:883) with a libcurl multi pool. A fetch is only queued (URLFetch, URLFetchStart); progress happens on every channel tick (URLChannelTick), so Container never blocks on the network. URLCancel sets a cancel flag and the next tick removes the transfer (URLChannel-CURL.md).
Schemes
http://, https:// and file:// go through libcurl. tachyon://host:port/path does not: it uses the TachyonDB page wire (PAGE_GET, tachyon_page.c) on a small helper thread (URLChannel.c:12). The contract says URLChannel tries Tachyon first and falls back to the Blitz docroot when a page is not found or Tachyon is down (WEB4-CONTRACT.md, “Storage”).
Sub-channels
3 file (131) built FileChannel.c: local file I/O through stdio (ch_id 8, FileChannel.c:148).
0 ftp (128)1 telnet (129)2 gopher (130)4 chat (132)5 irc (133) name only
Links
Chart allows System, Memory, Signal, Container, Server, STDIO. It denies Device, Thread, Media, Clock, Process0, Process1, Compiler, Debug, Nimosini. The Nimosini spec lists URL as never used by the AI (tier 3).
Example
A page asks for a picture: Image calls URLFetchStart; curl runs on the tick; the done-ring hands bytes back; Image paints them in interlaced passes.

9 Server config only

Purpose
Where this machine listens and answers. In the desktop runtime, ServerChannel only holds a listen port and a bind address. Its header says it plainly: “Does NOT bind a socket yet” (ServerChannel.h:4); the LISTENING flag is reserved and never set, and ServerChannel.c contains no bind, listen or accept calls. A future listener is to run on its own thread so the main loop never blocks.
Sub-channels
8 portserver (152) stub PortServerChannel.c hands off to ServerChannel.
5 bql (149) built BQLChannel.c keeps a query string and the TachyonDB connection settings and speaks PAGE_GET / PAGE_PUT. (Its ch_id in code is Process1, BQLChannel.c:105.)
4 bml (148) built, small BMLChannel.c is a buffer bridge whose stream starts with the magic bytes ‘B’, ‘M’, ‘L’, 0x02. The full walk is done by the bml/ library and BlitzBrowse. (Its ch_id in code is Process0, BMLChannel.c:90.)
0 socket (144)1 ftp (145)2 apache (146)3 mysql (147)6 blockc (150)7 debug (151) name only
Beyond the desktop
The site side is separate code: a headless daemon with the Blitz protocol on TCP 23232 (see Blit path and Blitz), and the mesh endpoint /cgi-bin/mesh.cgi that mesh/MESH-SPEC.md specifies for the mesh handshake. The sources do not show the mesh endpoint as live. In the Nimosini design, Server holds the pod’s signing key and signs the three whitelisted AI mesh messages (spec §8).
Links
Chart allows System, Memory, Signal, URL, Process0, Process1, STDIO. It denies Nimosini — see the conflict in open questions.

10 Process0 some built

Purpose
The first group of workers: crypto, counting, compression, colour, and a long reserve list of language and finance names.
Sub-channels
0 encryption (160) built EncryptionChannel.c: AES-256-GCM compiled in, no libsodium. Wire format nonce(12) | ciphertext | tag(16), so output is input + 28 bytes; an AAD variant binds CodeVault blobs (repo_id||"BLOB") and manifests (repo_id||"MANI") (EncryptionChannel.h:2-8, 49).
13 compression (173) partial CompressionChannel.c: STORE (raw) and a simple RLE of (count, value) pairs. DEFLATE is a TODO: “no zlib/miniz in tree” (CompressionChannel.c:2, 217-219). planned
1 statistics (161) stub a tick counter.
8 color (168) stub RGBA packing and a 256-entry palette.
2 transform (162)3 smc (163)4 js0 (164)5 js1 (165)6 c (166)7 fortran (167)9 antlr (169)10 bitcoin (170)11 wallet (171)12 piet (172) name only
Also homed here
JavaChannel.c (:90) and BMLChannel.c (:90) set ch_id = CHANNEL_PROCESS0; the name table lists java under Compiler and bml under Server and Process1.
Links
Chart allows Memory, Thread, Signal, Server, Process1, STDIO, Compiler, Debug, Nimosini. It denies System, Device, Media, Clock, Container, URL.
Example
Code Share uploads a project: the Code front asks Encryption for AES-256-GCM with the repository id as AAD, then Server carries the sealed blob. The key stays with the owner’s Ed25519 identity (SolidChannel.h:1-9).

11 Process1 some built

Purpose
The second group of workers: data, code, markets and location.
Sub-channels
12 code (188) built codechannel/CodeChannel.h: the Cont front for Code Share. One dispatcher with drivers for CodeVault (CODEVAULT 1, speaking PCL opcodes), git (2) and svn (3), with room for more; opened at boot step 12c and closed before URL (docs/CODECHANNEL.md). The core name table is untouched.
11 stock (187) built StockChannel.c: a quote sidecar around SP_StockConfig, a 48-byte record (symbol[16], exchange[8], last price × 10,000, bid, ask, flags, volume) (StockChannel.h:2-5).
3 bql (179) built the same BQLChannel listed under Server; its code is homed on Process1.
5 sql (181) stub SQLChannel.c is a sidecar with id 112; its driver kinds are NONE, STUB and SQLITE (reserved); there is no SQLite in the tree (SQLChannel.h:23). Opened only by CHANNELS7_OPEN_SQL=1.
9 state (185) stub StateMachineChannel.c: a state id.
0 gps (176)1 gprs (177) stub last-fix store and APN store; no NMEA parser, no modem. Homed on Device in code (see Device).
2 bml (178)4 html (180)6 emscripten (182)7 solid (183)8 xml (184)10 shopping (186) name only in this core.
SolidChannel
built SolidChannel.c is the SolidPod object sidecar. It is homed on Container (SolidChannel.c:93) and surfaced as Container’s solid sub-channel. It carries the CodeVault client hooks: client-side AES-256-GCM through Encryption, Ed25519 ownership signatures (ed25519_pod / cv_sign, secret key = seed‖public key, 64 bytes), and the signed request headers Code Share sends to the server (SOLID-AUTH-HEADERS.md): X-Solid-WebID, X-Solid-Ts, X-Solid-Pk (64 hex), X-Solid-Sig (128 hex) over the text CV-SOLID|v1|<webid>|<ts>|<METHOD>|<path>. SolidChannel never invents keys; they come from the caller’s buffers (SolidChannel.h:78, 110).
Links
Chart allows Memory, Thread, Signal, Server, Process0, STDIO, Compiler, Debug, Nimosini. It denies System, Device, Media, Clock, Container, URL.

12 STDIO built

Purpose
The cooked text hub: the command line, logging and key input. STDIOChannel (616-byte struct) has an input and an output ring. Writes go to the output ring and wake joined peers; STDIOTick drains it to a sink and reads events via EventChannelPopSTDIO. Printable keys arrive through STDIOFeedKey only (STDIOChannel.h:7).
Marshal prefixes
Lines are tagged with the sender’s clear name (CoreChannelClearNames, NetXecChannel.c:74-79), for example ContainerChannel:.
Sub-channels
0 cli (192) built CLIChannel.c (832-byte struct: line[256], prompt[32]). Commands: abort (leave a stuck display frame) and help or ? (CLIChannel.c:37, 48). STDIO is the only channel that fills ch_sub_channel[16].
Links
Chart allows every core except Device. At boot it is joined to Event and to Signal.

13 Compiler stub

Purpose
Turning source into programs. Today CompilerChannel.c stores a source path and nothing else (no code generation). stub
Sub-channels
4 java (212) stub JavaChannel.c records java_home from preferences; no JVM is started. 0 x64 (208)1 arm8 (209)2 c (210)3 fortran (211)5 emscripten (213)6 js (214)7 julia (215) name only
Links
Chart allows System, Memory, Process0, Process1, STDIO, Debug. Everything else is denied, including Signal and Nimosini. The Nimosini spec lists Compiler as never used by the AI (tier 3).

14 Debug slot only

Purpose
Reserved for debugging. There is no Debug source file; the core exists only as its slot, thread and lock. The Esc diagnostic menu in NetXec is a separate facility, not this channel (NetXecChannel.c:1059-1173).
Sub-channels
0 gdb (224)1 vc (225) name only
Links
Chart allows System, Memory, Signal, Process0, Process1, STDIO, Compiler. It also denies Nimosini; the Nimosini design would have Debug show counters, which the draft chart does not allow (see open questions).

15 Nimosini design / planned

Status, plainly
Core id 15 is reserved for Nimosini (defines.h:88), and the name table gives it twelve sub-channel names. There is no working Nimosini code in the running system. NimosiniChannel.c and NeuralNetChannel.c in channels7 are placeholders, they open only when CHANNELS7_OPEN_NIMOSINI=1, and nothing in this manual treats them as design sources. Everything below comes from the draft specification NIMOSINI-CHANNEL-SPEC.md (draft 2, 2026-10-02, “design only”). planned
Role
One Nimosini per pod. It is the AI aggregator and controller for that pod. On the mesh it appears as “Nimosini @ node id”: the same name and avatar everywhere, with the pod’s 64-bit node id as its instance id. A pod that has not granted anything stays dormant: it announces presence and does nothing else.
Sub-channels
Flat ids 240–255, all name only, no code behind them: 0–7 neural0…neural7 (240–247)8 grok (248)9 bert (249)10 chatgpt (250)11 neuralnet (251) and cells 252–255 are “null”. Design roles: nets 0–5 = cameras (vision and depth), net 6 = audio input, net 7 spare; grok is reserved and not wired; bert is the encoder slot and chatgpt the text slot (the spec calls them the “Burt” and “GPT” slots). Sub-channels have no crossbar slot of their own (channel_io.c:136-139). The staged prototype uses different names for 248–250; see open questions.
Nets
Each net is independent: its own ring, weights, thresholds and failure state. Frames are 8-bit ARGB words, big-endian, default 1080×720 = 3,110,400 bytes. Audio is signed 16-bit big-endian, mono, 16 kHz. Weight files are “NMW1”: a 64-byte header plus 32 bytes per layer, up to 64 layers.
How it is controlled
A one-time grant by the owner, scoped by a 15-bit mask (see AI records). Four tiers: 0 observe; 1 reversible and local; 2 outward or exposure-increasing — allowed only if the scope is granted and the action is untainted and rate limits allow; 3 never (grants, keys, weights, compiler or URL use, audit edits, avatar generation, peer commands). Anything built from text or audio the owner did not provide is tainted and capped at tier 1. Hard limits: a hash-chained audit log (32-byte records, 32,768 of them = 1 MiB), a kill switch that always wins (System channel, RT_STOPPING / RT_PAUSED), per-verb rate limits (tier 1 up to 20 per minute; tier 2 up to 12 per hour and 4 per hour per verb; mail up to 5 per hour), and a breaker that trips on 5 failures in 1 minute or 3 undo taps in 10 minutes.
Keys
Nimosini never holds the signing key. Server (channel 9) holds it and signs only three message types. Nimosini cannot sign anything else or impersonate the pod.
Resources
The owner sets RAM and disk for it: RAM 256–8,192 MiB (default 1,024), disk 2,048–65,536 MiB (default 8,192), never more than 50 % of physical RAM or 25 % of free disk (airec.h:38-63). Running a language model in the pod needs at least 2,048 MiB of RAM. The language-model engine itself is planned to be a separate OS process.
Lifecycle
INIT (read config; no grant = DORMANT) → PROBE → JOIN → RUN, with DEGRADED, PAUSED and BREAKER side states → STOPPING → STOPPED. Tick 16 ms, 12 ms AI budget per tick.
Links
Chart allows System, Memory, Thread, Signal, Container, Process0, Process1, STDIO. It denies Device (cameras reach it through Memory rings), Media (it never touches call media), Clock, URL, Server, Compiler and Debug. In the design: Memory holds the read-only frame and audio rings; Signal brings events; Container draws the owner’s setup and consent screen. The design also wants a tick from Clock, key custody and signing from Server, and counters on Debug, all three of which the draft chart denies (see open questions).
Not built
The Nexus pyramid share formula (60 % RAM / 40 % disk, weighted by 30-day uptime) is a proposal only. planned

Part 3

Sidecars, the Blitter Bus (crossbar) and the blit path

Sixteen cores are not enough for a whole system, so Channels has three more ideas that sit beside them. Sidecars are extra channels with ids of 100 and above. The join fabric says who is connected to whom. GPUChannel, the Blitter Bus (crossbar), is meant by design to carry the data between the cores: the Blitter Bus is the crossbar of the Web 4 Channel Paradigm. planned What exists today: NetXecChannel allocates the 8 MiB block Crossbar8MB (512 slots × 16 KiB, NetXecChannel.c:481); only SystemReadFromSignal writes to it; ChannelWriteSlot and ChannelReadSlot have no callers; and GPUChannel is not connected to it yet. Together these are the “bus” of this manual.

About the Blitter Bus. GPUChannel, the Blitter Bus (crossbar), is the crossbar of the Web 4 Channel Paradigm. Today that crossbar is the 8 MiB block that NetXecChannel allocates (NetXecChannel.c:481; see The crossbar below). Which file is meant matters. channels7/GPUChannel.c (153 lines) is a query-name stub with no device: nothing opens it at boot and no other file calls it (see Device). A separate file, channels7-read/GPUChannel.c (1,838 lines), is an offscreen renderer that uses CPU loops and does not use the crossbar; it does not build against channels7, because commands.h, BitPack.h and ThreadChannelGPUDrawLines are missing. There is no CHANNEL_GPU: “gpu” is Device sub-channel 0 (flat id 16), and the stub sets its channel id to Device (GPUChannel.c:90), so as a sidecar it has no slot in the crossbar. Do not confuse the Blitter Bus with two other things that carry similar names, both described in Blit path and Blitz: the Container’s dirty-rectangle blit that puts pixels on screen, and Blitz, the network protocol on TCP 23232. (Lineage only: the name echoes the blitterList / blitterLock graphics-update queue of the older Java HyperView.)

Sidecars

A sidecar is a channel that is not one of the sixteen. It has the same parts as a core (buffer, Runtime, RunInfo, lock) and can be joined to cores, but it lives outside the 16×16 matrix. Two kinds exist:

  • Own-id sidecars (id ≥ 100): they have an id of their own.
  • Homed sidecars: most of the code files (Image, URL helpers, Encryption, Stock, …) are sidecars that claim a core id as their home. They do not add a sixteenth-and-first core.
IdSidecarWhat it isStatus
110MainChannelThe session hub; formerly UserChannel (the old name remains as an alias). Holds a direct peers[16] table; MainJoinHub joins it to every live core; MainWriteTo is its direct write helper. Flags OPEN / READY / JOINED. STDIO prefix “MainChannel” (MainChannel.h:11, 28).built default on
111ContainerDisplayChannelA display-name layer around Container. Its core id stays 7 (CONTDISP_CORE_ID) (ContainerDisplayChannel.h:29).built default off
112SQLChannelDatabase front. Driver kinds NONE / STUB / SQLITE (reserved); no SQLite in the tree (SQLChannel.h:23). SQLJoinCore joins Server, Process1 and Memory.stub default off
100–104Config ids: Event 100, Bridge 101, Font 102, Stock 103, BQL 104Names used by the Container “config board” (ChannelConfig.h:25-29) so a link between two sidecars can be drawn. In memory only; 16 user-defined channels; operations LINK and SET_RT.built
—ArbitrationLock-request queue under Thread (see channel 3).not opened at boot

How a sidecar is joined. ChannelJoin stores a core peer at the index equal to the peer’s id; a sidecar takes the first free of the 16 listener slots, and the listener mask bit is the slot index (channel_io.c:50-64). Sidecars have no crossbar slot: ChannelBindIO leaves their input and output pointers NULL (channel_io.c:136-139). They use their own buffers and wake bits. A wake sent by any id of 16 or more is recorded as coming from Signal, nibble 4 (channel_io.c:158-160). The join policy for sidecars is kept apart from the core chart (docs/channel-joins.md, “policy by sidecar id ≥ 100”).

The crossbar (the Blitter Bus)

One contiguous block, allocated by Memory as shared memory at boot (NetXecChannel.c:481):

  • 512 slots = 16 channels × 16 peers × 2 directions, each 16 KiB, 8,388,608 bytes in all (defines.h:50-59).
  • Slot address: base + (((ch*16 + peer)*2 + dir) * 16384) (CROSSBAR_SLOT, defines.h:55).
  • Each core gets ch_input = [self][peer][READ] and ch_output = [self][peer][WRITE] for a joined core peer (channel_io.c:112-140). Before binding, ch_output = ch_input (NetXecChannel.c:545).
  • Data moves in 8-byte words. The writer advances the interrupt cursor; the reader advances the user cursor (channel_io.c:184-230).

Slot header (36 bytes) · channels.h:160-177

OffsetSizeFieldMeaning
08ptrPointer to external payload (if any)
88ext_sizeSize of the external payload
164interruptProducer write cursor (byte offset into data)
204userConsumer read cursor
244sizeUsable data size
284seq / reserved32Sequence counter if CROSSBAR_SEQ_ENABLED; that switch defaults to 0 (defines.h:64-67)
321typePayload type
331flagsSlot flags
342reserved16Reserved
3616,348data[]The payload (16,384 − 36)

The crossbar does not enforce per-writer permissions. It is one block in one process with no memory protection between slots. ChannelWriteSlot and ChannelReadSlot contain no permission test; the join mask is never consulted on a write (channel_io.c:184-230); ChannelWakePeer trusts the sender id the caller passes (channel_io.c:151-170). Any code running in the process can write any slot. Rules such as “this ring is written only by its producer” hold by convention, not by enforcement. This is the reason the AI design keeps keys out of the AI channel and routes signing through Server, and why the join chart (below) is still only a policy.

Two more facts a reader of the code will notice. ChannelWriteSlot(A,B) fills [A][B][WRITE] while ChannelReadSlot(B,A) reads [B][A][READ], which is a different address. The one handler written so far, SystemReadFromSignal, writes straight into the reader’s own READ slot (NetXecChannel.c:727-744). And a slot is a plain wrapping buffer of 8-byte words with no lock and no “full” check. A set of proposed fixes (per-pair lock, range checks, a status return from the wake call) exists as an unapplied patch.

Joins and the policy chart

  • ChannelJoin(a, b) is symmetric. It fails on self or NULL, and for a sidecar peer when the listener slots are all in use (core peers are stored at index = their channel id, so a core-to-core join cannot run out of slots, channel_io.c:50-55), and it rolls back if only one side succeeds (channel_io.c:85-100). ChannelLeave undoes it (:102-110); ChannelIsJoined asks (:172-182).
  • Joins made at boot: STDIO ↔ Event and Signal; MainChannel ↔ every live core (MainJoinHub). ClockJoinCore is not a join: it only seats Clock in channel_base[6] (ClockChannel.c:131-138, no ChannelJoin call). NimosiniJoinCore would seat channel_base[15] and join Signal and Memory when the optional stub is enabled; SQLJoinCore joins Server, Process1 and Memory (docs/channel-joins.md).
  • The draft join chart below is the policy the designers want: of the 256 ordered core pairs, 144 ALLOW, 96 DENY, 16 SELF. As undirected pairs that is 72 allowed links. Memory is allowed with all; the “dense core” is System, Memory, Thread, Signal, Clock, Container, STDIO; the rest are spokes. It is generated from docs/channel-joins-corexcore.csv.
  • Not enforced yet. The document itself says “No hard allow-table in binary yet.” A later step is a join_policy[16][16] table consulted inside ChannelJoin, and showing it in the Container config board. planned
  • Counting the name cells instead: 256 cells make 65,536 ordered pairs (about 255²). That figure shows why the design does not mesh everything.
src ↓ / tgt →0123456789101112131415
0 System·✓✓✓✓✓✓✓✓✓××✓✓✓✓
1 Device✓·✓✓✓×××××××××××
2 Memory✓✓·✓✓✓✓✓✓✓✓✓✓✓✓✓
3 Thread✓✓✓·✓×✓✓××✓✓✓××✓
4 Signal✓✓✓✓·✓✓✓✓✓✓✓✓×✓✓
5 Media✓×✓×✓·✓✓××××✓×××
6 Clock✓×✓✓✓✓·✓××××✓×××
7 Container✓×✓✓✓✓✓·✓×××✓××✓
8 URL✓×✓×✓××✓·✓××✓×××
9 Server✓×✓×✓×××✓·✓✓✓×××
10 Process0××✓✓✓××××✓·✓✓✓✓✓
11 Process1××✓✓✓××××✓✓·✓✓✓✓
12 STDIO✓×✓✓✓✓✓✓✓✓✓✓·✓✓✓
13 Compiler✓×✓×××××××✓✓✓·✓×
14 Debug✓×✓×✓×××××✓✓✓✓·×
15 Nimosini✓×✓✓✓××✓××✓✓✓××·

✓ ALLOW   × DENY   · SELF   Row = source channel, column = target channel; the column numbers are channel ids. For the interactive chart see /dev/channels/joins/.

Blit path and Blitz

The display blit (inside one machine)

Container draws every frame in the HyperView order animate → composite → status → present. To avoid redrawing the whole 640×480 view each time, it keeps a list of dirty rectangles: ContDirtyAddRect(x, y, w, h) adds one, ContDirtyClear empties the list, ContDirtyCount returns how many there are, and ContDirtySetFullBlit(on) says “redraw everything” (the count then reads −1) (ContainerChannel.h:727-730, cont_wave.c:734-745). Title bars and the wave code call the full-blit switch whenever something large changes (Titlebar.c:222, cont_wave.c:102).

Blitz (between machines)

Blitz is the binary request/response protocol the headless server speaks on TCP 23232, with BML pages as its content (WEB4-CONTRACT.md, “Blitz protocol”). All Blitz numbers are little-endian — unlike pod records, which are big-endian. A frame is [opcode u8][flags u8][reserved u16][length u32] then the payload. Flags: MORE 1, ERR 2. The tables below follow WEB4-CONTRACT.md and the channels7 copy blitzbrowse/blitz_proto.h; the newer master channels-server/blitz_proto.h adds opcode NOP 0x00, method PUT 0x04, two more header ids and the statuses 201, 401 and 409.

OpcodeNameDirectionPayload
0x01HELLOclientmagic “BLZ1”, version 1, caps u32, client name
0x02HELLO_ACKserversame shape
0x10REQUESTclientmethod (GET 1, HEAD 2, POST 3), URL
0x11 / 0x12HEADER / END_HEADERSclientfield id + value; ids 1 content-type, 2 content-length, 3 user-agent, 4 host, 5 connection, 6 accept
0x20RESPONSEserverstatus u16 (200, 400, 404, 408, 413, 500), then headers
0x21 / 0x22BODY / ENDserver16 KiB chunks, then end
0x30 / 0x31 / 0x32 / 0x7FCLOSE / PING / PONG / ERROReithercontrol

Capability bits: BML 1, CHDD 2, KEEPALIVE 4 (keep-alive is not implemented; one request per connection). Limits: payload 1 MiB, 64 headers, URL 1,024, header value 4,096, 30 s I/O timeout. The page store behind it is TachyonDB (PAGE_PUT / PAGE_GET, local port only). By contract (WEB4-CONTRACT.md, “Storage”), inline Blitz sends are capped at the crossbar slot payload, 16,348 bytes, while larger pages use references; no Blitz code uses crossbar slots today. The data object on the Blitz wire is CHDD. The blob starts with the u32 magic 0x43444844 (CHD_SER_MAGIC_CD, chd_serialize.h:20), written little-endian, so the first four bytes on the wire are 44 48 44 43; then version u32 = 1; then the 80-byte ChannelData body, 88 bytes in all (CHD_CD_WIRE_SIZE, chd_serialize.c:49). An object uses 0x4348444F (CHD_SER_MAGIC_OB). The comments in the source and WEB4-CONTRACT.md call the magic “CHDD”, but 0x43444844 does not spell that in either byte order; the name is a label, not the bytes. BML v2 pages start with ‘B’ ‘M’ ‘L’ 0x02 and are little-endian too.

Part 4

Take your pod with you, bind on demand

A solid pod is a person’s own store: identity, records, files and settings, owned by them and signed by their key. The Web 4 idea is that the pod does not live in a server. The pod is the thing, and a server or a device is somewhere it binds when it needs CPU and a network connection, and leaves when it does not.

Status. The pieces below are real; the whole journey is mostly a design (GALAXYGATE.md, “design lock” 2026-09-26). Each step is marked. Nothing in this section runs end to end today.

What makes a pod portable

  • Everything is a record, mostly fixed size, and most carry a version byte. Big-endian, one write per record, 64-bit node ids (records). A record can be copied to a drive, a phone or another server and still means the same thing.
  • Records are signed. Ed25519, compiled into the source (TweetNaCl-style), no external library. Each family has its own signing tag so a signature from one family can never pass as another’s: W4MESHv1 (mesh), W4NMv1 (Nimosini), W4PHv1 (phone).
  • Identity is a WebID, the standard Solid way. The pod’s node card lives in its Solid pod and is linked from the WebID profile (MESH-SPEC.md).
  • Threads are portable too. A PodThread is 256 bytes, signable with the pod key (Thread). Restoring one on the receiving side is a TODO. planned
  • Memory has a pod hook. The CLOUD allocator is marked TODO: remote pod-backed storage (MemoryChannel.c:275). planned
  • Data can carry a “belongs to the pod” tag. Three ChannelData flags are defined for this: HOME_BOUND (bit 19), TRANSPORT_HOME (20) and POD_AUTHORITATIVE (21) (defines.h:676-712). They are defined only; no behaviour is documented yet.

Bind on demand: the thumb-drive story

The design rule is one sentence: “The thumbdrive is the node. Host supplies CPU and network; drive supplies identity and data.” The drive holds a sealed pod package: WebID, sealed key store, friend (FOAF) list, phone number, a pointer to the DHT root, and a pod marker. It is not an operating-system image.

  1. Plug in. The host sees a removable volume. Device’s USB channel is to be the sensor, and today it is still a stub. planned
  2. Detect and bind. Container recognises the pod marker and binds: it opens the pod, loads the WebID and phone number, and starts a local front door (an Apache with the BML module, or a Solid endpoint) on a local address. planned
  3. Open the door, if allowed. If GalaxyGate is on, the host is on DHCP and the owner allows it, UPnP may open ports 80 and 443. planned
  4. Say where you are. The pod registers a signed record in the IP registry: “phone / WebID → current IP:port, with a time-to-live and the public key”. The signature is made with the pod’s Ed25519 key, so a random host cannot steal a number. planned
  5. Unplug. The pod unregisters, or its record simply expires. planned

Many pods, one machine. Plug several drives into a USB hub and many pods bind on one compute brick, each keeping its own WebID, phone number and port. planned

Trust rules locked in the design

  • Binding or publishing is never silent on an unknown host such as a café PC. It needs local consent, an unlock PIN or key, and/or a host allow-list.
  • The first mount on a host needs a confirmed phone number and an unlock.
  • A stolen drive must not advertise itself without being unlocked.
  • The registry says where, never what. Content stays in the pod or the DHT, so the registry is not a chokepoint for content. Where the registry runs is an open question.
  • A call needs mutual enable: A may ring B only if B is on A’s list and B has enabled A. The phone number is the human dial id; the friend graph is FOAF; Solid WebID stays the identity on the wire.
  • Not Kubernetes ingress, and not GalaxyCore (a thin Docker / kubectl relay). Content is never published automatically from a sealed pod on an unknown host.

Phase sketch (design)

#PhaseStatus
1Design documentdone
2ApacheChannel stub: open, start, stop, status, generate config with a sample BML locationplanned
3GalaxyGate flag: DHCP detection; call the existing UPnP helper only when the flag is on; no port mapping without consentplanned
4IP registry v0: signed register, lookup and TTL; dialling uses the lookupplanned
5Portable bind: volume marker, USB or volume watch, bind, registerplanned
6FOAF and mutual enable enforced on the call path; Solid WebID on the wireplanned

The flag name SP_FLAG_GALAXY_GATE is only proposed in the design note. It does not exist in defines.h. Pod cloud (a 4 KB resident file system per user) is likewise intent only.

The mesh: WebID, Ed25519 handshake, DHT

Pods find and trust each other without a central switchboard. The flow in mesh/MESH-SPEC.md (draft) is:

  1. Discovery. B fetches A’s WebID profile. The profile links to the pod’s node card: node id, public key, mesh endpoint.
  2. Challenge. A sends B a random one-time nonce with a short expiry.
  3. Proof. B signs with Ed25519; A checks the signature against the key in B’s profile. HELLO and CHALLENGE are unsigned, so nothing is trusted until the PROOF verifies.
  4. Admission. A adds B to its peer table with “WebID-verified” and “key-pinned” set; state goes handshake → online. B joins the DHT.
  5. Ongoing. Every message is signed. A key rotation must be signed by the old key.

The endpoint is /cgi-bin/mesh.cgi, and the message types are HELLO 1, CHALLENGE 2, PROOF 3, ACCEPT 4, PEERS 5, LEAVE 6. Safety rules: rate limits per address and per WebID, a banned state, never fetch private or loopback addresses when resolving a WebID, constant-time comparisons, no secrets in logs. The records are specified in meshrec.h and tested in C (node-records/test_*); a live mesh endpoint is not shown in the sources. records built · endpoint planned

What is signed. The signature is Ed25519 over the 8-byte tag W4MESHv1 followed by every byte of the message before the signature; the signature is always the last 64 bytes. The verifier rejects non-canonical S values and zero, identity or small-order keys (meshsig.h).

The DHT (planned)

Pod content is meant to be found by key through a Kademlia-style table with 64-bit routing keys and XOR distance: 64 buckets × 16 entries × 16 bytes = 16,384 bytes of routing table. Message types: PING 0x10 … STORED 0x18, and a HEAD record 0x40 of 174 bytes (dhtrec.h, draft 1; design in dht-fs/DESIGN.md). There is no live DHT. planned

One Nimosini per pod

The AI controller (channel 15) travels with the pod and is exactly one per pod. Every pod announces a presence record, even a dormant one (NM_PRESENCE, AI records), so peers see a single “Nimosini @ node” per pod. A pod advertises the AI capability bit (CAP_AI = 8) only while a valid, granted AI configuration exists; otherwise the bit is stripped before the hello or node card is built (airec.h:125-138). Peers may serve each other language-model requests only when the owner has switched that scope on.

Part 5

Solid pod structure: bits, sizes, capabilities

The pod has three layers, and this part of the manual covers all three. Read them from the inside out:

  1. The pod struct (struct SolidPod): a lean index of identity, settings and pointers. Big data stays as files in the encrypted pod archive (SOLID-POD-INTENT.md).
  2. Flag words: 64-bit words that switch features on and off, and pack small settings. Two sets exist in the sources: set A (defines.h, canonical) and set B (solid_pod.h, being conformed to A); both are shown.
  3. Wire records: big-endian, mostly fixed-size records that travel between pods. These are the pod’s public language.

Two flag sets. Set A is channels7/defines.h: SP_FLAG_* (64 bits) and SP_FLAG2_* (packed fields plus flag bits). Set A is canonical. Set B is the older pod header solid_pod.h v6.1 with SP_FEATURE_*, SP_USER_*, SP_SOCIAL_* and SP_STORE_*; it is being conformed to set A (a pending change, not done yet). The two sets describe the same fields with different names and bit numbers, and both headers define the five names SP_MAX_BLOG_POSTS, SP_GET_THEME, SP_SET_THEME, SP_GET_INTEREST_COUNT and SP_SET_INTEREST_COUNT with different definitions. This page prints both exactly as written and labels the file.

The SolidPod struct (v6.1)

From solid/solid_pod.h (660 lines): magic SP_POD_MAGIC 0x504F4453, version SP_POD_VERSION 0x00060001, config version SP_CONFIG_VERSION 2. In the pod file the first fields are the header, then identity, profile, bit words, times, quotas, home page and the collections. The offsets below were computed by compiling a small C program against that header with 64-bit gcc; the total is 78,416 bytes. Fields after sp_video_url contain pointers or nested structs whose sizes depend on the 64-bit build.

Note: the header comment says “HEADER – 16 bytes” but its fields (magic, version, size, checksum, config version) occupy 24 bytes. Offsets here follow the fields.

Struct fields with offsets and sizes (53 fields)
OffsetSizeFieldGroupMeaning
04sp_magicheadermagic number
44sp_versionheaderpod format version
88sp_sizeheadertotal size
164sp_checksumheaderchecksum
204sp_config_versionheaderconfig version
2432sp_usernameidentityuser name
5664sp_emailidentityemail
120128sp_webididentityWebID URL
24832sp_pod_ididentitypod id
28064sp_display_nameprofiledisplay name
344512sp_bioprofilebio text
85664sp_locationprofilelocation text
92032sp_avatar_hashprofileavatar hash
952512sp_pod_urlpodpod URL
14648sp_flagsbit wordsfeature bits (set B: SP_FEATURE_*; set A: SP_FLAG_* and SP_FLAG2_*)
14728sp_user_flagsbit wordsuser bits (set B: SP_USER_*; set A: SP_FLAG_* in sp_flags)
14808sp_social_flagsbit wordssocial link bits (set B: SP_SOCIAL_*; set A: SP_FLAG_SHOW_* for 8 of the 12)
14888sp_storage_flagsbit wordsstorage mode bits (SP_STORE_*)
14968sp_ui_prefsbit wordspacked UI preferences
15048sp_interestsbit wordspacked interests and position
15128sp_crc64bit wordsCRC-64
15208sp_session_bitsbit wordssession bits
15284sp_created_attimecreated
15324sp_last_modifiedtimelast modified
15364sp_last_logintimelast login
15404sp_last_backuptimelast backup
15444sp_session_expirysessionsession expiry
15484sp_session_idsessionsession id
15524sp_session_timeoutsessionsession timeout
15564sp_session_last_actsessionlast activity
15604sp_storage_quota_mbquotastorage quota MB
15644sp_storage_used_mbquotastorage used MB
15684sp_bandwidth_quota_mbquotabandwidth quota MB
15724sp_bandwidth_used_mbquotabandwidth used MB
157664sp_cloud_keystoragecloud key
1640256sp_local_pathstoragelocal path
1896128sp_home_titlehome pagehome title
20248192sp_home_contenthome pagehome content
10216512sp_video_urlhome pagevideo URL
1072847304sp_walletcollectionswallet block
58032128sp_calendarcollectionscalendar index
5816048sp_notescollectionsnotes index
5820848sp_bookmarkscollectionsbookmarks index
5825648sp_taskscollectionstasks index
5830448sp_contactscollectionscontacts index
5835256sp_messagescollectionsmessages index
584081480sp_blogcollectionsblog index
59888424sp_podfscollectionspod file-system index
60312480sp_dhtmeshDHT block
6079212616sp_aimeshAI block
73408776sp_nexusmeshNexus 8-layer pyramid
741843976sp_socialsocialsocial links
78160256sp_reservedtailreserved
Collection limits (SP_MAX_*)
CollectionMaximum
Blog posts512
Notes2,048
Messages2,048
Tasks2,048
Contacts1,024
Bookmarks4,096
Events, groups, pages, podcasts, badges256 each
Wiki, news, goals, achievements512 each
Reviews1,024
Leaderboards, tournaments128 each

Source: solid_pod.h (collection limits block). Only the blog-posts limit exists in both headers: 512 here in set B, 256 in set A (defines.h:352); the conform will take 256. The other limits in defines.h:349-353 exist only in set A and have no counterpart here: social links 32, cron jobs 16, webhooks 8, named flags 64.

Flag words and bit defines

Set A (canonical) · channels7/defines.h: SP_FLAG_ and SP_FLAG2_

Set A is the canonical flag set. These two tables list the defines.h names and bit numbers exactly as written (checked row by row against defines.h:157-276).

sp_flags · SP_FLAG_* (all 64 bits)

Several names overlap in meaning (for example UPNP_ENABLED 19 and ENABLE_UPNP 39; FEDERATION_ENABLED 17 and ENABLE_FEDERATION 41). They are printed as written. defines.h:157-220.

BitNameMaskSource
0SP_FLAG_EMAIL_CONFIRMED0x0000000000000001defines.h:157
1SP_FLAG_PHONE_CONFIRMED0x0000000000000002defines.h:158
2SP_FLAG_MEMBER0x0000000000000004defines.h:159
3SP_FLAG_DEVELOPER0x0000000000000008defines.h:160
4SP_FLAG_ADMIN0x0000000000000010defines.h:161
5SP_FLAG_ANIMATIONS0x0000000000000020defines.h:162
6SP_FLAG_COMPACT_MODE0x0000000000000040defines.h:163
7SP_FLAG_TWO_FACTOR_ENABLED0x0000000000000080defines.h:164
8SP_FLAG_CLOUD_BACKUP_ENABLED0x0000000000000100defines.h:165
9SP_FLAG_ENCRYPTION_ENABLED0x0000000000000200defines.h:166
10SP_FLAG_STREAMING_ENABLED0x0000000000000400defines.h:167
11SP_FLAG_RECORDING_ENABLED0x0000000000000800defines.h:168
12SP_FLAG_VIDEO_AUTO_ANSWER0x0000000000001000defines.h:169
13SP_FLAG_PAINT_AUTO_BACKUP0x0000000000002000defines.h:170
14SP_FLAG_AI_MODEL_ENABLED0x0000000000004000defines.h:171
15SP_FLAG_AI_SHARE_USAGE0x0000000000008000defines.h:172
16SP_FLAG_RECOVERY_ENABLED0x0000000000010000defines.h:173
17SP_FLAG_FEDERATION_ENABLED0x0000000000020000defines.h:174
18SP_FLAG_MESH_DISCOVERY_ENABLED0x0000000000040000defines.h:175
19SP_FLAG_UPNP_ENABLED0x0000000000080000defines.h:176
20SP_FLAG_UPNP_AUTO_REGISTER0x0000000000100000defines.h:177
21SP_FLAG_WEB4_ENABLED0x0000000000200000defines.h:178
22SP_FLAG_LOGGING_ENABLED0x0000000000400000defines.h:179
23SP_FLAG_METRICS_ENABLED0x0000000000800000defines.h:180
24SP_FLAG_METRICS_SHARE_NETWORK0x0000000001000000defines.h:181
25SP_FLAG_DEVELOPER_MODE0x0000000002000000defines.h:182
26SP_FLAG_TERMINAL_ENABLED0x0000000004000000defines.h:183
27SP_FLAG_API_ENABLED0x0000000008000000defines.h:184
28SP_FLAG_MEDIA_AUTOPLAY0x0000000010000000defines.h:185
29SP_FLAG_USE_EMBEDDED_HTML0x0000000020000000defines.h:186
30SP_FLAG_USE_BACKGROUND_IMAGE0x0000000040000000defines.h:187
31SP_FLAG_USE_BANNER0x0000000080000000defines.h:188
32SP_FLAG_USE_FAVICON0x0000000100000000defines.h:189
33SP_FLAG_USE_LOGO0x0000000200000000defines.h:190
34SP_FLAG_ENABLE_VIDEO_NETWORK0x0000000400000000defines.h:191
35SP_FLAG_ENABLE_DHT0x0000000800000000defines.h:192
36SP_FLAG_ENABLE_WEBSOCKET0x0000001000000000defines.h:193
37SP_FLAG_ENABLE_WEB40x0000002000000000defines.h:194
38SP_FLAG_ENABLE_PARALLEL_JOBS0x0000004000000000defines.h:195
39SP_FLAG_ENABLE_UPNP0x0000008000000000defines.h:196
40SP_FLAG_ENABLE_CLOUDRAM0x0000010000000000defines.h:197
41SP_FLAG_ENABLE_FEDERATION0x0000020000000000defines.h:198
42SP_FLAG_SHOW_FACEBOOK0x0000040000000000defines.h:199
43SP_FLAG_SHOW_TIKTOK0x0000080000000000defines.h:200
44SP_FLAG_SHOW_INSTAGRAM0x0000100000000000defines.h:201
45SP_FLAG_SHOW_YOUTUBE0x0000200000000000defines.h:202
46SP_FLAG_SHOW_MASTODON0x0000400000000000defines.h:203
47SP_FLAG_SHOW_BLUESKY0x0000800000000000defines.h:204
48SP_FLAG_SHOW_TWITTER0x0001000000000000defines.h:205
49SP_FLAG_SHOW_TELEGRAM0x0002000000000000defines.h:206
50SP_FLAG_BLOG_ENABLED0x0004000000000000defines.h:207
51SP_FLAG_BLOG_COMMENTS_ENABLED0x0008000000000000defines.h:208
52SP_FLAG_BLOG_MODERATION_ENABLED0x0010000000000000defines.h:209
53SP_FLAG_BLOG_RSS_ENABLED0x0020000000000000defines.h:210
54SP_FLAG_BML_ENABLE_EDITOR0x0040000000000000defines.h:211
55SP_FLAG_BML_ENABLE_PREVIEW0x0080000000000000defines.h:212
56SP_FLAG_BML_ENABLE_DEBUG0x0100000000000000defines.h:213
57SP_FLAG_BQL_ENABLE_CACHE0x0200000000000000defines.h:214
58SP_FLAG_BQL_ENABLE_INDEXING0x0400000000000000defines.h:215
59SP_FLAG_BQL_ENABLE_LOGGING0x0800000000000000defines.h:216
60SP_FLAG_PHONE_ENABLED0x1000000000000000defines.h:217
61SP_FLAG_VIDEO_WAN_ENABLED0x2000000000000000defines.h:218
62SP_FLAG_SFU_ENABLED0x4000000000000000defines.h:219
63SP_FLAG_FLAGS_INITIALIZED0x8000000000000000defines.h:220
sp_flags2 · packed fields (bits 0–29)

defines.h:226-247; accessors SP_GET_* / SP_SET_* at :279-337.

FieldShiftMaskBits
interest_count00x3F6
nexus_level60x073
theme (LIGHT 0, DARK 1, AUTO 2)90x032
log_level (OFF 0 … DEBUG 4; DEBUG does not fit the 2-bit field, so setting it stores 0)110x032
media_quality (AUTO, 1080P, 720P, 480P)130x032
paint_format (PNG, JPG, WEBP)150x032
cron_max_jobs170x0F4
profile_visibility (PUBLIC 0, FRIENDS 1, PRIVATE 2)210x032
online_status (HIDE 0, SHOW 1)230x011
last_seen_visibility240x032
cron_flags260x0F4
sp_flags2 · SP_FLAG2_* flag bits (28 bits: 30, 32–58)

defines.h:249-276.

BitNameMaskSource
30SP_FLAG2_SESSION_VALID0x0000000040000000defines.h:249
32SP_FLAG2_NEXUS_ENABLED0x0000000100000000defines.h:250
33SP_FLAG2_PAINT_ENABLED0x0000000200000000defines.h:251
34SP_FLAG2_VIDEO_ENABLED0x0000000400000000defines.h:252
35SP_FLAG2_MEDIA_ENABLED0x0000000800000000defines.h:253
36SP_FLAG2_CRON_ENABLED0x0000001000000000defines.h:254
37SP_FLAG2_PARALLEL_ENABLED0x0000002000000000defines.h:255
38SP_FLAG2_BML_ENABLED0x0000004000000000defines.h:256
39SP_FLAG2_BQL_ENABLED0x0000008000000000defines.h:257
40SP_FLAG2_WEB4_ENABLED0x0000010000000000defines.h:258
41SP_FLAG2_UPNP_ENABLED0x0000020000000000defines.h:259
42SP_FLAG2_DHT_ENABLED0x0000040000000000defines.h:260
43SP_FLAG2_FEDERATION_ENABLED0x0000080000000000defines.h:261
44SP_FLAG2_MESH_ENABLED0x0000100000000000defines.h:262
45SP_FLAG2_CLOUDRAM_ENABLED0x0000200000000000defines.h:263
46SP_FLAG2_TAR_ENCRYPTION_ENABLED0x0000400000000000defines.h:264
47SP_FLAG2_BACKUP_ENABLED0x0000800000000000defines.h:265
48SP_FLAG2_RECOVERY_ENABLED0x0001000000000000defines.h:266
49SP_FLAG2_AI_ENABLED0x0002000000000000defines.h:267
50SP_FLAG2_METRICS_ENABLED0x0004000000000000defines.h:268
51SP_FLAG2_LOGGING_ENABLED0x0008000000000000defines.h:269
52SP_FLAG2_DEVELOPER_ENABLED0x0010000000000000defines.h:270
53SP_FLAG2_API_ENABLED0x0020000000000000defines.h:271
54SP_FLAG2_TERMINAL_ENABLED0x0040000000000000defines.h:272
55SP_FLAG2_SOCIAL_ENABLED0x0080000000000000defines.h:273
56SP_FLAG2_BLOG_ENABLED0x0100000000000000defines.h:274
57SP_FLAG2_NOTIFICATIONS_ENABLED0x0200000000000000defines.h:275
58SP_FLAG2_WEBHOOKS_ENABLED0x0400000000000000defines.h:276
Roles, auth levels, reserved bit types
GroupValuesSource
Auth levelNONE 0, EMAIL 1, PHONE 2, HARDWARE 3defines.h:540-575
Roles (bits 0–6)MEMBER, DEVELOPER, MODERATOR, ADMIN, OWNER, SERVICE, GUESTdefines.h:540-575
Device trustlevels 0–3defines.h:540-575
ActionsACT_READ_PUBLIC 0 … ACT_RECOVERY_USE 16 (17 actions)defines.h:540-575
Reserved bit typesTERMINATE 1, FLUSH 2, PRIORITY 3, ERROR 4, HEARTBEAT 5, CONFIG_RELOAD 6, METRICS 7, SNAPSHOT 8, ZOMBIE 9defines.h:359-367
Phone / media limits8 phone devices, 512 call-history entries, 1,024 media streams; audio ring 64 KiB, video ring 4 MiBdefines.h:581-604
Cloud block4,096 bytes; magic 0x534F4C44defines.h:639-644
Crypto sizeshash 64, nonce 24, SRTP key 32, salt 14; ML-DSA-87 public / private / signature 2,592 / 4,896 / 4,624; ML-KEM-1024 public / private / ciphertext 1,568 / 3,168 / 1,568; X25519 32; Ed25519 32defines.h:523-534

Set B (being conformed to set A) · solid_pod.h v6.1: feature, user, social, storage bits

Set B is the older pod-header naming. It is being conformed to set A (a pending change, not done yet): names that exist in both sets will take the defines.h name and bit number, and the rest stay pod-only. Until that lands, these tables print the header as it stands, so the bit numbers below do not match set A.

Each is a 64-bit word in the struct (sp_flags, sp_user_flags, sp_social_flags, sp_storage_flags). The mask is 1<<bit.

sp_flags · SP_FEATURE_* (45 bits, 0–44)
BitNameMaskSource
0SP_FEATURE_BLOG_ENABLED0x0000000000000001solid_pod.h:73
1SP_FEATURE_CHANNELVAULT_ENABLED0x0000000000000002solid_pod.h:74
2SP_FEATURE_PAINT_ENABLED0x0000000000000004solid_pod.h:75
3SP_FEATURE_WEB4_ENABLED0x0000000000000008solid_pod.h:76
4SP_FEATURE_CRON_ENABLED0x0000000000000010solid_pod.h:77
5SP_FEATURE_NEXUS_ENABLED0x0000000000000020solid_pod.h:78
6SP_FEATURE_CLOUD_ENABLED0x0000000000000040solid_pod.h:79
7SP_FEATURE_DEVELOPER0x0000000000000080solid_pod.h:80
8SP_FEATURE_AI_ENABLED0x0000000000000100solid_pod.h:81
9SP_FEATURE_BACKUP_ENABLED0x0000000000000200solid_pod.h:82
10SP_FEATURE_ENCRYPTION_ENABLED0x0000000000000400solid_pod.h:83
11SP_FEATURE_TWO_FACTOR_ENABLED0x0000000000000800solid_pod.h:84
12SP_FEATURE_METRICS_ENABLED0x0000000000001000solid_pod.h:85
13SP_FEATURE_LOGGING_ENABLED0x0000000000002000solid_pod.h:86
14SP_FEATURE_API_ENABLED0x0000000000004000solid_pod.h:87
15SP_FEATURE_GALACTICORE_ENABLED0x0000000000008000solid_pod.h:88
16SP_FEATURE_CODE_SHARING_ENABLED0x0000000000010000solid_pod.h:89
17SP_FEATURE_WALLET_ENABLED0x0000000000020000solid_pod.h:90
18SP_FEATURE_CALENDAR_ENABLED0x0000000000040000solid_pod.h:91
19SP_FEATURE_NOTES_ENABLED0x0000000000080000solid_pod.h:92
20SP_FEATURE_BOOKMARKS_ENABLED0x0000000000100000solid_pod.h:93
21SP_FEATURE_TASKS_ENABLED0x0000000000200000solid_pod.h:94
22SP_FEATURE_CONTACTS_ENABLED0x0000000000400000solid_pod.h:95
23SP_FEATURE_DOCUMENTS_ENABLED0x0000000000800000solid_pod.h:96
24SP_FEATURE_MESSAGES_ENABLED0x0000000001000000solid_pod.h:97
25SP_FEATURE_STREAMING_ENABLED0x0000000002000000solid_pod.h:98
26SP_FEATURE_GALLERY_ENABLED0x0000000004000000solid_pod.h:99
27SP_FEATURE_GROUPS_ENABLED0x0000000008000000solid_pod.h:100
28SP_FEATURE_PAGES_ENABLED0x0000000010000000solid_pod.h:101
29SP_FEATURE_EVENTS_ENABLED0x0000000020000000solid_pod.h:102
30SP_FEATURE_JOBS_ENABLED0x0000000040000000solid_pod.h:103
31SP_FEATURE_MARKETPLACE_ENABLED0x0000000080000000solid_pod.h:104
32SP_FEATURE_WIKI_ENABLED0x0000000100000000solid_pod.h:105
33SP_FEATURE_PODCAST_ENABLED0x0000000200000000solid_pod.h:106
34SP_FEATURE_NEWS_ENABLED0x0000000400000000solid_pod.h:107
35SP_FEATURE_REVIEWS_ENABLED0x0000000800000000solid_pod.h:108
36SP_FEATURE_STORIES_ENABLED0x0000001000000000solid_pod.h:109
37SP_FEATURE_REELS_ENABLED0x0000002000000000solid_pod.h:110
38SP_FEATURE_GOALS_ENABLED0x0000004000000000solid_pod.h:111
39SP_FEATURE_BADGES_ENABLED0x0000008000000000solid_pod.h:112
40SP_FEATURE_ACHIEVEMENTS_ENABLED0x0000010000000000solid_pod.h:113
41SP_FEATURE_LEADERBOARDS_ENABLED0x0000020000000000solid_pod.h:114
42SP_FEATURE_TOURNAMENTS_ENABLED0x0000040000000000solid_pod.h:115
43SP_FEATURE_DHT_ENABLED0x0000080000000000solid_pod.h:116
44SP_FEATURE_AI_INFERENCE_ENABLED0x0000100000000000solid_pod.h:117
sp_user_flags · SP_USER_* (8 bits)
BitNameMaskSource
0SP_USER_EMAIL_CONFIRMED0x0000000000000001solid_pod.h:120
1SP_USER_PHONE_CONFIRMED0x0000000000000002solid_pod.h:121
2SP_USER_MEMBER0x0000000000000004solid_pod.h:122
3SP_USER_DEVELOPER0x0000000000000008solid_pod.h:123
4SP_USER_ADMIN0x0000000000000010solid_pod.h:124
5SP_USER_MODERATOR0x0000000000000020solid_pod.h:125
6SP_USER_PREMIUM0x0000000000000040solid_pod.h:126
7SP_USER_TWO_FACTOR0x0000000000000080solid_pod.h:127
sp_social_flags · SP_SOCIAL_* (12 bits)
BitNameMaskSource
0SP_SOCIAL_FACEBOOK0x0000000000000001solid_pod.h:130
1SP_SOCIAL_TIKTOK0x0000000000000002solid_pod.h:131
2SP_SOCIAL_INSTAGRAM0x0000000000000004solid_pod.h:132
3SP_SOCIAL_YOUTUBE0x0000000000000008solid_pod.h:133
4SP_SOCIAL_MASTODON0x0000000000000010solid_pod.h:134
5SP_SOCIAL_BLUESKY0x0000000000000020solid_pod.h:135
6SP_SOCIAL_TWITTER0x0000000000000040solid_pod.h:136
7SP_SOCIAL_TELEGRAM0x0000000000000080solid_pod.h:137
8SP_SOCIAL_DISCORD0x0000000000000100solid_pod.h:138
9SP_SOCIAL_REDDIT0x0000000000000200solid_pod.h:139
10SP_SOCIAL_LINKEDIN0x0000000000000400solid_pod.h:140
11SP_SOCIAL_GITHUB0x0000000000000800solid_pod.h:141
sp_storage_flags · SP_STORE_* (8 bits)
BitNameMaskSource
0SP_STORE_CLOUD_ONLY0x0000000000000001solid_pod.h:144
1SP_STORE_POD_ONLY0x0000000000000002solid_pod.h:145
2SP_STORE_BOTH0x0000000000000004solid_pod.h:146
3SP_STORE_LOCAL_ONLY0x0000000000000008solid_pod.h:147
4SP_STORE_AUTO0x0000000000000010solid_pod.h:148
5SP_STORE_BACKUP0x0000000000000020solid_pod.h:149
6SP_STORE_ENCRYPT0x0000000000000040solid_pod.h:150
7SP_STORE_COMPRESS0x0000000000000080solid_pod.h:151
sp_ui_prefs and sp_interests: packed fields
WordFieldShiftMaskNotes
sp_ui_prefstheme00x32 bits
sp_ui_prefsfont20xFstored value + 8
sp_ui_prefsscale60x3Fstored value + 50
sp_ui_prefsaccent120x73 bits
sp_ui_prefsflags23–27single bits23 ANIMATIONS, 24 COMPACT, 25 SHOW_AVATAR, 26 SHOW_STATUS, 27 SHOW_ONLINE
sp_interestsinterest 0 / 1 / 20 / 8 / 160xFF eachthree interest ids
sp_interestsposition X / Y24 / 320xFF eachposition on the galaxy map
sp_interestsinterest count400xF4 bits

Source: solid_pod.h, UI-prefs and interest packing macros.

Sticky pod words (PodStickyStore, 128 named bits)

Separate from the struct, each pod keeps two 64-bit sticky words = 128 bits that the owner can name and toggle from the web (pod_sticky.h, found in publish-vaultmagic/src, not in channels6-review/solid). The store has the magic 0x4B545350 (“PSTK” little-endian), version 1, the two words, a colour mode (blue 0 / green 1), an external-BQL switch and URL (256 bytes), a 32-byte name per bit and a 96-byte handler per bit. Neighbouring named bits form one multi-bit field. It is kept at /pod/<user>/sticky in TachyonMem, with a Redis mirror for the web side. The names and the blue / green grouping are still to be settled. planned

Wire records: the pod’s public language

Every record below is big-endian and written in one write; most are fixed size (a few carry a count byte, and PROFILE and the pod image entry have a length), and all use 64-bit node ids (id 0 is invalid). The mesh, AI, phone and DHT records start with a two-byte header: ver u8 (=1) then type u8; the node, edge, peer, workload, replica, avatar, news and theme records have no such header. Reserved bits must be 0, and readers reject any record with a reserved bit set, so a bit can only be given a meaning by raising the version. The local TacyonMem copy uses native byte order with the same bit layout (NODE-RECORD.md). In a browser, 64-bit ids need BigInt or hex strings (RECORDS-FOR-UI.md).

Node, peer and profile records

RecordBytesLayout (offset: field)Source
NODE110 id u64 · 8 flags · 9 RAM code (KiB) · 10 storage code (MiB)noderec.h:5-7
EDGE160 node id u64 · 8 friend id u64; stored sorted by node idnoderec.h:6, 18
PEER160 id u64 · 8 pflags · 9 hops/load · 10 last_seen u32 · 14 rtt u16peerrec.h:5-6
DEVICE row170 owner u64 · 8 device u64 · 16 flags (b0 primary, b1 revoked, b2–7 = 0)devrec.h:1-3
WORKLOAD130 id u32 · 4 image u32 · 8 want · 9 memory code (KiB) · 10 storage code (MiB) · 11 CPU (1/32 core) · 12 state b7–5, restart-always b4, pinned b3, spread b2, arch b1–0workrec.h:7-12
REPLICA180 workload u32 · 4 index u8 · 5 host node u64 · 13 state b7–5 + restarts b4–0 · 14 started u32workrec.h:13
PROFILE (v2)56 + 9L + 1 + Wheader 56: 0 ver (=2) · 1 flags · 2 node u64 · 10 since u32 · 14 name[32] · 46 WebID hash u64 · 54 link count u16; then L links of 9 (node u64 + online bit); then WebID length u8 (1–255) and the WebIDprofrec.h:1-4

NODE flags (byte 8)

b7ARM64b6–4OS (0 win, 1 linux, 2 mac, 3 bsd, 4 android, 5 ios, 6 other, 7 unknown)b3IPv6b2relayb1residentb0online

Size codes: value = ((8 + mantissa) << exponent) >> 3, where the code byte is exponent<<3 | mantissa (noderec.h, size_enc / size_dec). RAM is in KiB, storage in MiB.

PEER flags (byte 8) and hop/load (byte 9)

b7–5state: 0 unknown, 1 found, 2 handshake, 3 online, 4 degraded, 5 offline, 6 suspended, 7 bannedb4trustedb3inboundb2outboundb1WebID verifiedb0key pinned

Byte 9: high nibble = hops, low nibble = load in sixteenths. A peers body is ver 1 | count N | N × 16. The WebID side table is keyed by FNV-1a 64 of the WebID bytes, with the full WebID compared on lookup (peerrec.h:15).

Mesh messages

TypeMessageBytesLayoutSigned
1HELLO32hdr 2 · from u64 @2 · to u64 @10 (0 = any) · WebID hash u64 @18 · time u32 @26 · caps u16 @30no
2CHALLENGE54hdr · from A · to B · nonce[32] · expires u32no
3PROOF114hdr · from B · to A · nonce[32] · sig[64]Ed25519
4ACCEPT99hdr · from A · to B · status u8 · peer[16] (A’s view of B) · sig[64]; on refusal peer and sig are zeroEd25519
5PEERS75 + 16Nhdr · from u64 · count u8 (0–16) · N × peer[16] · sig[64]Ed25519
6LEAVE87hdr · from · to · reason u8 · time u32 · sig[64]Ed25519
—NODE CARD122ver @0 · flags @1 (b0 accepts mesh, b1 relay ok, b2 IPv6, b3–7 = 0) · node u64 @2 · WebID hash u64 @10 · public key[32] @18 · key time u32 @50 · port u16 @54 (0 = web port) · caps u16 @56 · sig[64] @58 over tag + bytes 0..57self-signed

Accept status: OK, RATE, BADPROOF, EXPIRED, BANNED, UNKNOWN, BADMSG (0–6). Leave reasons: NORMAL, SHUTDOWN, REKEY, MOVED (0–3). The node card is published in the pod and linked from the WebID profile; a key rotation is a new card also signed by the old key (MESH-SPEC.md; meshrec.h:1-27). Signing tag for every mesh message: W4MESHv1.

Capability bits

The 16-bit caps field of HELLO (offset 30) and of the node card (offset 56) (meshrec.h:27).

BitNameValueMeaning
0CAP_IPV61Node is reachable over IPv6
1CAP_RELAY2Node will relay for others
2CAP_DHT4Node takes part in the DHT
3CAP_AI8The pod has a granted Nimosini (set only while a valid AI configuration with a grant time exists)
4–15reserved0Readers reject any record with these set
—CAP_ALL15Mask of all defined bits (was 7 before CAP_AI). An older peer that still has CAP_ALL = 7 rejects bit 3 until it is updated.

meshrec.h:46, 85 (hello_get and card_get reject bits 4–15); airec.h:125-138 (ai_hello_caps).

AI records (Nimosini) staged

Defined in airec.h with passing C tests; staged, not live. Signing tag W4NMv1 (6 bytes), different from the mesh tag at byte 2, so one family’s signature can never pass as the other’s. Every Nimosini (NM_*) message carries to inside the signed bytes, and a reader rejects to ≠ its own node id, so a captured message cannot be replayed to another pod.

RecordTypeBytesLayout (offsets)
AICFG (local, unsigned, written once by owner setup, never on the mesh)826hdr 2 · node u64 @2 · ram_mib u32 @10 · disk_mib u32 @14 · grant_time u32 @18 (0 = not granted) · grant_mask u16 @22 · policy u8 @24 · must-be-0 @25
NM_PRESENCE (every pod announces, even dormant)1689from u64 @2 · to u64 @10 · time u32 @18 · state/LM/backend u8 @22 · net mask u8 @23 · load<<4 u8 @24 · sig[64] @25
NM_LM (language-model chunk)171,096to u64 @2 · slot @10 · kind/backend/final @11 · request id u32 @12 · chunk @16 · 0 @17 · used u16 @18 · peer u64 @20 · deadline u32 @28 · payload[1000] @32 · sig[64] @1032
NM_AICFG (resources, for Nexus; no grant data)1894from u64 @2 · to u64 @10 · ram_mib u32 @18 · disk_mib u32 @22 · time u32 @26 · sig[64] @30
LMMSG (local form of NM_LM; never valid on the wire)91,024slot @2 · kind @3 · request id @4 · chunk @8 · used @10 · peer @12 · deadline @20 · payload[1000] @24; slots 8 grok, 9 BERT, 10 GPT

Presence state: 0 dormant, 1 starting, 2 running, 3 degraded, 4 paused, 5 breaker, 6 leaving (sent once on a clean shutdown; the receiver treats the sender as gone at once instead of waiting for the record to go stale); 7 is rejected (airec.h:75-76, airec.h:200). Backend: 0 none, 1 CPU, 2 GPU. Receivers keep a seen-ring of 1,024 entries × 24 bytes (up to 128 per sender, 300 s windows) so a repeated request is refused; the deadline window is at most 300 s; a grant time may be at most 300 s in the future (AI_GRANT_SKEW_S, airec.h:36). A receiver verifies the signature before changing any state and admits only known peers (airec.h:236-250). A server may first run the read-only nm_lm_precheck_sender to drop a sender that already holds its 128 live entries without paying for the Ed25519 verify (airec.h:309-315).

AICFG grant mask (grant_mask, 15 bits, GS_ALL = 0x7FFF)

BitScopePre-ticked at setup (0x0205)Irreversible?
0LOCAL_TUNEtickedno
1CAMERA_USEoffno
2CALL_BASICtickedno
3CALL_VIDEO_DIALoffyes
4MAIL_SENDoffyes
5NEWS_PUBLISHoffyes
6PEER_ADMIToffyes
7WORKLOADoffno
8DATA_DELETEoffyes
9LM_PODtickedno
10LM_PEER_USEoffno
11LM_PEER_SERVEoffno
12AUDIO_INoffno
13SPEECHoffno
14TRANSLATEoffno
15reservedmust be 0—

Bits and names: airec.h:65-69 (bit 15 must be 0, comment at line 65). Pre-ticked default NM_GRANT_DEFAULT = 0x0205: airec.h:70-71. The “irreversible” column follows the spec’s list of mail, publish, dial, delete and peer admit.

Pre-ticked defaults. At setup only three scopes are pre-ticked: local tuning (bit 0), basic call handling (bit 2: decline) and the pod’s own language model (bit 9), which is 0x0205 (airec.h:70-71). Everything else is opt-in. An earlier draft pre-ticked camera, audio and peer scopes (0x1E87); that value is gone from the header. In every version, nothing is granted until the owner completes setup: grant_time = 0 means dormant, and the irreversible scopes (mail, publish, video dial, delete, admit) are off.

AICFG policy byte (byte 24)

b7POL_PEOPLE_ID 0x80b6POL_FRAMES_OFF_POD 0x40b5–4LM order, GPT slotb3–2LM order, BERT slotb1–0must be 0

LM order values: 0 pod, 1 peer, 2 pod then peer, 3 peer then pod. Both b7 and b6 default to 0. Bit 6 is named “frames off pod” and means that when it is set, camera frames are allowed to leave the pod; unset, they never do (airec.h:72-73; the later draft renames it FRAMES_MAY_LEAVE).

Resource limits: RAM 256–8,192 MiB (default 1,024); disk 2,048–65,536 MiB (default 8,192); RAM at most 50 % of physical, disk at most 25 % of free; a pod language model needs at least 2,048 MiB (airec.h:38-63).

Phone, pod files, ChannelData and the roadmap

Phone records staged

phonerec.h (v1) defines a video-phone built on the pod. Staged, not live. A pod has one pod number: 12 decimal digits, the first 1–9, the last a Luhn check digit, stored in 5 bytes and shown as 4444-4444-4444. Phone messages are signed with the pod server’s key; devices never sign. Signing tag W4PHv1. As with the AI records, to is inside the signed bytes and a reader rejects any message whose to is not the local node. A message older than 300 s (PH_FRESH_S) is stale; a seen-cache holds 128 call ids for 600 s.

RecordTypeBytesSignedNotes
PHONE4816stored rowThe member’s number and call settings
DEVICE4924stored rowOne device of the owner and what it can do
CONF5021stored rowA conference: id, host, settings
CALL (DIAL 32, RING 33, ANSWER 34, DECLINE 35, BUSY 36, HANGUP 37, CANCEL 38, TIMEOUT 39)32–39114yesAll eight call messages share one layout
CONFMSG (JOIN 40, LEAVE 41, STATE 42, KICK 43, LOCK 44, UNLOCK 45)40–45108yesConference control
ROSTER4696 + 14NyesN ≤ 24 (at most 432 bytes); a signed envelope of the CONFLIST
CONFLIST body—2 + 14Ninside ROSTERN ≤ 24 (at most 338 bytes): ver, count, then entries of 14 bytes

Type bytes are shared across families: mesh 1–6; Nimosini 8, 9, 16–18; DHT 0x10–0x18 and 0x40; phone 32–63 (32–39 call, 40–45 conference, 46 roster, 47 spare signed, 48–50 stored rows, 51–63 spare).

Field layouts: PHONE, DEVICE, CONF, CALL
RecordFieldOffsetSizeBits / meaning
PHONEver, type02ver 1, type 48
PHONEnumber2512-digit pod number, packed
PHONEowner node78u64
PHONEflags151b0 accept calls · b1 friends only · b2 do not disturb · b3 video allowed · b4 listed in directory · b5 may join conferences · b6 call waiting · b7 screen share allowed
DEVICEdevice node28u64
DEVICEowner node108u64
DEVICElast seen184u32 Unix seconds
DEVICEctl222b15–13 kind (0 phone, 1 tablet, 2 desktop, 3 browser, 4 tv, 5 camera, 6 speaker, 7 other) · b12 online · b11 ring enabled · b10 audio · b9 video · b8 can present screen · b7 preferred · b6 push-wakeable · b5 revoked · b4 encrypted media (DTLS-SRTP) · b3 needs relay · b2–0 reserved
CONFconference id28u64
CONFhost number105pod number
CONFctl152b15–11 max participants (2–24) · b10–9 default view · b8 locked · b7 video · b6 mute new joiners · b5 recording notice · b4 participants may share · b3 hands enabled
CONFcreated174u32 Unix seconds
CALLfrom node / to node2 / 108 + 8u64 each
CALLcall id188u64
CALLfrom device268u64
CALLfrom number / to number34 / 395 + 5pod numbers
CALLtime444u32 Unix seconds
CALLctl482b15–12 reason (0–10) · b11–9 device kind · b8–3 media (bit 0 audio, 1 video, 2 screen, 3 conference leg, 4 encrypted required, 5 relay required) · b2 waiting · b1 blob
CALLsignature5064Ed25519 over W4PHv1 + bytes 0..49

Call reasons: 0 none, 1 do-not-disturb, 2 no such number, 3 friends only, 4 blocked, 5 no video, 6 offline, 7 error, 8 not allowed, 9 answered elsewhere, 10 media failed. Participant state byte: b0 audio muted · b1 video off · b2 hand raised · b3 screen sharing · b4 host · b5 moderator · b6 spectator · b7 force-muted. A conference holds at most 24 people (CONF_MAXP).

How a call works. A call rings every ringable device the callee has. The first to answer wins; the others get a CANCEL with reason 9, “answered elsewhere”. The call state machine is DIALING, RINGING, CONNECTED, ENDED. The page never signs anything; the server does. A caller who is blocked is shown “no answer” (RECORDS-FOR-UI.md). The sound and picture travel through Media, encrypted with DTLS-SRTP; Nimosini may decline within its grant but never touches call media.

Other pod records

RecordBytesLayoutRules
AVATAR47flags @0 (b0–2 kind: 0 none, 1 png, 2 jpeg, 3 webp; b3 uploaded) · reserved u16 @1 · width u16 @3 · height u16 @5 · bytes u32 @7 · updated u32 @11 · SHA-256[32] @15At most 1,024 px a side. Nothing is ever generated: all zero means no picture and the page shows initials.
POD IMAGE ENTRY20 + name + dataheader 20: ver @0 · kind @1 (1 = PNG) · flags @2 (b0 re-encoded by server, b1 brand sign, b2 public-readable) · name length @3 (1–32) · data length u32 @4 · CRC-32 @8 · width @12 · height @14 · modified u32 @16; then name, then PNG bytesName: 1–32 characters from a-z 0-9 _ -, first character a-z or 0-9 (lowercase only), so a name cannot escape the pod. Proposed limits: 1 MiB and 4,096 px.
NEWS13subscribed mask u64 @0 (bit n = newspaper n, 0–63) · last seen u32 @8 · flags @12 (b0 member has chosen, b1 mail digest)All zero = never chosen; the site default applies.
THEME13background RGB @0 · foreground RGB @3 · background picture u16 @6 · foreground picture u16 @8 · flags @10 (b0 bg tile, b1 bg stretch, b2 fg tile, b3 fg stretch, b4 follow site) · 2 reservedAll zero = site defaults.
TV STATION LIST (v2)2 + 32Ncount, then N records of 32 bytes; 23 named categories (1–23)No web addresses on the wire.
DHT routing table16,38464 buckets × 16 entries × 16 bytes; HEAD record 0x40 = 174 bytes; PING 26, PONG 27, FIND_NODE 34, FIND_VALUE 58, HEADVAL 200, STORE_PROV 136, STORE_HEAD 200Draft 1; design only. planned

ChannelData flags (CD_FLAG_*)

ChannelData is the 80-byte typed header that wraps any value that moves between channels. It carries a 64-bit flag word (defines.h:676-712). Types: 32 values = 8 base types (byte, short, char, int, long, float, double, object) × 4 shapes (single, array, 2-D, 3-D) (defines.h:410-452). Content classes (:718-727): DATA 0, CONTROL 1, SIGNAL 2, STREAM_FRAG 3, FRAG_END 4, HEARTBEAT 5, ERROR 6, RETRY 7, OBJECT 8, REGISTRY 9. The flags marked pod are the hooks for “your data lives in your pod”.

All 33 flag bits
BitNameMaskSource
0CD_FLAG_OWNED0x0000000000000001defines.h:676
1CD_FLAG_READONLY0x0000000000000002defines.h:677
2CD_FLAG_DESTROY_ON_CONSUME0x0000000000000004defines.h:678
3CD_FLAG_CACHED0x0000000000000008defines.h:679
4CD_FLAG_PINNED0x0000000000000010defines.h:680
5CD_FLAG_ENCRYPTED0x0000000000000020defines.h:681
6CD_FLAG_INLINE0x0000000000000040defines.h:683
7CD_FLAG_EXTERNAL0x0000000000000080defines.h:684
8CD_FLAG_COMPRESSED0x0000000000000100defines.h:685
9CD_FLAG_SPARSE0x0000000000000200defines.h:686
10CD_FLAG_SIGNED0x0000000000000400defines.h:687
11CD_FLAG_PACKED0x0000000000000800defines.h:688
12CD_FLAG_REMOTE0x0000000000001000defines.h:690
13CD_FLAG_FETCHED0x0000000000002000defines.h:691
14CD_FLAG_FETCH_PENDING0x0000000000004000defines.h:692
15CD_FLAG_DOWNLOAD0x0000000000008000defines.h:693
16CD_FLAG_UPLOAD0x0000000000010000defines.h:694
17CD_FLAG_SYNC_REQUIRED0x0000000000020000defines.h:695
18CD_FLAG_SMART_BUFFER0x0000000000040000defines.h:697
19CD_FLAG_HOME_BOUND0x0000000000080000defines.h:698
20CD_FLAG_TRANSPORT_HOME0x0000000000100000defines.h:699
21CD_FLAG_POD_AUTHORITATIVE0x0000000000200000defines.h:700
22CD_FLAG_FEDERATED0x0000000000400000defines.h:701
23CD_FLAG_DHT_PINNED0x0000000000800000defines.h:702
24CD_FLAG_EPHEMERAL0x0000000001000000defines.h:704
25CD_FLAG_MONETIZED0x0000000002000000defines.h:705
26CD_FLAG_AI_LABELED0x0000000004000000defines.h:706
27CD_FLAG_MODERATION_PENDING0x0000000008000000defines.h:707
28CD_FLAG_SENSITIVE0x0000000010000000defines.h:708
29CD_FLAG_STREAM0x0000000020000000defines.h:709
30CD_FLAG_GAME_WINDOW0x0000000040000000defines.h:710
31CD_FLAG_OBJECT0x0000000080000000defines.h:711
32CD_FLAG_REGISTRY0x0000000100000000defines.h:712

Pod flags: HOME_BOUND 19, TRANSPORT_HOME 20, POD_AUTHORITATIVE 21. Also relevant to ownership: ENCRYPTED 5, SIGNED 10, FEDERATED 22, DHT_PINNED 23, SENSITIVE 28, AI_LABELED 26. Defined only; the sources do not describe their run-time behaviour.

Future plans

Everything on this list is planned. Each item says where the source marks it as not done.

AreaPlanWhere the source says so
DispatchHandlers for the other 511 cells of the dispatch tableNetXecChannel.c:701-756
Join policyA real join_policy[16][16] table inside ChannelJoin, shown on the config boarddocs/channel-joins.md
CrossbarPer-pair lock, range checks, sender-identity check on wake; 64-bit wake-bit macros for senders 8–15 (defines.h:41-44)proposed patch, not applied
ServerA real listening socket on its own threadServerChannel.h:4, 6-9
Devicelibusb and serial I/O; camera and microphone into Memory rings; pod-drive detectionstubs; GALAXYGATE.md
MemoryPod-backed CLOUD memory and a GPU buffer pathMemoryChannel.c:262, 275
ThreadRestore a signed pod thread (PodThreadToLocal); wire the arbitration queueThreadChannel.c:359-366
Process0DEFLATE compressionCompressionChannel.c:2, 217
Process1SQLite driver, GPS and modem parsersSQLChannel.h; stubs
MediaReal audio device, video decode and playerstubs
Compiler, DebugCode generation; a Debug channelstub; no source
NimosiniPhases M1–M6 from an observe-only skeleton to real nets, language-model use and peer serving; nothing goes live without a backup and the owner’s go-aheadNIMOSINI-CHANNEL-SPEC.md §13
Nexus pyramidEight-layer resource sharing; the 60 / 40 RAM-disk share formula is a proposalspec; sp_nexus
Portable podGalaxyGate flag, IP registry, drive bind, FOAF mutual enable (phases 2–6)GALAXYGATE.md
Mesh and DHTA live mesh.cgi endpoint; the pod DHT file systemMESH-SPEC.md; dht-fs/DESIGN.md
PhoneGo live with the phone records, conferences and the stored rowsphonerec.h (staged)
Pod flagsConform the pod header (set B) to the canonical set A in defines.h; name the 128 sticky bits; add a GalaxyGate flagpod_sticky.h (publish-vaultmagic/src); GALAXYGATE.md
Object outputExport .chd objects as a Java class, JavaScript object, JSON, TypeScript and Python (.py)channels6-review/channel_data.h:21-26

Part 6

Privacy and ownership: your data, your choice

Web 4 is solid. The pod is yours, the keys are yours, and every switch that matters is a switch you flip. This is how the design above turns that sentence into rules. Each rule points at the place in the sources where it is written.

RuleWhat it meansWhere
Consent starts offA pod with no grant is dormant: grant_time = 0 means “not granted”. Nimosini then announces its presence and does nothing else. The irreversible scopes — send mail, publish news, start video calls, delete data, admit peers — are off in every draft.airec.h:65-71; spec §5, §9
People-recognition is off by defaultPolicy bit POL_PEOPLE_ID (b7) is 0. Names and identities stay in the pod’s own Memory and never go on the wire.airec.h:72-73; spec §5
Frames stay in the podPolicy bit POL_FRAMES_OFF_POD (b6) is 0, which means raw camera frames never leave the pod. Embeddings stay in Memory too.airec.h:72-73
One grant, scoped, revocableThe owner grants specific scopes once, on a setup screen, and can pause or stop Nimosini at any time. The System channel’s stop and pause always win.spec §2, §5
The AI never holds the keyThe pod’s server signs; Nimosini cannot sign anything else, impersonate the pod, change grants, touch keys or weights, or use the compiler or URL channels.spec §5, §8
Outside words are not commandsText or audio the owner did not provide is tainted and can never trigger an outward action.spec §5
Indicators stay visibleCamera and microphone indicators are always on screen while in use.spec §5
Records are signed and addressedEach Nimosini (NM_*) and phone message names its receiver inside the signed bytes, so a captured message cannot be replayed to another pod. Receivers verify the signature before changing any state and admit only known peers.airec.h:15-17, 236-250
Nothing is generated for youIf you have no avatar, the page shows initials. A picture is never invented. Nimosini may not generate avatars (tier 3).avatarrec.h:1-14
Visibility is yours to setProfile visibility (public, friends, private), online status (hide or show) and last-seen visibility are fields in your own flag word.defines.h:226-247
Calls need mutual consentYou can ring someone only if they are on your list and have enabled you. A blocked caller sees “no answer”. Do-not-disturb, friends-only and listed-in-directory are your own phone flags.GALAXYGATE.md; phonerec.h
Binding is never silentA portable pod asks for your consent, an unlock key and/or a trusted host before it binds or advertises itself. A stolen drive stays quiet.GALAXYGATE.md (design)
Your resources are yoursYou choose how much RAM and disk the AI may use, and the system caps it at half of physical RAM and a quarter of free disk.airec.h:38-63
Analytics on this pageThis manual’s text, style and script come from this site. The only outside party is Google: the page loads gtag.js and sends page-view data to Google Analytics, which may set cookies (see the privacy page). The page has no ads and loads nothing else from any other site.this page

Only a few of these are running code today. The record formats, the policy bits and the grant checks are built and tested in C; the Nimosini channel and the portable-pod bind are designs. Privacy statements about Nimosini describe the design, not a deployed service.

Questions about your own pod: contact · privacy policy.

Part 7

Glossary

Web 4
The project’s name for a web built on solid pods: the owner holds the data and the keys, and servers are places a pod visits.
Solid pod
A person’s own data store: identity, profile, records, files and settings. Described in part 5. “Solid” also names the open standard for WebIDs and pods that the wire format follows.
WebID
A web address that names a person or pod and links to a profile document with its public key and node card.
FOAF
“Friend of a friend”: the friend graph. A call needs both sides to have enabled each other.
Channel
A small program with one job, a numbered place in the table, its own lock and run-state record.
Core channel
One of the sixteen channels with ids 0–15: System (NetXecChannel, Channel 0), Device, Memory, Thread, Signal, Media, Clock, Container, URL, Server, Process0, Process1, STDIO, Compiler, Debug, Nimosini.
Sub-channel
One of sixteen named cells under a core. The flat id is core × 16 + sub, 0–255.
Sidecar
A channel that is not itself one of the sixteen cores: it has an id of 100 or more, or is a code file homed on a core’s id (Image, Font, Video, CLI, BQL, GPU). A core’s own channel object (Container, URL, Media, Server, STDIO) is not called a sidecar here. Has no crossbar slot.
NetXecChannel
The System, core Channel 0, one of the sixteen cores. As the conductor it creates the cores (itself included), owns the crossbar (the Blitter Bus) and dispatch table, and runs the main loop.
Crossbar
See GPUChannel, the Blitter Bus (crossbar). A block of 512 slots (16 KiB each, 8 MiB in all), addressed [channel][peer][direction], that is meant by design to carry data between cores. Today NetXecChannel allocates it and only System←Signal writes to it.
Slot
One 16 KiB cell of the crossbar: a 36-byte header and 16,348 bytes of data.
Dispatch table
512 handlers indexed by source, target and direction.
Join
A symmetric link between two channels, held in each one’s listener table (16 slots).
HyperLock
A mutex plus condition variable, one per channel, that its thread sleeps on.
Event ring
The 64 KiB single-producer ring of 8-byte OS-event codes in the EventChannel.
Cont
The sources’ shorthand for the Container layer and its API and coding style (“Cont style”: no typedef, no enum, no union).
HyperView
The Java UI framework whose structure Container mirrors (gobs, gadgets, panes). The view is 640×480.
Blit
Copying finished pixels to the screen. Container tracks dirty rectangles or forces a full blit.
Blitz
The binary protocol on TCP 23232 that carries BML pages (little-endian).
BML
The binary page format. A v2 stream begins with the bytes B, M, L, 0x02.
BQL
The query side of page storage. BQLChannel holds a query string and the connection settings for TachyonDB.
TachyonDB / TacyonMem
The page store (PAGE_GET / PAGE_PUT, local port) and its in-memory copy of pod records (native byte order).
Code Share / CodeVault / PCL
Code hosting. CodeChannel is its front; PCL is its control language of one-byte opcodes.
ChannelData / CHDD / .chd
The 80-byte typed header for moving data; its 88-byte wire form starts with the u32 0x43444844 (bytes 44 48 44 43 on the wire; see Blit path and Blitz); saved objects are NAME.chd.
Node id
A 64-bit number naming a pod or device on the mesh. 0 is invalid.
Node card
The 122-byte self-signed record that tells peers a node’s id, key, port and capabilities.
Ed25519
The signature scheme used for every signed record. The code is compiled in (TweetNaCl-style); no library is needed.
Signing tag
A fixed prefix signed with the message so one record family cannot pass as another: W4MESHv1, W4NMv1, W4PHv1.
DHT
Distributed hash table; a Kademlia-style table of 64-bit keys for finding pod content. Planned.
GalaxyGate
The planned reachability mode: optional UPnP port mapping on a DHCP host and a signed IP-registry entry. Not Kubernetes ingress.
GalaxyCore
A thin Docker / kubectl relay. Different from GalaxyGate.
IP registry
A planned signed “number or WebID → where to reach it” directory with a time-to-live.
Pod number
The 12-digit phone number of a pod, last digit a Luhn check.
Nimosini
The planned AI controller, channel 15; one per pod.
Net
One of eight independent neural-network slots (neural0–7) in the Nimosini design.
Grant, scope, tier, taint
The owner’s one-time permission (grant) is split into scopes; actions have tiers 0–3; input the owner did not provide is tainted and capped at tier 1.
AICFG
The 26-byte local record that holds the owner’s grant, resource limits and policy byte.
Nexus
The eight-layer resource-sharing pyramid held in the pod struct. Not built.
Big-endian
Most-significant byte first. The byte order of every pod record. Blitz and BML are little-endian.

Part 8

Index A–Z

Known gaps and source notes

Where the sources disagree or are silent, this manual says so rather than guessing:

  • Two flag sets. Set A, SP_FLAG_* / SP_FLAG2_* (channels7 defines.h), is canonical. Set B, SP_FEATURE_* (pod header solid_pod.h v6.1), describes the same pod differently and is being conformed to A (pending, not done yet); both are printed in part 5.
  • The join chart is a draft. It is not enforced in the binary. It denies Nimosini↔Server, Nimosini↔Clock and Nimosini↔Debug (as well as Device, Media, URL and Compiler), while the Nimosini design relies on Server to hold the key and sign, on Clock for the tick and on Debug for counters; the chart and the design need reconciling.
  • Home core vs name table. GPS and GPRS are homed on Device in code but named under Process1; BML is homed on Process0 but named under Server and Process1; Java is homed on Process0 but named under Compiler.
  • Nimosini sub-channel names. The master table says grok / bert / chatgpt / neuralnet at 248–251. The staged prototype uses other names for 248–250 (aichannel, speech, translate). No code in the running system uses either.
  • Record sizes. An older Nimosini draft lists AICFG 32, NM_PRESENCE 81, NM_AICFG 86 and NM_LM 1,088 bytes. The record headers, which this page follows, say 26, 89, 94 and 1,096.
  • Handshake signing. The mesh note mentions libsodium and signing the nonce; the record header and the node-record note specify the compiled-in Ed25519 and the W4MESHv1 tag over every preceding byte. This page follows the record header.
  • Type bytes. DHT messages 0x10–0x12 reuse the numbers of the Nimosini mesh types 16–18; the signing tag and the channel keep them apart.
  • Pre-ticked AI scopes. The record header now holds the safe default 0x0205 (local tune, basic call, pod language model); an earlier draft's 0x1E87 is gone. See AI records.
  • Blitter Bus. GPUChannel, the Blitter Bus (crossbar), is the crossbar of the Web 4 Channel Paradigm. By design it carries data between the cores; today the crossbar is the block NetXecChannel allocates, only System←Signal writes to it, and channels7/GPUChannel.c (153 lines) is a query-name stub that is not connected to it. The 1,838-line channels7-read/GPUChannel.c is a different file and does not use the crossbar. The draft join chart gives Device (where GPUChannel is homed) only four partners (System, Memory, Thread, Signal), and the 512-entry dispatch table has one real handler (the other 511 are no-op defaults, NetXecChannel.c:746-755); both need work before the Blitter Bus carries data between all cores. See The crossbar.
  • Not documented in the sources: run-time behaviour of the three pod ChannelData flags; the Debug channel; handlers for 511 of 512 dispatch cells; a live mesh endpoint; a live DHT.

Source files this manual draws on

channels7: NetXecChannel.c, defines.h, channels.h, channel_io.c, ChannelConfig.h, MainChannel.h, ServerChannel.h, ThreadChannel.c, MemoryChannel.c, EventChannel.c, SignalChannel.h, ClockChannel.c, ContainerChannel.h, URLChannel.c, EncryptionChannel.h, CompressionChannel.c, SolidChannel.h, StockChannel.h, STDIOChannel.h, CLIChannel.c, GALAXYGATE.md, docs/channel-joins.md, docs/channel-joins-corexcore.csv, docs/CODECHANNEL.md, URLChannel-CURL.md, SOLID-AUTH-HEADERS.md. Pod: channels6-review/solid/solid_pod.h, pod_sticky.h (not in channels6-review/solid; it is in publish-vaultmagic/src), channel_data.h, handoff-solid-pod/SOLID-POD-INTENT.md. Records: node-records/*.h and NODE-RECORD.md, mesh/MESH-SPEC.md, WEB4-CONTRACT.md. Design: nimosini-channel/NIMOSINI-CHANNEL-SPEC.md.

Hits--