lead · Stage 5

証拠と撤退条件で技術方針を率いる

delivery metrics、倫理、security、cost、uncertainty、dissentを同じstrategy optionsへ結び、可逆な第一歩とwithdrawal conditionsを持つ技術方針を作る。

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

到達目標

  1. 技術方針をmetrics、risks、ethics、costs、uncertainties、dissentへ分解して監査可能にできる

    • 戦略、指標、リスク、投資順、撤退条件を含む技術方針
    • speed、security、ethics、cost、uncertaintyの衝突を隠さない投資判断
  2. 投資順、decision rights、可逆な第一歩、withdrawal conditionsを明示できる

    • 戦略、指標、リスク、投資順、撤退条件を含む技術方針
    • 良い指標が目標そのものではなく意思決定を校正する証拠であることを説明する7分発表
  3. risk toleranceだけを変え、同じstrategy optionsの選択を再評価できる

    • 戦略、指標、リスク、投資順、撤退条件を含む技術方針
    • risk toleranceだけを変えた同一strategy optionsの再選択

能力の進行

  1. recognize

    metric、risk、ethical duty、cost、uncertainty、dissentを異なる判断入力として識別できる

    証拠: 戦略、指標、リスク、投資順、撤退条件を含む技術方針

  2. explain

    metric改善、事業成果、社会的影響が自動的に一致しない理由を説明できる

    証拠: 良い指標が目標そのものではなく意思決定を校正する証拠であることを説明する7分発表

  3. apply

    budgetとrisk toleranceからstrategy optionsを順位付けし可逆な第一歩を選べる

    証拠: 戦略、指標、リスク、投資順、撤退条件を含む技術方針

  4. diagnose

    metric gaming、cost外部化、倫理の後付け、撤退不能なbig bangを反証できる

    証拠: speed、security、ethics、cost、uncertaintyの衝突を隠さない投資判断

  5. lead

    別のcontributorがdecision rightsと証拠を使い方針を独立再評価できる環境を作れる

    証拠: risk toleranceだけを変えた同一strategy optionsの再選択

なぜ重要か

技術リーダーの役割は、大きな移行を言い切ることではない。観測可能なstrategyを作り、影響を受ける人、異論を持つ人、実行するcontributorが同じevidenceから選択を再評価できるようにすることである。

ACM Code of Ethicsは社会へのharm、quality、privacy、securityを専門職の責任として扱う。DORAのfive metricsはdeliveryのspeedとstabilityを一つの数字へ潰さずに観測する。FinOps Framework 2026はcostを事業価値へ、NIST CSF 2.0はcybersecurity riskをgovernanceへ結ぶ。いずれも単独では十分なstrategyにならない。

メンタルモデル

strategyを予言ではなく、反証可能なoption portfolioとして扱う。目的と制約を置き、metric、risk、ethics、cost、uncertainty、dissentを比較し、小さく可逆な第一歩を選ぶ。withdrawal conditionsは失敗の宣言ではなく、害や埋没費用が増える前に学習を行動へ変える境界である。

期待値だけでなく制約と可逆性で選ぶdecision table
観測 判断 次の証拠
riskとbudgetを満たす 小さな第一歩へ投資 期限付きmetricとaffected-user feedback
倫理またはsecurity境界に違反 期待収益より先に停止 harm analysisとcontrol owner
withdrawal conditionを観測 stopまたはadapt decision logと回収可能なasset
多面的evidenceから可逆な投資と撤退判断へ進むleadership loop

注記

図を読む際の補足情報です。

  1. この注記は旧図の読み順を保持する補助です。
  2. Frame: system outcome、非目標、decision rightsを合意する。
  3. Measure: five metrics、risk、cost、利用者影響を別々に観測する。
  4. Challenge: uncertaintyとdissentから反証条件を作る。
  5. Order: 制約を守るoptionを投資順へ置く。
  6. Act: reversible first stepだけにtimeboxしたbudgetを与える。
  7. Review: withdrawal conditionsでstop、adapt、expandを判断する。

対立する指標と不確実性を、どの撤退条件を持つ投資判断へ変えるか。

