Back to index

Decision Record

Two Column
Generates documents
Decision Record

Seen as a design

Take it with you

Copy and paste, or save a file and hand it over. For a machine with no network, one “Everything” file is enough.

Everything

decision-record-everything.md

Everything in this panel, including the contents behind each URL, in one Markdown file

Prompt

1.7 KB
Build an HTML document with "Decision Record". This layout runs, so there is no composition to rebuild — what it needs is content.

## What this layout does
Decision Record with explicit source values and reading conditions.

## What you have to supply
- Provide the source values, labels and decision conditions described by the schema.

## The shape of the input
- `title` — string — 結論を伝える見出し
- `subtitle` — string? — 出典・時点・母集団や仮定
- `decisionId` — string — 決定の識別子
- `status` — string — 提案・採択・置換済み
- `date` — string — 決定または提案日
- `owner` — string — 決定責任者
- `context` — string — 背景と制約
- `decision` — string — 決定内容
- `consequences` — array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) — 引き受ける影響
- `alternatives` — array (0, 1, 2, 3, 4, 5, 6, 7) — 検討した代案
- `revisit` — string — 見直しの条件

schema.ts holds the machine-checkable validation. Ask rather than guess when an input is missing.

## When not to use it
- Do not compare values with incompatible units, populations, or assumptions.

## How to build it
Put the input in a JSON file and run:

```bash
node scripts/render.mjs decision-record <input.json> --theme ink -o out.html
```

The output is one self-contained file and fetches nothing at render time.

## The source
- https://design-vault.pages.dev/designs/decision-record/source/template.tsx
- https://design-vault.pages.dev/designs/decision-record/source/schema.ts
- https://design-vault.pages.dev/designs/decision-record/source/sample-data.json
- https://design-vault.pages.dev/designs/decision-record/sample.html

Files

Template, input schema, sample data and metadata. This document was generated from those four. The generated document

template.tsx

6.6 KB

/designs/decision-record/source/template.tsx

Show contents
import type { ReactNode } from "react";
import type { Props } from "./schema";
function Notes({children}:{children:ReactNode}) { return <details><summary>データ・判断条件を確認</summary>{children}</details>; }

