df940d75 Andy McCall 1 month ago ↶
1
{% extends "base.html" %}
2
{% import "repo_tabs.html" as m %}
3
{% block title %}Trust · {{ t.tag }} · {{ repo.owner }}/{{ repo.name }}{% endblock %}
4
{% block bodyattrs %} data-repo="{{ repo.url }}"{% endblock %}
5
{% block tabs %}{% call m::tabs(repo, "releases") %}{% endblock %}
6
{% block mainclass %} class="wide"{% endblock %}
7
{% block content %}
8
< div class = " head " > < h1 > Trust < small > release < a href = " {{ repo.url }}/releases/tag/{{ t.tag }}" > {{ t.tag }}</ a > {% if !t.title.is_empty() %} · {{ t.title }}{% endif %}</ small > </ h1 >
9
< a class = " go small " href = " ?format=json" download > Export JSON</ a > </ div >
10
< p class = " small mute " > Who wrote what this release holds, how it is authenticated, what built each asset and from what, with every claim audited below.{% if let Some(p) = t.since %} Changes are counted since the previous release, {{ p }}.{% endif %} The export carries the signed receipts: check each with < code > oxy receipt verify</ code > .</ p >
11
bf5101d3 Andy McCall 1 month ago ↶
12
< ul class = " plain trust-summary " > {% for b in t.summary() %}< li class = " tb tb-{{ b.class }} " > < span class = " tb-mark " aria-hidden = " true" > {% if b.class == "pass" %}< svg viewBox = " 0 0 16 16" width = " 14" height = " 14" > < path d = " M5 7V5a3 3 0 0 1 6 0v2" fill = " none" stroke = " currentColor" stroke-width = " 1.6" /> < rect x = " 3.5" y = " 7" width = " 9" height = " 7" rx = " 1.5" fill = " currentColor" /> </ svg > {% else if b.class == "warn" %}!{% else %}✘{% endif %}</ span > {{ b.text }}</ li > {% endfor %}</ ul >
13
df940d75 Andy McCall 1 month ago ↶
14
< section class = " panel audit audit-{{ t.verdict_class() }} " >
15
< h2 > Audit < span class = " small mute " > {{ t.audit.len()|plural("check", "checks") }}</ span > </ h2 >
16
< ul class = " plain checks " > {% for c in t.audit %}< li class = " {{ c.class() }} " > < span class = " glyph " > {{ c.glyph() }}</ span > < strong > {{ c.title }}</ strong > {% if !c.detail.is_empty() %} < span class = " small mute " > {{ c.detail }}</ span > {% endif %}</ li > {% endfor %}</ ul >
17
</ section >
18
19
< section class = " panel " >
20
< h2 > Graph</ h2 >
bf5101d3 Andy McCall 1 month ago ↶
21
< p class = " small mute " > Authors → the tagged state → the jobs that built the assets → the assets. A lock marks what is signed and checked, < strong > !</ strong > what is not (unsigned, or uploaded by hand), < strong > ✘</ strong > what fails. A dashed line is a build from another state than the tag's. Hover a box for the details.</ p >
df940d75 Andy McCall 1 month ago ↶
22
< div class = " trust-graph-wrap " > {{ graph|safe }}</ div >
23
</ section >
24
25
< section class = " panel " >
26
< h2 > Tag < span class = " lbl lbl-tag " > {{ t.tag }}</ span > </ h2 >
27
< dl class = " facts " >
28
< dt > Signature</ dt > < dd > {% if t.tag_signature == "valid" %}< span class = " sig sig-valid " > ✔</ span > valid{% else if t.tag_signature == "unsigned" %}< span class = " sig sig-unsigned " > ○</ span > unsigned{% else %}< span class = " sig sig-invalid " > ✘</ span > {{ t.tag_signature }}{% endif %}{% if let Some(k) = t.tag_signer %} · {% if let Some(a) = k.account %}< a href = " /{{ a }}" > {{ k.name }}</ a > {% else %}{{ k.name }}{% endif %} < code title = " {{ k.key }}" > {{ k.key|short }}</ code > {% endif %}</ dd >
29
< dt > State</ dt > < dd > {% for h in t.heads %}< a class = " chip " href = " {{ repo.url }}/change/{{ h }}" > {{ h|short }}</ a > {% endfor %}</ dd >
30
</ dl >
31
</ section >
32
33
< section class = " panel " >
34
< h2 > Authors < span class = " small mute " > {{ t.changes|plural("change", "changes") }}</ span > </ h2 >
35
< div class = " table " > < table >
36
< tr > < th > Author</ th > < th > Key</ th > < th > Changes</ th > < th > Signed</ th > < th > Sealed</ th > < th > Unsigned</ th > < th > Problems</ th > </ tr >
37
{% for a in t.authors %}< tr > < td > {% if let Some(acc) = a.who.account %}< a href = " /{{ acc }}" > {{ a.who.name }}</ a > {% else %}{{ a.who.name }}{% endif %}</ td > < td > < code title = " {{ a.who.key }}" > {{ a.who.key|short }}</ code > </ td > < td > {{ a.changes }}</ td > < td > {{ a.signed }}</ td > < td > {{ a.sealed }}</ td > < td > {% if a.unsigned > 0 %}< span class = " warn " > {{ a.unsigned }}</ span > {% else %}0{% endif %}</ td > < td > {% if a.invalid + a.revoked > 0 %}< span class = " bad " > {{ a.invalid }} invalid, {{ a.revoked }} revoked</ span > {% else %}none{% endif %}</ td > </ tr > {% endfor %}
38
</ table > </ div >
39
</ section >
40
41
< section class = " panel " >
42
< h2 > Assets</ h2 >
43
{% if t.assets.is_empty() %}< p class = " mute " > This release has no assets.</ p > {% endif %}
44
{% for a in t.assets %}
bf5101d3 Andy McCall 1 month ago ↶
45
< h3 > < a href = " {{ a.url }}" > {{ a.name }}</ a > {% if let Some(b) = a.build %}{% if b.receipt.is_some() & & b.receipt_problem.is_none() %}< span class = " tb tb-pass tb-sm " > attested build</ span > {% else %}< span class = " tb tb-warn tb-sm " > built, not attested</ span > {% endif %}{% else %}< span class = " tb tb-warn tb-sm " > uploaded by hand</ span > {% endif %} < span class = " small mute " > {{ a.size|bytes }} · blake3 < code title = " {{ a.blake3 }}" > {{ a.blake3|short }}</ code > </ span > </ h3 >
df940d75 Andy McCall 1 month ago ↶
46
{% if let Some(b) = a.build %}
47
< dl class = " facts " >
48
< dt > Built by</ dt > < dd > < a href = " {{ b.run_url }}" > run #{{ b.run }}</ a > job < strong > {{ b.job }}</ strong > {% if let Some(c) = b.exit_code %}, exit {{ c }}{% endif %}</ dd >
49
< dt > Runner</ dt > < dd > {% if let Some(r) = b.runner %}{{ r.name }} < code title = " {{ r.key }}" > {{ r.key|short }}</ code > {% if b.runner_known %} < span class = " tag " > runner key of this hub</ span > {% endif %}{% if b.runner_revoked %} < span class = " tag bad " > revoked</ span > {% endif %}{% else %}< span class = " mute " > no signed receipt</ span > {% endif %}</ dd >
50
< dt > Receipt</ dt > < dd > {% if let Some(u) = b.receipt_url %}< a href = " {{ u }}" > signed receipt</ a > {% if let Some(p) = b.receipt_problem %} < span class = " bad " > {{ p }}</ span > {% else %} < span class = " sig sig-valid " > ✔</ span > verifies{% endif %}{% else %}< span class = " mute " > none kept</ span > {% endif %}</ dd >
51
< dt > Environment</ dt > < dd > {{ b.runtime }} · rootfs < code title = " {{ b.rootfs }}" > {{ b.rootfs|short }}</ code > · environment < code title = " {{ b.environment }}" > {{ b.environment|short }}</ code > </ dd >
52
< dt > Inputs</ dt > < dd > state {% for h in b.heads.split('+') %}< a class = " chip " href = " {{ repo.url }}/change/{{ h }}" > {{ h|short }}</ a > {% endfor %}{% if b.same_state_as_tag %}< span class = " tag " > the tagged state</ span > {% else %}< span class = " tag warn " > not the tagged state</ span > {% endif %} · pipeline < code title = " {{ b.pipeline_hash }}" > {{ b.pipeline_hash|short }}</ code > · scope < code title = " {{ b.scope_tree_hash }}" > {{ b.scope_tree_hash|short }}</ code > </ dd >
53
</ dl >
54
{% else %}
55
< p class = " small warn " > No passed OxygenFlow job of this repository produced these bytes: uploaded by hand.</ p >
56
{% endif %}
57
{% endfor %}
58
</ section >
59
{% endblock %}