原因
Frame
system outcome、非目標、decision rightsを合意する。
機構
Measure
five metrics、risk、cost、利用者影響を別々に観測する。
Challenge
uncertaintyとdissentから反証条件を作る。
Order
制約を守るoptionを投資順へ置く。
Act
reversible first stepだけにtimeboxしたbudgetを与える。
結果
Review
withdrawal conditionsでstop、adapt、expandを判断する。
対策
Withdrawal conditions
害や埋没費用が増える前にstop、adapt、expandを判断する境界を固定する。
  • Frame → Measure: outcomeに必要な証拠を分ける
  • Measure → Challenge: 不確実性とdissentで反証する
  • Challenge → Order: 制約を守る投資順を作る
  • Order → Act: 可逆なfirst stepだけを実行する
  • Act → Review: 観測結果からstop、adapt、expandを判断する
  • Withdrawal conditions → Review: 撤退条件で害と埋没費用を抑える

system outcome、複数metric、反証条件、投資順、可逆なfirst step、withdrawal conditionを一つの判断経路として説明できる。

動く例で考える

stabilizeとreplatformをrisk toleranceで再評価する

前提
2つのsynthetic strategy optionsを同じbudget capで比較する。金額とscoreは市場価格や実績ではない。
入力
baseline risk tolerance 3、transfer 1、budget cap 50000、optionごとのcost、risk、lead time、metrics、ethics、uncertainty、dissentを与える。
操作
schemaとinvestment orderを検証し、許容riskとbudget内のoptionから選択する。可逆な第一歩とwithdrawal conditionsを選択結果へ結ぶ。
観測
tolerance 3ではreplatformが選ばれ、1ではstabilizeが選ばれる。options、budget、metricは同じで、変更はrisk toleranceだけである。
結論
report生成のcommand successはstrategyが有効というsystem outcomeではない。metric、倫理、risk、dissent、撤退判断を継続観測して初めて方針を維持できる。
python3.13 - <<'PY'
import json

HARNESS = "technical_strategy_lab_v1"
BASELINE_STRATEGY_CONTEXT = {
    "risk_tolerance": 3,
    "budget_cap": 50000,
}
TRANSFER_STRATEGY_CONTEXT = {
    "risk_tolerance": 1,
    "budget_cap": 50000,
}
OPTIONS = [
    {
        "option_id": "stabilize",
        "cost": 20000,
        "risk_score": 1,
        "lead_time_days": 30,
        "metrics": [
            "change-fail-rate",
            "failed-deployment-recovery-time",
        ],
        "risks": [
            "legacy coupling remains",
        ],
        "ethics": [
            "avoid service disruption for affected users",
        ],
        "uncertainties": [
            "root cause coverage may be incomplete",
        ],
        "dissent": [
            "delays removal of the legacy boundary",
        ],
        "withdrawal_conditions": [
            "change fail rate does not improve by the review date",
            "affected-user harm increases",
        ],
        "reversible_first_step": "instrument one release path",
        "withdrawal_triggered": False,
    },
    {
        "option_id": "replatform",
        "cost": 45000,
        "risk_score": 3,
        "lead_time_days": 14,
        "metrics": [
            "deployment-throughput",
            "change-lead-time",
            "change-fail-rate",
        ],
        "risks": [
            "migration rollback may be incomplete",
        ],
        "ethics": [
            "preserve access and data integrity during migration",
        ],
        "uncertainties": [
            "traffic behavior on the new platform is unobserved",
        ],
        "dissent": [
            "operational load may exceed team capacity",
        ],
        "withdrawal_conditions": [
            "rollback evidence is unavailable",
            "security risk exceeds the agreed tolerance",
        ],
        "reversible_first_step": "migrate one internal read-only slice",
        "withdrawal_triggered": False,
    },
]
INVESTMENT_ORDER = ("stabilize", "replatform")
STRATEGY_CONTEXT_FIELDS = {
    "risk_tolerance",
    "budget_cap",
}
OPTION_FIELDS = {
    "option_id",
    "cost",
    "risk_score",
    "lead_time_days",
    "metrics",
    "risks",
    "ethics",
    "uncertainties",
    "dissent",
    "withdrawal_conditions",
    "reversible_first_step",
    "withdrawal_triggered",
}
LIST_FIELDS = {
    "metrics",
    "risks",
    "ethics",
    "uncertainties",
    "dissent",
    "withdrawal_conditions",
}

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