const CSS = String.raw`
.asset{font-family:var(--font-sans);color:var(--color-primary);background:var(--color-surface);max-width:var(--container-slide);margin:auto;padding:3rem 2rem;line-height:1.6;font-size:var(--text-body-sm)}
.asset *{box-sizing:border-box}.asset header{margin-bottom:2rem}.asset .eyebrow{font-family:var(--font-mono);font-size:var(--text-label);letter-spacing:.08em;color:var(--color-secondary);margin-bottom:.75rem}.asset h1{font-size:var(--text-h1);font-weight:700;line-height:1.35;letter-spacing:-.025em;max-width:32em}.asset h2{font-size:var(--text-h3);font-weight:600;margin-bottom:.75rem}.asset h3{font-size:var(--text-body-md);font-weight:600}.asset .subtitle,.asset .muted{color:var(--color-secondary)}.asset .subtitle{margin-top:.75rem}.asset .number{font-variant-numeric:tabular-nums;font-family:var(--font-mono)}.asset .hero-number{font-size:var(--text-display);line-height:1.2;font-weight:700;letter-spacing:-.04em}.asset .callout{border-left:.25rem solid var(--color-tertiary);padding:1rem 1.5rem;background:var(--color-surface-subtle);margin-bottom:1.5rem}.asset .grid2{display:grid;grid-template-columns:1fr 1fr;gap:1.5rem}.asset .grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.5rem}.asset .panel{padding:1.5rem;background:var(--color-surface-subtle);border-radius:var(--radius-md);min-width:0}.asset .rule{border-top:1px solid var(--color-outline);padding-top:1rem;margin-top:1rem}.asset .pill{display:inline-block;padding:.25rem .75rem;border:1px solid var(--color-outline);border-radius:var(--radius-full);font-size:var(--text-label)}.asset .focus{background:var(--color-tertiary-container);color:var(--color-on-tertiary-container)}.asset .dark{background:var(--color-primary);color:var(--color-on-primary)}.asset .dark .muted{color:var(--color-on-primary-container)}.asset .row{display:grid;grid-template-columns:12rem minmax(0,1fr) 6rem;gap:1rem;align-items:center;padding:.75rem 0;border-bottom:1px solid var(--color-outline)}.asset .row>*{min-width:0}.asset .track{height:1rem;position:relative;background:var(--color-neutral);border-radius:var(--radius-sm)}.asset .bar{height:100%;background:var(--color-tertiary);border-radius:var(--radius-sm)}.asset .track.tall{height:2rem}.asset .flex{display:flex;gap:1rem;align-items:center;justify-content:space-between;flex-wrap:wrap}.asset .stack>*+*{margin-top:1rem}.asset ul{list-style:disc;padding-left:1.25rem}.asset li+li{margin-top:.5rem}.asset .plot{display:block;width:100%;height:auto;overflow:visible}.asset .plot text{font-family:var(--font-sans);font-size:14px;fill:var(--color-secondary)}.asset .plot .ink{fill:var(--color-primary)}.asset .plot .axis{stroke:var(--color-outline);stroke-width:1}.asset .plot .accent{stroke:var(--color-tertiary);fill:none;stroke-width:3}.asset .legend{display:flex;gap:1.5rem;flex-wrap:wrap;font-size:var(--text-label);margin-bottom:1rem}.asset .legend b{display:inline-block;width:.75rem;height:.75rem;margin-right:.5rem}.asset .ledger{border-collapse:collapse;width:100%;font-variant-numeric:tabular-nums}.asset .ledger caption{text-align:left;font-weight:600;margin:1rem 0}.asset .ledger th{font-weight:600;color:var(--color-secondary);text-align:left}.asset .ledger th,.asset .ledger td{padding:.75rem 1rem;border-bottom:1px solid var(--color-outline);vertical-align:top;overflow-wrap:anywhere}.asset .ledger th:first-child,.asset .ledger td:first-child{padding-left:0}.asset .ledger th:last-child,.asset .ledger td:last-child{padding-right:0}.asset .ledger tbody tr:hover{background:var(--color-surface-subtle)}.asset details{border-top:1px solid var(--color-outline);margin-top:1.5rem;padding-top:1rem}.asset summary{cursor:pointer;color:var(--color-secondary);padding:.5rem 0;min-height:2.75rem}.asset summary:focus-visible{outline:2px solid var(--color-tertiary);outline-offset:.25rem}.asset .small{font-size:var(--text-label)}.asset .mobile-only{display:none}.asset .horizontal-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem}.asset .board-column{border-top:.25rem solid var(--color-primary);padding-top:1rem;min-width:0}.asset .board-item{padding:1rem 0;border-bottom:1px solid var(--color-outline)}.asset .board-item p{margin-top:.5rem}.asset .statement{font-size:var(--text-h2);line-height:1.5;font-weight:600}.asset .meta-line{margin-top:.75rem;font-size:var(--text-label);color:var(--color-secondary)}.asset pre{white-space:pre-wrap;overflow-wrap:anywhere}.asset footer{margin-top:2rem;font-size:var(--text-label);color:var(--color-secondary)}
@media(max-width:640px){.asset{padding:1.5rem 1rem}.asset h1{font-size:var(--text-h2)}.asset header{margin-bottom:1.5rem}.asset .grid2,.asset .grid3,.asset .horizontal-list{grid-template-columns:1fr}.asset .row{grid-template-columns:minmax(0,1fr) 5rem;gap:.5rem}.asset .row>:first-child{grid-column:1/-1}.asset .desktop-only{display:none!important}.asset .mobile-only{display:block}.asset .panel{padding:1rem}.asset .ledger,.asset .ledger tbody,.asset .ledger tr,.asset .ledger td{display:block}.asset .ledger thead{display:none}.asset .ledger tr{padding:.75rem 0;border-bottom:1px solid var(--color-outline)}.asset .ledger td{display:grid;grid-template-columns:7rem minmax(0,1fr);gap:.75rem;border:0;padding:.25rem 0!important}.asset .ledger td:before{content:attr(data-label);color:var(--color-secondary);font-size:var(--text-label)}.asset .hero-number{font-size:var(--text-h1)}}
@media print{.asset{max-width:none;padding:1rem}.asset details>*{display:block}.asset summary{display:none}}
`;

