Problem
Our Lab works for us. Every piece of the platform starts as an RFC in the repository, the status log under each one is the timeline of what was built, studies report the numbers, and a redaction check refuses to publish a page that names a host, an address, a port, a path or a secret. The rule that holds it together is in our RFC index: a published RFC describes something that exists, so a change to the system changes the page in the same commit.
Two things are wrong with it as a product.
It only serves us. The Lab is a build step over one repository's Markdown. It has no accounts, no review, no way to read anyone else's code, and its redaction rules know only our own names. The pages are a list of documents with a timeline; nothing links an RFC to the ones it depends on, nothing says which claims are still true, and a reader cannot see what changed since they last read.
The part companies would pay for is the part they skip. The process is well known and well argued. Google's design docs exist to find design problems "when making changes is still cheap" (Ubl, 2020); Oxide runs every decision through an RFD with explicit states and publishes a subset (RFD 1); Uber's RFC process carried it from tens of engineers to the low thousands (Orosz). What stops most teams is the cost of writing the first set for a system that already exists, and of keeping it true afterwards. Documents rot, and a stale one is worse than none.
The tools on the market each do one half (all seen on 2026-10-03):
| Kind | Examples | Where it stops |
|---|---|---|
| Decision records as files | adr-tools (last release 2018), Log4brains (last release 2024-12), the Backstage ADR plugin | People write every word; nothing checks a record against the code |
| Architecture models | IcePanel ($40 to $80 per editor a month), Structurizr (its cloud service marked end of life) | The model is maintained by hand |
| Generated descriptions | DeepWiki, Driver AI, Eraser ($15 to $45 per member a month) | They describe what the code is, not what was decided, by whom, and what was rejected; no review, no redaction, nothing to publish |
| Well-architected reviews | AWS Well-Architected Tool (no charge, an agent in preview), Azure's review | A questionnaire and an improvement plan, not a document about the system |
Nobody we found keeps a decision document (problem, options, decision, status) tied to evidence in the code and current as the code changes, with a review that records who decided, and a way to publish the result safely.
There is also a reason a company has to keep these documents, beyond good practice. A SOC 2 report contains management's description of the system, prepared against the AICPA's Description Criteria (DC 200), and the Trust Services Criteria include change management (AICPA). ISO 27001 (the 2022 edition) Annex A asks for secure system architecture and engineering principles (8.27) and for change management (8.32). A dated, reviewed set of RFCs with a status log is evidence in the shape an auditor reads. It supports an audit; it does not pass one, and the product never says otherwise.
Proposal
Lab is a product of the console for every account, the same objects over the API,
the MCP server (RFC 0005) and iohr. It is not a page under the account's settings: it
is the first entry in the console's sidebar after Overview, the first of the products
the sidebar lists. Our own Lab is its first tenant: the site's Lab is
rendered by the same code a customer's is, so every improvement lands for both.
The objects
- A lab is one subject: a product, a system, a platform. A team can have several.
- A document is an RFC or a study, in the format our own use: front matter, the sections in a fixed order, a status log whose lines are the timeline. A document has versions; every version records who changed it and when.
- A claim is one statement in a document that points at evidence: a function or a type in a file at a commit, a contract (a proto or OpenAPI operation, by its name), a migration (by its file name), a deploy manifest. The lines a reader sees are where the evidence was found, not what it is. A claim is what can go stale.
- A source is where evidence comes from: a repository, reached through a connection (RFC 0018) and read-only by grant. A lab belongs to one account, and every source is a connection that account owns.
A diagram is drawn here in the RFCs product; this page does not show diagrams yet.
The repository stays the source of truth
A team that already keeps documents in Git connects the repository and the Lab reads them from there, as ours does. An edit made in the console becomes a pull request to that repository, never a commit on its default branch, so the team's review rules apply to documents as they do to code. A team without a repository for documents keeps them in the platform and can export them at any time as a folder of Markdown files in the same format. The format is files on purpose: leaving costs nothing.
iohr lab check runs the same checks as the console on a laptop or in the team's CI: the
front matter, the section order, the status log's shape, the redaction rules and every
claim's evidence. It is what our own build runs today, as a command.
The first draft, from the code
Connecting a repository offers a baseline: a first set of documents about the system as it stands, drafted by an agent (RFC 0011) with read-only tools over the source (RFC 0002), in a bounded loop, billed in units (RFC 0015).
- One document per boundary the agent can show: each service and what it owns, each contract between them, each data store, the edge and how callers are identified, how it is built and deployed.
- Every statement is either evidence or a question. A sentence that says what the system does carries its claim (the file, the lines, the commit) and the reader can open it. A sentence about why it was built that way cannot come from code, so the agent does not write one: it writes the question ("Why is the session store separate from the accounts database?") for a person to answer. Code shows what was decided; only people know why.
- Alternatives considered are left empty unless the repository's history or a document says what was rejected, with the link.
- Every paragraph a model wrote is marked as model-written until a person accepts or rewrites it, and the mark is shown to every reader (AI Act Art. 50 asks that people know when text is generated).
- A baseline is a set of drafts. Nothing is published, and nothing becomes
decided, until a person with the right role says so.
Kept true on every merge
When the source changes (the repository's push event, through a connection that receives webhooks), the Lab checks the claims that point into what changed:
- a claim whose lines changed is marked stale on the page, with the diff, until a person confirms it or the agent proposes a correction they accept;
- a change no document covers (a new service, a new public route, a new migration, a removed store) proposes either a status-log line on the document that owns the area or a new draft;
- a decided document is never rewritten silently: every change is a proposal, as a pull request or a console suggestion, with the evidence beside it.
A claim follows the code before it goes stale. Files move, most often in a large repository, and a claim tied to line numbers would go stale on every refactor. A claim records the file, the function or type it points at, a fingerprint of that code and the commit. When the code changes, the check looks for it in order:
- the same file under its new name, by Git's rename detection;
- the same function or type by name, with a parser for the language;
- the same code by its fingerprint, anywhere in the repository.
Only when all three fail is the claim stale. Contracts and migrations have names that do not move, so their claims never depend on lines. Parsers come first for Rust, Go, TypeScript, proto and SQL; a file in a language without one falls back to its lines and fingerprint, which marks more claims stale than it should, and the page says which claims are held that way.
A diagram is drawn here in the RFCs product; this page does not show diagrams yet.
Each document shows how many of its claims are current, and the lab shows which documents have drifted. This is our own rule, "a stale RFC is a false claim", turned into a check that runs on every merge.
Review that records a decision
A document moves through draft, open, decided and superseded, as ours do. Moving
to decided takes the approvals the team configured (a number of people, a role, named
owners per lab); the decision records who approved and when, and goes into the audit log
(who, what, outcome, never the text). Comments are threaded on a paragraph and resolved,
and a resolved thread stays with the version it was made on. A second agent, the
reviewer, can be asked for a pass on any document, a person's or a model's: missing
sections, a decision with no alternatives, a claim with no evidence, a sentence that would
fail redaction.
Published when ready, through redaction
Any document can be published to the team's public Lab, on our site under the team's name or on a host in a domain the team has verified (RFC 0030). Publishing runs the redaction check our Lab runs: host names, addresses, ports, paths, credentials and cluster names are refused, plus the team's own words and every name under its verified domains. A fact that belongs in the story is withheld in the open (a black bar with a public reason), never paraphrased away. A page that fails the check does not publish, and the console shows the line and the rule.
Public pages are static HTML with no script for the prose, as ours are, with a feed and a sitemap. Readers need no account.
A better Lab, for us first
What the console shows is what the site will show for our own Lab:
- the graph: an RFC's links to the ones it builds on and the ones that build on it, from the text, with backlinks on every page;
- one timeline across a lab, from every status log, filterable by document and status;
- versions with a diff, and "changed since you last read" for a signed-in reader;
- each claim's evidence one click away, and the share of current claims on every document;
- studies with their headline number and the RFC they measure, side by side;
- search over every document the reader may see.
Where the code is read
The code is the customer's data, and the rules for it are the platform's rules for customer data:
- Drafting and drift checks run on our self-hosted models (RFC 0001). No customer code or document is sent to a third-party model provider.
- A company that does not want its code to leave its network runs the work on its own agent (RFC 0029), which reads the repository inside the network and sends back only the drafted text and the claims' locations; the local policy decides what it may read.
- The platform stores the documents and the claims (paths, line ranges, commit ids), not a copy of the repository. A read for a drift check is done at the time and dropped.
- Documents are private to the team until published. Erasing a lab erases its documents, versions, comments and claims; the team's export works to the end.
The API
The same objects as REST routes, as tools over MCP and as iohr lab. Every list is shaped
as the platform's lists are: page_size and page_token in, the items first and
next_page_token out. Scopes are lab:read and lab:write, and publishing needs a
person in the console, never a key. Events, delivered as webhooks, MQTT or a stream
(RFC 0022): lab.document.drafted, lab.claim.stale, lab.document.decided,
lab.document.published.
Units
Reading and publishing are not metered beyond read. What needs no model is in every
plan, the free one included: labs from a repository, review and approvals, export,
publication through redaction and iohr lab check.
A baseline and a drift check cost units in the generate category for the tokens they
use. A drift check reads only the claims that point into what a merge changed, so its
cost follows the size of the change, not of the repository, and a quiet week costs
almost nothing. Every run has a ceiling and every month a cap, set by the plan; a run
that reaches its ceiling stops with a partial draft and says where it stopped. Public
pages cost the team nothing to serve.
We do not know yet what a baseline costs. Our own repository is the first measurement: the baseline and a month of drift checks on it, published as a study with the tokens per document and per merge. Until that study exists, every ceiling on the plans page is labelled as a placeholder.
Order of work
- Our own Lab on the new renderer: graph, timeline, versions, search;
iohr lab check. - Labs in the console for any team: documents from a connected repository, review and approvals, edits as pull requests, export.
- Publication: redaction with the team's words and domains, public pages on our site and on a verified domain.
- Claims and drift checks on merge.
- The baseline agent and the reviewer, on our models, then on the company's agent.
The first three need no model at all, and they are a product on their own: our Lab, for anyone.
Alternatives considered
Generate a wiki from the code. DeepWiki shows it can be done well and for free on public repositories. It is the wrong artifact: it regenerates a description, so it cannot hold a decision, a rejected option or an approval, and it cannot be published without a person reading every line. We use the same capability for the claims and stop there.
Host an existing decision-record tool. Log4brains and the Backstage plugin render files people write. They would give us a renderer and none of review, evidence, drift or redaction, which are the product.
Let the agent write the whole document, reasons included. The fastest first draft and the one most likely to be wrong where it matters: a model that guesses why a team chose a design states the guess with the same confidence as the facts. An auditor or a candidate reading a published page cannot tell the difference. Questions instead of guesses cost the team an hour of answers and keep every page true.
Keep the Lab ours. It costs nothing and leaves the most distinctive thing on the site as a brochure. The work to make it good for us is most of the work to make it good for anyone.
Sell architecture reviews as a service, by hand. Partners run AWS's reviews with AWS funding them, which anchors the price of a review near zero; the paid work is what follows. A review by an engineer can sit on top of a lab later, as an option; it does not replace the product.
Decision
Open. Proposed: Lab as a console area for every account, built on connections, agents and domains; the repository as the source of truth with edits as pull requests; evidence or a question for every statement, never a guessed reason; drift checks on merge; approvals recorded; publication only through redaction; customer code read only by our own models or inside the company's network; our own Lab as the first tenant.
Proposed for the three questions the first version left open:
- One account per lab. A lab's sources are connections of the account that owns it; people from another company take part by joining the team (RFC 0027), and an agency keeps one lab per client account. Every lab then has one owner for erasure, export and audit. A lab across accounts can be added later if it is asked for; taking it away after launch could not.
- Claims anchored to code, not lines. Rename detection, then the name of the function or type, then the fingerprint; stale only when all three fail; names for contracts and migrations.
- Ceilings from a measurement. The baseline and drift checks on our own repository, published as a study, set the first ceilings; until then they are placeholders, and what needs no model is free.
Publication
The console gains Lab. The site's Lab moves to the new renderer and gains the graph, the
timeline, versions and search. The developer docs gain the document format, iohr lab check, the redaction rules and the Lab API; the API reference gains its routes and the
lab:read and lab:write scopes.
Status log
- 2026-10-03: opened, after a survey of decision-record tools, architecture modelling, generated code documentation and well-architected reviews.
- 2026-10-03: proposals for the three open questions: one account per lab, claims anchored to the function or type and its fingerprint rather than lines, and ceilings set from a study of our own repository, with what needs no model in every plan.
- 2026-10-03: the first piece of step one is on the site. "RFC 0018" in any document's prose links to it, and every page lists what it mentions and what mentions it; a public page never links or names a draft.
- 2026-10-03: search and the timeline. The lab's index searches every public document by section (an admin's drafts too), and a lab's page shows its whole timeline by month, narrowed to one document on request.
- 2026-10-03: versions. Every document lists its versions from Git with their changes, and a returning reader is told what changed since their last visit. A public page shows only versions that were public and pass the redaction check as they stood.
- 2026-10-03: the checks are a contract. The redaction rules are data, generic ones
shared and a lab's own in its config, the document checks are one module, and fixture
documents with their expected findings pin both, published in the developer docs with
the document format for
iohr lab check, which is next. - 2026-10-03:
iohr lab checkis built: the same checks in the command line, offline, held to the site's findings by the shared cases and finding nothing in this Lab's own documents. It reaches users with the nextiohrrelease. Step one is done. - 2026-10-03:
iohr lab checkis released iniohr0.1.0-alpha.3. - 2026-10-03: Lab is in the console, the first product in the sidebar after Overview.
Its page says what is live (the check, with
iohr lab check) and lists the steps still to come; the labs themselves arrive with step two. - 2026-10-03: Lab is in the navigation of every host (the site's menu, the account menu,
the console's sidebar, search and Overview, the docs header), for admins only while it
is built. Approved next, in this order: a
labsservice that stores labs, documents, versions, comments and reviews in the platform (repository sync after), a document editor and an architecture diagram designer in the console, and review with recorded approvals. - 2026-10-03: the labs service is built, admin-only until launch: labs per account,
RFCs and studies numbered per lab with every version kept, a save from a stale version
refused rather than merged, the same checks as
iohr lab checkanswered on every save, comments on headings, review requests and approvals, decided only with the lab's approvals on the current version, superseded naming its successor, diagrams, and the whole lab exported as the filesiohr lab checkreads. Erasure and export of a person's data include it. The console's pages come next. - 2026-10-03: documents have parts. A sub-RFC is its own file,
0040.1-slug.mdwithparent: 0040-slug, one level deep, checked the same way by the site, the console and the conformance cases (iohr lab checkfollows in its next release). The site and the console list parts under their parent and number them 0040.1, and a part names its parent. The console's reading view now shows what the site's does: the documents a page mentions and those that mention it, the lab's timeline by month with a document filter, what a document supersedes and what supersedes it, what a study measures, and a study's headline number. - 2026-10-06: amended by RFC 0065. The RFCs product becomes the source of our own RFCs and
the repository its export, once the console editor (RFC 0062) is in use; until then a
merged change to the repository is imported. Every document gains an access level
(public, preview, partner, team, internal) in place of the
publicflag. - 2026-10-07: Checked: parts and the reading view (#202) and people (#256, RFC 0041) run in labs and console-ui. RFC 0065 amends it; repository sync (RFC 0036) is not built. Open.