{% if render_mode != 'fragment' %} {% if domain %}{% endif %} License Diff - Finite State Report {% include "_design_system.html" %} {% include "_console_shell.html" %} {% endif %} {% if render_mode != 'fragment' %} {% endif %} {% import "_console_macros.html" as fs with context %} {# Defensive defaults #} {% set summary = summary | default({}) %} {% if summary is not mapping %}{% set summary = {} %}{% endif %} {% set license_changes = license_changes | default([]) %} {% set copyleft_deltas = copyleft_deltas | default([]) %} {% set empty_side = empty_side | default(None) %} {% set left_label = summary.get('left_label', 'Left') if summary is mapping else 'Left' %} {% set right_label = summary.get('right_label', 'Right') if summary is mapping else 'Right' %} {# Summary counts — every dynamic number in this section comes from here #} {% set license_changes_count = summary.get('license_changes_count', 0) if summary is mapping else 0 %} {% set copyleft_additions_count = summary.get('copyleft_additions_count', 0) if summary is mapping else 0 %} {% set copyleft_removals_count = summary.get('copyleft_removals_count', 0) if summary is mapping else 0 %} {% set copyleft_changes_count = summary.get('copyleft_changes_count', 0) if summary is mapping else 0 %} {% if render_mode != 'fragment' %} {{ fs.topbar( crumbs=["Finite State", "License Diff"], meta=[ {"label": "Left", "value": left_label}, {"label": "Right", "value": right_label}, {"label": "Generated", "value": generated_at or "—"}, ], controls=[], ) }} {% endif %}

License Comparison

{{ left_label }} vs {{ right_label }}

{% if empty_side %}
{% if empty_side == 'both' %}

Both scopes had no component data.

{% elif empty_side == 'left' %}

{{ left_label }} scope had no data — nothing to compare.

{% elif empty_side == 'right' %}

{{ right_label }} scope had no data — nothing to compare.

{% endif %}
{% else %} {# Lede stat-line — fixed string + summary slots (README §03) #}

{{ license_changes_count }} license-set changes · {{ copyleft_additions_count }} copyleft added · {{ copyleft_removals_count }} removed · {{ copyleft_changes_count }} tier shifts across shared components.

● {{ left_label }} vs {{ right_label }} ●
{# KPI summary row #}
{{ fs.kpi_cell("License Changes", license_changes_count, dot=("high" if license_changes_count > 0 else None)) }} {{ fs.kpi_cell("Copyleft Added", copyleft_additions_count, dot=("critical" if copyleft_additions_count > 0 else None)) }} {{ fs.kpi_cell("Copyleft Removed", copyleft_removals_count, dot=("low" if copyleft_removals_count > 0 else None)) }} {{ fs.kpi_cell("Copyleft Tier Shifts", copyleft_changes_count, dot=("medium" if copyleft_changes_count > 0 else None)) }}
{# Aligned strip when the facet is FULLY clear. The spec's shorthand is (license_changes_count == 0 and copyleft_changes_count == 0); HARDENED here to gate on ALL FOUR summary counts — license_changes_count + copyleft_additions_count + copyleft_removals_count + copyleft_changes_count (copyleft_changes_count is only tier-shifts; additions/removals are separate) — so the facet is demoted ONLY when truly clear, never hiding an added/removed copyleft obligation. (Flagged in the build report.) #} {% if license_changes_count == 0 and copyleft_additions_count == 0 and copyleft_removals_count == 0 and copyleft_changes_count == 0 %} {# DEMOTED aligned state — single compact strip, fixed copy + summary slots #}
No action needed. Every shared component carries the same license set across {{ left_label }} and {{ right_label }} — no copyleft added, removed, or shifted tier.
{{ license_changes_count }} changes · {{ copyleft_additions_count + copyleft_removals_count }} copyleft · {{ copyleft_changes_count }} tier shifts
{% else %} {# License changes table #} {% if license_changes and license_changes | length > 0 %}
{{ fs.panel_head("License changes", meta=(license_changes | length | string) ~ " component" ~ ("s" if license_changes | length != 1 else "")) }}

Shared components whose license set changed between {{ left_label }} and {{ right_label }}.

{% for row in license_changes %} {% endfor %}
Component {{ left_label }} Licenses {{ right_label }} Licenses Project
{{ row.name or '—' }} {{ row.left_licenses or '(none)' }} {{ row.right_licenses or '(none)' }} {{ row.project_name or '—' }}
{% endif %} {# Copyleft deltas table #} {% if copyleft_deltas and copyleft_deltas | length > 0 %}
{{ fs.panel_head("Copyleft deltas", meta=(copyleft_deltas | length | string) ~ " component" ~ ("s" if copyleft_deltas | length != 1 else "")) }}

Components whose copyleft classification changed: added, removed, or tier-shifted (e.g. Strong ↔ Weak Copyleft).

{% for row in copyleft_deltas %} {% set family_cls = 'strong' if row.family == 'Strong Copyleft' else 'weak' %} {% set is_added = 'added' in row.direction %} {% endfor %}
Component Family Direction Project
{{ row.name or '—' }} {{ row.family or '—' }} {{ row.direction or '—' }} {{ row.project_name or '—' }}
{% endif %} {% if not license_changes and not copyleft_deltas %}

No license differences found between {{ left_label }} and {{ right_label }}.

{% endif %} {% endif %}{# end aligned vs tables #} {% endif %}{# end empty_side else #}
{% if render_mode != 'fragment' %} {{ fs.status_bar(items=[ "Recipe: License Diff", "Left: " ~ left_label, "Right: " ~ right_label, generated_at | default(''), ], version='fs-report ' ~ (fs_report_version | default('dev'))) }} {% include '_action_buttons.html' %} {% endif %}