def validate_strategy_context(context):
    valid = (
        type(context) is dict
        and set(context) == STRATEGY_CONTEXT_FIELDS
        and is_number(context["risk_tolerance"])
        and context["risk_tolerance"] >= 0
        and is_number(context["budget_cap"])
        and context["budget_cap"] > 0
    )
    if not valid:
        raise AssertionError(
            "leadership-transfer-invariant: invalid strategy context"
        )

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

def validate_options(options):
    valid = (
        type(options) is list
        and bool(options)
        and all(
            type(option) is dict
            and set(option) == OPTION_FIELDS
            and type(option["option_id"]) is str
            and bool(option["option_id"])
            and all(
                is_number(option[field]) and option[field] >= 0
                for field in {"cost", "risk_score", "lead_time_days"}
            )
            and all(
                type(option[field]) is list
                and bool(option[field])
                and all(
                    type(item) is str and bool(item)
                    for item in option[field]
                )
                for field in LIST_FIELDS
            )
            and type(option["reversible_first_step"]) is str
            and bool(option["reversible_first_step"])
            and type(option["withdrawal_triggered"]) is bool
            for option in options
        )
        and len({option["option_id"] for option in options}) == len(options)
    )
    if not valid:
        raise AssertionError(
            "leadership-input-invariant: invalid strategy option schema"
        )

def validate_investment_order(options):
    option_ids = {option["option_id"] for option in options}
    valid = (
        INVESTMENT_ORDER == ("stabilize", "replatform")
        and len(INVESTMENT_ORDER) == len(set(INVESTMENT_ORDER))
        and set(INVESTMENT_ORDER) == option_ids
    )
    if not valid:
        raise AssertionError(
            "leadership-order-invariant: invalid investment order"
        )

def validate_all_inputs():
    validate_strategy_context(BASELINE_STRATEGY_CONTEXT)
    validate_strategy_context(TRANSFER_STRATEGY_CONTEXT)
    validate_options(OPTIONS)
    validate_investment_order(OPTIONS)

def select_strategy(options, context):
    ranked = rank_strategies(options, context)
    eligible_ids = [
        item["option_id"]
        for item in ranked
        if item["eligible"]
    ]
    eligible = [
        option
        for option in options
        if option["option_id"] in eligible_ids
    ]
    if not eligible:
        raise AssertionError(
            "leadership-decision-invariant: no eligible strategy"
        )
    selected_id = eligible_ids[0]
    return next(
        option
        for option in eligible
        if option["option_id"] == selected_id
    )

def rank_strategies(options, context):
    ranked = sorted(
        options,
        key=lambda option: (
            not (
                option["cost"] <= context["budget_cap"]
                and option["risk_score"]
                <= context["risk_tolerance"]
            ),
            option["lead_time_days"],
            option["cost"],
            INVESTMENT_ORDER.index(option["option_id"]),
        ),
    )
    return [
        {
            "rank": rank,
            "option_id": option["option_id"],
            "cost": option["cost"],
            "risk_score": option["risk_score"],
            "eligible": (
                option["cost"] <= context["budget_cap"]
                and option["risk_score"]
                <= context["risk_tolerance"]
            ),
            "score_inputs": {
                "budget_cap": context["budget_cap"],
                "risk_tolerance": context["risk_tolerance"],
                "lead_time_days": option["lead_time_days"],
            },
        }
        for rank, option in enumerate(ranked, start=1)
    ]

def evaluate_withdrawal_conditions(selected):
    return selected["withdrawal_triggered"]

