Product decisions
Record product decisions — what to build and why, for which users, with the expected impact — and revisit them as context changes.
Create this collectionThe 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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`.
- 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`.
- 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.
- Check the Decision. PASS when it records a product choice — what to build (or not build), for which users, and why — tied to a user problem or a business goal. FAIL when it is a pure engineering or implementation choice with no product rationale (record that as an architectural decision instead).
- State the user problem and business goal the decision serves — capture it as a Rule (the decision driver) via `constrained_by`, or link the brief/research as a Reference via `supports`.
- Name the success metric and how it will be validated as an Eval linked by `supports`, so the decision can be judged against its expected impact, not just its intent.
- Every product decision is made in a context that will change. Note the review trigger in the prose — the date, assumption, or threshold that should prompt revisiting it — and supersede the record when that trigger fires.