{% extends "html/base.template.html" %} {% from "html/macros/forms.html" import plan_approval %} {% from "html/macros/layout.html" import narrative as render_narrative, action_list, summary_card, row_key %} {% from "html/macros/visualizations.html" import figure %} {% block human_content %}

{{ t('tasks.implementation-planning.what-the-plan-is-for') }}

{{ humanSummary.outcome | inline_code }}

{% for reason in humanSummary.whyItMatters %}{{ summary_card("", reason, "important") }}{% endfor %}
{% if planning.get("planningContract") == "selected-direction" %}

{{ t('tasks.implementation-planning.selected-direction') }}

{{ planning.selectedDirectionRef.optionId | inline_code }}

{{ t('tasks.implementation-planning.source-report') }} {{ planning.selectedDirectionRef.sourceReport | inline_code }}

{{ t('tasks.implementation-planning.snapshot') }} {{ planning.selectedDirectionRef.snapshotPath | inline_code }}

{% if planning.outcome == "plan-ready" %}

{{ t('tasks.implementation-planning.direction-realization') }}

{{ planning.directionRealization.goal | inline_code }}

{{ t('tasks.implementation-planning.core-mechanism') }} {{ planning.directionRealization.coreMechanism | inline_code }}

{{ t('tasks.implementation-planning.interfaces') }} {{ planning.directionRealization.interfaces | inline_code }}

{{ t('tasks.implementation-planning.blast-radius') }} {{ planning.directionRealization.blastRadius | inline_code }}

{{ t('tasks.implementation-planning.plan-coverage') }}

{{ t('tasks.implementation-planning.coverage-percent') }} {{ planning.coverageSummary.coveragePercent }}

{{ t('tasks.implementation-planning.scope-precision-percent') }} {{ planning.coverageSummary.scopePrecisionPercent }}

{% else %}

{{ t('tasks.implementation-planning.direction-invalidated') }}

{{ t('tasks.implementation-planning.code-evidence') }}

{{ t('tasks.implementation-planning.re-entry-route') }} {{ planning.routing | inline_code }}

{% endif %} {% else %}

{{ t('tasks.implementation-planning.implementation-options-compared') }}

{{ render_narrative(narrative.optionExplanation, "implementationPlanning.userNarrative.optionExplanation") }}
{% for row in planning.optionCandidates %}

{{ row.name | inline_code }}

{{ t('tasks.implementation-planning.interface') }} {{ row.interfaces | inline_code }}

{{ t('tasks.implementation-planning.blast-radius') }} {{ row.blastRadius | inline_code }}

    {% for file in row.fileStructure %}
  • {{ file.action }} {{ file.path }} — {{ file.summary | inline_code }}
  • {% endfor %}
{% endfor %}
{% for row in planning.tradeoffMatrix %}{% endfor %}
{{ t('tasks.implementation-planning.option') }}{{ t('tasks.implementation-planning.complexity') }}{{ t('tasks.implementation-planning.risk') }}{{ t('tasks.implementation-planning.reversibility') }}{{ t('tasks.implementation-planning.test-cost') }}{{ t('tasks.implementation-planning.rollout-cost') }}
{{ row.option | inline_code }}{{ row.complexity | inline_code }}{{ row.risk | inline_code }}{{ row.reversibility | inline_code }}{{ row.testCoverageCost | inline_code }}{{ row.rolloutCost | inline_code }}

{{ t('tasks.implementation-planning.recommended') }}

{{ render_narrative(narrative.recommendationExplanation, "implementationPlanning.userNarrative.recommendationExplanation") }}

{{ planning.recommendedOption.name | inline_code }}

{{ planning.recommendedOption.coreReason | inline_code }}

{{ planning.recommendedOption.rationale | inline_code }}

{{ t('tasks.implementation-planning.options-not-taken') }} {{ planning.recommendedOption.rejectedSummary | inline_code }}

{% endif %} {% if planning.get("outcome") != "direction-invalidated" %}

{{ t('tasks.implementation-planning.stage-map') }}

{% if narrative.get("stageStrategy") %} {{ render_narrative(narrative.stageStrategy, "implementationPlanning.userNarrative.stageStrategy") }} {% endif %} {{ figure(stageFigure) }}
{% for row in planning.stages %}

Stage {{ row.stage }} · {{ row.title | inline_code }}

{{ row.sliceValue | inline_code }}

{% endfor %}
{% if planning.get("designPreparation") %}

{{ t('tasks.implementation-planning.design-preparation') }}

{% if planning.designPreparation.mode == "no-design-inputs" %}

{{ planning.designPreparation.reason | inline_code }}

