human-product · Stage 3
読者の判断を支える設計文書とADRを構成する
同じ技術判断を、経営読者向けの短い要約と実装者向けの検証可能な付録へ分け、代替案、リスク、決定証拠を失わずに伝える。
到達目標
読者の責務と必要な判断から情報階層、用語、詳細度を設計できる
- 読者別の要約、代替案、リスク、決定を含む設計文書
- 要約、技術付録、ADRの役割と相互参照を説明する5分発表
代替案、評価基準、リスク、決定、検証を一つの追跡可能な文書へ結べる
- 読者別の要約、代替案、リスク、決定を含む設計文書
- 読者、根拠、代替案、リスク、検証の欠落を診断する回答
決定証拠を変えず、異なる読者が次の行動を取れる表現へ再構成できる
- 読者、根拠、代替案、リスク、検証の欠落を診断する回答
- 同じ決定証拠を経営読者向けから実装者向けへ再構成した記録
能力の進行
recognize
事実、推測、選択肢、決定、検証を文書内で区別できる
証拠: 読者別の要約、代替案、リスク、決定を含む設計文書
explain
one-page executive summary、technical appendix、ADRが別々に必要な理由を説明できる
証拠: 要約、技術付録、ADRの役割と相互参照を説明する5分発表
apply
読者の判断に必要な結論を先に置き、代替案と証拠へ追跡可能にできる
証拠: 読者別の要約、代替案、リスク、決定を含む設計文書
diagnose
要約と付録のdecision drift、未定義語、検証不能な断定を発見できる
証拠: 読者、根拠、代替案、リスク、検証の欠落を診断する回答
lead
複数職能が同じ証拠を参照し、決定と再評価条件を更新できる文書運用を主導できる
証拠: 同じ決定証拠を経営読者向けから実装者向けへ再構成した記録
なぜ重要か
設計文書の目的は、書き手の知識を保存することではなく、特定の読者が根拠を検査して次の行動を選べるようにすることである。経営読者には投資、期限、主要risk、承認事項が必要で、実装読者にはinterface、migration、失敗条件、validationが必要になる。しかし、両者が参照するalternatives、評価証拠、decisionは同じでなければならない。
このレッスンでは、one-page executive summary、technical appendix、ADRを重複文書ではなく一つの判断証拠に対する三つのviewとして設計する。plain languageは専門性を消す手法ではない。主語、行動、条件、未知を明示し、必要なtechnical detailへ到達できる情報設計である。
メンタルモデル
先に「誰が、何を判断し、読後に何をするか」を置く。次に、全読者で共有するdecision evidenceを一つだけ作り、読者ごとに順序と詳細度を変える。要約は結果と承認事項から始め、付録は再現手順と境界を、ADRはcontext、decision、alternatives、consequences、risks、validationの履歴を保持する。
情報量を減らす時も根拠との接続は切らない。「詳しくは付録」だけでは弱い。どのrisk、どの代替案、どのvalidationへ進むかを見出しと識別子で追えるようにする。未知は削除せず、仮定、owner、期限を付ける。
注記
図を読む際の補足情報です。
- Audience:
- Evidence:
- Decision:
- Executive view:
- Implementation view:
- Drift check: 要約、付録、ADRが同じdecisionを指すか検査する。
同じdecision evidenceを読者別viewへどう入れ子にし、driftを防ぐか。
- Decision record
- 選定結果、負うconsequence、再評価条件を明示する。
- Audience
- 責務、判断、既知の用語、時間制約を定義する。
- Executive view
- 結論、価値、主要risk、承認依頼を一頁へ収める。
- Implementation view
- interface、migration、rollback、validationを付録へ置く。
- Evidence
- 評価基準、入力、代替案、risk、検証結果を固定する。
- 代替案と基準
- 採用案だけでなく比較対象と評価基準を保持する。
- 検証と再評価
- 結果の確認方法とdecisionを開き直す条件を保持する。
共通decision recordの下にevidenceと読者別viewを置き、executiveとimplementationの詳細度だけを変えて同じdecisionを参照すると説明できる。
動く例で考える
通知基盤の選定を三つのviewへ変換する
- 前提
- lesson-defined synthetic scenarioとして、managed、self-hosted、hybridの三案をdelivery、operations、cost、reversibilityで比較する。実組織の見積りやproduction測定ではない。
- 入力
- 重みの合計を1.0とし、各案を1〜5で評価する。読者はbaselineではexecutive、transferではimplementerとする。評価入力、alternatives、risk、validation evidenceは変えない。
- 操作
- weighted scoreを計算し最高案をdecisionとする。one-page executive summary、technical appendix、ADRを同じdecisionから生成し、必須fieldと文書間driftを検査する。
- 観測
- 要約は1頁、80語以内となり、付録は全代替案、主要risk、検証証拠を保持する。audienceだけを変えても選定結果とdecision evidenceは一致する。
- 結論
- 短さは目的ではない。読者が必要な判断へ最短で到達し、その判断を同じ証拠から反証できることがtechnical communicationの品質である。
python3.13 - <<'PY'
import json
HARNESS = "technical_communication_lab_v1"
CRITERIA = {
"delivery": {"weight": 0.30, "meaning": "価値提供までの速さ"},
"operations": {"weight": 0.30, "meaning": "運用負荷の小ささ"},
"cost": {"weight": 0.20, "meaning": "予測可能な総費用"},
"reversibility": {"weight": 0.20, "meaning": "撤退と移行の容易さ"},
}
OPTION_FIXTURE = [
{
"id": "managed",
"ratings": {
"delivery": 5,
"operations": 5,
"cost": 3,
"reversibility": 4,
},
"risks": ["provider dependency", "egress cost"],
},
{
"id": "self-hosted",
"ratings": {
"delivery": 2,
"operations": 2,
"cost": 4,
"reversibility": 5,
},
"risks": ["on-call load", "capacity ownership"],
},
{
"id": "hybrid",
"ratings": {
"delivery": 3,
"operations": 3,
"cost": 3,
"reversibility": 4,
},
"risks": ["dual operation", "migration drift"],
},
]
REQUIRED_ADR_FIELDS = [
"context",
"decision",
"alternatives",
"consequences",
"risks",
"validation",
]
EXECUTIVE_TEXT = (
"Select managed delivery for the first release. "
"It has the strongest weighted evidence for delivery and operations. "
"Approve a reversible pilot, an egress cost limit, and a migration exit test. "
"The team will stop expansion if either guardrail fails."
)
TRANSFER_TASK = (
"経営読者から実装読者へaudienceだけを変え、同じ決定証拠を"
"再構成する"
)
def score_options(options):
scored = []
for option in options:
# 重み付きscoreを入力から導出し、要約だけを変えて結論を
# 書き換えられないようにする。
weighted_score = sum(
option["ratings"][criterion_id] * criterion["weight"]
for criterion_id, criterion in CRITERIA.items()
)
scored.append(
{
"id": option["id"],
"ratings": option["ratings"],
"weighted_score": weighted_score,
"risks": option["risks"],
}
)
return scored
def validate_adr(document):
missing_fields = [
field
for field in REQUIRED_ADR_FIELDS
if not document.get(field)
]
return {
"valid": not missing_fields,
"required_fields": REQUIRED_ADR_FIELDS,
"missing_fields": missing_fields,
}
def build_audience_view(audience, decision):
if audience == "executive":
sections = [
"reader-outcome",
"selected-option",
"business-risk",
"approval-request",
]
reader_outcome = "pilot承認とcost guardrailのowner決定"
elif audience == "implementer":
sections = [
"selected-option",
"interface-boundary",
"migration-sequence",
"rollback",
"validation-evidence",
]
reader_outcome = "pilot実装、exit test、rollback準備の開始"
else:
raise ValueError("unsupported-audience")
# audienceごとに構成は変えるが、decision evidenceは同じ入力から
# 再構成し、要約だけで選定根拠を書き換えられないようにする。
decision_evidence = {
"evidence_id": decision["evidence_id"],
"criteria_ids": sorted(decision["criteria"]),
"option_scores": [
{
"id": option["id"],
"weighted_score": option["weighted_score"],
}
for option in decision["options"]
],
}
return {
"audience": audience,
"decision": decision["selected_option"],
"decision_evidence": decision_evidence,
"sections": sections,
"reader_outcome": reader_outcome,
}
def main():
options = score_options(OPTION_FIXTURE)
selected_option = max(
options,
key=lambda option: option["weighted_score"],
)["id"]
decision = {
"criteria": CRITERIA,
"options": options,
"selected_option": selected_option,
"evidence_id": "notification-platform-comparison-v1",
}
baseline_view = build_audience_view("executive", decision)
transferred_view = build_audience_view("implementer", decision)
summary = {
"audience": baseline_view["audience"],
"page_budget": 1,
"word_limit": 80,
"word_count": len(EXECUTIVE_TEXT.split()),
"decision": selected_option,
"reader_outcome": baseline_view["reader_outcome"],
"text": EXECUTIVE_TEXT,
"audience_view": baseline_view,
}
appendix_decision = decision["selected_option"]
technical_appendix = {
"audience": transferred_view["audience"],
"alternatives": options,
"decision": appendix_decision,
"risks": [
risk
for option in options
for risk in option["risks"]
],
"validation_evidence": [
"synthetic weighted comparison",
"reversible pilot plan",
"exit test specification",
],
"audience_view": transferred_view,
}
adr_document = {
"context": "初回releaseの通知基盤を選ぶ",
"decision": selected_option,
"alternatives": [option["id"] for option in options],
"consequences": ["delivery短縮", "provider dependencyを受容"],
"risks": technical_appendix["risks"],
"validation": technical_appendix["validation_evidence"],
}
# 三つのviewが同じ決定を指すことを実行時不変条件にし、
# copy-and-pasteによる静かなdecision driftを失敗へ変える。
assert (
summary["decision"]
== appendix_decision
== adr_document["decision"]
), "communication-causal-invariant"
assert (
baseline_view["audience"] != transferred_view["audience"]
and baseline_view["sections"] != transferred_view["sections"]
and baseline_view["decision"] == transferred_view["decision"]
and baseline_view["decision_evidence"]
== transferred_view["decision_evidence"]
), "communication-audience-invariant"
audience_transfer = {
"changed_assumption": "audience",
"changed_fields": ["audience"],
"baseline_audience": baseline_view["audience"],
"transferred_audience": transferred_view["audience"],
"baseline_decision": baseline_view["decision"],
"transferred_decision": transferred_view["decision"],
"decision_evidence_unchanged": (
baseline_view["decision_evidence"]
== transferred_view["decision_evidence"]
),
"audience_specific_content_differs": (
baseline_view["sections"] != transferred_view["sections"]
),
"baseline_view": baseline_view,
"transferred_view": transferred_view,
}
report = {
"fixture_metadata": {
"kind": "synthetic",
"provenance": "lesson-defined synthetic scenario",
"limitations": (
"評価値と文章量は教材用であり実組織の承認を表さない"
),
},
"decision": decision,
"one_page_executive_summary": summary,
"technical_appendix": technical_appendix,
"adr_validation": validate_adr(adr_document),
"audience_transfer": audience_transfer,
"runtime_bound": {
"records": len(options) + len(CRITERIA) + len(REQUIRED_ADR_FIELDS),
"subprocesses": 0,
},
"mastery_evidence": {
"lab_steps": [
{"step": 1, "evidence": "audienceとreader outcome"},
{"step": 2, "evidence": "criteriaとweighted score"},
{"step": 3, "evidence": "one-page executive summary"},
{"step": 4, "evidence": "appendixとADR validation"},
{"step": 5, "evidence": "audience transfer"},
],
"assessments": [
{"assessment": 1, "evidence": "decision drift検査"},
{"assessment": 2, "evidence": "実装者向けvalidation情報"},
],
"rubric_dimensions": [
"technical-correctness",
"judgment",
"evidence",
"communication",
],
"transfer": {
"task": TRANSFER_TASK,
"changed_assumption": "audience",
"evidence": "決定証拠を維持した読者別再構成",
},
},
"external_network_used": False,
}
assert report["adr_validation"]["valid"], "adr-required-fields"
assert (
report["one_page_executive_summary"]["word_count"]
<= report["one_page_executive_summary"]["word_limit"]
), "executive-page-budget"
print(json.dumps(report, ensure_ascii=False, sort_keys=True))
main()
PY
トレードオフと失敗モード
| 状況 | 先に示す情報 | 残す証拠 | 失敗条件 |
|---|---|---|---|
| 経営判断 | 価値、decision、主要risk、承認事項 | 比較結果と再評価条件 | 結論はあるが次の行動がない |
| 実装開始 | interface、migration、validation | 付録とADRへの追跡 | 根拠と異なる仕様を実装する |
| 決定更新 | 変わった前提と新しい証拠 | 旧decisionとconsequences | 履歴を消して理由が失われる |
- 誤診: 誰も読まないのは文書が長いからだ。反証: 長さだけを削る前に、読者、必要なdecision、reader outcome、見出しから証拠までの経路を観察する。
- 誤診: ADR templateのfieldを埋めれば判断品質は保証される。反証: alternativesのscore、risk、validationを再計算し、要約と付録のdecision driftを検査する。
知識チェック
- 経営要約と実装付録で変えてよいもの、変えてはいけないものを一つずつ挙げよ。
- selected optionのscoreが最高でも、そのdecisionを採用してはいけない条件を二つ挙げよ。
- plain languageへ編集した結果、技術的な誤解が増えたことをどう検証するか。
- ADRのvalidation fieldへ、測定結果、rollback、再評価ownerをどう結ぶか。
出典と次の学習
architecture descriptionの構造はISO/IEC/IEEE 42010:2022、system decisionとverificationの考え方はNASA Systems Engineering Handbook Rev2、技術文書の表現はRFC 7322、ADRの最小構造はMADR 4.0.0、読者中心の表現はPlain language guide seriesを基準にした。いずれも文脈へ適用して検証するための一次資料または標準であり、形式だけを模写する根拠ではない。
次はcore20で、このdecisionがaffected peopleへ与えるuneven harm、data lifecycle、mitigation、residual riskを文書の制約へ追加する。
実践ラボ
通知基盤の選定を読者別の設計文書へまとめる
提出成果物: 読者別の要約、代替案、リスク、決定を含む設計文書
- 読者、必要な判断、読後に取る行動、用語境界を明示する
- 固定synthetic評価基準から三つの代替案のweighted scoreと選定結果を計算する
- one-page executive summaryへ結果、主要risk、承認依頼を収める
- technical appendixとADRへalternatives、consequences、validation evidenceを結ぶ
- 決定証拠を変えずaudienceだけを経営読者から実装読者へ変えて再構成する
説明して理解を確かめる
5分で、長い文書を短くするだけでは要約にならない理由と、plain languageを精度低下ではなく読者の次の行動を明確にする設計として説明する。
アセスメント
問い: 経営要約ではoption Aを推奨し、付録の比較表ではoption Bが最高点だった。どの証拠をどう直すか。
期待する証拠: 評価基準、score、decision、ADR、要約の追跡とdecision driftの修復
問い: 実装者が要約を読んでもmigrationとvalidationを開始できない。何を付録へ追加するか。
期待する証拠: 前提、interface、移行順序、失敗条件、rollback、検証owner、再評価条件
別問題へ転用する
経営読者から実装読者へaudienceだけを変え、同じ決定証拠を再構成する
復習スケジュール
- 1日後
要約と付録のdecisionが一致していることをどう検証するか
- 7日後
読者が変わっても変えてはいけない決定証拠は何か
- 30日後
plain languageと技術的精度を両立する編集を一つ説明する
- 90日後
要約と付録のdecisionが一致していることをどう検証するか
評価ルーブリック
| 観点 | 未達 | 発展途上 | 熟達 | 卓越 |
|---|---|---|---|---|
| technical-correctness | 結論だけを書き、用語、前提、代替案、検証が欠ける | 選択肢はあるが評価基準とdecisionの対応が曖昧である | 要約、付録、ADRで同じ代替案、risk、decision、validationを追跡できる | 前提変更時の再評価条件と文書間のdrift検査まで自動化する |
| judgment | 書き手が知っている情報を順番なく並べる | 読者を挙げるが必要な判断と情報量を対応させない | 読者の責務、判断、risk許容度から要約と付録の境界を選ぶ | 対立する読者要求を明示し、同じ証拠から複数の行動可能なviewを設計する |
| evidence | 権威や印象だけで選定を正当化する | scoreはあるが入力、尺度、validationの出自がない | 評価入力、weighted score、代替案、risk、validationを再計算可能に残す | 反証条件、再評価owner、decision drift検査を継続的な証拠へする |
| communication | 読者と次の行動が不明な長文を共有する | plain languageだが重要な制約かtechnical detailを失う | 結論を先に示し、読者別の詳細と共通の証拠を相互参照できる | 経営、product、実装、運用が一つの決定を異なる粒度で誤解なく更新できる |
出典
以下の外部資料は利用者が選択したときだけ開きます。