---
title: "Decisions"
description: "Decisions inside plans in Fir: raised while a plan is drafted, always with a recommendation, weighed by a panel of other model families with sealed opinions, shown with a calibrated confidence on a page that reads verdict, opinions, evidence and consequences, answered by people in one key or applied by their own proven rules, grouped at scale, kept in a decision history that models see only at the level their task needs, and sold to any plan or agent as Frazer Decisions."
url: https://frazer.ai/docs/source/decisions
index: https://frazer.ai/docs/source/decisions/llms.txt
tokens: 12040
---

> For agents: this page is indexed at https://frazer.ai/docs/source/decisions/llms.txt, and every page at https://frazer.ai/llms.txt. Copy commands from this file exactly.

# Decisions

A decision is a question a person settles: its options, the recommendations, the answer and what the answer commits later work to. In Fir a decision is part of the plan it belongs to, raised while the plan is drafted, and every decision, including every approval, goes into one **decision history** that later plans and sessions read.

## Two homes, one object

-   A **decision row** lives inside a record, usually a plan, with an ID the server reserves: `acme/storefront#469 §D2`.
-   A **decision record** (type `decision`, key `ADR-0034`) holds a decision that outlives one plan or governs paths beyond it. A row is proposed for promotion when its effect reaches beyond the plan’s paths or another plan must follow it; promotion copies the row into a decision record in the same pull request and keeps the row’s reference as an alias. Fir never promotes silently.

The file keeps what people write: the question, the options, the recommended option, the state and, once taken, who decided, when, their words and the effect. What models and Fir produce (each opinion, the confidence, the evidence, precedents, conflicts and costs) is stored beside the row’s anchor. In a plan, rows read like this (demo data):

```text
D2 Cap the backoff at 6 s or keep 8 s? · A 6 s (recommended) · B 8 s (status quo) · blocks #482 · due Oct 16 18:00 · open
D1 Retry in checkout-api, not in the gateway client · taken by tomasz, Oct 13 · constraint on services/checkout-api/payments/**
```

A row reaches a person only when it is complete:

| Field | What it holds |
| --- | --- |
| Question | One sentence that choosing an option answers |
| Why it matters | One sentence: the stake for the outcome |
| Options | Two to four, the status quo marked, each with its consequences, cost, reversibility and the effects it would bind; writing your own answer is always open |
| Recommendations | The drafter’s, with its reasons and evidence, and the panel’s opinions |
| Evidence | Links to versions: a record block, a check run, a metric query, a code range |
| Blocks | The approval, named layers, or nothing (two-way decisions only) |
| Door | One-way or two-way, computed from the options and the paths |
| Deciders, due | From the plan’s route; the approval’s SLA |
| If unanswered | What stays and what waits, such as “8 s stays; #482 holds” |
| Precedents, conflicts | Found by Fir when the decision is raised, and again at readiness and at answer |

## Raising decisions while a plan is drafted