{% else %} {% for row in planning.designPreparation["items"] %}{{ row_key(pairs=[(t('macros.layout.id'), row.id), (t('macros.layout.subject'), row.title), (t('macros.layout.kind'), row.kind)], status_name=t('macros.layout.status'), status_raw=row.status, status_text=row.status) }}{% endfor %}
{{ t('tasks.implementation-planning.design-item') }}{{ t('tasks.implementation-planning.what-it-needs') }}{{ t('tasks.implementation-planning.open-questions') }}
{{ row.need | inline_code }}{{ row.openQuestions | default([]) | join(" · ") | inline_code }}
{% endif %}
{% endif %}

{{ t('tasks.implementation-planning.where-implementations-diverge') }}

{% if planning.variationPointAnalysis.hasMultipleImplementations %} {% for row in planning.variationPointAnalysis.points %}{% set decision = row.extractionDecision %}{% endfor %}
{{ t('tasks.implementation-planning.action') }}{{ t('tasks.implementation-planning.implementations') }}{{ t('tasks.implementation-planning.extraction-call') }}{{ t('tasks.implementation-planning.evidence') }}
{{ row.behavior | inline_code }}{{ row.implementations | default([]) | join(" · ") | inline_code }}{% if decision is mapping %}{{ t('tasks.implementation-planning.extract') if decision.extract else t('tasks.implementation-planning.keep') }} · {{ decision.interfaceKind | enum_label('interfaceKind') }} · {{ decision.coveredBy | inline_code }} — {{ decision.rationale | inline_code }}{% else %}{{ decision | inline_code }}{% endif %}{{ row.evidence | inline_code }}
{% else %}

{{ planning.variationPointAnalysis.noVariationRationale | inline_code }}

{% endif %}
{% if planning.get("stepwiseExecution") %}

{{ t('tasks.implementation-planning.step-by-step-execution') }}

