lead · Stage 5

時差と言語を越える非同期RFCを設計する

timezone、language、contextの非対称性を明示し、dissentと応答期限を記録したRFCでmeetingなしにレビュー可能な意思決定を作る。

学習時間
300分
難易度
advanced
更新日
2026-07-30
到達証拠
成果物・説明・判断根拠・転用

到達目標

  1. timezone、language、前提、応答期限をRFCへ埋め込み、非同期レビューのcontextを完成できる

    • 時差、言語、文脈差を越える非同期RFCと決定ログ
    • 言語能力やtimezoneを参加能力と誤認しないレビュー判断
  2. 異論を人格から分離して記録し、根拠あるresolutionをdecision logへ残せる

    • 異論、応答、理由、期限、決定者を追跡できるdecision log
    • consensusと全員一致を区別し、meeting不要な条件を説明する5分発表
  3. timezone overlapだけを変え、同じproposal evidenceでmeetingなしのレビュー可能性を再評価できる

    • 時差、言語、文脈差を越える非同期RFCと決定ログ
    • timezone overlapを4時間から0時間へ変えた同一proposalの再構成

能力の進行

  1. recognize

    timezone、language、context、authorityの非対称性を識別できる

    証拠: 時差、言語、文脈差を越える非同期RFCと決定ログ

  2. explain

    consensus、投票、全員一致、沈黙の違いを説明できる

    証拠: consensusと全員一致を区別し、meeting不要な条件を説明する5分発表

  3. apply

    RFC section、応答期限、dissent responseを再現可能なdecision logへ組み立てられる

    証拠: 時差、言語、文脈差を越える非同期RFCと決定ログ、異論、応答、理由、期限、決定者を追跡できるdecision log

  4. diagnose

    meeting依存、暗黙context、言語によるstatus差、異論の消去を反証できる

    証拠: 言語能力やtimezoneを参加能力と誤認しないレビュー判断

  5. lead

    zero-overlapでも別のcontributorが判断根拠を再検証できる協働境界を運営できる

    証拠: timezone overlapを4時間から0時間へ変えた同一proposalの再構成

なぜ重要か

世界規模の協働では、同じ時間に集まれる人、会議のlanguageを速く話せる人、背景contextをすでに知る人だけが意思決定を支配しやすい。timezone overlapが小さいほど、会議の開催をcommand successとして数える運営は、検証可能なsystem outcomeから離れる。

RFC 7282はrough consensusを単純な投票や全員一致から区別し、重大な異論を理解して扱うことを重視する。RFC 7322は読者が一貫して解釈できる明確な文書を求める。W3Cの18 August 2025 ProcessとCall for Consensusも、応答期間と異論の処理を意思決定の一部として扱う。

メンタルモデル

非同期RFCを、情報を配る文書ではなく、別の時間帯にいるcontributorが判断を独立再実行するinterfaceとして設計する。結論より先にproblem、alternatives、evidence、risksを置き、dissentとresponse-windowを閉じない。

同期イベントではなくreview evidenceで選ぶdecision table
観測 判断 必要な次の証拠
contextと期限が完全 非同期reviewを継続 dissentへのreasoned response
暗黙の前提が残る decisionを保留 用語、owner、制約、反証条件
重大なdissentが未処理 consensusと呼ばない 影響、代替案、採否理由
proposal contextからreasoned decisionへ進む非同期review chain

timezone overlapがなくてもdissentと採否理由を第三者が再評価できる記録は何か。

  1. 文脈

    判断範囲、代替案、参加条件を文書へ揃える。

    1. Frame

      problem、decision rights、対象外を固定する。

      順序: 0

    2. Expose

      alternatives、evidence、uncertaintyを同じ文書に置く。

      順序: 1

    3. Include

      timezone、working language、用語、UTC期限を示す。

      順序: 2

  2. レビュー

    安全なresponse windowで異論と応答を追跡する。

    1. Invite

      dissentを安全に記録するresponse-windowを開く。

      順序: 3

    2. Resolve

      異論ごとのresponseと採否理由を残す。

      順序: 4

  3. 決定

    第三者がmeetingなしで再評価できる形にする。

    1. Replay

      meeting unnecessaryな状態で第三者が判断を再評価する。

      順序: 5

decision rights、evidence、参加条件、response window、異論への応答を再生可能なdecision logへ結べる。

動く例で考える

timezone overlapを4時間から0時間へ変える

前提
2人のreviewerが同じsimulated proposalを評価する。能力や文化を推定せず、入力されたtimezoneとworking languageだけを参加設計に使う。
入力
7つのRFC section、proposal evidence、2人のparticipant、UTC response deadline、baseline 4時間とtransfer 0時間のoverlapを与える。
操作
schemaとsection順をfail-closedで検証し、context completeness、dissent response、meeting necessityを同じ入力から導く。
観測
overlapが0時間でもproposal evidence、working language、deadline、異論へのresponseが維持され、reviewはmeetingなしで完了する。
結論
文書生成のcommand successは合意というsystem outcomeではない。異論が記録され、addressedで、別のcontributorが理由を再評価できることが成果である。
python3.13 - <<'PY'
import json

HARNESS = "async_rfc_decision_lab_v1"
BASELINE_ASYNC_CONTEXT = {
    "timezone_overlap_hours": 4,
    "working_language": "plain-English",
}
TRANSFER_ASYNC_CONTEXT = {
    "timezone_overlap_hours": 0,
    "working_language": "plain-English",
}
PROPOSAL = {
    "proposal_id": "rfc-async-deploy-window",
    "problem": "release decision depends on a regional meeting",
    "decision": "use an evidence-bound asynchronous review window",
    "alternatives": [
        "keep a rotating meeting",
        "delegate without a review record",
    ],
    "evidence": [
        "same proposal snapshot",
        "UTC response deadline",
        "independent reviewer acknowledgement",
    ],
    "risks": [
        "missing implicit operational context",
        "silence misread as agreement",
    ],
    "dissent": {
        "dissent_id": "dissent-rollback-authority",
        "concern": "rollback authority is unclear",
        "response": "name the incident commander and fallback owner",
        "resolution": "accepted and added to the decision record",
    },
    "response_deadline_utc": "2026-08-03T09:00:00Z",
}
PARTICIPANTS = [
    {
        "participant_id": "reviewer-alpha",
        "timezone": "UTC+09:00",
        "working_language": "plain-English",
        "acknowledged": True,
        "availability": {
            "baseline_local_hours": [9, 13],
            "transferred_local_hours": [9, 13],
        },
    },
    {
        "participant_id": "reviewer-bravo",
        "timezone": "UTC-07:00",
        "working_language": "plain-English",
        "acknowledged": True,
        "availability": {
            "baseline_local_hours": [17, 21],
            "transferred_local_hours": [9, 13],
        },
    },
]
RFC_SECTION_ORDER = (
    "problem",
    "decision",
    "alternatives",
    "evidence",
    "risks",
    "dissent",
    "response-window",
)
ASYNC_CONTEXT_FIELDS = {
    "timezone_overlap_hours",
    "working_language",
}
PROPOSAL_FIELDS = {
    "proposal_id",
    "problem",
    "decision",
    "alternatives",
    "evidence",
    "risks",
    "dissent",
    "response_deadline_utc",
}
DISSENT_FIELDS = {
    "dissent_id",
    "concern",
    "response",
    "resolution",
}
PARTICIPANT_FIELDS = {
    "participant_id",
    "timezone",
    "working_language",
    "acknowledged",
    "availability",
}
AVAILABILITY_FIELDS = {
    "baseline_local_hours",
    "transferred_local_hours",
}

def is_number(value):
    return type(value) in {int, float} and type(value) is not bool

def validate_async_context(context):
    valid = (
        type(context) is dict
        and set(context) == ASYNC_CONTEXT_FIELDS
        and is_number(context["timezone_overlap_hours"])
        and 0 <= context["timezone_overlap_hours"] <= 24
        and type(context["working_language"]) is str
        and bool(context["working_language"])
    )
    if not valid:
        raise AssertionError(
            "async-transfer-invariant: invalid async context schema"
        )

def changed_fields(baseline, transferred):
    validate_async_context(baseline)
    validate_async_context(transferred)
    changed = [
        field
        for field in sorted(set(baseline) | set(transferred))
        if baseline.get(field) != transferred.get(field)
    ]
    if changed != ["timezone_overlap_hours"]:
        raise AssertionError(
            "async-transfer-invariant: transfer changed wrong input"
        )
    return changed

def validate_proposal(proposal):
    valid = (
        type(proposal) is dict
        and set(proposal) == PROPOSAL_FIELDS
        and all(
            type(proposal[field]) is str and bool(proposal[field])
            for field in {
                "proposal_id",
                "problem",
                "decision",
                "response_deadline_utc",
            }
        )
        and all(
            type(proposal[field]) is list
            and bool(proposal[field])
            and all(type(item) is str and bool(item) for item in proposal[field])
            for field in {"alternatives", "evidence", "risks"}
        )
        and type(proposal["dissent"]) is dict
        and set(proposal["dissent"]) == DISSENT_FIELDS
        and all(
            type(value) is str and bool(value)
            for value in proposal["dissent"].values()
        )
        and proposal["response_deadline_utc"].endswith("Z")
    )
    if not valid:
        raise AssertionError(
            "async-input-invariant: invalid proposal schema"
        )

def validate_participants(participants):
    valid = (
        type(participants) is list
        and bool(participants)
        and all(
            type(participant) is dict
            and set(participant) == PARTICIPANT_FIELDS
            and all(
                type(participant[field]) is str and bool(participant[field])
                for field in {
                    "participant_id",
                    "timezone",
                    "working_language",
                }
            )
            and type(participant["acknowledged"]) is bool
            and type(participant["availability"]) is dict
            and set(participant["availability"])
            == AVAILABILITY_FIELDS
            and all(
                type(window) is list
                and len(window) == 2
                and all(type(hour) is int for hour in window)
                and 0 <= window[0] < window[1] <= 24
                for window in participant["availability"].values()
            )
            for participant in participants
        )
        and len(
            {participant["participant_id"] for participant in participants}
        ) == len(participants)
    )
    if not valid:
        raise AssertionError(
            "async-input-invariant: invalid participant schema"
        )

def timezone_offset_hours(timezone):
    valid = (
        type(timezone) is str
        and len(timezone) == 9
        and timezone.startswith("UTC")
        and timezone[3] in {"+", "-"}
        and timezone[6] == ":"
        and timezone[4:6].isdigit()
        and timezone[7:9] == "00"
    )
    if not valid:
        raise AssertionError(
            "async-timezone-invariant: invalid timezone"
        )
    magnitude = int(timezone[4:6])
    if magnitude > 14:
        raise AssertionError(
            "async-timezone-invariant: timezone out of range"
        )
    return magnitude if timezone[3] == "+" else -magnitude

def derive_overlap_hours(participants, window_field):
    utc_windows = []
    for participant in participants:
        offset = timezone_offset_hours(participant["timezone"])
        local_window = participant["availability"][window_field]
        utc_start = (local_window[0] - offset) % 24
        utc_end = utc_start + (local_window[1] - local_window[0])
        if not (0 <= utc_start < utc_end <= 24):
            raise AssertionError(
                "async-timezone-invariant: window crosses UTC day"
            )
        utc_windows.append([utc_start, utc_end])
    overlap = min(window[1] for window in utc_windows) - max(
        window[0] for window in utc_windows
    )
    return max(0, overlap)

def response_window_hours(overlap_hours):
    return 24 if overlap_hours == 0 else 8

def validate_section_order():
    expected = (
        "problem",
        "decision",
        "alternatives",
        "evidence",
        "risks",
        "dissent",
        "response-window",
    )
    if RFC_SECTION_ORDER != expected:
        raise AssertionError(
            "async-order-invariant: invalid RFC section order"
        )

def validate_all_inputs():
    validate_async_context(BASELINE_ASYNC_CONTEXT)
    validate_async_context(TRANSFER_ASYNC_CONTEXT)
    validate_proposal(PROPOSAL)
    validate_participants(PARTICIPANTS)
    validate_section_order()
    baseline_overlap = derive_overlap_hours(
        PARTICIPANTS,
        "baseline_local_hours",
    )
    transferred_overlap = derive_overlap_hours(
        PARTICIPANTS,
        "transferred_local_hours",
    )
    if (
        baseline_overlap
        != BASELINE_ASYNC_CONTEXT["timezone_overlap_hours"]
        or transferred_overlap
        != TRANSFER_ASYNC_CONTEXT["timezone_overlap_hours"]
    ):
        raise AssertionError(
            "async-timezone-invariant: overlap not availability-derived"
        )

def evaluate_context_completeness(review_input):
    proposal = review_input["proposal"]
    participants = review_input["participants"]
    context = review_input["context"]
    complete = (
        bool(proposal["problem"])
        and bool(proposal["decision"])
        and bool(proposal["alternatives"])
        and bool(proposal["evidence"])
        and bool(proposal["risks"])
        and bool(proposal["response_deadline_utc"])
        and bool(context["working_language"])
        and all(
            participant["acknowledged"]
            and participant["working_language"]
            == context["working_language"]
            for participant in participants
        )
    )
    return "complete" if complete else "incomplete"

def evaluate_dissent(review_input):
    dissent = review_input["proposal"]["dissent"]
    addressed = (
        bool(dissent["concern"])
        and bool(dissent["response"])
        and bool(dissent["resolution"])
        and "accepted" in dissent["resolution"]
    )
    return "addressed" if addressed else "unaddressed"

def evaluate_meeting_need(context_complete):
    meeting_required = not context_complete
    if meeting_required is not (not context_complete):
        raise AssertionError(
            "async-context-invariant: meeting derivation bypassed"
        )
    return meeting_required

def evaluate_review(
    proposal,
    participants,
    context,
    derived_overlap,
    derived_response_window,
):
    review_input = {
        "proposal": proposal,
        "participants": participants,
        "context": context,
    }
    context_complete = evaluate_context_completeness(
        review_input
    )
    if context_complete != "complete":
        raise AssertionError(
            "async-context-invariant: context derivation bypassed"
        )
    context_complete = context_complete == "complete"
    dissent_addressed = evaluate_dissent(
        review_input
    )
    if dissent_addressed != "addressed":
        raise AssertionError(
            "async-dissent-invariant: dissent derivation bypassed"
        )
    meeting_required = evaluate_meeting_need(context_complete)
    if (
        derived_overlap != context["timezone_overlap_hours"]
        or derived_response_window
        != response_window_hours(derived_overlap)
        or evaluate_meeting_need(False) is not True
    ):
        raise AssertionError(
            "async-timezone-invariant: async window derivation bypassed"
        )
    return {
        "context_complete": context_complete,
        "dissent_addressed": dissent_addressed == "addressed",
        "meeting_required": meeting_required,
        "derived_overlap_hours": derived_overlap,
        "response_window_hours": derived_response_window,
    }

