$ sudo science
~/projects/desh

DESH

prototype

aka “Developer Environment, Structured & Hypermediated

# the terminal, with the amnesia removed

Twenty-plus years of daily terminal use, and the verdict is in: terminals and shells both suck — not at the edges, at the defaults. Warp, Fig, and nushell each fixed a symptom; the model survived them all.

DESH starts from the opposite defaults: nothing is discarded, resources replace strings, affordances replace incantations, and pipelines compose incrementally — commands, outputs, timings, and effects all graph-backed, event-sourced objects.

desh.sudoscience.dev

problem

The shell forgets what you ran, when, how long it took, and whether it worked; outputs are burned into a scroll buffer on read; pipelines are composed blind and debugged by bisection; and every TUI is a private, uncomposable imitation of paper. Consider the cumulative waste of ls file, up-arrow, Home, delete-delete, cat file — two commands and five keystrokes of repair to look at one resource you already named.

thesis

A path is a request, not a syntax error. Plugins recognize resource types and answer with a safe read-only projection — listing, metadata, schema — plus the affordances the resource actually supports: preview, diff, watch, remove. Autocomplete becomes nested affordance traversal; recognizers ship as sandboxed WASM code-on-demand; and everything lands on a replayable ledger.

the indictment

the defaults are wrong

history is amnesia

Command strings are half-remembered; timing and outcome context — the expensive part — is dropped entirely.

outputs burn on read

The result the machine just computed becomes unaddressable text. Want it again? Re-run it.

pipelines run blind

a | b | c is composed in your head and debugged by bisection. Stage two's output should be visible while writing stage three.

apps pretend to be paper

Every pager and TUI is a one-off interactive surface with zero affordances exposed to the system around it.

the model

resources, projections, affordances

enter a resource

The default response to a path is the safe projection: type, listing, metadata, recency — what ls and stat were always circling.

plugins recognize types

Files, folders, processes, ports, repos, datasets — each mapped to a typed projection. A CSV is rows with a schema, not bytes that happen to print.

affordances over flags

The resource exposes its verbs in words — preview, edit, watch, diff, remove. cat and rm were names rationed by a teletype.

autocomplete is traversal

Completion expands nested affordances of the addressed resource — hypermedia navigation, not prefix matching.

code on demand

Recognizers and affordances ship as sandboxed WASM; the environment learns new types the way a browser learns new pages. Discovery rides an affordance registry in the spirit of mamund's GRAIL: the CSV that realizes it needs a viewer, finds a wasm csv-tui, and runs it sandboxed — acquisition logged, revocable.

incremental pipelines

find | grep, but you grepped wrong — fix the grep and replay find's buffered output instead of re-walking the disk. Matching is interactive (fff-style, as adopted by opencode), and stages get durable-execution semantics: resume from offsets, recompute only what changed.

the name

four readings, one tilde

*sh

A shell-like thing that knows its lineage: sh, bash, zsh, fish — desh.

d-e-sh

Developer Environment SHell. The acronym is the spec.

desh as home

In several South Asian languages, desh is home — and home was always ~. The tilde is load-bearing: the prompt is a place, not a void.

developer exhaust

DE also reads as developer experience — and developer exhaust. Shells discard the most valuable exhaust a DX team could wish for; desh captures it by default.

the substrate

channels, oplog fs, sandboxes

channels, not stdout/stderr

Line-prefixed named streams for arbitrary outputs and inputs. POC built: stream in/out against s2.dev as a replayable buffer — late consumers attach and read from an offset, the webpoke doctrine applied to process I/O.

POSEVEN

Content-addressed store + append-only oplog: one transaction applies many mutations, checkouts are pointer moves (no watcher churn), forks are O(1), and an in-memory projection spares the SSD. POSEVEN — the one after POS-six. Tagline: all you need is log (AYNIL).

a declarative strangler

Optic's move at the CLI boundary: observe invocations, accrete help/flags/types as data, and replace incantations with typed affordances verb by verb — lifting wrapped tools' stdout/stderr into structured channels along the way.

agentic sandboxes

Ledger + CAS fs + named channels is the substrate agents need: fork per attempt, replay as audit, grant verbs not paths.

unbundle the servers

Dev, CI, and app servers are three computers re-deriving the same outputs with incompatible caches. On a content-addressed substrate they become memoized nodes of one computation graph, rebundlable onto fewer machines — CI is the graph with stricter provenance; the dev server is the graph with a watcher.

the pipeline-to-prod pipeline

An exploratory pipeline is already a typed dataflow object, so promotion to production is an affordance, not a rewrite: name it, pin inputs, parameterize literals, attach a schedule, ship the same graph — under whichever scheduler and output engine fits: local incremental, durable-execution, batch orchestrator, stream processor; TUI, dashboard, file, or service. desh spots the candidates — the one-liner you've re-run fourteen times is asking.