{% for row in planning.stepwiseExecution %}{% endfor %}
#{{ t('tasks.implementation-planning.action') }}{{ t('tasks.implementation-planning.files') }}{{ t('tasks.implementation-planning.command-test') }}{{ t('tasks.implementation-planning.expected') }}
{{ row.step }}{{ row.action | inline_code }}{{ row.files if row.files is string else row.files | join(" ") }}{{ row.commandOrTest }}{{ row.expectedOutcome | inline_code }}
{% endif %} {# 검증 체크리스트·프로젝트 간 의존·마이그레이션 위험·롤백·활동 대장은 구현자와 감사 추적용이다. 계획 본문 검증의 판정과 근거는 승인 판단이라 이 화면에 남긴다. A-NNN 인용은 이 문서에 id 가 있어야 checkRef 가 산다. #}

{{ t('tasks.implementation-planning.how-each-requirement-gets-met') }}

{% if planning.get("planningContract") == "selected-direction" %} {% for row in planning.requirementCoverage %}{% endfor %}
{{ t('tasks.implementation-planning.original-requirement') }}{{ t('tasks.implementation-planning.stages') }}{{ t('tasks.implementation-planning.status') }}
{{ row.originalRequirementId | inline_code }}{{ row.stageRefs | join(", ") | inline_code }}{{ row.status | inline_code }}
{% else %} {% for row in planning.requirementCoverage %}{{ row_key(pairs=[(t('macros.layout.id'), row.id), (t('macros.layout.source'), row.source)], status_name=t('macros.layout.status'), status_raw=row.status, status_text=row.status) }}{% endfor %}
{{ t('tasks.implementation-planning.requirement') }}{{ t('tasks.implementation-planning.body') }}{{ t('tasks.implementation-planning.covered-by') }}
{{ row.requirement | inline_code }}{{ row.coveredBy | inline_code }}
{% endif %}
{% if planning.get("planBodyVerification") %}

{{ t('tasks.implementation-planning.plan-body-verification') }}

{{ planning.planBodyVerification.gateResult | enum_label('planGate') }}

{% if planning.planBodyVerification.get("uniformVerifiers") %}

{{ t('tasks.implementation-planning.uniform-verifier-label') }} — {% for row in planning.planBodyVerification.uniformVerifiers %}{{ row.worker | inline_code }} · {{ row.verdict | inline_code }} ({{ row.itemCount }}){% if not loop.last %}, {% endif %}{% endfor %}

{{ t('tasks.implementation-planning.uniform-verifier-legend') }}

{% endif %}
{% for item in planning.planBodyVerification.planItems %}

{{ item.id | inline_code }}{% if item.get("sourceSection") %} · {{ t('tasks.implementation-planning.source-section') }} {{ item.sourceSection | inline_code }}{% endif %}

{{ item.subject | inline_code }}

{% for vote in item.verdicts %}

{{ vote.worker | inline_code }} {{ vote.verdict }}{% if vote.get("breakageKind") %} · {{ t('tasks.implementation-planning.breakage') }} {{ vote.breakageKind | inline_code }}{% endif %}{% if vote.get("fixability") %} · {{ t('tasks.implementation-planning.fixability') }} {{ vote.fixability | inline_code }}{% endif %}{% if vote.get("claimKind") %} · {{ t('tasks.implementation-planning.claim') }} {{ vote.claimKind | inline_code }}{% endif %}{% if vote.get("reproductionResult") %} · {{ t('tasks.implementation-planning.reproduction') }} {{ vote.reproductionResult | inline_code }}{% endif %}

{% if vote.get("note") %}

{{ t('tasks.implementation-planning.note') }} {{ vote.note | inline_code }}

{% endif %}{% if vote.get("explanation") %}

{{ vote.explanation | inline_code }}

{% endif %}{% endfor %}
{% endfor %}
{% if planning.planBodyVerification.get("dissentLog") %}

{{ t('tasks.implementation-planning.dissent-left-standing') }}

{% endif %}
{% endif %} {% if planning.get("supersessionLedger") is not none %}

{{ t('tasks.implementation-planning.what-your-answers-overturned') }}

{# `supersededStatement` / `replacedWith` are optional — `SupersessionEntry` requires only `clarificationId` and `disposition`, and a `no-dependent-statement` row legitimately carries neither. Referencing them unconditionally under StrictUndefined meant a schema-valid report killed the renderer. #} {% set answered_ids = clarificationItems | map(attribute='id') | list %}{% for row in planning.supersessionLedger %}{{ row_key(pairs=[(t('macros.layout.answer'), row.clarificationId), (t('macros.layout.disposition'), row.disposition)]) }}{% else %}{% endfor %}
{{ t('tasks.implementation-planning.answer') }}{{ t('tasks.implementation-planning.statement-overturned') }}{{ t('tasks.implementation-planning.replaced-with') }}
{{ row.get("supersededStatement") | inline_code }}{{ row.get("replacedWith") | inline_code }}
{{ t('tasks.implementation-planning.no-answer-overturned-anything') }}
{% endif %} {% if planning.get("incrementalDecision") %}

{{ t('tasks.implementation-planning.scope-restated') }}

{{ t('tasks.implementation-planning.scope-restated-lede') }}

{{ planning.incrementalDecision.mode | enum_label('replanMode') }} — {{ planning.incrementalDecision.reason | inline_code }}

{% if planning.incrementalDecision.reverifyStages or planning.incrementalDecision.carryStages %}

{{ t('tasks.implementation-planning.stages-verified-again') }} — {{ planning.incrementalDecision.reverifyStages | default([]) | join(", ") | inline_code }} · {{ t('tasks.implementation-planning.stages-carried-over-as-they-were') }} — {{ planning.incrementalDecision.carryStages | default([]) | join(", ") | inline_code }}

{% endif %}
{% endif %} {% if planning.get("decisionDrafts") or planning.get("skippedAdrCandidates") %}

{{ t('tasks.implementation-planning.decision-record-draft') }}

{% for row in planning.get("decisionDrafts", []) %}

{{ row.number }} · {{ row.slug | inline_code }} ({{ row.status | inline_code }})

{{ t('tasks.implementation-planning.context') }} — {{ row.context | inline_code }}

{{ t('tasks.implementation-planning.decision') }} — {{ row.decision | inline_code }}

{{ t('tasks.implementation-planning.result') }} — {{ row.consequences | inline_code }}

{% else %}

{{ t('tasks.implementation-planning.there-is-no-decision-draft-to-record') }}

{% endfor %} {% if planning.get("skippedAdrCandidates") %}

{{ t('tasks.implementation-planning.what-was-deliberately-not-recorded') }}

{% for row in planning.skippedAdrCandidates %}{% endfor %}
{{ t('tasks.implementation-planning.topic') }}{{ t('tasks.implementation-planning.why') }}
{{ row.topic | inline_code }}{{ row.reason | inline_code }}
{% endif %}
{% endif %} {% endif %} {% if agentActivities %} {% endif %}

{{ t('tasks.implementation-planning.open-decisions-before-approval') }}

{% for row in openDecisions %}{{ summary_card(row.id ~ " · " ~ row.kind, row.statement, "important", anchor=row.id) }}{% else %}

{{ t('tasks.implementation-planning.no-open-decision-is-holding-approval') }}

{% endfor %}
{{ action_list(humanSummary.actions) }}
{{ plan_approval(approval) }} {% endblock %}