def evaluate_strategy(options, context):
    investment_order = rank_strategies(options, context)
    valid_order = (
        type(investment_order) is list
        and len(investment_order) == len(options)
        and all(
            type(item) is dict
            and set(item)
            == {
                "rank",
                "option_id",
                "cost",
                "risk_score",
                "eligible",
                "score_inputs",
            }
            and type(item["rank"]) is int
            and item["rank"] > 0
            and type(item["option_id"]) is str
            and type(item["eligible"]) is bool
            and type(item["score_inputs"]) is dict
            and bool(item["score_inputs"])
            for item in investment_order
        )
        and [item["rank"] for item in investment_order]
        == list(range(1, len(investment_order) + 1))
        and len({item["option_id"] for item in investment_order})
        == len(investment_order)
    )
    if not valid_order:
        raise AssertionError(
            "leadership-order-invariant: ranking derivation bypassed"
        )
    selected = select_strategy(options, context)
    independently_selected = select_strategy(options, context)
    if (
        selected["option_id"] != independently_selected["option_id"]
        or investment_order[0]["option_id"]
        != selected["option_id"]
        or not investment_order[0]["eligible"]
    ):
        raise AssertionError(
            "leadership-decision-invariant: selection derivation bypassed"
        )
    withdrawal_ready = evaluate_withdrawal_conditions(selected)
    independently_evaluated = selected["withdrawal_triggered"]
    if withdrawal_ready is not independently_evaluated:
        raise AssertionError(
            "leadership-withdrawal-invariant: withdrawal derivation bypassed"
        )
    return {
        "selected": selected,
        "withdrawal_ready": withdrawal_ready,
        "investment_order": investment_order,
    }

