aboutsummaryrefslogtreecommitdiffstats

Pure

Current app model (2026-09-27). Apps are written in aup and run as Pure modules (format v6), verified completely before they execute: declared states persist in Pure's store (lists as images and a log of their changes, the rest in its tree), every event is a transaction, views are pure functions of state. The same spec becomes a terminal UI, a CLI, spoken sentences and a web page through Vega, and an HTTP service through pure-serve: views are GETs and inputs are POSTs, with JSON bodies (groups included) read in place; answers are durable, a save being one log entry (and a tree commit when more than lists changed), each one write and one sync; views are read from a snapshot of the last save, so reads never wait for a sync. What an app sends is saved with its event and delivered over HTTP in order and in batches, and a receiving app applies each message once; sealed to the receiver's key (HPKE, one session a wire, authenticated by the sender's key), no relay between them can read or change it, at the speed of unsealed sends. People use a node through surfaces it runs, reading its states where they are (Vega's display: a two-node messenger shows a line on the other node's screen in about a millisecond). Queries are modules too: the app's states with views of their own (aup query), verified when registered and shown from snapshots. Folds run a leaf of a list at a time and a fold in a table's column is answered for every row from one pass over its list, so on pgbench's tables of 100,000 accounts a group-by, a join and a correlated rank run 3–420x faster than on SQLite, and faster than SQLite given a DBA's indexes but for one count, with no index declared. TPC-C's five transactions, written as one aup app, leave SQLite's state row for row from the same inputs, with one warehouse or four, and run 3.5–4x faster than a tuned SQLite in RAM (40,976 against 10,164 a second, HTTP and JSON included) and 4–11x faster on an SD card than SQLite tuned for the card and committing in groups as Pure does, both answering once the commit is on the device: SQLite writes whole pages, 8–18x the bytes a transaction (092, 106, 107). Measurements against axum and drogon on a Raspberry Pi 5 are in 075, 077, 080, 081, 082, 083, 086, 087, 088, 089, 090, 091 and 092; the status table is CHECKPOINT.md.

The source follows the principle below, a small core with the rest selected around it (layout):

Directory What Built as
core/ execution, ownership, limits and completion (runtime.c); the app model: modules verified before they run, events as transactions, states as drafts (module*.c); what the core asks of storage (state.h, store.h) build/libpure.a (with the store)
store/ the tree store: one file, a commit is one contiguous write and one sync (formats PURETRE3, PUREREC1) in libpure.a
link/ links without connections, the default between Pure nodes: saved sends over UDP, sealed with the two nodes' keys, no handshake (011, specified in 012); the crypto they and sealed sends use, OpenSSL's part apart, mapped only by a process that uses one build/libpure-link.a, build/pure-crypto.so
serve/ pure-serve: the HTTP host, outbound delivery, JSON read in place, surfaces for people run in the node (010) build/pure-serve
cli/ the command-line test host build/pure-run
prototypes/ the earlier document runtime (000-077), built against core/ and store/ make -C prototypes/connections
tests/ the hosts checked end to end, with apps built by aup (the sibling checkout) make check

make builds the library and the hosts; make check runs the store's and the app model's unit tests (beside their parts) and then tests/check.py. Interfaces for people are Vega, which links libpure.a. The text below records the earlier document runtime this grew from.

A standalone native micro runtime being designed as a small operating system. Pure owns the application model for execution, memory, protection, resource lifetimes, storage, and communication. Efficient connections between inputs, computation, state, and outputs guide that design, with the aim of reducing unnecessary representations, copies, retained data, and waiting.

Micro size is a primary constraint. The always-present core covers only the required execution, ownership, resource limits, and completion rules. Protocols, storage implementations, UI, and codecs are selected for the application; supporting them does not mean bundling or starting them all. Prefer build-time composition without requiring a dynamic plugin loader. Track core size, the complete selected build, idle memory, and per-active-work overhead separately; moving costs into dependencies does not count as a reduction.

The current 12,966-byte Linux AArch64 fixed document preview contains a parser-free native CLI. The 22,862-byte source-editable preview also includes an editable editor.pure. HTTP, authenticated peer, and GTK authoring are explicit selections. The archive was extracted elsewhere and passed an edit and restore check. The clean default-build check keeps the parser, HTTP, TUI and TLS out of make all runtime outputs. An authored final-size policy now guards the real document write under its storage lock. Source and fixed CLI, HTTP and terminal hosts share the policy; an optional authenticated peer was checked separately. The default core remains 4,632 B of object text. The selected GTK process still uses about 43 MiB RSS; compressed archive size is not a memory claim. The public checkpoint remains in progress.

The optional native document window can now switch among stored documents in one session while preserving unsaved document and definition drafts. It still uses GTK and remains outside the micro default. In one Linux test, switching two 1 MiB documents 64 times raised the window's RSS from 43,920 to 58,752 KiB. A controlled follow-up isolated the growth to repeated GTK text-view replacement; the optional window is not a low-memory runtime profile. See the memory analysis. The GTK window has no document list or multi-object update operation.

The optional native terminal editor uses the same build-time prepared document app as the CLI and HTTP host. It handles UTF-8 input, a bounded list of stored keys with prefix lookup, resize, revision conflicts, and a 1 MiB edit without GTK. Its current linked text is 32,023 B and its measured 1 MiB peak RSS was 3,168 KiB on the recorded Linux host. The current CLI+TUI artifact is 32,144 B compressed. It does not edit the .pure definition or establish a low-memory GUI result.

The source-loaded terminal variant reads editor.pure at startup and shares the CLI's document store. It is an optional 48,972 B linked-text host; the CLI+TUI archive is 51,398 B compressed. A changed definition takes effect in a new session. The default core and parser-free TUI do not link the .pure parser.

The selected 16 KiB-page native terminal app uses the same authored document program. On the recorded Linux/ext4 host, Ctrl+S for a one-byte edit in a 1 MiB document reached the completed screen in 93.17 ms with the default store and 22.04 ms with the selected page store (24 saves per profile). The 256 B case was 8.54 versus 9.23 ms. The selected source TUI adds 4,958 B linked text; its CLI+TUI archive is 57,788 B compressed and passed a relocated app check. Large documents use an incompatible on-disk page format, so this remains an opt-in Linux storage research profile. Its 16 KiB logical pages now admit OS page sizes that divide 16 KiB. The 16 KiB host passed the full selected suite, and a real 4 KiB QEMU guest passed the page-store assertions plus a 1 MiB native CLI edit and stale-revision check. Physical-disk durability, Linux x86_64 CI and macOS remain unverified; the default core and storage path are unchanged.

The selected single-file persistent tree questions the one-contiguous-file-per-document model instead. All documents share one append-only file of immutable extents. An insert, delete or append writes only the changed leaf and path, and unchanged extents are shared between versions. On the same ext4 host, a durable 1-byte middle insert into a 1 MiB document took 8.58 ms against 78.51 ms for the default store. The real TUI's Ctrl+S after typing one character took 16.60 ms against 84.59 ms. The unchanged runtime, splice, async and real-PTY TUI checks pass on it (make -C prototypes/connections check-tree). Its linked CLI is 12,710 B larger, contiguous reads of multi-leaf documents copy, and space is reclaimed only by compaction, so it remains an opt-in profile.

On that store the runtime can own an app's working version (drafts, state.h). A draft shares unchanged extents with the stored version, lends ordered extents without copying, and commits only its new nodes. Typing into the middle of a 1 MiB document and saving each character peaked at 1,648–1,664 KiB RSS with drafts. An app copy that is compared with storage on save peaked at 4,464–4,496 KiB. Saves were only about 1–2 ms faster; drafts are not yet exposed to .pure definitions or charged to the runtime budget.

The current execution profile has separate core, fixed-editor, editor, and server build targets. make all produces the core and the parser-free CLI from the build-time prepared editor.pure; it also builds a compiler tool that is not linked into the CLI. Source-loaded rule editing requires an explicit make editor, and HTTP requires make server. (cd prototypes/connections && make check-release) runs behavior tests and checks both the core and default linked hosts against reviewed release size and dependency ceilings. The default core is 4,632 B of object text and 120 B per idle domain and 216 B per active work slot on Linux AArch64. It contains no document interpreter; that code is linked with a selected host. The optional metrics profile uses 192 B per domain on this toolchain. The earlier 1,000-app comparison measured 80 KiB lower RSS for the default profile. These figures exclude the parser, selected backends, stacks, payloads and process memory. The default document CLI and HTTP host are separately checked at 36,135 B and 44,342 B of linked text, with libc as their only direct shared library. These are regression boundaries for the recorded toolchain, not total memory targets. The current authored policy and total cost. The verification device is the local Raspberry Pi 5 (Linux AArch64, 16 KiB pages, ext4 on SD); macOS is no longer a completion requirement. make -C prototypes/connections check-portable runs the C behavior checks without Linux-only size/RSS tools. make -C prototypes/connections check-portable-tui runs both terminal editors through real PTYs without Linux /proc; it does not measure their RSS. make -C prototypes/connections BUILD=build/native-checkpoint check-native-checkpoint combines those checks with real CLI document RSS samples for 1 MiB creation, read and 1 B revision edit. It adds no runtime code or macOS memory ceiling. The storage adapter now exposes the Darwin open flags it uses. These checks have passed on Linux AArch64. No macOS SDK build or native run has been completed, so this is not a macOS support claim. The Apple Silicon CI job remains an optional portability check for a GitHub-hosted copy. The optional make -C prototypes/connections check-portable-peer runs real authenticated TLS document work for both native peer profiles without Linux /proc; it requires OpenSSL and has separate Linux cost evidence. The current source-editable CLI archive includes editor.pure and is 22,862 B compressed. A separate native source preview contains the C execution path and Workbench sources without prior build/results trees. It was rebuilt and tested after extraction, including both PTY editors, native CLI RSS samples, in-process document fan-out, selected page-to-flat export and Linux release gates; see the clean-build evidence. Its 337,937 B compressed size is a source-distribution cost, not resident runtime memory. The CLI whole-process RSS gate checks a 1 B edit and 1 MiB edit/read on the recorded Linux AArch64 system. Document editing and the complete measured scope.

A build-time prepared runner executes the same document definition without linking the .pure parser: its linked text is now 19,268 B versus 36,135 B for the source-loading CLI. Its 1 MiB edit peak RSS was about 2.1 MiB in these runs, so this is a code-size gain, not a RAM gain. The parser-free HTTP host uses the same prepared app and now 26,689 B of linked text; the source-loading HTTP host uses 44,342 B. Source editing still uses the separate source-loading path. The previous CLI+HTTP artifact is 28,719 B compressed and was exercised after extraction; it has no dynamic definition editing. Both HTTP hosts now sleep until an event or connection deadline instead of waking every 50 ms while idle. A small POSIX signal pipe also wakes the host if shutdown arrives just before sleeping; macOS execution is untested.

The document service capacity check ran the same app with 1,024 stored 8 KiB documents and eight simultaneous clients: 4,096 checked HTTP operations per host, matching final documents, and 1,680 KiB peak RSS for the fixed-definition server in that run. This is a bounded correctness and resource result, not a throughput claim or a large-service comparison.

The optional asynchronous HTTP host keeps one read worker and one write worker. A deterministic test pauses a write before publication: the same document remains readable at its old revision, then exposes the new revision after the write completes. This adds 4,711 B of linked text over the default source HTTP host. The latest 1,024-document run observed 1,776 KiB peak RSS for this selected host versus 1,728 KiB for the default source host. The core also now binds work slots only while an app needs them: 1,000 real native apps retained 448 B less per controller and used 432 KiB less process RSS in the recorded comparison, while the core grew by 144 B.

The current host OS supplies resources and imposes execution constraints. Its processes, threads, file descriptors, and sockets are backend mechanisms, not the organizing model for Pure applications. Development starts hosted on existing systems; direct hardware execution remains a separate implementation target, not a prerequisite for defining Pure's own operating model.

Networking, RPC, databases, and UI are domains where this model applies. The research concerns how their data and work connect, including representation, ownership, lifetime, and execution timing. Servers and CLI tools must be able to use the runtime without loading UI. Web interoperability and standard formats remain compatibility requirements. End-to-end efficiency is a research goal, not an established result of the current prototypes.

Communication with non-Pure services, runtimes, and programs is a core requirement in both directions. Boundary adapters support the peer's protocols and data formats without requiring the peer to run Pure or making those formats the mandatory internal representation.

SQL and relational schemas are not Pure's internal data model. Memory and storage representations follow the data's access, update, and lifetime needs; the runtime must not require data to pass through a SQL engine. An optional inline/page storage experiment preserves the same contiguous read interface while reducing a 1 MiB document's one-byte replacement from 1,048,600 to 16,944 user-space file-write bytes. Unlike the earlier page-only experiment, a one-byte document still writes 25 bytes. In the current build the selected CLI grows from 35,783 to 41,040 linked text bytes. Large objects become unreadable by the default store after conversion. A separate offline export now preserves bodies and revisions in a new default-format directory, but this backend is not the micro default. A separate Linux file-copy experiment keeps the existing immutable file format and reduces user-space read/write calls for a one-byte edit of a 1 MiB document. It adds 269 B of linked CLI text when explicitly selected; the default core and build stay unchanged. This is syscall evidence, not a claim of less physical I/O or lower latency. A durable edit comparison now times the same 1 MiB native document action on ext4: the page profile has a much shorter median edit, while the file-copy path is not distinguishable from the default on this host. A 70-edit run exposes the page rebuild and occasional long delays, so the page format remains optional.

HTTP is a compatibility boundary, not the required model for Pure-to-Pure communication: between nodes, saved sends go over links without connections (specification). Selected scalar and document apps now use bounded binary peer protocols over mutually authenticated TLS 1.3/TCP. The document peer shares editor.pure work and storage with the CLI, HTTP adapter, and GTK window; its request can omit an output body that the caller will not consume. The plaintext HTTP/1.1 loopback adapter remains a separate compatibility path; neither peer is a QUIC implementation. See the native protocol design, scalar peer evidence, and document peer evidence and full cost.

Execution domains are internal units of Pure's operating model. The core defines their scheduling, ownership, authority, connections, and lifetimes; platform backends provide the mechanisms available to enforce those contracts. This is a design direction, not an implemented complete OS or sandbox. A limited execution core now owns admission, input budgets, ready work, completion, and borrowed results for the storage profile. The HTTP adapter uses the same core as local domain connections. Current host limits and native-code fault boundaries still apply. The optional in-process document mirror now forwards a real 1 MiB stored value to two domains without allocating target input buffers. Each target writes independently and reports its own revision conflict; the source mapping is released after both finish. This is one-shot domain composition, not yet a long-running app supervisor.

The first public checkpoint remains in progress. Its requirements include a real authored native app, internal and external communication, reproducible cost evidence, and a usable build and distribution path. An actual document-path comparison now checks direct store calls against the prepared Pure app on equal final files. The Pure benchmark executable links 8,276 B more text; the ext4 timing samples are too variable to establish a speed advantage. This comparison covers the valid document workflow, not a feature-equivalent direct runtime or RPC service. An authenticated document-peer comparison found a shared TCP stall in both direct and Pure servers; setting TCP_NODELAY removed it in the local repeated-read test. The optional server-only build links 3,472 B less text than the combined native peer. Its selected TLS process still occupies roughly 8–10 MiB here, so it is not the micro default. The server-only TLS archive is 47,686 B compressed, includes the source-editable CLI, and passed extracted external-client and document recovery checks. The corresponding combined client/server archive is 49,382 B; neither bundles OpenSSL or libc.

The browser, terminal, and optional Linux authoring window validate parts of the execution and authoring model. They do not yet implement the full application runtime or its network, RPC, database, and general native UI subsystems. See the native runtime roadmap for the current direction.

Current experiment: author a work from a blank document.

The same authored scalar definitions can now be built as a standalone native CLI, optional Linux GTK authoring window, or optional authenticated peer. Independent calculation instances, inputs, snapshots, plan replacement, and conditional storage use the execution core. The CLI runs without Node, GTK, or Wasm. The authoring window uses Node and a C compiler to apply edits, and its complete memory cost is much larger than the execution-only CLI. Native window evidence and separate costs. Fixed-definition CLI and peer builds now share one immutable program across independent scalar instances. For the routed layout, each instance occupies 280 B and the compiled program occupies 2,480 B once; the measured 1,000-instance comparison and complete build costs keep the authoring window and Wasm at full capacity. The native app controller now occupies 408 B per idle instance, down from 928 B after idle work-slot binding and optional metrics. The peer host uses the same app operations without adding OpenSSL to the CLI or core; its complete process cost is measured separately.

The native path is runnable: author storage and response connections. It resolves named boundary fields, constant byte ranges and aliases before serving local TCP requests, evaluates ranges that depend on input values, preserves bounds failures and storage effects, and holds source data through transfer completion. A text-selection client exercises this path with UTF-8 files. This is a limited native authoring profile, not yet a general-purpose I/O execution model or an end-to-end performance result.

The authored document splice program now also runs through an optional Linux GTK document window. The same document is edited by the native CLI and HTTP boundary with revision conflicts; GTK and its measured 44 MiB process cost stay outside the micro core. This is a hosted native app experiment, not the final low-memory UI backend. The window also edits and safely applies its .pure definition in place; the selected app cost and recovery checks are reported separately from the default runtime. An optional authenticated document peer now performs the same edit and read over TLS without adding TLS to the default CLI, HTTP host, or execution core.

python3 prototypes/workbench/manage.py serve --port 8766

Open http://127.0.0.1:8766. Declare your own states, inputs, shapes, and event handlers. Apply edits while preserving states by name. Browser and terminal use the same Zig execution core, with separate instances. Optional examples never run automatically. The prototype is an authoring experiment, not a claim of superior developer experience or performance.

The earlier Dino demo tests changing predefined rules while keeping state; it does not establish development experience.

Research in progress: