Decisions

Key decisions

The two dozen decisions that shaped Loams, why each was made, what was rejected, and which ones were later reversed.

Loams keeps a single decision log. Every architectural choice gets a row with an ID, a date, the decision, the reason and a status. By now there are about a thousand rows. Most of them are details: a file layout, a timeout, which crate pins which version. This page picks out the roughly two dozen that explain why Loams looks the way it does, groups them by theme, and links each one to the product page that explains it.

Reversals get the most space here. A decision that was later overturned tells you more about the design than one that has never been tested. Where the log has the evidence, each entry also says plainly whether the decision has held up.

How to read the log

The full log is docs/design/13-decision-log.md on GitHub. This page links the dev branch, because main only catches up at each release and is missing the newest rows.

IDs. Decisions are numbered D1, D2 and onwards, in roughly the order they were made. A few series have their own prefix: D-SC-n for the showcase suite and D-SF-n for the software factory. Some early rows say "number assigned at merge", which means two branches picked IDs at the same time and one was renumbered when they merged. Open questions are a separate series, Q1 and onwards, kept in their own table further down the file. When a question is answered, its row points to the decision that answers it. In the log, §NN means design document NN: §20 is 20-reactive-database-on-tikv.md.

Statuses. The last column is the one to trust, and it is updated in place:

StatusMeaning
ApprovedAccepted and in force. Approved (owner) means the project owner made or confirmed the call.
Approved (owner defaults, 2026-10-02)On 2026-10-02 the owner accepted the recommended default for every open question and proposed decision in that round of design work ("do suggested for all"). That covers most of D273 to D459.
Approved directionThe owner set the direction. The details in the same row may still be Proposed.
Owner rulingA direct instruction from the owner, recorded as given.
ProposedWritten up by the design work but not yet ruled on. Many proposed rows already describe shipped code. The log tracks when a ruling was made, not what has been built.
Amended by DnStill in force, but a later decision changed part of it. Read both rows.
Superseded by DnReplaced. The later row is the one in force.
Reversed by DnOverturned, either completely or for one product.
MovedThe decision was moved to the separate platform repository. Since D1119 (2026-10-19) Loams has no open core, and that code is moving into the open repo now.

Owner rulings. The log quotes the owner's own words where a ruling came from a message, for example D820's "let the neon fork be hard fork". Those quotes are the strongest evidence of intent in the log. When a later ruling changes a design document, the document's status line says so (the design index marks design 23, for example, as amended by design 28), so check the status line before relying on a document's text.

Two habits make the log easier to use. First, start from the newest row that mentions a topic and work backwards through the "amends" and "supersedes" links. Second, read the Rationale column next to the Status column: a row's reason often explains why a later row overturned it.

Reversals at a glance

OriginalChanged byWhat changedWhy
D2: OLTP is out of scopeD130, D117, D231Loams Live, Loams Postgres and Loams SQL became product lines outside the retrieval engineThe owner widened the product to an AI-native cloud (D116)
D3: speak Kafka, ES, Qdrant, Neo4j and ClickHouseD42Narrowed to the native API, Flight SQL, Qdrant and an Elasticsearch subset"Emulating five products' protocols is a five-product trap"
D43: Kafka gateway deferred past v1.0D74, then D408Brought back for M5, then deferred again in favour of Iggy's Kafka gatewayContribute to one Kafka front end instead of building a second
D45: no ClickHouse surfaceD347Reversed for the House onlyIt made "ClickHouse compatible" testable, so ClickHouse-native apps run unchanged
D44: no CypherD748 (proposed)Cypher returns as an opt-in dialect, off by defaultLangChain and LlamaIndex generate Cypher
D10/D58: FoundationDB, then TiDB, as metastore backendsD71, D124, D260FoundationDB was dropped, then TiDB was replaced by TiKVNative libfdb_c on every host and no managed offering, then one store and one client stack
D123: MySQL through unmodified TiDBD260, D301, then D721TiDB was removed, an earlier MySQL design took its place, and then TiDB came back as Loams SQL's compute"InnoDB semantics on TiKV is TiDB"
D151: Neon pinned and ownedD231, then D820A soft fork, then a hard fork named Loams PostgresUpstream went silent
D679: own agent chat UID797The chat UI is adapted from the DSH client packagesThe owner's decision of 2026-10-09
D184: Envoy at the edgeD1010, D1011An Apache-2.0 Rust gateway, loams-gatewayPostgres clients send SSLRequest before TLS, so a generic SNI router sees no SNI
D28: seeded simulation onlyD313, D947Bit-exact simulation for the commit paths, and only thereA narrow version of an outside proposal that was rejected as a whole (D946)

Foundations

D1: the bucket is the only source of truth

2026-09-22 · Approved; amended by D130 (holds for the retrieval engine, not for Loams Live) · Engine · Concept · Design 01

Object storage holds every durable byte, and compute is stateless. The log gives three reasons: the turbopuffer, WarpStream and ClickHouse Cloud model, cost, and operability. The alternative it set aside is the usual one, a database whose truth lives on replicated local disks. That alternative came back, on purpose and in a fenced-off place. D130 (2026-09-27) says D1 holds for the retrieval engine and not for Loams Live, whose truth is TiKV's Raft-replicated local disks. D1057 (2026-10-16) then gives each storage layer one role. TiKV Raft handles small transactions and metadata. loams-wal is the high-volume ordered log for Postgres WAL. The bucket holds history, branches and archives. The reason D1057 gives is measured: TiKV pays for a timestamp fetch, a Raft log write and a RocksDB apply on every append, and the Postgres benchmarks in design 46 showed the cost.

Held up? Yes, within its scope. Each later exception was written down as an exception rather than slipped in. Even Git's TiKV-backed ref log (D1025) mirrors every entry into the bucket WAL, so the bucket stays the record.

D4: the log is the spine

2026-09-22 · Approved; amended by D89 · Engine · Concept · Design 02

Every write lands in a stream first. Tables, collections and graphs are materialisations of that stream, kept up to date by links. The reasons given are zero-ETL, consistency tokens, and having one durability mechanism instead of one per object kind. D89 (2026-09-26) added conditional writes: a write may depend on the current state of its key, and the condition is checked when the op is applied, in log order. The log also records what D89 rejected. Checking conditions on a per-key owner before the WAL append would need a leader per key, and the WAL is deliberately leaderless.

Held up? Yes. Later products kept the pattern instead of inventing their own. Loams Graph writes each committed transaction as a GraphChangeSet into the graph's stream before acknowledging it (D742). Loams Git's refs are a per-repository log of create-only segments (D388).

D6, D7, D8: open formats, chosen per workload

2026-09-22 · Approved; D8 amended by D94 (f16, i8 and u8 vectors) · Engine · Concept · Design 03

Tables use Iceberg, through Lakekeeper (Iceberg tables are planned and not in 0.1.0). Collections use Lance. Full-text search uses Tantivy, with Quickwit's storage, DSL and aggregation crates forked. Vectors keep an IVF index in Lance as the durable tier and an HNSW index derived from Qdrant in the hot tier. The reasons in the log are short. Iceberg was a requirement for analytics. Lance is "the only Rust substrate with columns + vectors + versioning". Tantivy was preferred to Lance's own full-text search for its maturity, its aggregations, and because Quickwit already translates the Elasticsearch DSL to it. For vectors, "Lance wins storage/cost/versioning; Qdrant wins serving latency/filtered recall/freshness".

Held up? Yes, and it was reaffirmed under pressure. When the House arrived, D762 (2026-10-08) rejected MergeTree on S3 disks and kept Iceberg as the House's only storage of record.

D11: Apache-2.0, with no AGPL, BSL, SSPL or ELv2 dependencies

2026-09-22 · Approved; applied to connectors by D359; the open-core boundary of D220 is superseded by D1119 · Design 00

The reason given is one line: "Big-company adoption". The rule covers what Loams links. Software that Loams only runs beside itself, unmodified, can carry another licence. That is why PgDog (AGPL-3.0) can be Loams Postgres' front door as a separate, unmodified service (D708). D359 enforces the rule for connectors in CI and refuses AGPL, BSL, SSPL, ELv2 and unknown licences. D220 once set an open-core boundary, keeping metering, billing and commercial APIs private. D1119 (2026-10-19) superseded it: Loams is fully open source, and Ostrium Labs sells services (infrastructure efficiency, SLAs, support), not a paid edition.

