Process
Requests for Discussion (RFDs) capture ideas early enough to shape them through
written discussion and preserve the reasoning behind decisions. An RFD is not
authoritative merely because it exists; its state says how it should be read.
Writing an RFD
On a branch, run make new TITLE="..." to start the next RFD from the
template, which
creates rfd/NNNN/README.adoc and its implementation checklist, already
linked to each other. The template’s comments describe what a good RFD covers.
Every RFD answers three questions first:
-
Goal: what is true once the RFD is done, and for whom.
-
Problem: what is wrong or missing today, with the evidence.
-
Objectives: the outcomes that decide whether the proposal worked, and what it deliberately leaves out.
The Proposal then explains how the objectives are met. Alternatives, supporting material such as data or proof-of-concept results, and open questions are there when they help; rename, drop, or add sections as the topic needs. Above all, write for someone who was not in the room: lead with the conclusion, keep paragraphs short, and use plain words.
Use prediscussion while writing, or ideation for a topic placeholder. When
the document is ready for review, open a pull request, set the state to
discussion, and add that pull request as the discussion URL.
Before merging a proposal that represents project direction, move it to
published. Once the described work is entirely implemented, update it to
committed. Material changes to a published or committed RFD go through a new
pull request and retain the original discussion link unless the RFD explicitly
documents a replacement. Changes that supersede a committed or abandoned RFD use
a new RFD and cross-link the historical decision.
Source format
Each RFD lives at rfd/NNNN/README.adoc, where NNNN is a four-digit number.
The document starts with canonical AsciiDoc attributes and an unpadded title:
:authors: Name <email@example.com>
:state: prediscussion
:discussion:
:labels: renga, software, process
= RFD 5 Example title
authors contains semicolon-separated owners. discussion contains the RFD’s
pull-request URL once discussion starts. labels is a comma-separated set of
searchable topics, starting with the project the RFD belongs to. The document
is the single source of truth for this metadata; the index intentionally does
not duplicate it.
An RFD is public unless it sets :visibility: private. A private RFD’s page,
and its place in the lists, appear only to readers who have signed in; a public
RFD must not link to a private one. Labels and visibility are
the attributes that may change after an RFD is committed or abandoned.
Implementation progress lives separately in rfd/NNNN/IMPLEMENTATION.adoc,
following the AsciiDoc checklist convention; the checker also accepts the
legacy IMPLEMENTATION.org and IMPLEMENTATION.md formats, and an RFD must
have exactly one format.
The RFD and checklist link to each other, keeping design and decision history
stable while implementation tasks are checked off.
An RFD that mentions another RFD links to it with a relative source link, such
as RFD 5, or
RFDs 13 and 14; the site
turns these into page links. make link-rfds links every unlinked mention, and
make check-rfds rejects unlinked mentions, links to RFDs or sections that do
not exist, and cross references to sections an RFD does not have. Mentions in
titles, comments, attributes, inline literals, and listing blocks are left
alone. Linking a mention, or rewrapping lines, is not a change to a final RFD.
Run make check-rfds to validate source layout, metadata, state, title, and the
checker’s tests, and make status to list each RFD’s progress. CI also supplies
RFD_BASE_REF so the checker can reject lifecycle regressions, historical
deletion, and changes to final RFDs against the pull-request or push base. A
local review can do the same with RFD_BASE_REF=<git-revision> make check-rfds.
The Progress column reports the percentage of checklist tasks completed; state
describes the decision’s lifecycle rather than duplicating that implementation
count.
States
-
prediscussion: actively being written and not ready for broad review. -
ideation: a narrowly scoped topic or scratchpad without active revision. -
discussion: under active review in the linked pull request. -
published: discussion has converged and the RFD expresses project direction. -
committed: the proposal is fully implemented and describes current behavior. -
abandoned: deliberately not proceeding or retained only for history.
The usual path is prediscussion or ideation to discussion, then
published, and eventually committed. abandoned is an off-ramp before a
final state.
Checklist progress never changes state automatically, but committed requires a
non-empty checklist with every task complete.
prediscussion and ideation may move between each other or advance to any
later state. discussion may advance to published, committed, or
abandoned; published may advance to committed or abandoned. Published and
committed decisions never regress to drafting states. A committed or abandoned
RFD is immutable: replace or supersede it with another RFD rather than rewriting
its lifecycle.
Renga design principles
-
Context functions enforce authorization; hiding a control in the UI is never an authorization boundary.
-
Every user-facing query is scoped to the current organization in the database.
-
Browser routes requiring login use the existing authenticated router scope and LiveView session. Machine APIs use narrowly scoped bearer authentication.
-
Raw observations remain immutable; processing and reconciliation state live in separate records.
-
Canonical inventory remains source-neutral while retaining per-source evidence.
-
Desired state, observed facts, and manual corrections remain distinct.
-
Stable, frequently queried inventory uses typed PostgreSQL projections; JSONB is reserved for variable desired state, detailed evidence, and vendor data.