fix(export): compliance bundle was 842 MB dashboard mirror#279
Merged
Conversation
The release pipeline shipped `rivet-v0.9.0-compliance-report.tar.gz` at
842 MB — a static mirror of the `rivet serve` dashboard (index.html,
coverage/, help/, validate/, matrix/, graph/, per-schema help pages,
AADL viewer JS, source mirrors). That's a browseable website dump,
not the audit-quality bundle the artifact name implies. Auditors got
a confusing browse tree instead of a focused dossier.
Three changes restore the audit-bundle shape:
1. **rivet-cli/src/main.rs (`cmd_export_html`):** the `single_page`,
`theme`, and `offline` parameters were all `_`-prefixed — explicitly
ignored by the function body. The CLI surface advertised them and
the help text described them, but the binary swallowed them silently.
Un-underscored and wired through: when `--single-page` is true, the
function now calls `rivet_core::export::render_single_page` and
writes one `index.html` to the output directory, returning early
before the multi-page mirror path. `--offline` is honored by
building the `ExportConfig` with `offline: true`. `--theme` selects
`ExportTheme::Dark` or `ExportTheme::Light`.
2. **rivet-core/src/export.rs (`render_single_page` callee):** byte-
indexing panic at line 1875. The graph-node sublabel did
`&title[..26]` which panics on any title with a multi-byte UTF-8
character at the 26-byte boundary (e.g. an em-dash `—` at chars
25-27). Replaced with `title.chars().take(26).collect::<String>()`
plus an ellipsis. Surfaces on the rivet repo's own dogfood —
"Human review degradation — reviewer trusts AI without
verification" hits this case.
3. **.github/actions/compliance/action.yml:** add `single-page: true`
as a new input (default true — the action is purpose-built for
compliance reports, where single-page is the right shape) and
flip `offline: 'false' → 'true'` as default (auditors open bundles
disconnected). Pass `--single-page` and `--offline` through to the
`rivet export` invocation.
Result on the rivet repo's own dogfood:
before: rivet-v0.9.0-compliance-report.tar.gz 842 MB
after: single-page index.html 1.4 MB
(600× smaller, all 9 sections inline:
index / requirements / documents / stpa /
eu-ai-act / coverage / matrix / validation / graph,
zero external resources, inline CSS, browser-openable)
Refs: REQ-010 (export contract), REQ-007 (CLI surface)
📐 Rivet artifact deltaNo artifact changes in this PR. Code-only changes (renderer, CLI wiring, tests) don't touch the artifact graph. |
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'Rivet Criterion Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.
| Benchmark suite | Current: adfd297 | Previous: ff89f98 | Ratio |
|---|---|---|---|
store_insert/10000 |
14562227 ns/iter (± 1944650) |
11199692 ns/iter (± 431145) |
1.30 |
This comment was automatically generated by workflow using github-action-benchmark.
3 tasks
avrabe
added a commit
that referenced
this pull request
May 15, 2026
…284) Three PRs today (#279, #281, and previously #275/#278) failed CI on the same test: `graph_focused_view_renders_svg`. Cause is structural, not a real-flake: the test's `fetch()` helper hardcodes a 5s read timeout, and the focused /graph endpoint takes ~5s on the dogfood corpus (742 nodes, 1477 edges) — BFS frontier + etch layout pass. The test sits exactly on the edge; CI runner load tips it over. Add a `fetch_with_timeout(port, path, htmx, timeout)` variant. Keep the default 5s `fetch()` for everything else. Bump the graph test's deadline to 15s — well past the genuine wall-clock for this endpoint and short enough that a real performance regression still bubbles up. The wall-clock `Instant::elapsed()` log line stays, so an actual slow regression would still be visible in the test output even though the read timeout no longer blocks it. Verified locally: `cargo test -p rivet-cli --test serve_integration graph_focused_view_renders_svg` passes in 2.79s with the new helper. Refs: REQ-007 (CLI surface)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The release pipeline shipped `rivet-v0.9.0-compliance-report.tar.gz` at 842 MB — a static mirror of the `rivet serve` dashboard (every page, source mirror, AADL viewer JS, per-schema help pages). That's a browseable website dump, not the audit-quality bundle the artifact name promises. Auditors opening this archive got a confusing browse tree instead of a focused dossier.
Three surgical changes restore the audit-bundle shape:
1. `rivet-cli/src/main.rs` — wire the CLI flags through
`cmd_export_html` declared `single_page`, `theme`, and `offline` parameters all prefixed with `_` — explicitly ignored. The CLI advertised `--single-page` in `--help`; the binary swallowed it silently. Un-underscored and wired through:
2. `rivet-core/src/export.rs` — UTF-8 boundary panic in `render_single_page`
The graph-node sublabel at line 1875 did `&title[..26]` which panics on any title with a multi-byte UTF-8 character at the 26-byte boundary. Hits this dogfood title: "Human review degradation — reviewer trusts AI without verification" (em-dash at bytes 25-27). Replaced with `chars().take(26).collect::()` + ellipsis.
3. `.github/actions/compliance/action.yml` — new `single-page` input
Adds `single-page: true` (default) as a new action input. Compliance reports want single-page by default; the multi-page mirror remains opt-in. Also flips `offline: 'false' → 'true'` as default — auditors typically open bundles disconnected from the internet.
Result (rivet's own dogfood)
Inline sections in the new bundle:
`index`, `requirements`, `documents`, `stpa`, `eu-ai-act`, `coverage`, `matrix`, `validation`, `graph`.
Test plan
Trailer
`Fixes: REQ-010` (export contract integrity) · `Refs: REQ-007` (CLI surface)
🤖 Generated with Claude Code