{# T2 - PCCP performance-evaluation report (D4 section 3): the cover and nine sections through base.html's furniture (build day 10, E10). Every value comes from proofpack.render.t2's context (Number cells carry data-ref / data-kind / data-facet); every sentence is a claim of run.json rendered by proofpack.render.sentences; customer text is escaped inside .customer-text; status words only inside .status, and T2's record string only on a not_met row. No arithmetic here. #} {% extends "base.html" %} {% from "_criteria.html" import criteria_table %} {% macro ncell(c, extra="") -%} {{ c.text }} {%- endmacro %} {% macro notes(key) -%} {% for ref in anchors[key] %}{{ margin_note(ref) }} {% endfor %} {%- endmacro %} {% macro narrative(items) -%} {% if items %}
{% for s in items %}

{{ s.html }}

{% endfor %}
{% endif %} {%- endmacro %} {% macro margin_status(ms) -%} {% if ms %}{% for m in ms %}{{ m.id }} (row {{ m.position }}): {{ m.statistic }} {{ m.comparator }} {{ m.value }}{% if not loop.last %}
{% endif %}{% endfor %}{% for m in ms %}{{ m.status_word }}{% if m.status == "not_assessable" %} ({{ m.reason_code }}){% endif %}{% if m.record %} - {{ not_met_record }}{% endif %}{% if not loop.last %}
{% endif %}{% endfor %}{% else %}——{% endif %} {%- endmacro %} {% macro comparison_row(r) -%} {{ r.label }}{% if r.op %} ({{ r.op }}){% endif %}{{ ncell(r.prior) }}{{ ncell(r.new) }}{{ ncell(r.delta) }}{{ r.method.text }}{{ r.b }} / {{ r.c }}{{ r.p }} ({{ r.mcnemar_method }}){% if tables.has_margin %}{{ margin_status(r.margins) }}{% endif %} {%- endmacro %} {% block pages %}
{{ page_header() }}

{{ template_name }}

{{ cover_note }}

{{ cover_stamps() }} {{ notes("s0") }} {% for label, value in version_rows %} {% endfor %} {% for label, value, mono in cover_rows %} {{ value }} {% endfor %}
Cover block - PCCP identity (section 0)
{{ label }}{{ value }}
{{ label }}
Guidance versions referenced{% for ref in guidance_refs %}{{ ref.label }}{% if not loop.last %}; {% endif %}{% endfor %}
Customer sections outstanding{{ outstanding }}

0. PCCP identity

{{ placeholder(slots["CT-20"]) }} {{ page_footer() }}
{{ page_header() }}

{{ long_form_title }}

{{ notes("scope") }}
    {% for title, body in long_form_items %}
  1. {{ title }} {{ body }}
  2. {% endfor %}
{% for ref in guidance_refs %} {% endfor %}
Guidance versions referenced in this render, labelled from the guidance map; a draft is a draft in the label and in the structured data
Internal idDocument, version or date, statusDraft
{{ ref.id }}{{ ref.label }}{% if ref.draft %}yes{% else %}no{% endif %}
{{ page_footer() }}
{{ page_header() }}

1. Description of modifications

{{ notes("s1") }} {{ placeholder(slots["CT-21"]) }} {{ no_data("Table T2-1 - " ~ t2_1_note) }}

2. Modification protocol (1) - data management

{{ notes("s2") }} {{ placeholder(slots["CT-22"]) }} {{ placeholder(slots["CT-23"]) }}
{% for label, value in flow_rows %} {% endfor %}
Table T2-flow - flow of rows of each version's table (D4 section 5.10); the comparison pairs the analysed rows on row_id
CountNew versionPrior version
{{ label }}{{ value }}{% if prior_flow_rows %}{{ prior_flow_rows[loop.index0][1] }}{% else %}—{% endif %}
Pairs (row_id join){{ tables.n_pairs }}
Rows in one version only, or with differing labels{{ tables.excluded }}
{% for r in table1_rows %} {% endfor %}
Table T2-1b - Table 1 of the evaluation set (the new version's table; D4 section 5.4)
AttributeLevelTest n (%)
{{ r.attribute }}{{ r.level }}{{ r.n }} ({{ r.pct }})

3. Modification protocol (2) - re-training practices

{{ notes("s3") }} {{ placeholder(slots["CT-24"]) }} {% for label, value in version_rows %} {% endfor %}
Version fields, echoed from criteria.yaml (the engine describes no training)
{{ label }}{{ value }}
{{ page_footer() }}
{{ page_header() }}

4. Modification protocol (3) - performance evaluation

{{ notes("s4") }} {{ placeholder(slots["CT-25"]) }} {{ placeholder(slots["CT-26"]) }}

4.1 Acceptance criteria as declared (Table T2-2)

{% if has_criteria %} {{ criteria_table(criteria_rows) }} {% else %}

No acceptance criteria were declared; estimates and intervals only.

{% endif %}

4.2 Paired comparison, new version against prior (Table T2-3)

{% if tables.has_margin %}{% endif %} {% for block in tables.per_op %} {% for r in block.rows %} {{ comparison_row(r) }} {% endfor %} {% endfor %} {% for r in tables.free_rows %} {{ comparison_row(r) }} {% endfor %} {% for r in tables.calibration_rows %} {{ comparison_row(r) }} {% endfor %}
Table T2-3 - {{ tables.caption }}. Δ is new − prior; proportions in percentage points, AUROC, Brier and slope on their own scale; the interval method of each Δ is in its Method column{% if not tables.has_margin %}; no paired_difference_vs_prior criterion is declared, so no margin and no status column is printed{% endif %}
Metric (operating point)Prior version k/n (%) [95% CI]New version k/n (%) [95% CI]Δ new − prior [95% CI]MethodDiscordant b / cMcNemar p (method)Margin (criterion id)Status

Clustering route: {{ tables.clustering_route }}; bootstrap B {{ tables.bootstrap.B }}, seed {{ tables.bootstrap.seed }}, {{ tables.bootstrap.interval }} interval (the paired bootstrap differences and any cluster-bootstrap difference).

{{ narrative(comparison_sentences) }}

4.3 Per-subgroup paired comparison (Table T2-4)

{% if tables.subgroup_rows %}
{% for block in tables.per_op %}{% endfor %} {% for s in tables.subgroup_rows %} {% if s.computed %}{% for o in s.ops %}{{ ncell(o.se) }}{{ ncell(o.sp) }}{% endfor %}{{ ncell(s.auroc) }}{% else %}{% endif %} {% endfor %}
Table T2-4 - paired differences (new − prior, percentage points; AUROC on its own scale) per subgroup level, on the pairs in that level of the new version's table; the criterion column prints each paired_difference_vs_prior criterion scoped on the level with its status. Attainability of a paired margin at n is not computed in this build (dash)
AttributeLeveln pairsΔ {{ tables.se_label }} ({{ block.op }})Δ {{ tables.sp_label }} ({{ block.op }})Δ AUROCCriterion (id) and status; attainable at n
{{ s.attribute }}{{ s.level }}{{ s.n_pairs }}not computed ({{ s.reason }}){% for c in s.criteria %}{{ c.id }} (row {{ c.position }}, {{ c.op }}) → {{ c.status_word }}{% if c.record %} - {{ not_met_record }}{% endif %}; attainable: {{ c.attainable }}{% if not loop.last %}
{% endif %}{% else %}—{% endfor %}
{% else %} {{ no_data("Table T2-4 is not printed: per-subgroup paired differences were not computed (" ~ (tables.subgroups_not_computed or "no subgroup rows") ~ ").") }} {% endif %}

4.4 Calibration comparison

The Brier-score and calibration-slope rows of Table T2-3 are the paired bootstrap differences (new − prior) on the same pairs; a score that is not a declared probability carries the typed reason instead of an interval.

4.5 Threshold-free comparison

The AUROC row of Table T2-3 is the paired DeLong difference on independent rows, or the cluster-bootstrap difference with the DeLong refusal recorded beside it on a clustered plan.

4.6 Pairing

{% if tables.paired %}

The two versions were evaluated on the same rows: {{ tables.n_pairs }} pairs joined on row_id.

{% else %}

UNPAIRED - {{ tables.label }}: every difference in this report is between different rows and carries the label in its method.

{{ narrative(unpaired_sentences) }} {% endif %}

4.7 Statement per criterion

{{ narrative(criterion_sentences) }} {% if not criterion_sentences %}

No acceptance criterion was declared, so no criterion statement is made.

{% endif %} {{ page_footer() }}
{{ page_header() }}

5. Modification protocol (4) - update procedures

{{ notes("s5") }} {{ placeholder(slots["CT-27"]) }}

Version stamp: this report evaluates version {{ version_rows[1][1] }} against prior version {{ version_rows[2][1] }}.

{{ narrative(monitoring_sentences) }}

6. Impact assessment inputs

{{ notes("s6") }} {{ placeholder(slots["CT-28"]) }} {{ placeholder(slots["CT-29"]) }}
{% for r in impact_rows %} {{ ncell(r.prior) }}{{ ncell(r.new) }}{{ ncell(r.delta) }} {% endfor %}
Table T2-5 - quantitative deltas: {{ impact_caption }}
MetricScopePrior [95% CI]New [95% CI]Δ [95% CI]
{{ r.metric }}{{ r.scope }}
{{ narrative(impact_sentences) }}

7. Test-set ledger

{{ notes("s7") }}

This test set (SHA-256 {{ ledger.short }}) has been used in {{ ledger.prior_runs }} prior version comparisons recorded in the local ledger; the manufacturer's declared ledger limit (ledger.warn_after_acceptance_runs) is {{ ledger.warn_limit }}.

{% if ledger.limit_reached %}
The count of version comparisons recorded against this test set has reached or exceeded the manufacturer's declared ledger limit (ledger.warn_after_acceptance_runs).
{% endif %} {{ narrative(ledger_sentences) }}

8. Traceability skeleton

{{ notes("s8") }}
{% for r in traceability_rows %} {% else %} {% endfor %}
Table T2-6 - one row per evaluated criterion, by position; the modification id and the monitoring metric ids are the manufacturer's (CT-21, T3) and are not read in this build
#Modification idMP section(s)Criterion idStatusImpact-assessment slotT3 monitoring metric ids
{{ r.position }}{{ r.modification }}{{ r.mp_section }}{{ r.criterion_id }}{{ r.status_word }}{{ r.impact_slot }}{{ r.monitoring }}
No criterion was declared; no traceability row exists.
{{ page_footer() }}
{% endblock %}