field cards (via rhett)

Filed by hand against this page: Kreps' 2013 log essay (the AYNIL ancestor), Rama's depots and PStates (AYNIL at industrial scale), Temporal and Azure Durable Functions (the engines pipeline-to-prod targets), direnv (the prompt is a place, folk edition), and nix (POSEVEN's instincts behind a grammar people refuse to learn). The full tray renders on the Rhett page.

return values

a function returns a value; a process returns a shrug

An exit code and a puddle of text is the entire calling convention of the operating surface. desh gives processes named, typed return values, bound into the scope that called them — the question that won't go away: what if binaries weren't limited to stdout/stderr and could output variables for shells?

exit status was the MVP

One byte was all POSIX let a process say about what it computed. $(command) substitution is the confession: we wanted values; we got text and a parser.

declared at the boundary

A command's boundary description declares its outputs — or the strangler observes them. deploy exports $deploy.url, $deploy.version, $deploy.took; the next command references them by name. No capture ceremony, no eval.

CI already proved the demand

GitHub Actions reinvented process outputs as a temp-file convention ($GITHUB_OUTPUT) because the shell never shipped them. desh makes the pattern native: typed, declared, completable.

composition beyond the pipe

A pipe composes two adjacent processes once; variables compose the whole session. Any command references any prior result by name — dataflow across time, and the session starts behaving like a notebook whose cells are commands.

variables are ledger facts

Typed, timestamped, provenance-linked to the invocation that produced them; replay restores them. An agent reading the session reads $deploy.url, not scrollback regex.

consequences

what the ledger buys

organizational replay

"How did this system get into this state" becomes a query over the ledger.

docs that execute

Examples are live objects with provenance, not copy-paste fossils.

handoff without loss

A session hands to a colleague — or an agent — as structure, not a screenshot of green text.

near misses

everyone fixed a symptom

Warp

Modernized the chrome — blocks, real editing — and kept strings-over-hidden-state underneath.

Fig

Proved the appetite for affordances as an overlay; bolted onto strings, acquired by Amazon, sunset.

nushell

Structured pipes are the right instinct, inside a forgetting shell with a new grammar to memorize.

Jupyter

Keeps outputs — and proves how much that alone is worth — but it's a document about computation, not an operating surface.

artifacts

status, honestly

sitelive

desh.sudoscience.dev

stream in / stream outprototype

named replayable I/O channels over s2.dev as the buffer

agentic workflow cookbookprototype

one recipe spec, two engines: recipes as pure logic behind ports + typed traces, run unchanged under Temporal and AWS durable Lambdas, parity enforced by shared given/when/then scenarios — the pipeline-to-prod claim, demonstrated

resource & affordance modelprototype

in the web shell (desh.sudoscience.dev/demo): recognizers map files to types, types render typed projections with a raw-bytes escape hatch, and verbs run from the resource — exporting typed return values into session scope as $names

recognizer plugin interfaceprototype

in the web shell: a CSV recognizer arrives as code on demand — fetched over the (canned) network, gated as an effect even when the user asked, and identified by its content hash; only allowlisted hashes ever compile. The full design is sandboxed WASM

POSEVEN fssketch

all you need is log — content-addressed store + append-only oplog; O(1) forks

event-store comparisonsketch

five CQRS/ES substrates — cq-rs, Emmett, Concordance, lix, atomic.dev — scored on one dimension table before the lab bet on its own log, with a benchmark taxonomy attached: time to first working system, time to prod with required gates, cost of the next ten changes. From the same research run that seeded Rhett

session ledger formatsketch

commands, effects, outputs, timings as typed events

waste audit promptlive

on the desh site — paste into your agent; it computes your personal waste number, locally

terminal plugin (Atuin/Warp)roadmap

growth vector: ledger sessions inside the shell people already run

web shellprototype

live at desh.sudoscience.dev/demo — a small desh in the browser: append-only ledger with a raw-log panel, content-addressed outputs you can re-view and replay pipe stages from, time-travel scrubbing with O(1) forks, an effect-gated agent you approve or deny on the record, typed resources with verbs and code-on-demand recognizers, and sessions shareable as read-only replay links

prototype shellroadmap

one ledger, one structural renderer, live pipelines, replay

edges

connected investigations

absorbed prior work — named, never shipped, not available

Sgittish

A repo-level object store drafted long before the lab: an append-only ledger of codebase facts — command history, profiling, issues, dependency changes — consumed by simpler, more powerful editors. Never built; its ledger became desh's session ledger and its store became POSEVEN.

Twenty-plus years of near-daily terminal use; the ritual finally itemized. The questions that started it: "can we reimagine the shell?", "what if binaries weren't limited to stdout/stderr and could output variables for shells?", "what strategic data are we not using from developer exhaust?"