DocoAlpha 23cf7ea · just now

Architectural decisions (ADR)

Record architecturally significant decisions (ADRs) — system structure, technology, and how data is modeled, stored, and governed — as an append-only log of context, options, choice, and consequences.

Create this collection

The policies it ships with

People and their agents follow these when they record in a collection made from this template. Its owners can change them.

  1. Only Decision, Principal, Rule, Eval, and Reference belong in a decision record. A Decision is the record itself (its question, the options considered, the chosen path, and the rationale). Principals are who decided and who is accountable; Rules capture the decision drivers and criteria; Evals confirm or validate a decision; References supply context and link out to the artifacts a decision concerns. Actions, States, and other flow nodes belong in a process collection.
  2. Only these relationship edge types may be used in a decision record: `attributed_to` (a Decision → the Principal who decided or is accountable), `constrained_by` (a Decision → a Rule that drove it), `supports` (an Eval or Reference → the Decision it confirms or informs), `replaces` (a new Decision → the one it supersedes), `derived_from` (provenance from a prior decision or source), and `relates_to` (a see-also link between related decisions). Sequence flow (`flows_to`) and pool membership (`has_parent`) belong in a process collection.
  3. A committed (proposed or accepted) Decision names its `chosen` option — the path it lands on. A `drafting` decision may leave `chosen` empty while the choice is still open.
  4. A committed (proposed or accepted) Decision is attributed to the Principal who made it or is accountable for it — an `attributed_to` edge from the Decision to that Principal. A `drafting` decision may defer naming the decider.
  5. A committed (proposed or accepted) Decision is attributed to AT MOST one Principal — the single decider who made it or is accountable for it. It carries at most one `attributed_to` edge to a Principal; two named deciders leaves accountability ambiguous. A `drafting` decision may defer naming the decider.
  6. Check the Decision's `question`. PASS when it poses a genuine decision — a choice to be made, with real alternatives and consequences (e.g. `Which datastore backs the event log?`, `Do we gate signups behind an invite?`). FAIL when it is a vague topic with no choice in it (`Database stuff`), merely restates the chosen answer, or describes a task to perform rather than a decision to make.
  7. Check the Decision's `decision` prose together with `chosen`. PASS when it states BOTH the context that made the decision necessary AND the rationale for the chosen option — why this option over the alternatives. FAIL when it records what was chosen with no reasoning, or describes context with no decision. A record without its justification can't be re-evaluated when the circumstances that drove it change.
  8. Check the Decision's `alternatives`. PASS when the real options that were weighed are listed, each with why it lost (`rejected_because`), OR when the decision genuinely had a single viable path and the prose says so. FAIL when alternatives are omitted on a decision that plainly had them, so a reader can't tell what trade-off was made.
  9. Map a decision's status onto the node lifecycle: `drafting` = a draft or RFC still being explored (the choice may be open); `queued` = proposed and awaiting sign-off (fully formed — it already names its `chosen` option and its decider Principal); `active` = accepted and in force; `retired` = deprecated or superseded. `queue` a decision to propose it, `activate` it once accepted, and `supersede` it (the op creates the replacement and links the two with a `replaces` edge) when a later decision overrides it.
  10. A decision record is append-only. When the direction changes, do NOT rewrite an accepted Decision — supersede it: create the new Decision, link it to the old one with a `replaces` edge, and `retire` the old one. This preserves the history of what was decided and why the direction shifted, which is the whole point of keeping the log.
  11. Capture the forces that drove a decision — its drivers, criteria, and constraints — as Rules, and link each to the Decision with a `constrained_by` edge. Making the drivers explicit lets a reader judge whether they still hold, which is what tells you when a decision is due to be revisited.
  12. Confirm a decision with an Eval linked by `supports` — the check, test, or measure that tells you whether the decision is holding up. Link the context a decision concerns — specs, components, mockups, data sources, external docs — as References, also via `supports`.
  13. Capture exactly one decision per Decision node. A record that bundles several choices can't be superseded, re-evaluated, or linked cleanly. Split a compound decision into separate records and connect them with `relates_to`.
  14. Agents should read `GET /<handle>/api/authoring-contract.json` and write with `POST /<handle>/api/changesets.json`, creating each Decision together with its `attributed_to`, `constrained_by`, and `supports` edges in the same changeset rather than as disconnected nodes.
  15. Check the Decision. PASS when it records an architecturally significant choice — one that shapes system structure or runtime topology, selects a core technology or the datastore an application runs on, affects a quality attribute (scalability, performance, reliability, maintainability), spans components, or is costly to reverse. This includes how data is structured and governed within the system: the data model, schema, or grain; the storage format, partitioning, or layout of a dataset; pipelines and transformations; the source of truth; data lineage; and retention, privacy, or governance rules. FAIL when it is a routine, local coding choice with no structural or cross-cutting impact, a non-technical product or design decision, or a security decision — a choice made to protect the system, its data, or its users, such as access control, secrets, encryption, or an accepted security risk — record those in their own logs.
  16. An ADR's decision drivers are its architecturally significant requirements — the quality attributes and constraints it must satisfy (a latency budget, a compliance rule, team skills, cost). Capture each as a Rule linked by `constrained_by`.
  17. Spell out the technical consequences in the `decision` prose, including what becomes harder: the new constraints, the operational burden, and the technical debt the choice deliberately takes on.
  18. Reference the components, services, and external standards an ADR governs so the record sits next to the architecture it concerns.
  19. Name the migration, backfill, or cutover a decision requires — the operational path to adopt it — in the `decision` prose, so the record carries not just the choice but how the system gets there.
  20. When a decision concerns data, make its data dimension explicit: the grain and source of truth it establishes (what one row or record represents, and which system owns it), the lineage it affects, and its governance impact — privacy classification, retention, and access. Capture data contracts, SLAs, and quality thresholds as Rules via `constrained_by`, and the data-quality checks that enforce them as Evals via `supports`.