def main():
    validate_all_inputs()
    changed = changed_fields(
        BASELINE_STRATEGY_CONTEXT,
        TRANSFER_STRATEGY_CONTEXT,
    )
    baseline_context = json.loads(
        json.dumps(BASELINE_STRATEGY_CONTEXT, ensure_ascii=False)
    )
    transferred_context = json.loads(
        json.dumps(TRANSFER_STRATEGY_CONTEXT, ensure_ascii=False)
    )
    options = json.loads(
        json.dumps(OPTIONS, ensure_ascii=False)
    )
    transferred_options = json.loads(
        json.dumps(OPTIONS, ensure_ascii=False)
    )
    validate_options(options)
    validate_options(transferred_options)
    validate_investment_order(options)
    baseline = evaluate_strategy(options, baseline_context)
    transferred = evaluate_strategy(
        transferred_options,
        transferred_context,
    )
    same_strategy_options = options == transferred_options
    if not same_strategy_options:
        raise AssertionError(
            "leadership-transfer-invariant: strategy options drifted"
        )
    if (
        baseline["selected"]["option_id"] != "replatform"
        or transferred["selected"]["option_id"] != "stabilize"
    ):
        raise AssertionError(
            "leadership-decision-invariant: unexpected strategy selection"
        )
    selected = baseline["selected"]

    report = {
        "harness": HARNESS,
        "technical_strategy": {
            "metrics": selected["metrics"],
            "risks": selected["risks"],
            "ethics": selected["ethics"],
            "costs": {
                "selected": selected["cost"],
                "budget_cap": baseline_context["budget_cap"],
            },
            "uncertainties": selected["uncertainties"],
            "dissent": selected["dissent"],
            "withdrawal_conditions": selected["withdrawal_conditions"],
            "withdrawal_ready": baseline["withdrawal_ready"],
            "reversible_first_step": selected["reversible_first_step"],
            "selected_option": selected["option_id"],
            "investment_order": baseline["investment_order"],
        },
        "contributor_enablement": {
            "other_contributor": "strategy-reviewer",
            "decision_rights": {
                "proposal_owner": "technical-lead",
                "risk_acceptance": "accountable-service-owner",
                "withdrawal": "incident-commander",
            },
            "review_evidence": {
                "metrics": selected["metrics"],
                "dissent": selected["dissent"],
                "withdrawal_conditions": (
                    selected["withdrawal_conditions"]
                ),
            },
        },
        "risk_tolerance_transfer": {
            "changed_assumption": "risk-tolerance",
            "changed_fields": changed,
            "same_strategy_options": same_strategy_options,
            "baseline_selected_option": (
                baseline["selected"]["option_id"]
            ),
            "transferred_selected_option": (
                transferred["selected"]["option_id"]
            ),
            "baseline_investment_order": (
                baseline["investment_order"]
            ),
            "transferred_investment_order": (
                transferred["investment_order"]
            ),
            "baseline_context": baseline_context,
            "transferred_context": transferred_context,
        },
        "fixture_metadata": {
            "kind": "synthetic",
            "provenance": "lesson-defined technical strategy fixture",
            "limitations": (
                "not production cost, delivery, security, or harm evidence"
            ),
            "synthetic_or_observed_explicit": True,
            "hidden_assumption": (
                "risk scores are ordinal lesson inputs, not universal truth"
            ),
        },
        "input_derived_evidence": {
            "option_ids": [
                option["option_id"] for option in options
            ],
            "selected_option": selected["option_id"],
            "metric_count": len(selected["metrics"]),
        },
        "runtime_bound": {
            "records": (
                len(options)
                + sum(len(option["metrics"]) for option in options)
                + sum(len(option["risks"]) for option in options)
            ),
            "subprocesses": 0,
            "maximum_iterations": (
                len(options) * len(INVESTMENT_ORDER)
            ),
        },
        "external_network_used": False,
        "command_success_distinction": {
            "command_completed": True,
            "system_outcome_checked": (
                bool(selected["metrics"])
                and bool(selected["ethics"])
                and bool(selected["withdrawal_conditions"])
            ),
            "command_success_equals_system_outcome": False,
            "outcome_evidence": {
                "selected_option": selected["option_id"],
                "reversible_first_step": (
                    selected["reversible_first_step"]
                ),
                "withdrawal_ready": baseline["withdrawal_ready"],
            },
        },
        "mastery_evidence": {
            "lab_steps": [
                {"step": 1, "evidence": baseline_context},
                {
                    "step": 2,
                    "evidence": baseline["investment_order"],
                },
                {
                    "step": 3,
                    "evidence": {
                        "first_step": selected["reversible_first_step"],
                        "withdrawal": selected["withdrawal_conditions"],
                    },
                },
                {
                    "step": 4,
                    "evidence": {
                        "dissent": selected["dissent"],
                        "reviewer": "strategy-reviewer",
                    },
                },
                {"step": 5, "evidence": transferred},
            ],
            "assessments": [
                {
                    "assessment": 1,
                    "evidence": {
                        "metrics": selected["metrics"],
                        "ethics": selected["ethics"],
                        "withdrawal": selected["withdrawal_conditions"],
                    },
                },
                {
                    "assessment": 2,
                    "evidence": selected["reversible_first_step"],
                },
            ],
            "rubric_dimensions": [
                "technical-correctness",
                "judgment",
                "evidence",
                "communication",
            ],
            "transfer": {
                "task": (
                    "risk toleranceだけを変え、同じstrategy optionsの"
                    "指標、倫理、cost、投資順、可逆な第一歩と"
                    "withdrawal条件を再評価する"
                ),
                "changed_assumption": "risk-tolerance",
                "evidence": {
                    "baseline": baseline,
                    "transferred": transferred,
                },
            },
            "contributor_enablement": {
                "other_contributor": "strategy-reviewer",
                "review_evidence": {
                    "options": [
                        option["option_id"] for option in options
                    ],
                    "dissent": selected["dissent"],
                },
            },
        },
    }
    print(json.dumps(report, ensure_ascii=False, separators=(",", ":")))

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

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

evidenceを増やすほど判断は遅くなり、metricを絞るほど盲点が増える。影響と可逆性に比例して証拠量を変え、不可逆なharm、security boundary、重大なcost commitmentには高いreview barを置く。

  • 誤診: DORA metricが改善したので利用者価値も改善した。反証: delivery performanceとは別にoutcome、harm、security、costを観測する。
  • 誤診: 予算内なので投資は安全である。反証: ethics、operational load、uncertainty、撤退費用をbudget gateと独立して確認する。
  • 失敗モード: dissentをalignment不足として除く。反対理由をrisk hypothesisに変え、ownerと反証期限を与える。
  • 失敗モード: sunk costの増加でwithdrawal conditionsを無視する。開始前にstop authorityと回収可能なartifactを定義する。

