{% extends "base.html" %} {% block title %}{{ phase.key }}{% endblock %} {% block body %}
{{ phase.product }}

{{ phase.name }}

closed {{ phase.closed }}{% if summary.first_dispatch %} · worked {{ summary.first_dispatch }} → {{ phase.closed }}{% endif %} · {{ summary.tasks_done }} of {{ summary.tasks_total }} tasks done{% if summary.has_records %} · {{ summary.prs_merged }} PR(s) merged · spent ${{ '%.2f' % spent }}{% else %} · no run records for this phase{% endif %}

{% if has_retro %}Retro{% endif %}HerbariumBoardTrellis
{% if retro_verdict %}
Retro verdict

{{ retro_verdict.word }}

{% if retro_verdict.accepted_by %}accepted by {{ retro_verdict.accepted_by }}{% if retro_verdict.accepted_at %} at {{ retro_verdict.accepted_at }}{% endif %}{% else %}recorded {{ retro_verdict.at }}{% endif %}{% if retro_verdict.note %} · {{ retro_verdict.note }}{% endif %}{% if retro_verdict.pr %} · retro PR ↗{% endif %}

{% if retro_verdict.tasks %} {% for t in retro_verdict.tasks %}{% endfor %}
taskkindstatustitle
{{ t.id }}{{ t.kind }}{{ t.status.replace('_',' ') }}{{ t.title }}
{% endif %}
{% endif %}
Persona reviews
{% for r in review_heads %}
{{ r.persona }}{% if r.score %} score {{ r.score }}{% endif %} {{ r.date }} · full report
{% if r.overall %}

{{ r.overall }}

{% endif %} {% if r.highs %}
    {% for h in r.highs %}
  • {{ h }}
  • {% endfor %}
{% endif %} {% if r.tasks %}
filed: {% for t in r.tasks %}{{ t.id }} {% endfor %}
{% endif %}
{% else %}
no persona reviews were run in this phase
{% endfor %}
Outcomes
{{ goals_html|safe }}
tasks donePRs mergedrevise roundsavg leadfirst passcostdates
{{ summary.tasks_done }} / {{ summary.tasks_total }}{% if summary.has_records %}{{ summary.prs_merged }}{% else %}{% endif %}{{ summary.revisions }} {% if summary.avg_lead_hours is not none %}{{ summary.avg_lead_hours }} h{% endif %} {% if summary.first_pass_rate is not none %}{{ (summary.first_pass_rate * 100)|round|int }}%{% endif %} {% if summary.has_records %}${{ '%.2f' % spent }}{% else %}{% endif %} {% if summary.first_dispatch %}{{ summary.first_dispatch }} → {% endif %}{{ phase.closed }}
{% if not summary.has_records %}

this phase predates run records: PRs merged and cost are not available

{% endif %} {% if metrics.by_difficulty %} {% for tier in ['easy','medium','hard'] %}{% if metrics.by_difficulty.get(tier) %}{% set d = metrics.by_difficulty[tier] %}{% endif %}{% endfor %}
tiertasksdoneavg revfirst-passcost
{{ tier }}{{ d.tasks }}{{ d.done }}{{ d.avg_revisions }}{% if d.first_pass_rate is not none %}{{ (d.first_pass_rate * 100)|round|int }}%{% endif %}${{ '%.2f' % d.cost_usd }}
{% endif %}
Pull requests
{% for row in merged_rows %} {% else %}{% endfor %}
prtasktitletiermerged
#{{ row.number }}{{ row.t.id }}{{ row.t.title }}{{ row.t.difficulty }}{{ row.merged }}
no merged PRs recorded
{% if unmerged_rows %}
Closed unmerged
{% for row in unmerged_rows %}{% endfor %}
#{{ row.t.pr.rsplit('/', 1)[-1] }}{{ row.t.id }}{{ stage(row.t.status.value, 18) }}{{ row.t.status.value.replace('_',' ') }}{{ row.why }}
{% endif %}
Tasks
{% for t, eff, st, u in rows %} {% else %}{% endfor %}
idstatustiertitleprcost
{{ t.id }}{{ stage(eff, 18) }}{{ eff.replace('_',' ') }}{{ t.difficulty }}{{ t.title }} {% if t.pr %}#{{ t.pr.rsplit('/', 1)[-1] }}{% endif %} {% if u.runs %}${{ '%.2f' % u.cost_usd }}{% endif %}
no tasks
{% set plate_src = plate(phase.plant) %} {% if plate_src %}
{{ sheet.info.latin }}, plate from {{ PLATE_CREDIT }}
{% else %}
{{ plant(phase.plant, 240, 360) }}
{% endif %}
{{ phase.product }} · plate {{ phase.plate }}
{{ phase.name }}
{{ sheet.info.latin }} — {{ sheet.info.common }}
{{ summary.tasks_done }} of {{ summary.tasks_total }} tasks done{% if summary.has_records %} · {{ summary.prs_merged }} merged
closed {{ phase.closed }} · spent ${{ '%.2f' % spent }}{% else %}
closed {{ phase.closed }} · no run records{% endif %}{% if plate_src %}
plate: {{ PLATE_CREDIT }}{% if sheet.info.get('plate_note') %}, {{ sheet.info.plate_note }}{% endif %}{% endif %}
pressed
Artifacts
{% endblock %}