Docs / Contributing
Decisions
Every decision in ivralo that would surprise you without its reason is written down as a short record. This page explains what those records are, how to read one, and which ones matter most if you run ivralo.
What a decision record is
An architecture decision record, or ADR, is a short file that states one decision and why it was made. In ivralo a decision gets one when it meets three tests:
- it is hard to reverse;
- it would surprise someone who did not know the context;
- it came out of a real trade-off, where the other option had something going for it.
A record is one to three sentences, sometimes with a short list of consequences. It lands in the same pull request as the code that carries it out, so the reason and the change arrive together. Code comments and the guide cite records by number, as in "ADR 0113".
Where they live
The records are in docs/adr/ in the repository, one Markdown file each, named NNNN-slug.md and numbered in the order they were made. There are 169 on main. The repository is private; access is given on request at kemalcalak@gmail.com.
How to read one
---
status: accepted
supersedes: 0051 (the table half; the reference syntax and the announcement stand)
---
# 0056 - The provider list is agno's, discovered, not written - and the embedder is chosen the same way
A model is named ``<package>[.<Class>]:<model>`` where the package is a
directory under `agno.models` ...
- The title is the decision itself, as a sentence. Reading the titles alone gives you most of the design.
- The body says why: what was chosen, what it was chosen over, and what it costs.
- status reads
acceptedonce the decision is taken. A superseded record keeps its status; the record that replaces it is what tells you. - A record is never edited to change its decision. Reversing one takes a new record that supersedes it, named in its frontmatter or in its first sentence. Often only part of the old record is replaced, and the new one says which part still stands, as above.
So to know whether a decision still holds, look for a later record that names its number. ADR 0051, for example, said that embeddings stay on Ollama; ADR 0056 replaced that half and lets the embedder be any provider, while 0051's rule that a hosted model is always announced still stands.
When a record and the code disagree, the code is what runs. The record tells you what the code was meant to do and why.
The decisions that matter most when you run ivralo
| ADR | Decision | In one line |
|---|---|---|
| 0004 | All conversational state lives in PostgreSQL | Sessions, runs and memory are in your database, never in local files |
| 0026 | The web is on by default, keyless, and the documents stay home | Only a search query leaves; no search key is needed |
| 0036 | Spans leave the machine only through an endpoint you set | Tracing is off until IVRALO_OTEL_ENDPOINT names a collector |
| 0052 | A specialist's Python runs in a worker process of its own | A timeout, a memory cap and no credential in reach |
| 0056 | The provider list is agno's, discovered, not written | Any agno provider works, for the model and the embedder |
| 0075 | The core is surface-free; a capability never lives in a client | The command line, the session and the API all call the same core |
| 0113 | One egress policy, enforced at every exit | One rule for web, browser, worker and shell; a guardrail, not a boundary |
| 0115 | An incident's facts are computed and its outcome is a gate | Code counts, one member judges, code decides the outcome |
| 0116 | Clients talk to the core through one local API, off by default | ivralo serve on loopback, behind a token |
| 0128 | A turn's edits can be one changeset | Staged, verified in the staged tree, landed or dropped as one |
| 0130 | A workspace's declarations run only once a person trusted the folder | A repository's commands and settings wait for your yes |
| 0149 | ivralo's own secrets never reach a model or a reply | Keys and passwords ivralo holds are masked before a model reads anything |
| 0155 | ivralo pushes one kind of branch | The one it made, for the draft pull request it opens; never a merge |
| 0157 | The main agent holds tools and delegates for a fresh context or a narrower grant | One agent does most of the work under the same approvals |
| 0167 | A hosted incident run requires its identifiers masked | Evidence reaches a hosted model only as placeholders |
Architecture shows how these fit together, and What leaves the machine follows the privacy decisions through.