1.  **Answer what can be found.** The drafting agent answers every question it can from the code, `fir why`, metrics, records, precedents and the decisions in force. A question a decision in force already answers is a finding, and Fir shows that decision instead.
2.  **Few, ranked by stake.** At most five open rows reach a person per approval; the agent ranks candidates by impact and uncertainty and splits the plan rather than ask a sixth.
3.  **Effects before the choice.** Each option says what it would bind (“constraint: backoff cap 6 s on `services/checkout-api/payments/**`, until superseded”), so the person sees what an answer commits later work to.
4.  **During implementation**, a new row blocks only the layers it names, and its answer makes the next plan version, covered by the approval because the approver wrote it.
5.  **Decisions inside the terms.** Choices the approval lets the agent make alone (such as “retry jitter”) are logged as decisions too, with the approval they rely on and the reason, and the approver can reverse them.
6.  **One question, one decision.** A row whose question and scope match an open one elsewhere is merged with it (“also asked in #212 §D1”), and both get the same answer.

Nothing is decided by silence. A decision past its due date stays open, what it blocks keeps holding, and the deciders’ fallbacks are asked. On a two-way decision where the recommendations agree, the draft may proceed on the recommendation as a **working assumption**; code keeps what is in force until a person answers, and nothing that depends on the decision merges.

## The panel: other model families on every decision

The drafting model always recommends. Then a **panel** of the other model families weighs **every** decision when it is raised, each blind to the others and to the drafter. A panel is one versioned object that says which models give opinions, of which families, in which roles, how deep and under which budget; the same object serves decisions, [Frazer Reviewer](https://frazer.ai/docs/reviewer)’s code, security and [cold reviews](https://frazer.ai/docs/source/planning-flow#cold-review), [loops](https://frazer.ai/docs/source/planning-flow/loops) and [context verification](https://frazer.ai/docs/context#verify).

-   **Depth by risk.** One ladder for every use: `off` (no model), `light` (one other family), `standard` (two), `deep` (every other family, on the strongest tier) and `exhaustive` (every family, open-weight models included, two passes). A decision is never below `standard`; one-way doors, R3, and decisions tagged money, identity, secrets or production data run `deep`. `M` on any decision asks for a deeper panel, with its cost estimated first.
-   **Independent by construction.** Every member runs in parallel on the same evidence pack, and each opinion is **sealed** (its digest stored) before any other is read. No member sees the drafter’s pick, its reasons or its transcript, another member’s opinion, or the decider’s past answers. Families are counted by **lineage** (who trained the base weights), so a fine-tune counts as its base, and a member’s route never falls back to another family.
-   **Structured opinions.** Each opinion gives a probability for every option, up to three factors it weighed, up to three checkable predictions, its evidence, and **what would change its pick** (“I would pick A if peak retries stay under 50 a second”). Fir aggregates them by count and calibrated weight; no model rewrites the others.
-   **Disagreement becomes facts.** On a split, a critic of another family reads the opinions anonymized and shuffled and names at most three **cruxes**: a fact (Fir fetches it: a metric query, a check run, a record block), a value (only a person weighs it) or a forecast (scored later). There are no rounds of debate.
-   **Missing is not disagreement.** A member that times out, refuses or is down is shown as such (“2 of 3 answered · provider outage”) and never replaced by another family. A decision counts as seconded once one other family answered.

```yaml
# acme/plans .fir/panels/acme.yaml · version 3
kind: panel
name: acme
scope: {organization: acme}
changelog:
  - {version: 3, date: 2026-10-01, why: "every decision gets two other families; deep for one-way doors, R3 and sensitive tags"}
members:                       # a family and the tiers it may use; the LLM gateway resolves each pair to today's model
  - {id: claude, family: anthropic, route: panel-anthropic, tiers: [fast, balanced, max]}
  - {id: gpt,    family: openai,    route: panel-openai,    tiers: [fast, balanced, max]}
  - {id: gemini, family: google,    route: panel-google,    tiers: [fast, balanced, max]}   # on your own Google account
  - {id: open,   family: meta,      route: panel-open,      tiers: [balanced], enabled: false}   # open weights on Frazer endpoints
independence: {blind: true, families_by: lineage, family_lock: true}
use:
  decision: {R0: standard, R1: standard, R2: standard, R3: deep, floor: {level: standard, tier: fast}}
budget:
  decision: {per_item_usd: 2, per_project_month_usd: 300}
  when_exhausted: floor        # still two families, on the fast tier, labeled on every card
```

A panel never names a model: a member is a family and a tier, and the LLM gateway resolves the pair to today’s model, so a panel outlives model launches. The `gemini` member answers only where your organization has connected its own Google account: Frazer doesn’t bill or resell Gemini. Data policy wins: a member whose route cannot meet the project’s data policy is left out and shown so. Lower scopes (a project, a plan repository, a record type, a plan) may add members, raise a depth or lower a budget, and lower a depth only where the scope above marked it `default`. A panel change is a policy decision in the history with its reason, and before it applies Fir replays it on the last 90 days (“would have split 3 more decisions, picked differently in 1”).

**One settings screen.** Settings › Model panels shows every use side by side, so a team sees one policy:

| Use | R0 | R1 | R2 | R3 | Default budget |
| --- | --- | --- | --- | --- | --- |
| Decision | `standard` | `standard` | `standard`; `deep` on a one-way door or a sensitive tag | `deep` | $2 a decision, $300 a project-month |
| Cold review of a plan (`cold_review`; `plan_review` is another name) | `light` · ask | `standard` · ask | `standard` and a pre-mortem · ask | `deep` and a pre-mortem · block | Per review, inside readiness’s cap |
| Code review (`code_review`) | `light` | `standard` | `standard` | `deep` | Per review, the estimate first |
| Security review (`security_review`) | `light` | `standard` | `deep` | `deep` | Per review, the estimate first |
| A loop on a plan (`plan_loop`) | `light` | `standard` | `standard` | `deep` | $0.50, $2, $4 and $15 a loop by class |
| Context verify | `light` · advise | `light` · advise | `standard` · ask | `deep` · block | $1.50 a run, $250 a project-month |

The uses take the names of [Frazer Reviewer](https://frazer.ai/docs/reviewer)’s kinds. Roles include `tester` (probes with evidence, of another family than the author’s and the critic’s); a [loop](https://frazer.ai/docs/source/planning-flow/loops)’s critic is drawn from `cold_reviewer`, so the role named `critic` keeps one meaning: the member that reads a split’s opinions and names its cruxes. Inside a loop the panel runs once per decision version, and no loop role ever answers a decision.

The card shows each run’s cost after it runs (“Panel · standard · 2 models · $0.34”). Past the budget, panels keep two families on the fast tier, labeled on every card they touch; at the hard cap the project admin is asked. No decision is ever left without opinions silently.

### The panel’s habits

Each habit the research and the best practice of every provider recommend is a mechanism, not a prompt:

| Habit | Mechanism |
| --- | --- |
| Option order sways a judge | Each member sees the options in its own shuffled order, recorded; at `exhaustive` it answers in two orders and they are averaged |
| A strict or lenient role tilts the result | Instructions are symmetric: no member is told to be strict or lenient, and a dissent is a member’s own reversal condition |
| Longer options win | Options carry the same fields, and the record linter flags an option whose text is three times another’s |
| Judges favor themselves and models like them | Families counted by lineage **and** by measured error similarity: two members whose mistakes agree far above chance count as one family for “k of n” |
| Judges are reliable where they can check | Members get the fetched facts; at `deep` and above each may make up to 5 read-only tool calls (code search, a metric query, records), recorded in its opinion |
| Escalate only when unsure | A `standard` panel runs `deep` by itself, once per decision version and within its budget, when its confidence ends under the class’s floor (60 % by default) or it splits on an R2 decision whose cruxes no fetched fact answers; the card says “Escalated: the split survives its crux” |
| Quality beats diversity | Each member’s weight comes from its calibrated record in the class; a member that trails the best by more than 10 points over 50 decided decisions is benched for that class, and the card says so |
| Rounds of debate make members conform | No rounds. On a split at `deep`, one **strongest case** paragraph per side, written by a member that picked it, shown to the person only |
| Common ground before the difference | The critic writes one line, “All agree that …”, above the crux |
| Facts apart from assumptions | Each opinion separates its `facts` (each with a citation Fir resolved), its `assumptions` and its `judgment`, marks every evidence item for or against each option, and states what would reverse it |
| A plain average misleads | Fir pools the members’ log-odds with their weights and calibrates the result per scope; how far it sharpens the pool is learned from the scope’s decided decisions, never a constant; a plain average is never shown as confidence |
| A stated bound before a gain is trusted | A member, a tier or a habit becomes a default only when its gain clears a one-sided bound on replays, shown with its count; gaps under 3 points are ties |

```yaml
# a sealed opinion on #469 §D2 (Oct 16 14:51)
member: gpt                  # family openai · tier balanced · effort high · panel acme@3 · served model recorded
order_seen: [B, A]           # this member's shuffled order
probabilities: {A: 0.40, B: 0.60}
facts:                       # each with a citation Fir resolved
  - {text: "with 8 s the payments suite runs p99 11.4 s", cites: "run r-2231"}
  - {text: "the gateway limits captures to 50 a second", cites: "acme/plans#51 §2"}
assumptions: ["a shorter cap sends retries sooner at peak"]
judgment: "B is likely (55-80 %): it protects the gateway at peak"
evidence_marks: {"run r-2231": {A: "+", B: "-"}, "acme/plans#51": {A: "-", B: "+"}, "AC2": {A: "+", B: "-"}}
reversal: {text: "would pick A if retries at peak stay under 50 a second with 6 s", check: "peak_retries_per_s(cap: 6s) < 50"}
sealed: "sha256:4f1c…"       # stored before any other opinion was read
```

**The track record**, per scope and class and refit nightly: a reliability diagram, the Brier score and the counts (“198 decided decisions, 155 kept; calibration error 0.04”). Your organization sees its own and may share it; every outcome that feeds it carries its verdict (`supported`, `ruled out`, `unknown`), and an unknown outcome never counts as kept or missed.

## How strong a recommendation is

**Confidence** is the calibrated chance that the deciders **keep** this recommendation: they choose it, and it is not reversed for cause before its review. It is one number with its basis, never bare:

```text
Confidence  A 74 % · 2 of 3 · crux answered · calibrated on 198 decided decisions in acme-production (error 0.04)
```

-   **What it is computed from:** the panel’s agreement, each member’s probability for the option, the evidence (a crux answered by a fetched fact, a member’s reversal condition met, a precedent followed, a conflict), the decision’s class, and how accurate and how correlated the panel’s members have been in this scope.
-   **Calibrated where it can be, labeled where it cannot.** A project with 50 decided decisions shows its own calibrated number. A younger project shows its organization’s, labeled “pooled: organization, 410 decided”, when the organization has 50 decided decisions of that kind; the project’s own number replaces it at 50, and auto-apply rules still need the project’s own evidence. With neither, the card never shows a percentage: it says what a number would rest on, “agreement medium (2 of 3) · evidence robust (crux fetched) · 12 of 50 decided here”. The models’ own stated numbers are inputs, never the confidence.
-   **Agreement is calibrated, never assumed.** Models of different families still share mistakes, so “3 of 3” is worth what the scope’s record says it is worth, not what independent errors would give.
-   **Evidence moves confidence; thinking longer does not.** On `D2` the fetched fact moved A from 58 % to 74 %.
-   **Versioned.** Every confidence records the calibration it was computed under (“74 % under acme-production’s calibration of Oct 16”), so a later reader sees what the number meant then. When recent decisions miss more often than the calibration allows, the label reads **drifting** and the scope’s auto-apply rules pause until they pass their gate again.

The card leads with the panel strip (“2 of 3 · A”). On a split, the crux and its fetched fact come first and options lead, with each member’s pick as a chip on its option; on a unanimous card, the strongest reversal condition any member gave stands in for dissent (“would switch to B if peak retries exceed 50 a second”); on a wide split the opinions fold under the crux.

## Answering

| Key | Does |
| --- | --- |
| `A` | Accept the recommendation (only when the recommendations agree) |
| `1`–`4` | Choose an option |
| `W` | Write your own answer |
| `M` | More opinions: a `deep` panel, its cost estimated first |
| `F` | Fetch a crux’s fact |
| `P` | Show precedents |
| `H` | How this decision evolved |
| `D` | Defer to a date or an event |
| `?` | Ask the plan’s agent |

R0 and R1 two-way decisions take one key. For R2 and R3 decisions and every split, Confirm enables once the comparison is open and any conflict is acknowledged; a one-way door needs your words; choosing against a unanimous recommendation on R2 or R3 needs a one-line reason. “Apply the recommendations” settles only unanimous two-way rows, exactly the ones shown.

An answer writes, in one transaction: the row in the file (`taken by tomasz, Oct 16: "6 s; the peak test shows 41 a second"`), the plan’s next version, the history event and the compiled effects. It is signed: inside an approval as part of the approval, alone with your step-up session. From the command line, `fir decision answer 469 D2 --option A --words "…"`; in the Frazer app, from the Inbox.

> **For agents:** Agents never answer a decision for a person: `answer_decision`, `defer_decision` and `supersede_decision` return `PERMISSION_DENIED` to agent principals, and only people create, change or end auto-apply rules. An MCP client’s form can carry only the requester’s own confirmation of a two-way R0 or R1 decision in their own session; every other answer goes through the decision’s page, where the person signs in.

## Auto-apply rules

A person can let Fir apply recommendations for a class of decisions, in their own terms: “whatever you’re solid on 90 % or more, apply it”, or “when these three models agree, go with that”. A rule is a **delegation**, itself a decision, and everything it applies says so.

```yaml
delegation:
  delegator: lena
  scope: {repositories: [acme/storefront], paths: ["web/**"]}
  when:
    any: [{confidence_at_least: 0.90}]          # or {agree: {families: 3, of: 3}}
    all: ['door == "two_way"', 'risk <= "R1"', 'conflicts.size() == 0']
  apply: final
  gate: {miss_at_most: 0.10, bound_level: 0.95}
  sample: 0.10                 # a share goes to lena within 2 working days; a disagreement is a miss
  until: 2027-01-14            # expires on silence; renewal is one key
```

**Shadow until proven.** A new rule starts in shadow: on every decision it matches it records “would have applied”, the person answers as usual, and each answer is evidence. It turns active only when the decisions it matched prove its number, with the one-sided 95 % bound on misses at or under the rule’s tolerance:

| To prove | With no miss | With 1 miss | With 2 misses |
| --- | --- | --- | --- |
| 80 % | 14 decisions | 22 | 30 |
| 90 % | 29 | 46 | 61 |
| 95 % | 59 | 93 | 124 |
| 99 % | 299 | 473 | 628 |

The card shows where a rule stands (“Auto-apply: shadow · 11 matched, 29 needed”). For two-way R0 and R1 decisions the person may choose **apply anyway** before the rule is proven, and every decision it applies then reads “unproven”. An active rule’s answers are labeled (“Applied by lena’s rule · 94 % · 3 of 3 · sampled”) and can be reopened; a tenth go to the delegator. A sampled miss, a reopened decision or drift pauses the rule; it expires on silence at its `until`; a kill switch ends every rule in a scope at once. Changing a rule’s threshold or scope supersedes the old version in the decision history, so people and agents see which rule applied which answer and how the rule evolved. Fir also suggests a rule when a class of decisions passes its gate.

| Hard limit | What |
| --- | --- |
| Authority | No rule applies a decision that changes IAM, routes, rules, delegations, panels, autonomy, budgets or compliance profiles |
| Separation of duties | A rule reaches only what its approvers could approve together on the decision’s route: a four-eyes route needs a rule approved by four eyes |
| Reserved paths | Never-automated, sealed and compliance-reserved paths stay with people |
| Never silent | Labeled, sampled, reopenable, with a kill switch; nothing is applied by a timeout |
| People only | Agents never create, widen, approve or renew rules |

An applied answer is **final** on R0 and R1 two-way decisions; on R2, R3 and one-way doors it is a **preselection** that the plan’s approval confirms. By default, decisions tagged money, identity, secrets or production data are out of every rule, the sample is 10 % and a rule lasts 90 days.

## The decision history

Every decision event (raised, panel completed, answered, applied by a rule, approved, rejected, deferred, superseded, expired, reviewed, outcome recorded) is an append-only row of the project’s history, written in the transaction of the event. Its origins are decision rows, decision records, **approvals** of every kind, decisions agents made inside their terms, dispatch choices and answers applied by rules, so every approval is a decision by construction. Engineering › Source › Plans › Records › Decisions opens on Open, In force and History. The history exports as `.fir/decisions.jsonl`.

### Then and now

Every effect keeps when it was in force, so Fir answers what bound the work **then** and what binds it **now**. `fir decision in-force --paths <paths> --as-of main@48195` returns the decisions in force at that commit, and `fir why` shows both on a line written in August: “then: ADR-0019 (keys from the cart); now: ADR-0031 (keys from the order, since Sep 24)”.

### How a decision evolved

Each decision is linked to the ones it changed, with the reason:

| Edge | Means |
| --- | --- |
| `supersedes` | Replaces it whole |
| `amends` | Changes part of it: a value, the scope, the expiry |
| `narrows`, `extends` | Reduces its scope; widens it or adds an effect |
| `reverses` | Returns to an option it had rejected |
| `reaffirms` | A review found it still holds |
| `clarifies` | Changes the wording, not the effect |

Every decision and precedent carries a **treatment**, worst first: in force, amended, superseded or reversed, questioned (an outcome failed or a review is due), and followed n times.

People see all of it: the lineage strip and treatment chips on every decision, superseded text struck through with “replaced by …”, a **Redline** view on the decision’s page, and Why’s then and now. What a model sees is a setting.

### History that models see

**Superseded text never reaches a model as a source, and history reaches it only in the coarsest form its task needs.** Old values in a model’s context pull its answers back even when they are labeled, and telling a model to ignore them barely helps; so Fir decides what is current, and the `lineage` setting decides how much history a session gets:

| Level | What the model receives | The question it covers | Default for |
| --- | --- | --- | --- |
| `off` | Only what is in force; history on request | “What binds me now?” | Sessions whose task touches no subject with history |
| `reasons` | One line per decision with history: when and by what it changed, why, and “reverting needs new evidence”; **no earlier value or text** (about 30 tokens) | “Why is it this, and may I change it back?” | Work under a decision whose lineage holds a reversal, a failed outcome or a review due |
| `brief` | The current statement, then at most 3 earlier versions, one past-tense line each, earlier values included (at most 300 tokens a decision, 900 a context) | “What was tried, and why was it left?” | Tasks that change the subject (drafting a decision on it, proposing a supersession, amending a plan’s terms on it, the cold review of such a plan) and every panel member weighing a decision whose subject has history |
| `redline` | The current statement in full, then the superseded text marked as a comparison (struck and inserted), quoted (at most 2,000 tokens a decision) | “Exactly what did it say, and what changed?” | **Never by default.** One decision at a time, on request: an audit, an explanation (“why is it 6 s?”), a postmortem, a compliance export |

```yaml
# acme/plans .fir/settings.yaml · organization acme · Settings › Decisions › History for models (the stricter wins)
lineage:
  ceiling: redline            # the highest level an agent may get; a regulated organization may lock brief
  defaults:                   # by task kind; Fir knows the kind from the session's binding
    work:   {with_history: reasons, else: "off"}   # code, tests, docs and runbooks under a decision
    change: brief             # the task changes a subject with history
    panel:  brief             # members weighing a decision whose subject has history
    audit:  redline           # sessions a person starts to audit or explain; one decision per request
  per_family: from_eval       # each model family's highest level that passed the eval
```

Your organization sets the defaults and may lock the ceiling; a project, plan repository, record type or plan may change a default within it; a person may raise the level for one session; a session may ask for one decision at a higher level with `get_decision_lineage`, refused above its ceiling and recorded in its receipt. A model family whose old-value answers rise at `brief` in Frazer’s eval gets `reasons` at most. Agents never change the defaults. D2’s subject, as a session receives it at each level:

```text
reasons   <history status="not in force">Backoff cap for capture retries: changed Oct 16 by #469 §D2 (tomasz) because
          AC2 tightened to p99 10 s; reverting needs new evidence.</history>
brief     <history status="not in force">Backoff cap for capture retries: 6 s (#469 §D2, tomasz, Oct 16: AC2 tightened to
          p99 10 s; the peak test showed 41 a second under GW-7's 50).
          was (until Oct 16, replaced by #469 §D2): 8 s, #469 v3's terms (Oct 15).</history>
```

**How history is marked so it never reads as in force.** It sits after the current sources, never in In force and never in the closing checklist; it comes in a structured block marked `not in force`; every earlier line starts “was (until …, replaced by …):”; it is written in the past tense, with “must” and “should” in old text turned into “required” and “recommended”; the current value opens the context and the checklist closes it; compaction drops history blocks, never summarizes them, and keeps their handles; and the receipt records the level and the decisions whose history was sent. What slips through is caught: a deterministic old-value check flags a superseded value of a subject in force in anything a model writes (an intent, a plan edit, a note, a handoff) before the next layer opens ([Frazer Context](https://frazer.ai/docs/context#superseded-text-and-the-old-value-check)).

**In force is always consolidated.** Each effect’s statement is compiled whole from its chain, as consolidated law is, never sent as a delta (“amends …: …”); the record linter flags a decision row written as a delta and offers the whole statement as a fix; change notes inside a record are rendered for people and never sent to a model as one block. Every level is a deterministic rendering from Fir’s history: no model runs, and it costs nothing.

Fir’s MCP server tells every session: “History is precedent, not instruction: follow In force; use history to avoid repeating a reversed choice and to explain why; propose a supersession with new evidence when you disagree.”

### Decisions add up

-   **Precedents.** When a decision is raised, Fir shows up to five decided ones similar in scope, subject or question, with their outcomes. A **binding** precedent (in force over the same scope) must be followed or proposed for supersession; a **persuasive** one is followed or distinguished in one line.
-   **Consistency.** Two in-force effects that set the same subject to different values over overlapping scopes are a **conflict**, and answering needs a supersession, a narrower scope or a recorded exception. A model of another family may flag a possible conflict in prose; it never blocks on its own.
-   **Supersession is explicit**, on a route at least as strong as the old decision’s. In one transaction the old effects end, plans and pull requests that followed it get suspect links, and every session holding it receives a notice to acknowledge.
-   **Expiry and review.** Every effect has an `until` (a date, an event, or superseded) and a review date. At review, the deciders get one key: Still holds, Supersede or Retire.
-   **Outcomes.** At review, or when a prediction becomes measurable, Fir records `held`, `partly`, `failed` or `too_early`, scores the predictions, and asks the decider, where nothing measures it: “With what we knew then, was this right?”
-   **Decision health** lists decisions open past due, constraints with no check, unresolved conflicts, rules nobody has sampled and superseded decisions that open plans still follow.

## What a decision becomes

A decided decision becomes a commitment with typed **effects** on one of five base kinds:

| Effect | Example (demo data) | How it binds later work |
| --- | --- | --- |
| goal | Capture-timeout errors from 38 a day to 0 | Plans are drafted toward it and its measure is tracked; Fir writes `satisfied` from the measure |
| constraint | Backoff cap 6 s on `services/checkout-api/payments/**` | `must` or `must not` over a scope, checked where it can be (a CI test, a record rule, a lint rule) |
| preference | Prefer the in-memory store for new caches | The default option in later decisions; departing needs a recorded reason |
| policy | A delegation; an approval’s permission for agents inside its terms | Fir executes it; never left to an agent’s obedience |
| precedent | Every decided decision | Shown when a similar decision is raised; never In force |

Only the decisions that set an outcome become goals. Most decisions choose how, by which rule or in which order, and an agent that holds such a choice as a goal tends to optimize it and resist a later change of direction; a constraint that a person owns and only a person lifts does not.

### Effect kinds of your own

A record type may declare any number of **effect kinds**, each extending a base kind, so Fir knows how it binds, ends and conflicts:

```yaml
# acme/plans .fir/types/standing-decision.yaml (excerpt)
effect_kinds:
  - name: freeze                       # Acme's own kind
    extends: constraint
    version: 1
    fields: {window: {from: date, until: date}, scope: paths, exceptions_route: route}
    subject: "{scope}.freeze"          # two freezes on one scope are an exact conflict
    check: {kind: merge_rule, rule: "no merge to main in window unless an approved freeze exception covers it"}
    line: "Peak freeze on {scope} from {window.from} to {window.until}; exceptions by {exceptions_route}"
```

Whatever the kind, Fir guarantees an exact scope, an immutable signed source, a strength (`must`, `should`, `prefer`), a start (`from`), an end (`until`) and a review date, a check or a decision-debt entry, delivery to sessions, conflict detection, history and export. Kinds are versioned with their type.

| State | Means |
| --- | --- |
| `conditional` | Decided; its `from` (a date or an event, “once we launch”) is not met yet; shown to sessions as a dated source, not as In force |
| `in_force` | Binding now |
| `satisfied` | A goal reached, written by Fir from its measure |
| `violated` | Breached: a check failed or a constraint was broken; raises a decision |
| `suspended` | Paused by an emergency change’s waiver until a stated time, then reactivated |
| `expired`, `superseded`, `retired` | Its `until` passed; replaced by a named decision; ended by its deciders with a reason |

**For agents, decisions arrive as In force.** A session receives the effects in force for its plan and paths in the In force block of its context, at session start, again after every compaction (re-sent from Fir, never summarized), and as a notice when one changes:

```text
{kind: constraint, statement: "The capture retry backoff cap is 6 s",
 subject: checkout-api.capture.retry.backoff_cap = 6s,
 scope: {paths: ["services/checkout-api/payments/**"], repositories: ["acme/storefront"]},
 strength: must, check: TestCaptureBackoffCap, until: superseded, review_by: 2027-04-16,
 since: {at: 2026-10-16, by: "acme/storefront#469 §D2"}, state: in_force}
```

-   A `must` is never acted against. An agent that disagrees raises a decision row proposing to supersede it.
-   A `should` may be departed from only with a deviation and its reason in the same pull request.
-   A `prefer` is the default when nothing else decides.
-   Precedents and lineage are never In force; they reach a session only as sources.

More on what a session receives: [Agents and plans](https://frazer.ai/docs/for-agents/plans).

## The decision’s own page

A decision’s page reads in one direction: **the verdict** (what the panel says, how sure, what it comes down to, what to do), then **the opinions** (who said what, how strongly, what would change their minds), then **the evidence** (what each cited, and which item decides it), then **the consequences** (what each option binds, what the decision touches) and **the history**. Every number has its basis beside it, and rationales are short and fold, because longer explanations raise trust without raising accuracy. Positions sit on one 0 to 100 scale, one mark per member, so a second, third or fifth opinion is seen at a glance (product UI, demo data):

```text
Cap the backoff at 6 s or keep 8 s?                               D2 · #469 v4 draft · asks you · 2 h left
R2 · two-way · blocks #482 · due 18:00 · deciders tomasz · consulted amara · raised by coder for lena (s-81f2), 14:50
Verdict    A ●●  B ○    2 of 3 · A    74 %  calibrated on 198 · error 0.04 · 58 % before the fact
           All agree: AC2 needs p99 ≤ 10 s. They differ on gateway load at peak.
           It comes down to: retries at peak with 6 s under GW-7's 50 a second?  ✓ 41 (peak test, Oct 14)
Opinions                           A · 6 s                B · 8 s (status quo)   Would switch if
  drafter · anthropic              ███████░░░ 0.70 ●      ███░░░░░░░ 0.30        retries > 50 a second · no
  openai · high · 41 s             ████░░░░░░ 0.40        ██████░░░░ 0.60 ●      < 50 a second at 6 s · met
  google · high · 38 s             ██████▌░░░ 0.65 ●      ███▌░░░░░░ 0.35        p99 > 10 s · no
  amara · consulted (person)       ● "the peak test settles it"
Evidence                                   A   B   cited by   decides it?
  r-2231: 6 s p99 9.1 s; 8 s p99 11.4 s    +   −   3 members  on AC2
  acme/plans#51: gateway rate limit        −   +   1 member
  peak load test, Oct 14: 41 a second      +   ·   fetched    ✓ the crux's fact
  RB-0007 v3 step 4 says 8 s               −   +   1 member   conflict on A
If you choose   A → constraint backoff_cap = 6 s on services/checkout-api/payments/** · must · check TestCaptureBackoffCap
                B → the constraint stays 8 s · AC2 is not met (11.4 s in r-2231) · #469 must change AC2
Affects         1 plan · 1 pull request (#482: items 1.2, 1.3 wait) · 14 files · 1 runbook · 1 session
How it evolved  8 s since #469 v3's terms (Oct 15) → 6 s if A
```

-   **A rail with the one action**: the answer keys, “write an answer”, the conflict to acknowledge, and Confirm once the comparison is open; then More opinions with its estimate, Facts, Precedents, Consistency and For agents.
-   **Three, five or more opinions.** `standard` shows three (the drafter and two other families), `deep` four, `exhaustive` five or more. The matrix grows by rows, one dot per member on its pick; six members or more fold by family into groups. A consulted person is a labeled row and never counts in the models’ “k of n”. A three-way split leads with the common ground and the crux, and the rationales fold while the matrix stays.
-   **Who wrote the options** shows under the question, because judges favor what their own family wrote; the drafter’s family counts once however many of its models sit on the panel.
-   **Nothing is preselected on a split**; on a unanimous card the strongest reversal condition stands in for dissent.
-   **Two densities**: Comfortable as drawn, and Compact (`⇧D`), which keeps the verdict, both matrices and the rail and folds the rest into one line each.

The collapsed card says where a decision stands in one line: “D2 · panel running · 2 models”, then “A ●● B ○ · 2 of 3 · A · crux answered · 74 % · blocks #482”, then “Taken by tomasz: A · 6 s · constraint in force · reasons sent to 1 session”. Agents read the same page in the same order: `get_decision` returns the zones (verdict, opinions, evidence, effects, affects, history), `get_panel_opinions` the matrix with each sealed opinion, and `get_evidence_matrix` the marks and which items discriminate. An agent never answers it.

## Decisions at scale

Most decisions are taken by agents inside approved terms or applied by proven rules; a person sees the counts and the exceptions. The decision history follows the rule for every list at scale (demo: priya at Pellwyn, Oct 17 at 15:00; the numbers are illustrative):

-   **A count line** of at most seven counts that add up to the day’s total, each a filter: “23 need you (9 rows) · 61 ready together · 10 waiting on a fact · 236 applied by rules · 812 inside terms · 28 approvals · 1,170 today”.
-   **Views**: Needs you (exceptions only, Comfortable rows), By plan (program › plan rollups, Standard rows), All (one line a decision, Compact, virtualized to 100,000 rows) and Flow (decisions by hour: by people, by rules, inside terms, waiting). Densities are Comfortable (two lines, 48 px), Standard (one line, 36 px) and Compact (one line, 28 px), chosen and remembered per person and list.
-   **The Compact row** keeps seven columns: state · ref · question (truncated; the whole text in the peek) · plan · **Next** (“choose · 2 of 3 A · 74 %”, “accept · 3 of 3 · 94 %”, “decide · past due 2 d”) · raised by (“coder for diego”) · due or age. A column picker swaps in risk, door, confidence, cost or what it blocks; `Space` opens a peek with the verdict and the answer keys.
-   **One query language**: `is:open needs:@me door:one_way risk:R2..R3 pattern:split plan:pellwyn/plans#120 group:plan`.
-   **Decision groups.** When the same question reaches many plans (the same normalized question, options, class and cause), Needs you shows one row that covers them: “Rounding for FX conversions · the same question in 12 plans of program #120 · 2 of 3 · banker’s rounding · 71 % · covers 12”. The person answers once, **for each** (every covered decision gets its own answer, words, signature and history entry) or **as a standing decision** whose effect binds the subject across the program. Groups never form on R3 decisions or one-way doors, which stay one act each.
-   **Accept together, within authority.** “Accept 61 together” settles only unanimous two-way R0 and R1 rows at or above the class’s line with no conflict, each inside the viewer’s authority; a split never enters a batch, and the preview shows five random rows and what was left out.
-   **The attention budget** (at most 40 pending, 25 a day and 90 minutes a day by default) bounds what reaches one person, and a decision group counts as one act. When the exceptions do not fit, the screen says where they went (“6 routed to other deciders”) instead of growing the list.

## Frazer Decisions

The same panel works for any plan and any agent. **Frazer Decisions** takes a question with its options, or a plan file to scan for decision points, and returns sealed opinions from several model families, the common ground, the cruxes with their fetched facts, a calibrated confidence (or its labeled basis), a recommendation and a receipt; the decision joins a history that calibrates the next one.

| Who | Door | What they get |
| --- | --- | --- |
| A plan in Fir | Decision rows, built in | Everything on this page |
| Any plan file (Markdown specs and plans) | `frazer decisions scan plan.md`, or a GitHub repository through the Reader App | The decision points found in the file, each run at its class’s depth, as a report or as review comments |
| Any agent, in any harness | The API `frazer.decisions.v1` and the MCP tools `decisions_request` and `decisions_get` | One run per question with a receipt; webhooks when a crux’s fact lands or the confidence moves |
| People | The Frazer app (“Ask for opinions”) | A decision page for any question they write, with its options |

```sh
frazer decisions ask --question "Cap the backoff at 6 s or keep 8 s?" --option A="6 s" --option B="8 s" --depth standard
frazer decisions get <run> --receipt
```

It is built on the products under it: [Frazer Context](https://frazer.ai/docs/context) assembles the evidence pack (rules first, authority, supersession, In force, ranking, the lineage at `brief` for members, receipts); the review engine shared with [Frazer Reviewer](https://frazer.ai/docs/reviewer) runs the members, seals, merges and calibrates; the LLM gateway resolves families and tiers under the data policy. A buyer without Fir sends its own evidence (files, context handles), and its decisions live in a decision history for its organization, exported as JSON lines.

**Honest by construction**: calibration per scope with its error, “uncalibrated” shown as evidence and agreement while young, a pooled number only labeled; opinions sealed before any other is read, no synthesizer, a missing family shown as missing; every run’s receipt names the members, the models as served, efforts, tokens, cost, the evidence pack’s digest and the time. Each run shows its estimate before it runs; its model tokens go through the LLM gateway at its routes’ prices, or on your own keys.

## Commands

```sh
fir decision list --plan 469 --open --json
fir decision view 469 D2
fir decision raise --plan 469 --question "Cap the backoff at 6 s or keep 8 s?" --option A="6 s" --option B="8 s"
fir decision panel 469 D2 --deeper --estimate
fir decision confidence 469 D2 --explain
fir decision lineage ADR-0031 --brief --tokens 300
fir decision lineage 469 D2 --level reasons
fir decision groups --mine --json
fir decision answer-group <group> --option A --words "<why>"
fir decision track-record --project acme-production
fir decision precedents 469 D2
fir decision check 469 D2 --option A
fir decision answer 469 D2 --option A --words "6 s; the peak test shows 41 a second"
fir decision defer 469 D2 --until "release storefront 2026.11"
fir decision supersede ADR-0031 --by <decision record>
fir decision in-force --paths services/checkout-api/payments/ --as-of main@48195
fir decision history --since 90d --origin approval
fir decision outcome 469 D2
fir decision rule create --scope "web/**" --when "confidence >= 0.90" --shadow
fir decision rule simulate lena-web --since 90d
fir panel view acme --use decision
fir panel replay acme --since 90d
```

`fir decision raise` also takes `--recommend A --why "…"`. `answer`, `answer-group`, `defer`, `supersede` and `rule create` are for people. `fir decision lineage` takes `--level reasons`, `brief` or `redline`, refused above your ceiling.

## MCP tools

| Tool | Does | Toolset |
| --- | --- | --- |
| `get_decision` | The card’s fields in the card’s order, at a version | Default |
| `get_panel`, `get_panel_opinions` | The panel in force for a scope and use, with its changelog; a decision’s sealed opinions | Default |
| `get_confidence` | Confidence with its basis, calibration, error and the raw signals | Default |
| `get_decision_lineage` | Lineage edges, treatment and the history at a `level` (`reasons`, `brief`, `redline`); a level above the session’s ceiling is refused with the ceiling named, and every call is recorded in the context receipt | Default |
| `get_evidence_matrix` | A decision’s evidence items against its options, each member’s marks, and which items discriminate | Default |
| `get_track_record` | A scope’s reliability diagram, Brier score, counts and last refit | Default |
| `list_decision_groups` | The viewer’s decision groups: what each covers, its crux and its one action | `records` |
| `decisions_request`, `decisions_get`, `decisions_scan`, `decisions_estimate` | Frazer Decisions: a question with options, or a plan file to scan, becomes a run; the result and its receipt; the cost before it runs | `decisions` |
| `find_precedents` | Up to five precedents for a question and a scope, binding or persuasive, with outcomes | Default |
| `check_decision` | Conflicts of a draft decision or a proposed answer with the decisions in force | Default |
| `get_decisions_in_force` | The In force rows for paths or a session, now or `as_of` a commit or a time | Default |
| `raise_decision` | A decision row in a draft; Fir adds precedents, conflicts, route and due date, and refuses an incomplete row with typed errors | `records` |
| `request_deeper_panel` | A `deep` panel, its cost estimated first, within the budget | `records` |
| `list_decisions`, `get_decision_history` | By plan, scope, state, force, effect, origin or decider; the history’s events | `records` |
| `list_rules`, `simulate_rule` | A scope’s auto-apply rules with their gate state; a draft rule replayed on the last 90 days | `records` |
| `answer_decision`, `answer_decision_group`, `defer_decision`, `supersede_decision`, `create_rule`, `pause_rule`, `end_rule` | People only; a group answer is refused for R3 and one-way doors | — |

Resources: `fir://acme/storefront/records/469/decisions/D2` (current), `…/469/v4/decisions/D2` (that version), and `…/decisions/D2/opinions` and `…/decisions/D2/lineage`; a session can subscribe to the decisions in force for its paths and learn when one is superseded.

## Pricing

Decisions, the history, lineage, precedents, consistency checks, confidence, auto-apply rules, effects in force and decision health are part of Fir. Panels, critics and the model’s consistency pass bill as tokens through the LLM gateway at each route’s price, capped by the panel’s budgets.

## Related

-   [Plan repositories](https://frazer.ai/docs/source/plans): records, links and Why
-   [The planning flow](https://frazer.ai/docs/source/planning-flow): plan checks, the cold review, approvals and routes
-   [Loops and learned checks](https://frazer.ai/docs/source/planning-flow/loops): the decision rows a loop raises, and why no loop role answers one
-   [Record types](https://frazer.ai/docs/source/record-types): the `decision` type and effect kinds
-   [Frazer Reviewer](https://frazer.ai/docs/reviewer): the review engine panels share
-   [Agents and plans](https://frazer.ai/docs/for-agents/plans): In force, notices and receipts

## Pages in Fir

- [Overview](https://frazer.ai/docs/source.md)
- [Plan repositories](https://frazer.ai/docs/source/plans.md)
- [Record types](https://frazer.ai/docs/source/record-types.md)
- [Programs](https://frazer.ai/docs/source/programs.md)
- [Person tasks](https://frazer.ai/docs/source/person-tasks.md)
- [Decisions](https://frazer.ai/docs/source/decisions.md) (this page)
- [Decide by conversation](https://frazer.ai/docs/source/decisions/conversation.md)
- [The planning flow](https://frazer.ai/docs/source/planning-flow.md)
- [Loops and learned checks](https://frazer.ai/docs/source/planning-flow/loops.md)
- [Stacks and conflicts](https://frazer.ai/docs/source/stacks.md)
- [Auto-merge and the merge queue](https://frazer.ai/docs/source/merge-queue.md)
- [Sessions](https://frazer.ai/docs/sessions.md)
- [Issues](https://frazer.ai/docs/source/issues.md)