def main():
    validate_all_inputs()
    changed = changed_fields(
        BASELINE_ASYNC_CONTEXT,
        TRANSFER_ASYNC_CONTEXT,
    )
    proposal = json.loads(
        json.dumps(PROPOSAL, ensure_ascii=False)
    )
    transferred_proposal = json.loads(
        json.dumps(PROPOSAL, ensure_ascii=False)
    )
    participants = json.loads(
        json.dumps(PARTICIPANTS, ensure_ascii=False)
    )
    transferred_participants = json.loads(
        json.dumps(PARTICIPANTS, ensure_ascii=False)
    )
    baseline_context = json.loads(
        json.dumps(BASELINE_ASYNC_CONTEXT, ensure_ascii=False)
    )
    transferred_context = json.loads(
        json.dumps(TRANSFER_ASYNC_CONTEXT, ensure_ascii=False)
    )
    validate_proposal(proposal)
    validate_proposal(transferred_proposal)
    validate_participants(participants)
    validate_participants(transferred_participants)
    baseline_overlap = derive_overlap_hours(
        participants,
        "baseline_local_hours",
    )
    transferred_overlap = derive_overlap_hours(
        transferred_participants,
        "transferred_local_hours",
    )
    baseline_response_window = response_window_hours(
        baseline_overlap
    )
    transferred_response_window = response_window_hours(
        transferred_overlap
    )
    baseline_review = evaluate_review(
        proposal,
        participants,
        baseline_context,
        baseline_overlap,
        baseline_response_window,
    )
    transferred_review = evaluate_review(
        transferred_proposal,
        transferred_participants,
        transferred_context,
        transferred_overlap,
        transferred_response_window,
    )
    same_proposal_evidence = (
        proposal == transferred_proposal
        and participants == transferred_participants
    )
    if not same_proposal_evidence:
        raise AssertionError(
            "async-transfer-invariant: proposal evidence drifted"
        )
    zero_overlap_review_completed = (
        transferred_context["timezone_overlap_hours"] == 0
        and transferred_review["context_complete"]
        and transferred_review["dissent_addressed"]
        and not transferred_review["meeting_required"]
    )
    if not zero_overlap_review_completed:
        raise AssertionError(
            "async-transfer-invariant: zero overlap review incomplete"
        )

    report = {
        "harness": HARNESS,
        "async_rfc": {
            "context_complete": baseline_review["context_complete"],
            "meeting_required": baseline_review["meeting_required"],
            "meeting_need_derived_from_context": (
                baseline_review["meeting_required"]
                == (not baseline_review["context_complete"])
            ),
            "derived_timezone_overlap_hours": baseline_overlap,
            "response_window_hours": baseline_response_window,
            "sections": list(RFC_SECTION_ORDER),
            "timezone_context": baseline_context,
            "language_context": baseline_context["working_language"],
            "response_deadline": proposal["response_deadline_utc"],
        },
        "decision_log": {
            "dissent_recorded": bool(proposal["dissent"]["concern"]),
            "dissent_addressed": baseline_review["dissent_addressed"],
            "reasoned_resolution": proposal["dissent"]["resolution"],
            "reviewable_without_meeting": (
                baseline_review["context_complete"]
                and baseline_review["dissent_addressed"]
                and not baseline_review["meeting_required"]
            ),
        },
        "timezone_overlap_transfer": {
            "changed_assumption": "timezone-overlap",
            "changed_fields": changed,
            "same_proposal_evidence": same_proposal_evidence,
            "zero_overlap_review_completed": zero_overlap_review_completed,
            "derived_baseline_overlap_hours": baseline_overlap,
            "derived_transferred_overlap_hours": transferred_overlap,
            "baseline_response_window_hours": (
                baseline_response_window
            ),
            "transferred_response_window_hours": (
                transferred_response_window
            ),
            "baseline_context": baseline_context,
            "transferred_context": transferred_context,
        },
        "fixture_metadata": {
            "kind": "simulated",
            "provenance": "lesson-defined asynchronous RFC fixture",
            "limitations": (
                "not evidence about any culture, language group, or person"
            ),
            "synthetic_or_observed_explicit": True,
            "hidden_assumption": (
                "acknowledgement means the record was received, not agreement"
            ),
        },
        "input_derived_evidence": {
            "proposal_id": proposal["proposal_id"],
            "participant_count": len(participants),
            "response_deadline": proposal["response_deadline_utc"],
        },
        "runtime_bound": {
            "records": (
                len(participants)
                + len(proposal["alternatives"])
                + len(proposal["evidence"])
                + len(proposal["risks"])
            ),
            "subprocesses": 0,
            "maximum_iterations": (
                len(participants) + len(RFC_SECTION_ORDER)
            ),
        },
        "external_network_used": False,
        "command_success_distinction": {
            "command_completed": True,
            "system_outcome_checked": (
                baseline_review["context_complete"]
                and baseline_review["dissent_addressed"]
            ),
            "command_success_equals_system_outcome": False,
            "outcome_evidence": {
                "dissent_id": proposal["dissent"]["dissent_id"],
                "reviewers": [
                    item["participant_id"] for item in participants
                ],
            },
        },
        "mastery_evidence": {
            "lab_steps": [
                {"step": 1, "evidence": baseline_context},
                {"step": 2, "evidence": list(RFC_SECTION_ORDER)},
                {"step": 3, "evidence": proposal["dissent"]},
                {"step": 4, "evidence": baseline_review},
                {"step": 5, "evidence": transferred_review},
            ],
            "assessments": [
                {
                    "assessment": 1,
                    "evidence": "silence is not recorded as agreement",
                },
                {
                    "assessment": 2,
                    "evidence": baseline_review,
                },
            ],
            "rubric_dimensions": [
                "technical-correctness",
                "judgment",
                "evidence",
                "communication",
            ],
            "transfer": {
                "task": (
                    "timezone overlapだけを4時間から0時間へ変え、"
                    "同じproposalをmeetingなしでレビューできるRFCと"
                    "決定ログへ再構成する"
                ),
                "changed_assumption": "timezone-overlap",
                "evidence": {
                    "baseline": baseline_review,
                    "transferred": transferred_review,
                },
            },
            "contributor_enablement": {
                "other_contributor": "reviewer-bravo",
                "review_evidence": proposal["evidence"],
            },
        },
    }
    print(json.dumps(report, ensure_ascii=False, separators=(",", ":")))

if __name__ == "__main__":
    try:
        main()
    except AssertionError as error:
        raise SystemExit(str(error)) from None
PY

トレードオフと失敗モード