Held up? Yes. Later rows keep citing it to reject candidates. Sōzu was rejected as AGPL in D184 and again in D1013. HydraDB, an AGPL-3.0 graph database, is used only as a source of ideas (D1072).

D10 to D260: the metastore, from Raft to TiKV

2026-09-22 to 2026-09-29 · D10 Approved and amended by D47, D58, D71, D124 and D260 · Engine · Architecture · Design 18

D10 put metadata in an embedded Raft group (openraft) by default, with FoundationDB and Postgres as pluggable options. The reason given was "Kafka-rate metadata cannot run on S3 CAS". Within a week the options changed. D47 put every backend behind a semantic MetaStore trait. D58 named Postgres and DynamoDB for v1.0, and gave TiDB the scale-out role. D71 (2026-09-26) dropped FoundationDB, because it "needs native libfdb_c at the cluster's API version on every host and has no managed offering". D124 (2026-09-27) replaced the TiDB backend with loams-meta-tikv, written against tikv-client directly. Loams Live was going to run a TiKV cluster anyway, and TiKV meets the strict contract: a snapshot per call, atomic multi-partition commits and a monotonic clock. D260 (2026-09-29) then removed TiDB from the engine entirely.

Held up? Yes. The TiKV metastore is Available in 0.1.0 (--meta tikv://…), and openraft remains the default for single-node use. The FoundationDB reversal is a good example of a choice made on paper and dropped once its operating cost was counted.

D28 and D947: determinism, narrowly

2026-09-24 and 2026-10-15 · D28 Approved; scope amended by D313 and D947 · Engine · Design 55

D28 chose a seeded, in-process simulation (loams-sim) over a full deterministic simulator such as madsim or turmoil. The log's reason is that openraft, redb and object_store do real I/O and start blocking work, so bit-exact replay "would need a madsim port of every dependency", and a seed sweep on every PR finds the same classes of bugs. D313 (2026-10-01) added bit-exact simulation for control-plane code written without I/O. On 2026-10-15 an outside proposal called "Loam Io" asked for a capability handle threaded through every engine function. D946 rejected it as written: it would have touched about 800 production call sites across 60 crates, and the engine's dependencies start tasks and read clocks themselves. D947 adopted a narrow version. Code on the commit paths (manifest commits, leases, journals, Live's commit journal, graph ownership) reads time and randomness only through an injected Clock and Entropy, and those decisions move into machines simulated bit-exactly. D953 and D958 turn this into a pilot "after v0.1.0-preview.3" (the release that shipped as 0.1.0), with a go/no-go test. Go means the pilot finds a defect the current suites missed, or proves two of its four properties, within a cost budget.

Held up? Too early to say. This entry is here to show how the log handles a large proposal: keep the parts that pay for themselves and set a test that can stop the rest.

Retrieval engine and protocols

D42: the protocol footprint is narrowed

2026-09-25 · Approved (owner; architecture review); replaces D3 · Engine · Design 01

D3 (2026-09-22) had scoped Loams as Kafka, Elasticsearch, Qdrant, Neo4j and ClickHouse combined. Three days later D42 cut that to Loams' native API, Arrow Flight SQL, the Qdrant REST and gRPC API, and a targeted Elasticsearch subset. Kafka was deferred (D43), Neo4j Bolt and Cypher were dropped (D44), and the ClickHouse interface was dropped (D45). The reason given is "Emulating five products' protocols is a five-product trap". Qdrant and Elasticsearch carry adoption by AI frameworks, and Flight SQL (D49) is the clean path for every language. D13 had already set the rule for how far compatibility goes: external conformance suites decide.

Held up? Mostly. The four surfaces in D42 are all Available in 0.1.0, tested with named clients. Two of the three cuts were later partly reversed, each for one product and with its own test suite (D347, D748). The pattern is the decision working as intended, not failing: compatibility is added one product at a time, behind a conformance gate.

D43, D74, D408: the Kafka gateway, deferred twice

2026-09-25, 2026-09-26, 2026-10-02 · D408 Approved (owner defaults) · Engine · Design 02

D43 deferred a Kafka wire gateway past v1.0, because "rebuilding a Kafka broker (consumer-group rebalancing, KIP-848, transactions) is a project of its own". A day later D74 brought it back for M5. The reasons were that WarpStream, AutoMQ and Bufstream show stream tools connect to a Kafka-compatible log, and Loams' WAL already stores Kafka RecordBatch v2 bytes. D74 also rejected a Kinesis-compatible subset as reaching fewer tools. Then D405 put event ingestion on Apache Iggy, and D408 deferred Loams' own gateway again, "not cancelled": Kafka clients use Iggy's Kafka gateway, with Loams contributing upstream. Loams' gateway comes back only if Iggy's cannot serve consumer groups with committed offsets.

Held up? The deferral has. Kafka wire is still listed as Planned in the 0.1.0 feature table, and the native produce, fetch and subscribe API (D72) is what ships. This is the clearest example in the log of choosing to contribute to an existing component instead of building a second one.

D15 and D51: one query engine, and no embedded foreign engines

2026-09-22 and 2026-09-25 · D15 Approved; D51 Approved, amended by D343 · Engine · Design 05

D15 made DataFusion the single query engine, distributed with datafusion-distributed rather than Ballista, for its extensibility, its ecosystem, and interactive distributed execution. D51 said Loams integrates with the AI data ecosystem through protocols and open formats, "never by embedding other engines". The reason is version lockstep: engines built on DataFusion or Arrow pin specific versions (Lance 12 pins DataFusion 54 and arrow 58), so linking another engine forces the whole workspace onto its versions. D343 (2026-10-01) amended this for the House. The engine binary stays free of other engines, but a separate service binary owned by Loams may link one. That is how chDB entered the system: in loams-fabric, never in loams.

Held up? Yes. The amendment kept the original reason and moved the boundary from "Loams" to "the engine binary".

D1030 and D1031: Postgres wire, and no TDS

2026-10-16 · Approved direction (owner) · Postgres · Design 58

Postgres wire is the SQL protocol for Loams' Postgres product. New capability is added through opt-in protocol extensions and APIs around it, never through a new wire protocol. The log cites the market as the reason: "Postgres wire won", naming CedarDB, Aurora DSQL, Neki, Multigres and TiDB's Postgres preview. D1031 rejected building a SQL Server (TDS) server for now. The reasons given are possible Microsoft patents, the catalog emulation SSMS needs, the cost of T-SQL semantics, BI tools moving to ADBC, and that no Rust TDS server exists. If a paying SQL Server migration ever needs it, Babelfish would be ported onto loams-postgres rather than T-SQL being written in Rust.

Held up? Too new to judge. It is here because it closes off an option that keeps coming up, and the log records why.

D44 to D748, and the Grafeo fork: graph, three times over

2026-09-25 to 2026-10-12 · D44 Approved; D634 Approved; D740 to D759 Proposed; Grafeo fork by owner decision (GR1, 2026-10-12) · Graph · Design 48

D44 said graph is native, with no Cypher and no Bolt. Graphs would be mapped over collections and expanded one or two hops inside a hybrid search query. The reason given is that "GraphRAG needs vector/BM25 seeds → 1–2 hops → rerank, in one planned query", and that Cypher had a fraction of the demand. D350 (2026-10-01) looked at Grafeo, an embedded graph engine written in Rust, and turned it down for the House. The repository was eight months old, had one maintainer in practice, and stored data locally only. Three days later, D634 made GQL (ISO/IEC 39075) Loams' graph surface and embedded Grafeo as the reference engine. The reasoning: GQL is the standard, Grafeo links in-process with no wire protocol to secure, and Grafeo is "a test target, not a foundation". The standard is the commitment, and the engine can be replaced. D742 (2026-10-08) made that last promise concrete. The graph's truth is its log and the bucket, not Grafeo's files, because Grafeo's own WAL "defaults to periodic fsync and never reaches the bucket". D748 (proposed) brings Cypher back as an opt-in dialect, because LangChain and LlamaIndex generate it. On 2026-10-12 the owner decided to build Grafeo from a fork, ostrium-labs/grafeo, kept as a patch queue. Its first patches fix correctness issues that GR1 had been working around: a commit listener, timeouts on parameterised statements, and DETACH DELETE.

Held up? The surface is still settling, but the safeguard worked. Because D742 kept durability in Loams' log, taking on a young engine meant forking it, not losing data. Loams Graph is Available in 0.1.0, running on the fork. D44's planned one-to-two-hop expansion inside retrieval queries is still Planned.

The OLTP line: Live, Postgres and Loams SQL

D2 and D130: OLTP, out of scope and then back in

2026-09-22 and 2026-09-27 · D2 Approved (user), amended by D130; D130 Proposed; D116 Approved (owner) · Live · Concept · Design 20

D2 put OLTP (Postgres) out of scope. Its reasoning: "Millisecond interactive transactions conflict with S3-native design; Neon needed a Paxos tier; users keep a small Postgres and stream CDC in." Five days later D116 widened Loams into an "AI-native cloud" with an application database, SQL and retrieval on shared infrastructure. D130 then said exactly where the line falls. D1 and D2 still hold for the retrieval engine. Loams Live is a separate OLTP product line whose truth is TiKV. The log notes that mandatory backup of Live's keyspaces to object storage "softens the D1 tension".

Held up? This is the most consequential reversal in the log, and it was handled cleanly. The engine's rules were not weakened. A new product line was drawn around them instead. D2's own reason, that Neon needed a Paxos tier, did not go away either. Loams Postgres carries one (safekeepers, with loams-wal as the planned replacement), which is the cost D2 described. D130 itself is still marked Proposed, even though Live ships.

D117: Loams Live, a Convex-style reactive database on TiKV

2026-09-27 · Approved (owner); the name was proposed · Live · Design 20 · Design 45

TiKV supplies ACID transactions, Raft replication, MVCC and timestamps. Loams builds the rest on top: a reactive query engine that tracks each query's read set and reruns it when a commit touches that set, server functions, a protobuf sync API, and a bridge from Live tables into collections. The reason given is that Convex's developer model "is what app builders want", and TiKV supplies the hard distributed-storage parts under Apache-2.0. The log names the collections bridge as the differentiator. The concepts come from Convex's public documentation, and Convex's FSL-licensed code is never copied. D125 put Loams' own control-plane tables on Live, so Loams uses its own database. It rejected TiDB SQL for this, while admitting TiDB is "more mature and better for ad-hoc reporting", because it would need polling or TiCDC to push changes.

Held up? Yes. Live is Available in 0.1.0, on an embedded store or on TiKV, with LiveAdminService for deploys and rollback.

D123 to D721: MySQL, and TiDB's two exits

2026-09-27 to 2026-10-08 · D123 superseded by D260; D301 superseded by D721; D720 and D721 Proposed · Loams SQL · Design 47

D123 offered MySQL through unmodified TiDB on the same TiKV cluster, with one TiDB pool for each tenant's keyspace. Two days later D260 (2026-09-29) removed TiDB from everything: "one store and one client stack, with no MySQL dialect as a second data-access style". MySQL access became an open question. On 2026-10-01 D301 chose an earlier MySQL design, a real mysqld storing its data on the bucket. D301 rejected "InnoDB semantics on TiKV" explicitly, because that "is TiDB rebuilt", which D260 had ruled out. On 2026-10-08 the owner asked for a Neon-like MySQL. D720 and D721 took D301's own argument and followed it the other way. If InnoDB semantics on TiKV is TiDB, then use TiDB. Loams SQL is stateless TiDB v8.5.x compute for each branch, on Loams' TiKV, one keyspace per branch, behind a Rust gate (loams-sqlgate). D721 amends D260 so that TiDB is allowed only as Loams SQL compute, "never shared, never without keyspace-name". It also notes there is "no GPL on the path". TiKV's Raft log serves as the WAL (D725). The compatibility contract is TiDB's own, published as it is: snapshot isolation for repeatable read, and no stored procedures or triggers (D735).

Held up? The direction has held since 2026-10-08. Loams SQL is Available in 0.1.0 on a patched TiDB, v8.5.8-loams.1. The sequence is worth reading in full in the log. The argument that removed TiDB is the same argument that brought it back.

D231 and D820: Loams Postgres, a hard fork of Neon

2026-09-29 and 2026-10-09 · D231 Approved (owner); D820 Approved direction (owner), details Proposed · Postgres · Design 28 · Design 51

D149 first proposed running unmodified Neon for the showcase apps' Postgres. D230 superseded it the same day: the showcase apps run plain Postgres on CloudNativePG, keeping fork work off that critical path. D231 made Loams Postgres a fork of Neon that Loams owns. The reason given is that upstream had been dormant since August 2025, with compute Postgres stuck at 16.9 and 17.5. Because Neon's control plane was never open source, D232 made Loams' control plane its primary one. D820 (2026-10-09) turned the fork into a hard fork named loams-postgres. There is no mirror branch, no weekly merge, and upstream commits are cherry-picked by hand as numbered patches. In the owner's words, Neon "stopped open source after databricks acquisition and went silent". The log notes neondatabase/neon had had no commit since 2026-08-31. The rejected path, D811's scheduled syncs from upstream Neon, was struck out in place.

Held up? Yes. Loams Postgres is Available in 0.1.0, and the owner's later rulings build on it (D1030). The cost is stated openly: D824 estimates the one-time and ongoing engineering effort of owning the fork.

Analytics

D45 and D347: no ClickHouse surface, then Loams House on chDB

2026-09-25 to 2026-10-08 · D45 reversed for the House by D347; D342, D343 Approved (owner defaults); D760 to D762 Proposed · House · Design 32 · Design 49

D45 dropped the ClickHouse interface. Analytics would be Iceberg tables, and anyone who wanted ClickHouse could point ClickHouse at the Iceberg catalog. Its reason: "Data is already open Iceberg; a ClickHouse server inside Loams would be redundant." A week later D347 reversed this for the House only. It declared a versioned ClickHouse surface, chsurface-1, where "100 % compatible" means every test of the declared surface passes and deviations are listed explicitly. The reason given is that this makes the compatibility goal testable and lets ClickHouse-native apps run unchanged. Loams tables elsewhere stay Iceberg-only. D342 chose chDB through an FFI that Loams owns. It rejected unmodified clickhouse-server, which "cannot merge Fluss's tail or honour consistency tokens" and wants its own disks, as well as a ClickHouse dialect on DataFusion and DuckDB. D761 put chDB only in sealed worker processes, because testing showed libchdb can crash with SIGSEGV on some paths and cannot interrupt a running statement. D762 rejected MergeTree on S3 disks and kept Iceberg as the House's only storage of record. In 2026-10-12's HS1 ruling R-ACL.1, the owner made chDB's own access control the first line of defence, with the statement deny list second and the OS sandbox as the outer boundary.

Held up? The reversal held, and D45's main point survived it: the data is still open Iceberg. The House ships in 0.1.0 as Experimental behind --profile house. The engine reaches it over TLS on a private network, and lake tables take inserts and compaction. The feature table still lists general Iceberg analytics as Planned.

Durable execution

D19 and D261: Resonate, embedded, with state on TiKV

2026-09-24 and 2026-09-29 · D19 Approved (user), amended by D138 to D145; D261 Approved (owner) · Durable · Design 14 · Design 21

D19 adopted the Resonate protocol for durable execution instead of building one. The reasons given: agents need durable runs next to their memory, and Resonate is Apache-2.0, formally specified, already S3-native on the same object_store crate, and plugin-based, "so this is buy, not build". D139 proposed TiDB as the cluster backend, through Resonate's MySQL plugin. When D260 removed TiDB, D261 replaced that with a native TiKV store, resonate-server-tikv, and marked mysql:// as legacy and deprecated. SQLite stays for loams dev and standalone use.

Held up? The choice of Resonate has. Durable is Available in 0.1.0 on SQLite. The TiKV store is still In progress, so D261's cluster backend is the part still to be delivered.

Agents: Git, Studio, sandbox and memory

D23 and D388: Git on the bucket

2026-09-24 to 2026-10-16 · D23 Approved (user); D388, D389 Approved (owner defaults); D1025 Approved (owner) · Git · Design 15 · Design 36

D23 made Loams the state layer for agent sandboxes: Git on the bucket with O(1) forks, environment images and caches. Runtimes would be integrated, never built. The reasoning: sandboxes are stateless compute, their state fits the bucket model, "and agents already speak Git". D388 moved a repository's refs out of a single compare-and-swap document and into a per-repository WAL of create-only segments, because "agent fleets create thousands of branches" and one document rewritten on every push contends on one key. D389 made the create-only PUT of the next segment the commit point, with no head pointer. The reason is that R2 allows one write per second per key, which would cap a CAS'd head at one commit a second. D1025 (2026-10-16) added an optional TiKV-backed ref log for busy repositories. It is chosen per repository, and every entry is still mirrored to the bucket.

Held up? Yes, so far. Loams Git ships in 0.1.0 as Experimental. git-remote-loams comes with the loams CLI packages and pushes and fetches straight to a bucket, with no server in between. The repository service is not in the release images yet.

D780 and D900: one agent daemon, and Studio as a console mode

2026-10-08 to 2026-10-13 · D780 Approved (owner); D797 Approved (owner), reverses D679; D900, D906, D911 Proposed, built by SD1 · Studio · Desktop and CLI · Design 50 · Design 53

D780 merged every agent loop into one per-user Rust daemon, loams-agentd, with Electron as just a client, because "agent turns must survive the UI closing". D679 had decided the desktop's agent chat would be a panel built from scratch. A day later D797 reversed that: the chat streaming and plugin UI are adapted from the MIT-licensed DSH client packages, with attribution, and without embedding their runtime. D900 made Studio a mode of the single console rather than a second app. D906 made loams-agentd Studio's only backend for code work. D911 made approvals real: a supervised thread surfaces every permission request for its owner to resolve. The owner's decision of 2026-10-15 made supervised mode the default everywhere.

Held up? Yes. The status column records each of them as built by SD1, with one gap noted in D900: the docked agent panel does not share Studio's store yet. Studio ships in 0.1.0 as an experimental mode. Loams Desktop opens in Studio. In the browser, Studio works against a remote daemon and sits behind the instance feature studio.

D990 to D994: one sandbox crate with an adapter ladder

2026-10-15 · Approved direction (owner) · Design 56 · Security model

D990 puts every isolation mechanism behind a single crate, loams-sandbox, driven by a declarative SandboxSpec. The spec covers the filesystem, network, syscalls, resources and identity. It says what is allowed, never how it is enforced. An adapter that cannot enforce a field refuses to spawn the process, unless that field is marked best-effort, "so nothing is weakened silently". D992 sets the ladder of adapters: linux by default, then wasm, gvisor and microvm, plus seatbelt on macOS and appcontainer on Windows. D993 sets the threat model. A self-hosted single tenant runs linux. Hostile multi-tenant code runs the same spec inside gvisor or microvm, and a cloud deployment refuses to start a multi-tenant product on bare linux. D994 sets the order of work, starting with extracting the House's existing OS sandbox, along with its escape tests, into the crate.

Held up? Not yet tested: SB1 has not been built, and is not in 0.1.0. It is here because it replaces several sandboxes built separately (House, Live, agentd, functions) with one contract and one conformance kit.

D870: memory is a product on Loams' own primitives

2026-10-13 · Proposed (MM1) · Graph · Design 52

Loams Memory is not a new storage engine. Its truth is collections (episodes, entities, facts, edges, blocks). A linked Loams Graph is used for traversal, embeddings stay in collections, and history uses Loams' log and bucket. D875 makes raw episodes the ground truth, so every fact names the episodes it came from. D888 states that "memories are data, never instructions": episodes carry a trust level, and content that looks like an instruction is quarantined.

Held up? Too early to judge. Memory is a plan (MM1) and is not in the 0.1.0 feature table. Its value is as a test of D4 and D742: if the primitives are right, a memory product should need no new storage. This design is the first to try that.

Operations

The release model, and D580: the stack runs on your side

2026-10-02 to 2026-10-13 · D580 Owner ruling; release model in docs/release/preview.md · Desktop and CLI · Design 43 · Release notes

The release model has no D-row of its own. It is set out in the release document, docs/release/preview.md, which now describes 0.1.0, released on 2026-10-18. Features ship as Available or Experimental. You run the stack yourself with Docker Compose, either on your laptop or on your own VMs. You reach it over your own Tailscale tailnet. Ostrium hosts only the static console and, for the optional oidc mode, the auth service. "The engine is never exposed on the public internet." D580 is the decision underneath that: the private network is optional and its provider is pluggable. The owner's ruling was "for now make it BYOK Tailscale, make it configurable", with Headscale documented and switching done in configuration alone. The log's reasons are added security, a single place to handle access, the official clients used unmodified, "and no lock-in to either control server".

Held up? Yes, through both previews and 0.1.0. Headscale and self-hosting the console on your own Vercel or Cloudflare account are still listed as coming soon.

D923 to D932: upgrades that keep data

2026-10-13, approved 2026-10-16 · Approved (owner) · Desktop and CLI · Design 54

D923 sets the starting point. Upgrades that keep data begin at v0.1.0-preview.3: a preview.2 stack upgrades in place, while a preview.1 stack starts fresh. D924 says every persisted format carries a version and readers support N and N−1. The engine refuses to start on data it cannot read. D925 says upgrades go one step at a time, from each release to the next. D932 says rollback restores the snapshot taken before the upgrade, which means writes made after the upgrade are lost, and the CLI says so. A migration is classed as either reversible or a point of no return, and the release notes list each one's class.

Held up? Yes, it was delivered. The release after preview.2 shipped as 0.1.0, not as preview.3. It includes loams upgrade and the one-shot migrate service, and loams upgrade --to 0.1.0 is the first upgrade that keeps data. CI gained an Upgrade: previous release → candidate gate. The decision is notable for being strict on purpose: no skipping releases, and no silent data loss on rollback.

D184 to D1011: an own Rust gateway instead of Envoy

2026-09-29 to 2026-10-16 · D184 Proposed; D1010, D1011 Approved (owner); D1013 Proposed · Postgres · Design 57

D184 proposed a Rust gateway behind Envoy as the edge. It rejected Sōzu (AGPL-3.0, no HTTP/3, no gRPC routes) and named Pingora as the library to use if a Rust layer-7 component was needed. D708 made PgDog Loams Postgres' front door, one per namespace, selected by SNI at a layer-4 listener. D1010 and D1011 (2026-10-16) record the owner's decision to "build a crate instead of adding Envoy or Traefik". loams-gateway is Apache-2.0, has a core of listeners, protocol sniffers and a hot-reloaded route table, and adds one module per protocol: pg first, then http, llm and mcp. The deciding technical reason is in D1011. Postgres clients send a plaintext SSLRequest before TLS starts, "so a generic SNI router reads no SNI". PgDog stays the front door for Postgres semantics, and the gateway only picks the namespace.

Held up? Too new to judge; GW1 is the plan. The reversal from D184 is narrow. Pingora, D184's chosen library, is still the proposed basis for the HTTP, LLM and MCP modules (D1013). What changed is that the edge is no longer an off-the-shelf proxy, because the first protocol it needed to route is one off-the-shelf proxies cannot read.

What the reversals have in common

Read together, the reversals follow a pattern. The early decisions (D2, D3, D45) drew the scope tightly around a retrieval engine. Later decisions added products alongside it without loosening the engine's own rules. D130 drew the OLTP boundary, D343 drew the boundary around foreign engines, and D347 limited ClickHouse compatibility to one product with its own test suite. Where Loams changed course on a dependency (FoundationDB, TiDB twice, Neon, Grafeo, Envoy), the log gives a concrete cause: operating cost, a dormant upstream, correctness bugs, or a protocol detail. Taste alone was never the stated reason. That is the main reason to read the log rather than the summaries: the reason column usually says what evidence would change the decision again.

On this page