Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 56 additions & 13 deletions crates/rite-render/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,22 +492,27 @@ pub(crate) fn render_prose_html(text: &str) -> String {
}

/// Build a deterministic, unique abbreviation for every role, keyed by id.
#[allow(clippy::arithmetic_side_effects)]
fn build_abbrevs(resolved: &Ceremony) -> HashMap<RoleId, String> {
let mut used: HashSet<String> = HashSet::new();
let mut out = HashMap::new();
for (id, role) in resolved.roles.iter() {
let base = abbrev_of(&role.name);
let mut candidate = base.clone();
let mut n = 2u32;
while used.contains(&candidate) {
candidate = format!("{base}{n}");
n += 1;
}
used.insert(candidate.clone());
out.insert(id.clone(), candidate);
resolved
.roles
.iter()
.map(|(id, role)| (id.clone(), unique_abbrev(&abbrev_of(&role.name), &mut used)))
.collect()
}

/// Reserve a unique abbreviation derived from `base`, suffixing `2`, `3`, ...
/// on collision. Records the chosen value in `used` so later calls stay unique.
#[allow(clippy::arithmetic_side_effects)]
fn unique_abbrev(base: &str, used: &mut HashSet<String>) -> String {
let mut candidate = base.to_string();
let mut n = 2u32;
while used.contains(&candidate) {
candidate = format!("{base}{n}");
n += 1;
}
out
used.insert(candidate.clone());
candidate
}

/// Derive a short abbreviation from a role name.
Expand Down Expand Up @@ -559,6 +564,8 @@ pub struct ReportView {
pub deviations: Vec<DeviationView>,
/// Produced artifacts.
pub artifacts: Vec<ArtifactView>,
/// Distinct roles seen in the log, with abbreviations (legend).
pub roles: Vec<ReportRoleView>,
/// Per-step execution log.
pub steps: Vec<ExecStepView>,
/// The `rite` version that produced the report.
Expand Down Expand Up @@ -617,6 +624,15 @@ pub struct ArtifactView {
pub sha256: String,
}

/// A role in the report's roles legend.
#[derive(Debug, Clone, Serialize)]
pub struct ReportRoleView {
/// Human-readable role name.
pub name: String,
/// Short abbreviation, unique within the report.
pub abbrev: String,
}

/// A per-step row in the report execution log.
#[derive(Debug, Clone, Serialize)]
pub struct ExecStepView {
Expand All @@ -626,6 +642,8 @@ pub struct ExecStepView {
pub label: String,
/// Role name.
pub role: String,
/// Role abbreviation, matching the roles legend.
pub role_abbrev: String,
/// Formatted start timestamp.
pub started: String,
/// Formatted completion timestamp, if any.
Expand Down Expand Up @@ -673,6 +691,25 @@ impl ReportView {
})
})
.collect();
// The report is transcript-only, so roles come from the names recorded
// in the log. Abbreviate them with the same helpers the script uses, so
// a run's report and its script agree on `CO`, `Wi`, and so on.
let mut used = HashSet::new();
let mut roles: Vec<ReportRoleView> = Vec::new();
for name in data.steps.iter().map(|s| &s.role) {
if roles.iter().any(|r| &r.name == name) {
continue;
}
roles.push(ReportRoleView {
name: name.clone(),
abbrev: unique_abbrev(&abbrev_of(name), &mut used),
});
}
let abbrev_by_name: HashMap<&str, &str> = roles
.iter()
.map(|r| (r.name.as_str(), r.abbrev.as_str()))
.collect();

let steps = data
.steps
.iter()
Expand All @@ -684,6 +721,11 @@ impl ReportView {
ExecStepView {
step_id: s.step_id.clone(),
label: s.label.clone(),
role_abbrev: abbrev_by_name
.get(s.role.as_str())
.copied()
.unwrap_or_default()
.to_string(),
role: s.role.clone(),
started: format_datetime(&s.started_at),
completed: s.completed_at.as_ref().map(format_datetime),
Expand All @@ -710,6 +752,7 @@ impl ReportView {
attempts,
deviations,
artifacts,
roles,
steps,
rite_version: env!("CARGO_PKG_VERSION").to_string(),
}
Expand Down
18 changes: 14 additions & 4 deletions crates/rite-render/templates/report.html.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
{%- if branding.brand_name %}
<p class="brand-name">{{ branding.brand_name }}</p>
{%- endif %}
<h1>{{ report.ceremony_name }} &middot; Ceremony Report</h1>
<p class="doc-eyebrow">Ceremony Report</p>
<h1>{{ report.ceremony_name }}</h1>
</header>

<div class="summary-box">
Expand Down Expand Up @@ -63,7 +64,7 @@
{%- if report.artifacts %}
<h2>Artifacts</h2>
<table class="artifacts">
<thead><tr><th>Name</th><th>Step</th><th>Path</th><th>SHA-256</th></tr></thead>
<thead><tr><th>Name</th><th>Step</th><th>Path</th><th>Fingerprint</th></tr></thead>
<tbody>
{%- for a in report.artifacts %}
<tr><td>{{ a.name }}</td><td><code>{{ a.step_id }}</code></td><td><code>{{ a.path }}</code></td><td><code class="hash">{{ a.sha256 }}</code></td></tr>
Expand All @@ -72,13 +73,22 @@
</table>
{%- endif %}

{%- if report.roles %}
<h2>Roles</h2>
<ul class="roles">
{%- for r in report.roles %}
<li><span class="role-abbrev">{{ r.abbrev }}</span> <strong>{{ r.name }}</strong></li>
{%- endfor %}
</ul>
{%- endif %}

{%- if report.steps %}
<h2>Execution Log</h2>
<table class="execution-log">
<thead><tr><th>Step</th><th>Label</th><th>Role</th><th>Started</th><th>Completed</th><th>Outcome</th></tr></thead>
<thead><tr><th class="step-num">Label</th><th>Step</th><th class="role">Role</th><th>Started</th><th>Completed</th><th>Outcome</th></tr></thead>
<tbody>
{%- for s in report.steps %}
<tr><td><code>{{ s.step_id }}</code></td><td>{{ s.label }}</td><td><code>{{ s.role }}</code></td><td>{{ s.started }}</td><td>{{ s.completed if s.completed else "&ndash;" | safe }}</td><td>{{ s.outcome }}</td></tr>
<tr><td class="step-num">{{ s.label }}</td><td><code>{{ s.step_id }}</code></td><td class="role">{% if s.role_abbrev %}<abbr title="{{ s.role }}">{{ s.role_abbrev }}</abbr>{% else %}{{ s.role }}{% endif %}</td><td>{{ s.started }}</td><td>{{ s.completed if s.completed else "&ndash;" | safe }}</td><td>{{ s.outcome }}</td></tr>
{%- endfor %}
</tbody>
</table>
Expand Down
2 changes: 2 additions & 0 deletions crates/rite-render/templates/themes/formal.css
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,8 @@ code, .hash {
}
.hash {
word-break: break-all;
/* Slightly smaller so a full fingerprint stays compact in a narrow column. */
font-size: 0.75em;
}
.status-completed {
color: #1f6b2e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,8 @@ code, .hash {
}
.hash {
word-break: break-all;
/* Slightly smaller so a full fingerprint stays compact in a narrow column. */
font-size: 0.75em;
}
.status-completed {
color: #1f6b2e;
Expand Down Expand Up @@ -527,7 +529,8 @@ code, .hash {
</head>
<body class="theme-formal report">
<header class="doc-header">
<h1> &middot; Ceremony Report</h1>
<p class="doc-eyebrow">Ceremony Report</p>
<h1></h1>
</header>

<div class="summary-box">
Expand Down
6 changes: 4 additions & 2 deletions crates/rite-render/tests/snapshots/render__script_demo.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ expression: html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Root Signing Key Ceremony</title>
<title>Demo: Root Signing Key Ceremony</title>
<style>
/* Formal theme: a serif "ceremony protocol" look.
Shared by ceremony scripts and post-ceremony reports.
Expand Down Expand Up @@ -447,6 +447,8 @@ code, .hash {
}
.hash {
word-break: break-all;
/* Slightly smaller so a full fingerprint stays compact in a narrow column. */
font-size: 0.75em;
}
.status-completed {
color: #1f6b2e;
Expand Down Expand Up @@ -528,7 +530,7 @@ code, .hash {
<body class="theme-formal">
<header class="doc-header">
<p class="doc-eyebrow">Ceremony Protocol</p>
<h1>Root Signing Key Ceremony</h1>
<h1>Demo: Root Signing Key Ceremony</h1>
</header>
<section>
<h2>Overview</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,8 @@ code, .hash {
}
.hash {
word-break: break-all;
/* Slightly smaller so a full fingerprint stays compact in a narrow column. */
font-size: 0.75em;
}
.status-completed {
color: #1f6b2e;
Expand Down
42 changes: 26 additions & 16 deletions docs/demo/demo-report.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Root Signing Key Ceremony &middot; Ceremony Report</title>
<title>Demo: Root Signing Key Ceremony &middot; Ceremony Report</title>
<style>
/* Formal theme: a serif "ceremony protocol" look.
Shared by ceremony scripts and post-ceremony reports.
Expand Down Expand Up @@ -443,6 +443,8 @@
}
.hash {
word-break: break-all;
/* Slightly smaller so a full fingerprint stays compact in a narrow column. */
font-size: 0.75em;
}
.status-completed {
color: #1f6b2e;
Expand Down Expand Up @@ -523,35 +525,43 @@
</head>
<body class="theme-formal report">
<header class="doc-header">
<h1>Root Signing Key Ceremony &middot; Ceremony Report</h1>
<img class="brand-logo" src="data:image&#x2f;svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMzIuMjE0IiBoZWlnaHQ9IjU0OS4wODYiIHZpZXdCb3g9IjAgMCAzMzIuMjE0IDU0OS4wODYiPjxwYXRoIGQ9Ik0xNDEuMjE0IDU0OS4wODZIMGMyNS4yODctNzkuMTQ0IDUwLjc0LTE1OC4yOTUgNzUuNjI4LTIzNy41NDcgMS4wNDUtNy4xNDgtMTAuMzYxLTkuNTIzLTEzLjk0My0xNS4zMDItMTguODA2LTE3LjQ3NC0zMy42Mi0zOS4xODMtNDEuNjItNjMuNjgzLTYuODQ3LTE5Ljc5OS05LjI1Ny00MC44MjgtNy4yNjctNjEuNjY1IDEuNTM3LTMwLjI3IDE0LjIyNC01OS4zNyAzMi41NjktODMuMjMgMjQuMjQyLTI5Ljk2IDU5LjY3Ny01MS4zMyA5OC4xNi01Ni4xNDctMyAxMi4xMTYtNS42OTYgMjQuMzAyLTguMzMzIDM2LjUwMi0yOS4yNjMgNy41OS01NS4wODQgMjcuMjYyLTcxLjAxMSA1Mi44MzMtMTIuNTQ0IDIwLjg5My0xOS4yMDggNDUuMjY2LTE3LjMgNjkuNjU2LjM2NSAyMS42NzQgOC45MzYgNDIuODA0IDIwLjYzNSA2MC44MzUgMTIuMDExIDE3LjE4OCAyOC41IDMwLjUzOCA0Ni45MiA0MC4zNiA1Ljk0OSAzLjYyNi0yLjYyMiAxMi45MTQtMi42NzQgMTguOTgyLTIxLjA5OCA2OC4yNS00My4yNzEgMTM2LjI5NC02NC41NSAyMDQuNDA2aDk0em0xMi4wNzYgMGMtLjU3My0zMC45MDIuMzY0LTYyLjE2NC0xLjE0OC05Mi44NDItNS4zOTEtMTMuMjI4LTEzLjU5MS0yNC42NS0yMy4wNTUtMzUuMjYgOS42My0yNy4yMzYgMTAuNjA2LTU2LjYyNSAxMS40NTEtODUuMjMzLjY5LTc3Ljg5NS40NzMtMTU1Ljg1NCAxLjcyNy0yMzMuNzA4QzE0Ni40ODggNjcuMjUgMTUzLjQyIDMyLjQzOCAxNjYuOTY2IDBjMTIuMjg1IDMzLjQ2NSAyMC44MzMgNjguMjM4IDI0LjE0NiAxMDMuNzc0IDEuNDI0IDgzLjA3Ny44ODcgMTY2LjI3IDIuMDcxIDI0OS4zNyAxLjQxNyAyMy4xMyAzLjkxMyA0Ni4yOTYgMTEuMDY3IDY4LjQ0Mi0xMS43NzQgMTIuNDM2LTIyLjQ1NyAyNy40My0yNC4wMTEgNDQuODVsLS4wMjUgNDguNjVoMTA1LjEzNWMtMjMuMjY2LTczLjkyLTQ2LjkwNi0xNDcuNzM0LTcwLjIxLTIyMS42MzggMjMuMzI0LTExLjk4IDQ0LjIyMi0yOS43MTcgNTYuNTA3LTUzLjE4MiAxMi45MDMtMjMuOTA1IDE3Ljc4NS01Mi4zODYgMTIuMDk2LTc5LjA3Mi02LjcxMy0zNy4yNTUtMzIuNjg3LTcwLjItNjYuODg2LTg2LjE2My02LjE5NS0yLjcwOC0xMi44NzctNC42MjEtMTguODAxLTcuNzctMi42OTQtMTIuMDk3LTUuNTAzLTI0LjE2Ny04LjExMi0zNi4yODEgMjkuODY2IDUuMDgzIDU4LjEyIDE4LjM2OCA4MC40NTQgMzguOTQ1IDI1LjU2MiAyMy4zIDQyLjU1IDU1LjM4IDQ4LjQ2OCA4OS40MDkgMS40MiAxNS4zOTcgMS4wNDMgMzEuMzEzLjMxMiA0Ni43NjItNS43NCAzNi44ODktMjQuODQzIDcxLjU2Mi01My45ODggOTUuMDY0LTcuNDI1IDQuMjAxLTEwLjk3NyA5LjQwOC02LjIyNSAxNy4zNDMgMjQuNDQ3IDc2Ljg0NiA0OC45NTEgMTUzLjcxMyA3My4yNSAyMzAuNTgzSDE1My4yOW0xMi42MjgtOTdjMS45NDctNS40NTMuNzg3LTE0LjQ3MiAxLjI5Ni0yMS44Mi0uMzI1LTExMy4yNjEuNjgxLTIyNi41MzMtLjU2NS0zMzkuNzg3bC0uNzY2LTQ4Ljc1NGMtOC4xMTMgMjkuOTY4LTEzLjM3IDYwLjk1OC0xMi4xMSA5Mi4wOTgtLjY3IDc1LjE5Mi0uMzk2IDE1MC40MzMtMS42NTcgMjI1LjU5NS0xLjcwNCAxOS45OC00LjE4OCAzOS45MjctOS4xNTUgNTkuMzg2IDkuMjEyIDkuNzI5IDE0Ljk5NiAyMS44MDcgMjEuNjYxIDMzLjI4MmgxLjI4NHoiIHN0eWxlPSJmaWxsOiMwMDAiLz48L3N2Zz4=" alt="">
<p class="brand-name">Rite-ly</p>
<p class="doc-eyebrow">Ceremony Report</p>
<h1>Demo: Root Signing Key Ceremony</h1>
</header>

<div class="summary-box">
<p><strong>Status:</strong> <span class="status-completed">Completed</span></p>
<p><strong>Started:</strong> 2026-07-07 19:23:18 UTC</p>
<p><strong>Completed:</strong> 2026-07-07 19:23:18 UTC</p>
<p><strong>Started:</strong> 2026-07-23 16:09:32 UTC</p>
<p><strong>Completed:</strong> 2026-07-23 16:09:33 UTC</p>
<p><strong>Duration:</strong> 0s</p>
<p><strong>Transcript fingerprint:</strong> <code>sha256:14847d519a3aeaff043c753e2085174875a6b0d2ea8e135c0cc361efa778f636</code></p>
<p><strong>Transcript fingerprint:</strong> <code>sha256:dc1b8eec6e91ac01d0d870142b641c7ba303c2fec78b1763cd388fee92d30d0a</code></p>
</div>
<h2>Artifacts</h2>
<table class="artifacts">
<thead><tr><th>Name</th><th>Step</th><th>Path</th><th>SHA-256</th></tr></thead>
<thead><tr><th>Name</th><th>Step</th><th>Path</th><th>Fingerprint</th></tr></thead>
<tbody>
<tr><td>root_cert</td><td><code>issue_root_cert</code></td><td><code>artifacts&#x2f;root_cert.pem</code></td><td><code class="hash">sha256:18748c897380c803a6647cb02d678a0b1459ae29c3a295264cdce9835be5882e</code></td></tr>
<tr><td>root_public_key</td><td><code>export_public_key</code></td><td><code>artifacts&#x2f;root_public_key.pem</code></td><td><code class="hash">sha256:ecd78f448fe482966f74c350a8c852c7f7a63e69b1c6c9685e8aed0f0958e7f9</code></td></tr>
<tr><td>root_cert</td><td><code>issue_root_cert</code></td><td><code>artifacts&#x2f;root_cert.pem</code></td><td><code class="hash">sha256:6138e4d87a2eeea14b40f5de8f520143e42f9ed47d074d38019103faedf6f32d</code></td></tr>
<tr><td>root_public_key</td><td><code>export_public_key</code></td><td><code>artifacts&#x2f;root_public_key.pem</code></td><td><code class="hash">sha256:a589d40b33a937c3f477ff0550516b7ff2ee12210d3ae6a6381f60f207cdb256</code></td></tr>
</tbody>
</table>
<h2>Roles</h2>
<ul class="roles">
<li><span class="role-abbrev">CO</span> <strong>Crypto Officer</strong></li>
<li><span class="role-abbrev">Wi</span> <strong>Witness</strong></li>
</ul>
<h2>Execution Log</h2>
<table class="execution-log">
<thead><tr><th>Step</th><th>Label</th><th>Role</th><th>Started</th><th>Completed</th><th>Outcome</th></tr></thead>
<thead><tr><th class="step-num">Label</th><th>Step</th><th class="role">Role</th><th>Started</th><th>Completed</th><th>Outcome</th></tr></thead>
<tbody>
<tr><td><code>verify_air_gap</code></td><td>1</td><td><code>Crypto Officer</code></td><td>2026-07-07 19:23:18 UTC</td><td>2026-07-07 19:23:18 UTC</td><td>completed, Verification confirmed</td></tr>
<tr><td><code>generate_root_key</code></td><td>2</td><td><code>Crypto Officer</code></td><td>2026-07-07 19:23:18 UTC</td><td>2026-07-07 19:23:18 UTC</td><td>completed, RSA-4096 keypair generated</td></tr>
<tr><td><code>generate_root_csr</code></td><td>3</td><td><code>Crypto Officer</code></td><td>2026-07-07 19:23:18 UTC</td><td>2026-07-07 19:23:18 UTC</td><td>completed, PKCS#10 CSR generated</td></tr>
<tr><td><code>issue_root_cert</code></td><td>4</td><td><code>Crypto Officer</code></td><td>2026-07-07 19:23:18 UTC</td><td>2026-07-07 19:23:18 UTC</td><td>completed, X.509 certificate issued from CSR</td></tr>
<tr><td><code>export_public_key</code></td><td>5</td><td><code>Crypto Officer</code></td><td>2026-07-07 19:23:18 UTC</td><td>2026-07-07 19:23:18 UTC</td><td>completed, Public key exported</td></tr>
<tr><td><code>witness_attest</code></td><td>6</td><td><code>Witness</code></td><td>2026-07-07 19:23:18 UTC</td><td>2026-07-07 19:23:18 UTC</td><td>completed, Attestation recorded for Witness</td></tr>
<tr><td><code>officer_attest</code></td><td>7</td><td><code>Crypto Officer</code></td><td>2026-07-07 19:23:18 UTC</td><td>2026-07-07 19:23:18 UTC</td><td>completed, Attestation recorded for Crypto Officer</td></tr>
<tr><td class="step-num">1</td><td><code>verify_air_gap</code></td><td class="role"><abbr title="Crypto Officer">CO</abbr></td><td>2026-07-23 16:09:32 UTC</td><td>2026-07-23 16:09:32 UTC</td><td>completed, Verification confirmed</td></tr>
<tr><td class="step-num">2</td><td><code>generate_root_key</code></td><td class="role"><abbr title="Crypto Officer">CO</abbr></td><td>2026-07-23 16:09:32 UTC</td><td>2026-07-23 16:09:32 UTC</td><td>completed, RSA-4096 keypair generated</td></tr>
<tr><td class="step-num">3</td><td><code>generate_root_csr</code></td><td class="role"><abbr title="Crypto Officer">CO</abbr></td><td>2026-07-23 16:09:32 UTC</td><td>2026-07-23 16:09:32 UTC</td><td>completed, PKCS#10 CSR generated</td></tr>
<tr><td class="step-num">4</td><td><code>issue_root_cert</code></td><td class="role"><abbr title="Crypto Officer">CO</abbr></td><td>2026-07-23 16:09:32 UTC</td><td>2026-07-23 16:09:33 UTC</td><td>completed, X.509 certificate issued from CSR</td></tr>
<tr><td class="step-num">5</td><td><code>export_public_key</code></td><td class="role"><abbr title="Crypto Officer">CO</abbr></td><td>2026-07-23 16:09:33 UTC</td><td>2026-07-23 16:09:33 UTC</td><td>completed, Public key exported</td></tr>
<tr><td class="step-num">6</td><td><code>witness_attest</code></td><td class="role"><abbr title="Witness">Wi</abbr></td><td>2026-07-23 16:09:33 UTC</td><td>2026-07-23 16:09:33 UTC</td><td>completed, Attestation recorded for Witness</td></tr>
<tr><td class="step-num">7</td><td><code>officer_attest</code></td><td class="role"><abbr title="Crypto Officer">CO</abbr></td><td>2026-07-23 16:09:33 UTC</td><td>2026-07-23 16:09:33 UTC</td><td>completed, Attestation recorded for Crypto Officer</td></tr>
</tbody>
</table>

Expand Down
8 changes: 6 additions & 2 deletions docs/demo/demo-script.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Root Signing Key Ceremony</title>
<title>Demo: Root Signing Key Ceremony</title>
<style>
/* Formal theme: a serif "ceremony protocol" look.
Shared by ceremony scripts and post-ceremony reports.
Expand Down Expand Up @@ -443,6 +443,8 @@
}
.hash {
word-break: break-all;
/* Slightly smaller so a full fingerprint stays compact in a narrow column. */
font-size: 0.75em;
}
.status-completed {
color: #1f6b2e;
Expand Down Expand Up @@ -523,8 +525,10 @@
</head>
<body class="theme-formal">
<header class="doc-header">
<img class="brand-logo" src="data:image&#x2f;svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMzIuMjE0IiBoZWlnaHQ9IjU0OS4wODYiIHZpZXdCb3g9IjAgMCAzMzIuMjE0IDU0OS4wODYiPjxwYXRoIGQ9Ik0xNDEuMjE0IDU0OS4wODZIMGMyNS4yODctNzkuMTQ0IDUwLjc0LTE1OC4yOTUgNzUuNjI4LTIzNy41NDcgMS4wNDUtNy4xNDgtMTAuMzYxLTkuNTIzLTEzLjk0My0xNS4zMDItMTguODA2LTE3LjQ3NC0zMy42Mi0zOS4xODMtNDEuNjItNjMuNjgzLTYuODQ3LTE5Ljc5OS05LjI1Ny00MC44MjgtNy4yNjctNjEuNjY1IDEuNTM3LTMwLjI3IDE0LjIyNC01OS4zNyAzMi41NjktODMuMjMgMjQuMjQyLTI5Ljk2IDU5LjY3Ny01MS4zMyA5OC4xNi01Ni4xNDctMyAxMi4xMTYtNS42OTYgMjQuMzAyLTguMzMzIDM2LjUwMi0yOS4yNjMgNy41OS01NS4wODQgMjcuMjYyLTcxLjAxMSA1Mi44MzMtMTIuNTQ0IDIwLjg5My0xOS4yMDggNDUuMjY2LTE3LjMgNjkuNjU2LjM2NSAyMS42NzQgOC45MzYgNDIuODA0IDIwLjYzNSA2MC44MzUgMTIuMDExIDE3LjE4OCAyOC41IDMwLjUzOCA0Ni45MiA0MC4zNiA1Ljk0OSAzLjYyNi0yLjYyMiAxMi45MTQtMi42NzQgMTguOTgyLTIxLjA5OCA2OC4yNS00My4yNzEgMTM2LjI5NC02NC41NSAyMDQuNDA2aDk0em0xMi4wNzYgMGMtLjU3My0zMC45MDIuMzY0LTYyLjE2NC0xLjE0OC05Mi44NDItNS4zOTEtMTMuMjI4LTEzLjU5MS0yNC42NS0yMy4wNTUtMzUuMjYgOS42My0yNy4yMzYgMTAuNjA2LTU2LjYyNSAxMS40NTEtODUuMjMzLjY5LTc3Ljg5NS40NzMtMTU1Ljg1NCAxLjcyNy0yMzMuNzA4QzE0Ni40ODggNjcuMjUgMTUzLjQyIDMyLjQzOCAxNjYuOTY2IDBjMTIuMjg1IDMzLjQ2NSAyMC44MzMgNjguMjM4IDI0LjE0NiAxMDMuNzc0IDEuNDI0IDgzLjA3Ny44ODcgMTY2LjI3IDIuMDcxIDI0OS4zNyAxLjQxNyAyMy4xMyAzLjkxMyA0Ni4yOTYgMTEuMDY3IDY4LjQ0Mi0xMS43NzQgMTIuNDM2LTIyLjQ1NyAyNy40My0yNC4wMTEgNDQuODVsLS4wMjUgNDguNjVoMTA1LjEzNWMtMjMuMjY2LTczLjkyLTQ2LjkwNi0xNDcuNzM0LTcwLjIxLTIyMS42MzggMjMuMzI0LTExLjk4IDQ0LjIyMi0yOS43MTcgNTYuNTA3LTUzLjE4MiAxMi45MDMtMjMuOTA1IDE3Ljc4NS01Mi4zODYgMTIuMDk2LTc5LjA3Mi02LjcxMy0zNy4yNTUtMzIuNjg3LTcwLjItNjYuODg2LTg2LjE2My02LjE5NS0yLjcwOC0xMi44NzctNC42MjEtMTguODAxLTcuNzctMi42OTQtMTIuMDk3LTUuNTAzLTI0LjE2Ny04LjExMi0zNi4yODEgMjkuODY2IDUuMDgzIDU4LjEyIDE4LjM2OCA4MC40NTQgMzguOTQ1IDI1LjU2MiAyMy4zIDQyLjU1IDU1LjM4IDQ4LjQ2OCA4OS40MDkgMS40MiAxNS4zOTcgMS4wNDMgMzEuMzEzLjMxMiA0Ni43NjItNS43NCAzNi44ODktMjQuODQzIDcxLjU2Mi01My45ODggOTUuMDY0LTcuNDI1IDQuMjAxLTEwLjk3NyA5LjQwOC02LjIyNSAxNy4zNDMgMjQuNDQ3IDc2Ljg0NiA0OC45NTEgMTUzLjcxMyA3My4yNSAyMzAuNTgzSDE1My4yOW0xMi42MjgtOTdjMS45NDctNS40NTMuNzg3LTE0LjQ3MiAxLjI5Ni0yMS44Mi0uMzI1LTExMy4yNjEuNjgxLTIyNi41MzMtLjU2NS0zMzkuNzg3bC0uNzY2LTQ4Ljc1NGMtOC4xMTMgMjkuOTY4LTEzLjM3IDYwLjk1OC0xMi4xMSA5Mi4wOTgtLjY3IDc1LjE5Mi0uMzk2IDE1MC40MzMtMS42NTcgMjI1LjU5NS0xLjcwNCAxOS45OC00LjE4OCAzOS45MjctOS4xNTUgNTkuMzg2IDkuMjEyIDkuNzI5IDE0Ljk5NiAyMS44MDcgMjEuNjYxIDMzLjI4MmgxLjI4NHoiIHN0eWxlPSJmaWxsOiMwMDAiLz48L3N2Zz4=" alt="">
<p class="brand-name">Rite-ly</p>
<p class="doc-eyebrow">Ceremony Protocol</p>
<h1>Root Signing Key Ceremony</h1>
<h1>Demo: Root Signing Key Ceremony</h1>
</header>
<section>
<h2>Overview</h2>
Expand Down
Loading