非同期化は記録と参加機会を増やす一方、文書作成時間と応答latencyを増やす。すべてをRFCにせず、不可逆性、影響範囲、異論の可能性に応じて記録量とresponse-windowを調整する。

  • 誤診: 返答がないのでconsensusである。反証: timezone、通知到達、language、期限理解を確認し、沈黙を賛成票に変換しない。
  • 誤診: meetingで全員が頷いたので判断はreview可能である。反証: alternatives、evidence、dissent responseが記録されなければ第三者は独立再評価できない。
  • 失敗モード: plain languageを情報量の削減と取り違える。用語を定義し、制約とuncertaintyを残したまま文を短くする。
  • 失敗モード: すべてのdissentを解消済みに見せる。未解決の懸念、owner、観測条件、再検討日をdecision logに保持する。

知識チェック

  1. 4時間のtimezone overlapを0時間へ変えるとき、proposal evidenceまで変えてはいけないのはなぜか。
  2. Call for Consensusのresponse-windowと沈黙による同意はどう違うか。
  3. meeting unnecessaryでもsystem outcomeを確認できる証拠を3つ挙げよ。
  4. dissentがrecordedだがaddressedではない具体例を作り、次のactionを説明せよ。

出典と次の学習

一次規範としてRFC 7282、RFC 7322、W3C 18 August 2025 Processを読み、W3C GuidebookのThe Art of ConsensusでCall for Consensusと異論処理の実務を確認する。

次に、自分の直近のdesign decisionをこの7 sectionへ再構成する。別timezoneのcontributorに同期説明をせず、曖昧なcontext、未処理のdissent、期限の解釈差をreview evidenceとして返してもらう。

実践ラボ

4時間のtimezone overlapを0時間へ変えてRFCを再評価する

提出成果物: 時差、言語、文脈差を越える非同期RFCと決定ログ

  1. proposal、participant、timezone、working languageのfixtureと限界を固定する
  2. problemからresponse-windowまでのRFC sectionと応答期限を構成する
  3. dissentを記録し、evidenceに基づくresponseとreasoned resolutionを残す
  4. meetingの成否ではなくcontext completenessとreview evidenceを検証する
  5. timezone overlapだけを4時間から0時間へ変えて同じproposalを再評価する

説明して理解を確かめる

5分で、RFC 7282のrough consensus、RFC 7322の明確な文書、W3CのCall for Consensusを、全員一致や沈黙の同意ではなく検証可能な非同期判断へ結ぶ。

アセスメント

  1. 問い: 期限まで返答がないparticipantを賛成として数えてよいか。

    期待する証拠: timezone、通知到達、language context、response deadline、明示的dissent、decision rule

  2. 問い: meetingでは合意したがalternativesと異論へのresponseが残っていない。system outcomeをどう判定するか。

    期待する証拠: command successとの区別、context completeness、reasoned resolution、reviewable record

別問題へ転用する

timezone overlapだけを4時間から0時間へ変え、同じproposalをmeetingなしでレビューできるRFCと決定ログへ再構成する

復習スケジュール

  1. 1日後

    meetingを開かずにcontext completenessを判定する最小証拠は何か

  2. 7日後

    dissentを記録しただけではaddressedにならない理由は何か

  3. 30日後

    timezone overlapが0時間のときresponse-windowをどう設計するか

  4. 90日後

    meetingを開かずにcontext completenessを判定する最小証拠は何か

評価ルーブリック

4段階の評価基準
観点未達発展途上熟達卓越
technical-correctness結論だけを書き、前提、alternatives、期限がないsectionはあるがtimezone、language、dissentが判断へ結び付かない全section、participant context、応答期限、異論とresponseを同じ入力から導く順序、schema、changed fieldを検証し、zero-overlapでも同じ結果を再現できる
judgmentmeeting参加または沈黙を合意とみなす異論を集めるが重要度やresponseを記録しない重大な異論を根拠で解消または未解決としてdecision logへ残す文化、言語、権限の非対称性を補正し、少数意見から決定を更新できる
evidence会議を実施した事実だけを示す文書はあるがinput provenanceとdecision ruleがないproposal、alternatives、evidence、dissent、response、deadlineを監査可能に残す別timezoneのcontributorが同期説明なしで判断を独立再評価できる
communication暗黙知、略語、local timeだけで伝える平易だが読者、用語、期限の基準が曖昧であるplain language、UTC基準、用語、owner、response-windowを明示する翻訳可能性と心理的安全性を保ち、異論が意思決定品質を上げる

出典

以下の外部資料は利用者が選択したときだけ開きます。