Every boundary decision in bingo, one line each, in the order they were taken.
What an ADR is here
One record per boundary decision: a trait shape, a wire format, a persisted
format, a dependency, a crate split, a threshold family. Each is capped at 120
lines and follows one template — Context, Decision, Consequences, Supersedes.
Longer material goes to docs/design/ and is linked from the record. Bug fixes
are commit bodies, not ADRs.
They live in docs/adr/ in the repository. Thirty-three so far.
Foundations
#
title
in one line
0001
Crate map and dependency direction
Four layers, one direction, five forbidden edges the build asserts.
0002
One event stream: frames, journal, reducers, intents
One Frame type, a per-session ordered journal, two pure reducers, and writes that return nothing.
0003
Settings: three JSONC layers, merged per key by the claiming plugin
The kernel owns five keys; every other key belongs to the plugin that claims it, with its own merge rule.
0004
Model facts: the catalogue owns the model, the provider owns the endpoint, the server corrects the window
Three owners, no overlap, and one pure resolver that fails closed on what a wrong guess would reject.
0005
Session persistence: a JSONL journal per session, a sidecar lock, a derived summary
A session directory is portable, the lock is the only claim, and the summary can always be rebuilt.
0006
Context budget: the kernel measures and cuts, the plugin summarises and remembers
One threshold family in the kernel, a compaction accepted only if it shrinks, and a breaker after three failures.
The kernel’s surfaces
#
title
in one line
0007
The wire: JSON-RPC 2.0 over NDJSON, methods 1:1 with HostApi, events verbatim
The wire is the sdk with an envelope and nothing else; the schema is committed and drift-tested.
0008
Commands: parsed and dispatched by the session actor, outcomes as acks
No surface parses a command it does not own; an instant command runs during a turn, anything else queues.
0009
Contribution sources: tools and commands that exist only after I/O
A source is registered synchronously and answers from what it has now — answering with nothing is never wrong.
0010
Sub-sessions: peer delivery, redirect, tree attachment
deliver is the one door into another session’s queue, and a tree attachment carries every descendant’s frames.
0011
Log sessions, plugin state in the journal, the host in hand
A session without a model records and never runs a turn; plugin state is a journal event, not a file beside one.
0013
UI as data: one view vocabulary, three lanes, actions
A plugin describes what to show; the surface decides how, and every node has one text fold.
Credentials, providers and models
#
title
in one line
0012
OAuth credentials: a library tier, one store, login as an interaction
A third tier below plugins for shared code, one 0600 credential file, and a login that is an ordinary question.
0017
Named provider instances and paste login for keys
instances under each provider key registers more endpoints by name; environment variables feed the defaults alone.
0026
The model catalog reaches the model
The catalogue’s facts ride the existing entries’ metadata, and one read-only tool hands them to a model.
Plugins and the process boundary
#
title
in one line
0015
The cross-process plugin bridge
A plugin.json, a process on stdio, and the sdk’s own types as JSON — a bingo-native plugin in any language.
0030
Fixed-interface capabilities cross the bridge
Proxy structs implementing the sdk’s own traits, zero new traits, and a deadline on every crossing.
0031
Wire services
In process a service is met by type; across one, by key, method and schema — and only if its owner opened a wire face.
0032
Hooks cross the bridge
HookOutcome has no Allow, so an external hook can only tighten what happens, never widen it.
0033
The allowance: a host capability, lent for one crossing
One reserved bingo.host service, two doors, and a grant that dies when its crossing ends.
Features that are not the kernel’s
#
title
in one line
0014
Experience: procedural memory as files, recalled by rank
Playbooks as files under a minted id, ranked by BM25, with the permission card as the propose step.
0016
IM channels: one deliverer, adapters that hand over their mechanism
A capability is an accessor that returns the mechanism, so it cannot drift from the renderer that draws it.
0018
Background commands, and async by default
A long command detaches to a log file, and only completion or a named condition wakes the session.
0019
Schedules: deferred and recurring turns
A small grammar instead of cron, a fire is a turn on the schedule’s own session, and no daemon is pretended.
0020
The gateway: a resident bingo, managed like a service
One resident host per data directory, a pidfile, a doctor, and a per-user launchd or systemd unit.
Collaboration between sessions
#
title
in one line
0021
OpenRoom: agents may open rooms
An agent convenes its own children by default, or its siblings with shared — one door, the same seating code.
0022
Mentions: what a room post owes
@name opens a debt closed by that member’s next post, derived from the journal and chased by one bounded timer.
0023
The board: a room’s task list
A room is a session, so its task list is the shared board; a claim is stamped at runtime and staleness is rendered, never written.
0024
Peer messages: sibling addresses, one delivery
Agent names resolve child-first then sibling, and SendMessage always wakes — the second delivery mode is deleted.
0025
The serial room
A post must follow everything its author could have seen; a stale one bounces carrying what it missed.
0027
Spawn ≠ wake: the standby member
A briefing can be delivered without demanding an answer to it, so a seated member idles at zero tokens.
0028
The holder on the roster
The session a room hangs under may sit on its roster and hear it, and @parent owes an ordinary debt.
0029
The ear on every seat
Every seat has a patience in seconds: zero is a live ear, thirty or more a patient one, and the band between is refused.
Reading them
Start with 0001 and 0002 — every other record assumes them. 0007, 0013 and
0015 are the three boundaries an integrator meets first. The collaboration
records, 0021 through 0029, read as one sequence and are best taken in order.
Their live text is in docs/adr/ in the repository, and the plans that carried
each one out are in docs/plans/.