知識チェック

  1. DORAのfive metricsを一つのperformance scoreに統合しない理由を説明せよ。
  2. FinOps Framework 2026のcost判断とACM Code of Ethicsが衝突したとき、どの制約を先に置くか。
  3. reversible first stepを「小さいtask」ではなく「撤退可能な学習option」にする条件を3つ挙げよ。
  4. risk toleranceだけを変更したtransferで、optionsやbudgetまで変えると因果説明が壊れる理由は何か。

出典と次の学習

ACM Code of Ethicsで優先すべき専門職責任を確認し、DORAのfive metricsをspeedとstabilityの診断へ使う。FinOps Framework 2026でvalueとcostのownerを、NIST CSF 2.0でsecurity riskのgovernanceをstrategyへ接続する。

次に、自分の技術方針を二つ以上のstrategy optionsへ分解する。別のcontributorへdecision rights、review evidence、dissent、withdrawal conditionsを渡し、同じ入力から選択と反証条件を独立再評価してもらう。

実践ラボ

同じstrategy optionsを異なるrisk toleranceで再評価する

提出成果物: 戦略、指標、リスク、投資順、撤退条件を含む技術方針

  1. strategy context、options、metric、倫理、costのsynthetic fixtureと限界を固定する
  2. riskとbudgetの制約を満たすoptionを根拠付きで順位付けする
  3. 選択したoptionへ可逆な第一歩とwithdrawal conditionsを結ぶ
  4. dissentとdecision rightsを記録し別contributorが再評価できる証拠を作る
  5. risk toleranceだけを変え同じstrategy optionsの選択を再計算する

説明して理解を確かめる

7分で、DORAのfive metrics、FinOps Framework 2026、NIST CSF 2.0、ACM Code of Ethicsを、単一scorecardではなく相互に反証する意思決定入力として使う理由を説明する。

アセスメント

  1. 問い: delivery throughputは改善したがchange fail rateと利用者へのharmが増えた。方針を継続できるか。

    期待する証拠: five metricsの関係、ethical impact、risk owner、withdrawal conditions、system outcome

  2. 問い: replatformの期待値は高いがuncertaintyが大きく撤退費用も高い。第一歩をどう設計するか。

    期待する証拠: reversible slice、budget cap、evidence deadline、dissent、stopまたはexpand条件

別問題へ転用する

risk toleranceだけを変え、同じstrategy optionsの指標、倫理、cost、投資順、可逆な第一歩とwithdrawal条件を再評価する

復習スケジュール

  1. 1日後

    five metricsを一つの生産性scoreへ潰すと何を見失うか

  2. 7日後

    reversible first stepとwithdrawal conditionsはどう接続するか

  3. 30日後

    dissentを方針の遅延ではなく品質証拠に変えるには何を残すか

  4. 90日後

    five metricsを一つの生産性scoreへ潰すと何を見失うか

評価ルーブリック

4段階の評価基準
観点未達発展途上熟達卓越
technical-correctness一つのmetricまたは主観だけで方針を決める複数入力はあるが単位、owner、選択式が結び付かないmetrics、risk、ethics、cost、uncertainty、dissentを同じoption schemaから導く入力schema、順位、changed field、withdrawal derivationをfail-closedで検証する
judgment権威または最大期待値へ追従するtrade-offを挙げるが撤退条件がないrisk tolerance、budget、倫理、可逆性から選び反証条件を置く不可逆な害を先に制約し、観測に応じてstop、adapt、expandできる
evidence目標値だけを示し入力出自がないdashboardはあるが意思決定とdissentに接続しないprovenance、limitations、metric、cost、risk、decision logを再実行可能に残す別のcontributorが同じoptionを独立再評価し選択差を説明できる
communication技術刷新を目的として宣言するbenefitはあるが影響を受ける人とdecision rightsが不明である目的、非目標、owner、dissent、投資順、撤退条件を平易に伝える経営、product、security、operations、contributorが同じ証拠で異議を検証できる

出典

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