export default function Template(d: Props) {
const names={proposed:"提案",accepted:"採択",superseded:"置換済み"};
return <section className="asset asset-decision-record"><style>{CSS}</style><header><p className="eyebrow">DECISION RECORD</p><h1>{d.title}</h1>{d.subtitle && <p className="subtitle">{d.subtitle}</p>}</header>
<div className="flex"><span className="pill">{d.decisionId} · {names[d.status]}</span><span className="small muted">{d.date} / {d.owner}</span></div><div className="callout" style={{marginTop:"1.5rem"}}><p className="statement">{d.decision}</p></div><div className="grid2"><article><h2>背景と制約</h2><p>{d.context}</p><h2 className="rule">見直し条件</h2><p>{d.revisit}</p></article><article><h2>引き受ける影響</h2><ul>{d.consequences.map((s,i)=><li key={i}>{s}</li>)}</ul></article></div><Notes><h3>検討した代案</h3><ul>{d.alternatives.map((s,i)=><li key={i}>{s}</li>)}</ul></Notes>
<footer>提案と採択を区別し、決定者と見直し条件を残す。</footer></section>;
}

schema.ts

1.1 KB

/designs/decision-record/source/schema.ts

Show contents
import { z } from "zod";
const text = z.string().trim().min(1).max(160);
const short = z.string().trim().min(1).max(48);
const value = z.number().finite();
const positive = value.positive();
const date = z.string().regex(/^\d{4}-\d{2}-\d{2}$/).refine(s => Number.isFinite(Date.parse(s)) && new Date(s).toISOString().slice(0,10) === s, "実在する日付を YYYY-MM-DD で指定する");

export const schema = z.object({
  title: text.describe("結論を伝える見出し"),
  subtitle: text.optional().describe("出典・時点・母集団や仮定"),
  decisionId:short.describe("決定の識別子"),status:z.enum(["proposed","accepted","superseded"]).describe("提案・採択・置換済み"),date:date.describe("決定または提案日"),owner:short.describe("決定責任者"),context:text.describe("背景と制約"),decision:text.describe("決定内容"),consequences:z.array(text).min(2).max(5).describe("引き受ける影響"),alternatives:z.array(short).min(1).max(4).describe("検討した代案"),revisit:text.describe("見直しの条件"),
}).strict();
export type Props = z.infer<typeof schema>;

meta.yaml

1.6 KB

/designs/decision-record/source/meta.yaml

Show contents
id: decision-record
name:
  ja: 意思決定の記録
  en: Decision Record
purpose:
  ja: 決定・背景・選択肢・影響・見直し条件を1枚にまとめる。
  en: Decision Record with explicit source values and reading conditions.
status: published
still: ./still.png
category: decision
catalogOrder: 490
jobs:
  - assign-governance
useCases:
  - summary
layoutKinds:
  - 2-column
tags:
  - decision-record
  - decision
  - offline
  - responsive
whenToUse:
  - ja: 決定・背景・選択肢・影響・見直し条件を1枚にまとめる。
    en: Use to communicate decision record.
avoidWhen:
  - ja: 同じ条件・単位で比較できないデータには使わない
    en: Do not compare values with incompatible units, populations, or assumptions.
requiredInputs:
  - ja: 提案と採択を区別し、決定者と見直し条件を残す。
    en: Provide the source values, labels and decision conditions described by the schema.
relatedLayouts:
  - options-tradeoff
  - assumption-evidence
dataSchema:
  title: string — 結論を伝える見出し
  subtitle: string? — 出典・時点・母集団や仮定
  decisionId: string — 決定の識別子
  status: string — 提案・採択・置換済み
  date: string — 決定または提案日
  owner: string — 決定責任者
  context: string — 背景と制約
  decision: string — 決定内容
  consequences: array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) — 引き受ける影響
  alternatives: array (0, 1, 2, 3, 4, 5, 6, 7) — 検討した代案
  revisit: string — 見直しの条件
sources: []

sample-data.json

826 B

/designs/decision-record/source/sample-data.json

Show contents
{
  "title": "受付の移行を先行し、審査基盤は継続する",
  "subtitle": "架空サンプル|レイアウトの使用例",
  "decisionId": "ADR-018",
  "status": "proposed",
  "date": "2026-09-08",
  "owner": "業務・IT合同会議",
  "context": "年度内に受付体験を改善する必要がある。審査基盤は次年度更改を計画。",
  "decision": "申込受付と進捗照会を先行移行し、審査基盤とはAPIで連携する。",
  "consequences": [
    "並行運用期間のデータ整合性を監視する",
    "審査側の変更を最小化できる",
    "移行後もAPIの保守責任が残る"
  ],
  "alternatives": [
    "全領域の一括更改",
    "現行UIのみ改善"
  ],
  "revisit": "API障害が月3件を超える場合、連携方式を再評価する"
}