Skip to content

Decision log

Record why your SpecsGraph model changed: numbered decision records with context, the decision and its consequences, linked to requirements and proposals.

Why keep a decision log

Requirements say what the system does. A decision says why. Without it, the next person (or agent) to read ORD-12 has to guess why stock is reserved before payment, and may "simplify" the rule away without knowing what it prevents.

The decision log is the project's numbered list of these records. Open Decisions in the sidebar to read it, newest first. The practice is close to architecture decision records; Domain-driven and behavior-driven foundations covers the background.

What a decision record holds

FieldWhat it holds
NumberFour digits, assigned in order within the project and never reused, such as 0007.
TitleThe decision as a short statement: "Reserve stock before payment", not "Stock and payment".
StatusProposed, Accepted or Superseded.
ContextThe situation that forced a choice: the problem, the constraints and what was known at the time.
DecisionWhat the team will do, stated plainly, including the main alternative it turned down and why.
ConsequencesWhat becomes easier and what becomes harder. Include the costs, not only the benefits.
LinksThe requirements it explains, the proposal that carried it, and any decision it supersedes or that supersedes it.

Decision statuses

StatusWhat it means
ProposedDrafted inside a proposal that is not Published yet, by a person or an agent. Reviewers can comment on it like any other node.
AcceptedThe proposal that carried it is Published. It is part of the spec.
SupersededA later decision replaced it. The record stays in the log unchanged, with a link to its replacement.

Example: 0007 Reserve stock before payment

Northwind recorded this decision in the proposal on spec/checkout-reserve, next to the requirements it explains. On approval, SpecsGraph wrote it to specsgraph/decisions/0007-reserve-stock-before-payment.md, and it became Accepted when the pull request was merged:

specsgraph/decisions/0007-reserve-stock-before-payment.mdMarkdown
# 0007 Reserve stock before payment

- Status: Accepted
- Proposal: Checkout reserves stock before payment (spec/checkout-reserve)
- Requirements: ORD-12, ORD-13, BIL-04

## Context

Checkout captured payment first and checked stock afterwards. When two
Customers bought the last unit at the same moment, one of them paid for an
item Fulfilment could not ship, and Billing refunded it by hand.

## Decision

Orders reserves stock for every line item when checkout starts (ORD-12).
Billing captures payment only once every line item is reserved (BIL-04).
A reservation is released after 15 minutes idle, so abandoned carts do not
hold stock (ORD-13).

We turned down capturing first and refunding automatically on a shortfall:
refunds reach the Customer days later and still cost support time.

## Consequences

- Customers can no longer pay for stock that is gone.
- Checkout asks Catalog for stock before payment, so Catalog latency now
  adds to checkout time.
- A popular item can look sold out for up to 15 minutes while carts sit idle.
- Billing needs a scenario for a reservation that lapses between
  authorization and capture.

ORD-12 and BIL-04 link back to 0007, so anyone reading either requirement, in the web app or in the repository, is one click away from the reason.

When to record a decision

  • A rule exists for a reason that is not obvious from the rule itself.
  • The team weighed real alternatives and picked one.
  • A context is split, merged or reclassified as core, supporting or generic.
  • Two contexts deliberately have no relationship, and someone might add one later without knowing why.
  • A change reverses earlier behavior, including a rollback.

Skip it for wording fixes, new scenarios that only spell out existing behavior, and anything the requirement already explains on its own.

Supersede a decision

Accepted decisions are not rewritten when the team's thinking changes. The old reasoning was true when it was made, and later readers need to see it. Write a new decision that supersedes the old one instead.

  1. Draft the new decision in a proposal

    Say Northwind later decides to reserve stock when a line item is added to the cart. Draft 0014 "Reserve stock when a line item is added to the cart" and mark it as superseding 0007. Update the affected requirements in the same proposal.

  2. Review it like any other change

    Reviewers see the new decision and the one it replaces side by side, so they can check that every consequence of the old one is still handled.

  3. Publish

    When the proposal is published, 0014 becomes Accepted and 0007 becomes Superseded, with links in both directions. Both changes land in the same commit, and the text of 0007 stays as it was.

Tip

Small corrections are fine

Fixing a typo or a broken link in an accepted decision is a normal proposal. If the change alters what was decided or why, write a new decision.

Agents drafting decisions

Agents draft decisions with record_decision, which adds a decision to a proposal and links it to requirements or to the proposal itself. The draft is Proposed until the proposal is Published, like every other change an agent makes.

PromptText
We chose to reserve stock before payment instead of capturing payment first.
Record a decision for it in the proposal on spec/checkout-reserve, link it to
ORD-12, ORD-13 and BIL-04, and include the downsides the Billing reviewer raised.

Review the draft with care. Agents write fluent reasoning, but the context section must describe what actually happened, and the consequences must include the costs. Ask for changes in a thread if either reads like a justification written after the fact.

Agents also read the log with list_decisions and search_graph before they propose. A well-kept log stops them from reopening questions the team has already settled.

Next steps