CONDUIT: multi-protocol network client
First-party on-device program #5 (ADR-0042).
v1.2 | 2026-07-30
Canonical per ADR-0042. ICE BREAKER drives a CONDUIT session (it hands CONDUIT a target) but never contains, replaces, or gates it. See the program roster.
Tier 1 — Treatment
Section titled “Tier 1 — Treatment”Gate: draft (written 2026-07-30, against the ICE Breaker Tier 1 and aethernet.md).
The hook
Section titled “The hook”“Be on the box.” Once the operator holds an endpoint and a credential, CONDUIT is where they type at the target and it answers: the primary interactive terminal into a single host, over SSH, Telnet, FTP, or raw TCP. Everything it touches is an authored in-world host model, and nothing is real I/O.
What the operator does
Section titled “What the operator does”Dial, get past auth, work the shell, take what the run came for, hang up before the trace lands.
One typed line carries all of it, and its meaning is the session state. At the dialer the line takes an endpoint; at the auth prompt it takes a credential; on an open session it takes a command. That collapses three interactions into one grammar with nothing new to learn per state, and it is what makes the surface a session instead of a menu.
The repeating decision is how long to stay. Every moment on the box is yielding something and costing exposure, and the operator alone decides when the yield stops paying for the dwell.
Inside, and alone. bzbx surveys many hosts from outside; CONDUIT is the one place the operator is within a system, with a cursor blinking and a machine answering. The scrollback fills with an exchange that reads like a real session, because the host’s shell is an authored table rather than a puzzle box.
Pressure arrives as a number and a bar, and CONDUIT names no defender and no awareness state. Magnitude here, interpretation there: CONDUIT shows how exposed the operator is, and ICE Breaker says what is coming. The two can never contradict each other because only one of them speaks about defenders.
The credential chain is the through-line. Each reached box prints what opens the next, so the operator reads an access number off the transcript and types it at the following door. That is the System 15000 clue-chain, and it means the session yields the next session.
Feasibility verdict
Section titled “Feasibility verdict”The session model, the transcript, the host and auth and file records, DIAL, PULL, HANGUP, and the guarded DOSSIER paths all ship today in runtime/programs/conduit/conduit.lsp, with eight live-world reads and 19 passing cases.
- Reuses: the knEmacs comint line discipline (shared with the REPL), minibuffer completion, tree-cursor listing, and the World Engine’s target-host model.
- New surface required: the typed input line. Today
LINKcycles a canned command table one press at a time and nothing accepts characters. The router already routes printable ASCII to a registered handler, and the REPL is the working precedent, so this is program work rather than engine work. - Blocked on hardware: free-typed letters need a program-tier text-entry seam over the multi-tap machine, which is currently private to nEmacs and the OOBE surface. The emulator accepts text today; the Sweep does not.
Open questions
Section titled “Open questions”- Deferred to the tiers below (see Open / deferred in Tier 3).
Tier 2 — Operator spec
Section titled “Tier 2 — Operator spec”Gate: approved (the v1 design; merged through PR review).
Identity
Section titled “Identity”CONDUIT is the deck’s multi-protocol live-intrusion network client (SSH / Telnet / FTP / raw TCP): the operator’s primary interactive terminal into a single target host. “Be on the box”: once the operator holds an endpoint and a credential, CONDUIT is where they type at the target and it answers.
- Operator program #5 (ADR-0042). First-party, ships in the system image, always-present, bare-launchable, never superseded by a cart. ICE BREAKER drives a CONDUIT session (hands it a target) but never contains, replaces, or gates it.
- Generic verb floor (ships, bare-launchable): DIAL/CONNECT (open a session to an endpoint from the phonebook; OTE-1993 dialer lineage), command↔response, PULL/PUSH (FTP transfer), HANGUP, browse the endpoint phonebook. Carts overlay domain verbs (per-target shell verbs, exploit/escalate, exfil targets).
Like every first-party program, CONDUIT is a lens and a cart supplies the world it looks at (enrichment-contract.md §1). It crunches whatever target-host model the world region holds; it knows nothing about a specific intrusion domain.
The typed line
Section titled “The typed line”One input line, and the session state decides what it means: an endpoint at the dialer, a credential at the auth prompt, a command on an open session. ENT submits. BACK backspaces, and on an empty line hangs up, which is the shell’s own convention and saves a key.
This is the piece the shipped program lacks. conduit/on-key currently binds LINK to a canned command table that advances one entry per press, and no path accepts characters. The router already dispatches printable ASCII to a handler a screen registers, and the REPL registers through it, so the work is a composer in conduit.lsp rather than anything new in the engine. Free-typed letters on the physical deck additionally need a program-tier text-entry seam (see Open / deferred).
What CONDUIT shows about exposure
Section titled “What CONDUIT shows about exposure”CONDUIT is the only current reader of the region trace meter, and the division that keeps it from contradicting the cart is magnitude here, interpretation there.
- Shows: the trace value and its bar, read live from the engine on every render, plus the dwell time for this session, because dwell is the operator’s only lever inside CONDUIT. A session dropped by the far end appears in the transcript as an observed event.
- Leaves to the cart: every awareness state, the defenders and their identities, any countermeasure, and any word naming a threshold. CONDUIT prints no state name, so the operator reads the number as exposure and looks to the cart for what is coming.
One honesty fix. On a bare launch there is no live world, and the fallback counter is currently labelled TRACE, which claims a defender that does not exist on the operator’s own loopback shell. That readout is DWELL when no live handle is bound, and TRACE only when one is.
Bare-launch default world
Section titled “Bare-launch default world”Per the global bare-launch default-world policy (enrich-never-gate, ADR-0042): bare CONDUIT opens a loopback session to the deck itself (localhost).
- A genuine self-shell: auth is open, since the deck is the operator’s own box; no external endpoints, no exfil targets, no mission keys.
- It is a real utility (inspecting the operator’s own deck) and the honest tutorial for the comint surface: the protocol selector, the input line, scrollback, history recall, command-by-name completion, all demonstrable with truthful local content, nothing faked.
- Enrich-never-gate, made concrete: insert ICE BREAKER and the identical surface now targets
fin-relay-07over the cart’s world; the grammar the operator learned onlocalhosttransfers unchanged.
What CONDUIT does NOT own
Section titled “What CONDUIT does NOT own”CONDUIT rides one host (access / session, inside). It does not own:
- The wire. Probing the network (many hosts, ports, services, captured streams) is bzbx’s layer (
bzbx.md). bzbx finds the door; CONDUIT walks through it. - File logistics. Moving / staging / exfil-routing files between mounts is Kinoshita Kommander’s filesystem layer (
kommander.md). CONDUIT pulls a file into the session; Kommander carries it home. - The org / relationship graph. Who connects to whom (people, corps, accounts and their edges) is RIPSAW’s layer (
ripsaw.md). - Missions / economy / the durable record. Contracts, the objective graph, credits / reputation, and the persistent intel store are mission-layer + DOSSIER (
dossier.md). CONDUIT emits keys; durable consequence is the engine’s via the sanctioned outcome path (ADR-0040).
Tier 3 — Detailed design
Section titled “Tier 3 — Detailed design”Gate: approved (the v1 design; merged through PR review).
Implementation seam (GWP-629): file names, FFI signatures, and ADR contracts appear from here down.
The world it reads (:world)
Section titled “The world it reads (:world)”CONDUIT’s :world is its slice of the central World Engine’s generated world (see ../runtime/world-engine.md): a single target-host model, the authored, in-world “box” the operator is on, coherent with the rest of the generated world (the host bzbx found, owned by the entity RIPSAW maps, holding the file Kommander stages). It is materialized lazily on connect; all I/O is simulated / in-world (enrichment-contract.md §2). Record types:
| Node | Key fields | DOSSIER-discoverable key, or flavor? |
|---|---|---|
host | :endpoint (id) · :protocol · :banner · :reachable? · :auth-state · :revealed? (the shared-region reveal flag bzbx set) | host existence / banner is usually flavor here (bzbx’s job) |
auth | :method (:password / :key / :none) · :accepts (which cred opens it) · :cred-required? | a validated cred = key host:<id>:cred (:verified once it opens the session) |
fs-node | :path · :kind · :size · :readable? · :exfil-target? | files tagged :exfil-target? = key host:<id>:file:<path>; ambient files = flavor |
cmd-response | :cmd (pattern) · :response · :reveals (keys) · :state-effect (reveal subtree / flip auth-state) | the authored shell: responses are flavor, their :reveals are keys |
session-finding | :name · :value · :links (e.g. :routes-to another host) | key host:<id>:finding:<name>: leaked routes, config secrets, secondary creds |
The world region is the single shared mission world-region (run-state): one region per mission, every program launch-app’d during that mission reads the same region (enrichment-contract.md §4). The cart’s world-archetype seeds the host (its fs depth, command table, what’s hidden) and tags which facts are keys.
Tick-event aware: a CONDUIT session observes World Engine clock events mid-session: a node coming online, a :routes-to host appearing, or (on a cart’s wall-clock heat) a trace advancing toward the operator while they linger. CONDUIT re-renders on the event; it never drives the clock.
Scope-line: construction (knEmacs mode vs cell-API)
Section titled “Scope-line: construction (knEmacs mode vs cell-API)”Verdict: knEmacs mode, the data / structured-navigation tier of the ADR-0046 scope line (ADR-0046), comint / shell-mode lineage. One surface, text over structured data.
A CONDUIT session is a buffer: a scrollback of command↔response plus an input line. That is comint (Emacs’s shell and REPL line discipline), which the engine already carries for the REPL. Three reasons put it on the engine rather than the cell-API:
- the target’s “shell” is an authored, deterministic
cmd-responsetable (above), so a session is text I/O over structured data rather than a control loop; - the FTP file surface is a Dired-like listing: the engine’s tree-cursor (CAR/CDR/BACK) over
fs-nodes, the same library RIPSAW / Kommander / DOSSIER reuse; - command-by-name, host/path completion, and history recall are the engine’s minibuffer + rings, solved once and inherited here (the 34-key lifeline).
Boundary against the cart (updated 2026-07-30). ICE BREAKER’s loop is a finite loadout of breaker programs spent against stationary ICE while sweeps advance (
../cartridges/modules/ice-breaker.mdTier 1). That contest is a cart surface authored on theui/cell-API. The cart can run it and then drop the operator into a CONDUIT session on the system it cleared; the two are different surfaces. CONDUIT stays grammar. The earlier OODA netrun framing this note described is retired.
:payload
Section titled “:payload”Small launch params only: a by-value snapshot, never the host model (that arrives via :world):
(launch-app :conduit :world relay-7-host ; opaque handle to the target-host model :payload '(:endpoint "fin-relay-07" ; which host (id into the world) :protocol :ssh ; initial protocol :cred key-handle-3 ; credential handle → resolved vs Keyring/DOSSIER :open-at "/var/log")) ; optional initial path / prompt context:endpoint/:protocol/:open-at: where to land and how.:cred: a handle or reference that stands in for the secret. Resolved against Keyring (live keystore) or a DOSSIERhost:<id>:credfact at session open (see Objective-graph ties). Absent ⇒ CONDUIT opens at the auth node and the operator must supply a cred to proceed (the program launches either way; what the auth node gates is access, in-world).- Bare (
launch-app :conduitwith no:world/:payload) ⇒ the loopback default world (see Bare-launch default world in Tier 2).
Export to DOSSIER
Section titled “Export to DOSSIER”CONDUIT emits durable facts only through the sanctioned (dossier-commit <key>) primitive, never a raw write (ADR-0049, ADR-0005). The fact-node fields it supplies are the canonical schema (dossier-data-model.md §3):
| Key | When | Carries |
|---|---|---|
host:<id>:cred | a credential actually opens the session | :conf :verified; :links (:controls "<id>") |
host:<id>:file:<path> | a tagged exfil-target file is seen / pulled | :value (the file ref); :links (:located-at "<id>") |
host:<id>:finding:<name> | a session-finding surfaces (leaked route, config secret, secondary cred) | may carry :routes-to "<other-host>": the chaining edge that feeds the next bzbx scan / CONDUIT hop |
Reads ((dossier-has? <key>): de-risk or in-world gate):
(dossier-has? host:<id>:cred)→ present ⇒ CONDUIT opens pre-authenticated (a cred cracked in Keyring, learned in an earlier session, or received through a kn9 dead-drop de-risks this access); absent ⇒ the operator faces the auth node.(dossier-has? host:<id>:reachable)→ present ⇒ the host bzbx already mapped is targetable here (the cross-program reveal: bzbx finds it, CONDUIT rides it).
Objective-graph ties
Section titled “Objective-graph ties”Which CONDUIT verbs fire the goal verbs (ADR-0043). CONDUIT reports; the engine / mission flips goals and owns the clock.
- DIAL/CONNECT → auth accepted (session opens) →
(goal-complete 'access)for ACCESS / PENETRATE goals: the canonical moment of entry. - PULL a tagged exfil file →
(goal-complete 'obtain-<file>)(OBTAIN facet); a dotfile / config naming a new box may also(goal-reveal 'host-<n>). - A session-finding that names a new entity / route →
(goal-reveal …)(a leaked routing table reveals the next hop; a:routes-toedge seeds a follow-on phase, and feeds the next bzbx scan / RIPSAW lookup). - Observes tick events: a World Engine clock event (node-online, trace-advance) appears live in the session; on wall-clock heat, a
:holdtrace closing in is the pressure that forces the operator to finish + HANGUP. The engine watches the:hold/ TTL; CONDUIT just keeps reporting.
Engine reuse
Section titled “Engine reuse”CONDUIT is a thin conduit-mode on the knEmacs application engine; the major-mode + minibuffer command-by-name surface landed (kec-lisp ADR-0004; see ADR-0046). It consumes:
- comint / line-discipline: input line + scrollback + history ring, shared with the REPL. CONDUIT’s core surface.
- minibuffer + ido-narrowing completion (the command-by-name surface): command-by-name, host/path completion, and the endpoint phonebook (OTE-1993 dialer: pick a connection point to DIAL).
define-major-mode+ keymap-as-data dispatch: aconduit-modekeymap; protocol / session commands are named KEC commands, inspectable + scriptable from the Mission Runner.- tree-cursor (CAR/CDR/BACK) for the FTP / Dired
fs-nodelisting.
Contributes back (rule of three): the comint / session-buffer half is CONDUIT’s generic core; extract it when the second comint consumer arrives (a second protocol shell, or bzbx’s applet output). CIPHER stays OLED-exclusive.
Interfaces
Section titled “Interfaces”- Launch:
(launch-app :conduit :world <host-handle> :payload '(:endpoint … :protocol … :cred … :open-at …)): NoshAPI Tier 1 (ADR-0049, ADR-0005).:worldis the live target-host model;:payloadis small params only. - Export:
(dossier-commit <key>): sanctioned fact-node deposit; read:(dossier-has? <key> &key min-conf): de-risk / in-world gate (ADR-0049, ADR-0005). - Display: draws on the cartridge / content rows (1–73) per the canonical grid (see the Canonical Hardware Specification); grid queried via the cell-API getters.
- Authored in KEC Lisp. Program source lives at
runtime/programs/conduit/(ADR-0042).
Open / deferred
Section titled “Open / deferred”- The opaque live
:worldhandle. The bzbx → CONDUIT live, same-mission reveal (a host revealed in the run-region but not yet a DOSSIER fact) needs the opaque live handle. (Update 2026-07-18: the ADR-0049 amendment landed, 2026-06-28, N1/N5–N8; the live handle is built and tested. See the worked mission walkthrough.) v1 fallback while it was pending: commit reachability as ahost:<id>:reachablekey, then gate on it. - The shared
tabulated-listlibrary. The FTP / Diredfs-nodelisting wants the same table RIPSAW / kn9 / Kommander want; the rule-of-three extraction of one shared library is engine work and does not block CONDUIT. - The World Engine spec. The generator + clock + typed-event bus the tick-awareness above depends on is specified in
../runtime/world-engine.md. - Program-tier text entry on hardware. The typed line works in the emulator, where the host feeds SDL text input to the registered handler. On the Sweep, letters come from the multi-tap machine in
runtime/src/nokia.c, which is instantiated privately by nEmacs and the OOBE surface and bound to Lisp only under OOBE-specific names. Every future composer program needs the same seam, so it belongs to the engine. Interaction design is in progress. - Recon heat / exposure. Ownership is settled: the engine holds region trace, a cart moves it through play, and every program reports it (
aethernet.md). Lingering on a host costs exposure through the mission’s rules, and CONDUIT reports the meter without touching it.
Migration notes
Section titled “Migration notes”- 2026-07-18 tier migration: content re-cut under tier headings from the v1 design; no mechanics changed. The “forthcoming ADR-0049 amendment” tracking notes were stale: the amendment landed 2026-06-28 (N5–N8) and live cross-program
:worldthreading is built and tested (worked-mission-walkthrough.md); the Open / deferred bullet is annotated in place.
References
Section titled “References”enrichment-contract.md: lens / world / shared-region /dossier-commitcontract (§1–§6).dossier-data-model.md: the fact-node schema a finding commits as (§3).dossier.md: the durable intel store CONDUIT emits into.bzbx.md: the network-recon program that reveals the hosts CONDUIT rides.kommander.md·ripsaw.md: the filesystem and org-graph layers of the recon cluster.../runtime/world-engine.md: the central World Engine (generator + World Clock + typed-event bus) CONDUIT’s:worldslice reads.../gameplay-framework.md: the gameplay framework the World Engine serves as world model for.- ADR-0042: first-party programs; carts enrich, never gate.
- ADR-0046: the knEmacs application engine (major modes + minibuffer command-by-name).
- ADR-0049 · ADR-0005: the NoshAPI FFI surface (
launch-app/dossier-commit/dossier-has?). - ADR-0043: the mission objective model CONDUIT’s verbs fire.
- ADR-0040: the UDS sanctioned-write boundary
dossier-commitrespects.
Inspirations
Section titled “Inspirations”Assigned by Josh in the kn86-inspo workbench. Full map: cart-inspiration-map.md.
A row marked (cross-listed) was placed on another destination first and serves this one too (2026-07-29 workflow sweep).
| Source | Category |
|---|---|
| mcfly | file browser |
| System 15000 (1984) | hacking sim (cross-listed) |