Skip to content

adapters: asset-inlining infra + assets/MANIFEST.toml provenance - #26

Merged
cmbays merged 3 commits into
mainfrom
adapters-10-asset-inline
May 22, 2026
Merged

cmbays merged 3 commits into
mainfrom
adapters-10-asset-inline

Conversation

@cmbays

@cmbays cmbays commented May 22, 2026 •

Copy link
Copy Markdown
Contributor

PR 8a (#10) — asset-inlining infrastructure. The vendored frontend
bundle embedded into the binary's .rodata, its supply-chain provenance
contract, and a placeholder smoke renderer proving the bundle assembles
into one self-contained, zero-egress HTML document. Not blocked on the
Claude Design hand-back — that gates PR 8b only.

What shipped

  • Vendored bundle (assets/): Sakura 1.5.0, jQuery 3.7.1,
    DataTables 2.1.8 (JS + CSS), Mermaid 11.15.0 (UMD). Each committed file
    is byte-identical (SHA-256) to a fresh download from its canonical
    URL
    — verified at vendor time — and is the same bundle the R1 spike
    empirically proved renders offline with zero network requests.
  • assets/MANIFEST.toml — one [[asset]] entry per file (name,
    version, path, canonical source URL, sha256, SPDX license; all
    MIT). The supply-chain artifact for the frontend bundle.
  • src/adapters/asset_embed.rs — each asset embedded via
    include_str! into .rodata as a pub const &str. Every v0.1 asset
    is text, so there is no include_bytes! user; the favicon is an
    empty data: URI. MERMAID_INIT is a static constant
    (securityLevel:'strict' + system fontFamily) pinned exact-match by
    a test, so any edit that could reintroduce egress fails the build.
  • smoke_report_html(&CteGraph) — a documented placeholder
    renderer: assembles a self-contained HTML inlining all five assets and
    renders the graph as a Mermaid graph LR diagram. PR 8b replaces it
    with the askama renderer and wires that into the run loop; PR 8a does
    not touch cli.
  • Tests — tests/assets_manifest.rs (provenance integrity: every
    asset listed / SHA-256 matches disk / permissive license / complete
    provenance) and tests/asset_embed.rs (integration coverage against
    the real jaffle-shop CteGraph). A chrome_only-based egress
    self-test scans cute-dbt's own HTML — not the inlined bundles — for
    resource-loading constructs.
  • CI — a new assets-manifest-gate job mirroring
    fixture-manifest-gate: structural enforcement that no assets/ file
    is unlisted and no asset license is copyleft.
  • Doc sync — ARCHITECTURE.md §5 corrected (drop the stale
    include_bytes!/binary-favicon claim; url → source + add path);
    mod.rs + templates/README.md PR-number references updated.

.feature scenarios advanced

report_generation.feature (the self-contained-bundle aspect) and
zero_egress.feature (the asset-manifest invariant + the inlined-bundle
/ data: favicon foundation). Full cucumber wiring lands PR 10.

Quality

cargo fmt, clippy --all-targets pedantic -D warnings, nextest
187 passed, cargo-deny, cargo doc -D warnings.

/atdd gates — crap4rs strict worst 10.0 (threshold 15);
cargo-mutants 98 mutants, 85 caught, 13 unviable, 0 survivors;
CAO clean-arch PASS (0 HIGH; 1 MEDIUM — the ARCHITECTURE.md §5
include_bytes! drift — folded into this PR; 3 INFO carried forward).

Carried to PR 8b (#11)

  • smoke_report_html + its rendering helpers must be deleted (not
    left as dead public surface) when render.rs lands.
  • The CTE→Mermaid string generation is rendering logic; PR 8b decides
    whether askama templates or a render.rs helper own it.

Closes #10

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Self-contained HTML "smoke report" generator with frontend assets inlined as text and an empty favicon data URI.
    • Vendored frontend bundle added (Sakura CSS, jQuery, DataTables JS/CSS, Mermaid) and exposed for embedding.
  • Chores

    • CI job added to validate assets/MANIFEST.toml, file presence, checksums, and approved licenses.
  • Tests

    • Integration tests for asset embedding and manifest provenance/validation.
  • Documentation

    • Updated Architecture and templates docs to reflect embedding and manifest schema.

Review Change Stack

PR 8a (#10). The vendored frontend bundle embedded into the binary's
.rodata, its supply-chain provenance contract, and a placeholder smoke
renderer proving the bundle assembles into one self-contained,
zero-egress HTML document.

- Vendor the five-asset bundle into assets/: Sakura 1.5.0, jQuery 3.7.1,
  DataTables 2.1.8 (JS + CSS), Mermaid 11.15.0 (UMD). The committed bytes
  are byte-identical (SHA-256) to a fresh download from each asset's
  canonical URL — the same bundle the R1 spike empirically proved renders
  offline with zero network requests.
- assets/MANIFEST.toml: one [[asset]] entry per file with name, version,
  path, canonical source URL, SHA-256, and SPDX license (all MIT). This
  is the supply-chain artifact an auditor reads for the frontend bundle,
  paired with Cargo.toml / Cargo.lock / deny.toml for the crate graph.
- src/adapters/asset_embed.rs: each asset embedded via include_str! into
  .rodata as a pub const &str. Every v0.1 asset is text, so there is no
  include_bytes! user; the favicon is an empty data: URI. MERMAID_INIT is
  a static constant (securityLevel:'strict' + system fontFamily — the
  empirical zero-egress contract, ADR-4 §5), pinned exact-match by test.
- smoke_report_html(&CteGraph): a placeholder renderer assembling a
  self-contained HTML that inlines all five assets and renders the graph
  as a Mermaid graph LR diagram. PR 8b replaces it with the askama
  renderer and wires that into the run loop; PR 8a does not touch cli.
- tests/assets_manifest.rs: a cargo test asserting every assets/ file is
  listed, every SHA-256 matches disk, every license is permissive, and
  provenance is complete. tests/asset_embed.rs: integration coverage
  against the real jaffle-shop CteGraph.
- A new assets-manifest-gate CI job, mirroring fixture-manifest-gate:
  structural enforcement that no file under assets/ is unlisted and no
  asset license is copyleft.
- Doc sync (folds in the CAO clean-arch review's MEDIUM): ARCHITECTURE.md
  §5 corrected to drop the stale include_bytes!/binary-favicon claim and
  to rename the MANIFEST field url -> source plus add path; mod.rs and
  templates/README.md PR-number references updated.

Advances report_generation.feature (the self-contained-bundle aspect)
and zero_egress.feature (the asset-manifest invariant plus the
inlined-bundle / data: favicon foundation); cucumber wiring lands PR 10.

Quality: fmt, clippy pedantic -D warnings, nextest 187, cargo-deny,
cargo doc -D warnings. /atdd: crap4rs strict worst 10.0 (threshold 15);
cargo-mutants 98 mutants, 85 caught, 13 unviable, 0 survivors; CAO
clean-arch PASS (0 HIGH; 1 MEDIUM folded in; 3 INFO carried to PR 8b).

Closes #10

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 22, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 99f13277-c1a7-45ff-9e22-359fdda6b5b6

📥 Commits

Reviewing files that changed from the base of the PR and between fa1d1c0 and 57a8591.

📒 Files selected for processing (2)
  • src/adapters/asset_embed.rs
  • tests/assets_manifest.rs

📝 Walkthrough

Walkthrough

This PR inlines vendored frontend assets at compile-time, populates assets/MANIFEST.toml with provenance metadata, adds smoke-report HTML generation that inlines assets and renders a Mermaid graph from a CteGraph, and enforces manifest invariants via tests and a CI job.

Changes

Asset Embedding & Smoke Report

Layer / File(s) Summary
Provenance contract and vendored asset files
ARCHITECTURE.md, assets/MANIFEST.toml, assets/sakura-1.5.0.css, assets/datatables-2.1.8.min.css
assets/MANIFEST.toml schema specifies name, version, path, source, sha256, and license for each vendored asset; Sakura and DataTables CSS files are committed; documentation describes the favicon as an empty data:, URI and the embedding approach via include_str!.
Asset embedding constants and smoke report HTML generation
src/adapters/asset_embed.rs
Module exports string constants for each vendored asset via include_str!, MERMAID_INIT, and FAVICON_DATA_URI. smoke_report_html generates a self-contained HTML document with all assets inlined as <style> and <script> tags. mermaid_block, node_lines, edge_lines, and escape_label helpers render the input CteGraph as a Mermaid graph LR block with mapped join labels and escaped node/label text. Comprehensive unit tests validate pinned assets, escaping, empty-graph rendering, and absence of external-resource egress.
Module export and adapter integration
src/adapters/mod.rs
Adds pub mod asset_embed; declaration and updates documentation to reference concrete PR numbers for asset embedding (8a/#10) and template rendering (8b/#11).
End-to-end integration tests with real dbt fixture
tests/asset_embed.rs
Tests load a real v12 dbt manifest, extract the customers model's compiled SQL into a CteGraph, generate smoke-report HTML via smoke_report_html, and assert that all asset constants are inlined, Mermaid graph includes real and synthetic CTE nodes with correct join-edge labels, and output HTML is well-formed with correct doctype, closing tag, Mermaid container, and empty favicon data URI.
Manifest invariant validation tests
tests/assets_manifest.rs
Loads assets/MANIFEST.toml and validates four invariants: all committed files under assets/ are listed in the manifest and all listed paths exist on disk; each asset's SHA-256 matches the file computed on disk; every license is in a fixed permissive allowlist (MIT, BSD-2-Clause, BSD-3-Clause, Apache-2.0, ISC, 0BSD); every entry records complete provenance (name, version, source as https://…, sha256 as exactly 64 hex characters).
CI enforcement gate and documentation updates
.github/workflows/ci.yml, ARCHITECTURE.md, templates/README.md
Adds assets-manifest-gate CI job that enforces the same manifest invariants via bash/awk (files listed, existence check, license allowlist, SHA-256 verification). Updates ARCHITECTURE.md and templates/README.md to replace #TBD placeholders with concrete PR references and clarify asset embedding details.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #1 — Epic: asset-inlining/manifest (PR8a). This PR implements the asset inlining, populated manifest, and tests/CI described by the epic.

Poem

🐰 A rabbit sings for bundled code and style,
Inlined at build-time, every asset compiled.
Hashes and sources noted, licenses kept light,
No CDNs called — the report is offline and tight.
Hops of joy for a self-contained site!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main objective: asset-inlining infrastructure plus the MANIFEST.toml provenance contract.
Linked Issues check ✅ Passed All acceptance criteria from issue #10 are met: assets vendored with SHA-256/license in MANIFEST.toml, cargo test validates asset integrity, constants exposed via include_str!, Mermaid init static + secure, favicon data URI, smoke template provided, crap4rs passed.
Out of Scope Changes check ✅ Passed All changes are in scope: asset files, MANIFEST.toml, asset_embed.rs embedding logic, tests, CI gate, and documentation updates align directly with issue #10 objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch adapters-10-asset-inline

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the frontend asset-inlining infrastructure, embedding CSS and JS dependencies like Sakura, jQuery, DataTables, and Mermaid directly into the binary's read-only data section at compile time. It establishes a supply-chain provenance contract via assets/MANIFEST.toml and includes a placeholder smoke renderer to verify the generation of self-contained, offline-capable HTML reports. Feedback identified a security vulnerability in the smoke renderer where unescaped CTE names are interpolated into the Mermaid diagram, which could break rendering syntax or lead to Cross-Site Scripting (XSS).

Comment thread src/adapters/asset_embed.rs Outdated
fn node_lines(nodes: &[CteNode]) -> String {
let mut out = String::new();
for (index, node) in nodes.iter().enumerate() {
let _ = writeln!(out, " n{index}[\"{}\"]", node.name());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The node.name() is interpolated directly into the Mermaid block without escaping. This presents two risks:

  1. Mermaid Syntax: If a CTE name contains double quotes (e.g., from a quoted identifier in SQL), it will break the ["..."] node label syntax.
  2. Security (XSS): Since this block is inlined into an HTML <pre> tag, a name containing </pre><script>...</script> could lead to XSS or broken rendering when the report is viewed in a browser.

Even for a placeholder renderer, user-provided identifiers should be sanitized by escaping double quotes and HTML special characters.

Suggested change
let _ = writeln!(out, " n{index}[\"{}\"]", node.name());
let _ = writeln!(out, " n{index}[\"{}\"]", node.name().replace('&', "&amp;").replace('"', "&quot;").replace('<', "&lt;").replace('>', "&gt;"));

CTE names are input-derived — they come from the manifest's compiled
SQL. `node_lines` interpolated them unescaped into the Mermaid `["..."]`
label inside the `<pre>` block, so a quoted SQL identifier carrying a `"`
would break the label syntax, and one carrying HTML metacharacters could
break out of the `<pre>` (broken render or script injection) when the
report is opened in a browser.

Add `escape_label` (escapes `& < > "`, with `&` first so the
substitutions cannot compound) and apply it to every CTE name in
`node_lines`. Covered by a direct unit test and a hostile-name smoke
test. Flagged by the gemini-code-assist bot review on PR #26.

Quality: fmt, clippy pedantic -D warnings, nextest 189. /atdd: crap4rs
strict worst 10.0 (threshold 15); cargo-mutants 100 mutants, 87 caught,
13 unviable, 0 survivors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 299-312: The assets-manifest-gate job is using actions/checkout@v4
without a pinned commit, not setting persist-credentials: false, and the
workflow lacks an explicit least-privilege permissions block; update the job so
the checkout step references a full commit SHA for actions/checkout, add
persist-credentials: false to that checkout step, and add a minimal permissions
block (e.g., contents: read and any other exact scopes needed) at the job (or
top-level) to restrict the token; target the job named assets-manifest-gate and
the checkout step in the steps list when making these changes.

In `@src/adapters/asset_embed.rs`:
- Around line 169-174: The escape_label function currently replaces double
quotes with the HTML entity "&quot;" which breaks Mermaid node labels; change
the replacement for '"' to use Mermaid-safe "`#quot`;" in the escape_label
function and update the corresponding unit test expectations (the test covering
label escaping that asserts for "&quot;") to expect "`#quot`;" instead so the test
reflects the new Mermaid-safe escaping.

In `@tests/assets_manifest.rs`:
- Around line 88-94: The code inserts filesystem paths from
abs.strip_prefix(&root)...to_string() into the set `out` using platform-native
separators, causing mismatches with manifest paths that use POSIX `/`; update
the logic around the `rel` variable (the value passed into `out.insert(rel)`) to
normalize separators to POSIX form before insertion (e.g., convert backslashes
to forward slashes or use a canonical POSIX-style join) so all entries inserted
by the `rel` computation are compared using `/` separators.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e48f7e46-406d-4a61-b4b5-7abcd9b9869a

📥 Commits

Reviewing files that changed from the base of the PR and between 8900ce2 and fa1d1c0.

⛔ Files ignored due to path filters (3)
  • assets/datatables-2.1.8.min.js is excluded by !**/*.min.js
  • assets/jquery-3.7.1.min.js is excluded by !**/*.min.js
  • assets/mermaid-11.15.0.umd.min.js is excluded by !**/*.min.js
📒 Files selected for processing (10)
  • .github/workflows/ci.yml
  • ARCHITECTURE.md
  • assets/MANIFEST.toml
  • assets/datatables-2.1.8.min.css
  • assets/sakura-1.5.0.css
  • src/adapters/asset_embed.rs
  • src/adapters/mod.rs
  • templates/README.md
  • tests/asset_embed.rs
  • tests/assets_manifest.rs

Comment thread .github/workflows/ci.yml
Comment on lines +299 to +312
assets-manifest-gate:
# Vendored-asset provenance invariant. Every file under `assets/`
# (except MANIFEST.toml itself) MUST be listed in `assets/MANIFEST.toml`
# with a permissive (non-copyleft) SPDX license. This is the STRUCTURAL
# gate; `tests/assets_manifest.rs` mirrors the constraint and adds
# SHA-256 verification for fast local signal. Shape mirrors
# `fixture-manifest-gate`. No untrusted GitHub event interpolation in
# any `run:` block.
name: Asset-provenance gate (every asset listed in MANIFEST.toml)
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Every assets/* file must be listed in MANIFEST.toml

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify the new job block has explicit permissions and hardened checkout settings.
awk '
  /^  assets-manifest-gate:/ {in_job=1}
  in_job {print}
  /^  resource-ref-lint:/ {in_job=0}
' .github/workflows/ci.yml > /tmp/assets-manifest-gate.yml

echo "== uses entries =="
rg -n 'uses:' /tmp/assets-manifest-gate.yml

echo "== permissions block =="
rg -n '^    permissions:|^      contents:' /tmp/assets-manifest-gate.yml || true

echo "== checkout credential persistence =="
rg -n 'persist-credentials' /tmp/assets-manifest-gate.yml || true

Repository: breezy-bays-labs/cute-dbt

Length of output: 187


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=".github/workflows/ci.yml"

echo "== workflow top-level permissions (if any) =="
rg -n "^(permissions:|default:|on:)" "$file" || true
head -n 120 "$file" | nl -ba | sed -n '1,120p'

echo
echo "== assets-manifest-gate job block (context) =="
nl -ba "$file" | sed -n '250,360p'

echo
echo "== uses entries within assets-manifest-gate =="
awk '
  /^  assets-manifest-gate:/ {in_job=1}
  in_job {print}
  /^  [a-zA-Z0-9_-]+:/ { if (seen && !/^  assets-manifest-gate:/) exit }
  BEGIN{seen=0}
  /^  assets-manifest-gate:/ {seen=1}
' "$file" | rg -n "uses:|with:|permissions:|persist-credentials" || true

echo
echo "== checkout occurrences elsewhere (to see existing hardening pattern) =="
rg -n "uses:\s*actions/checkout@" "$file" -n

Repository: breezy-bays-labs/cute-dbt

Length of output: 182


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=".github/workflows/ci.yml"

echo "== first 140 lines (for top-level permissions/default) =="
sed -n '1,140p' "$file" | cat -n

echo
echo "== assets-manifest-gate job block (around 250-380) =="
sed -n '250,380p' "$file" | cat -n

echo
echo "== assets-manifest-gate: uses/with/permissions/persist-credentials =="
awk '
  /^  assets-manifest-gate:/ {in_job=1}
  in_job {print}
  /^  [a-zA-Z0-9_-]+:/ { if (in_job && !/^  assets-manifest-gate:/) {exit} }
' "$file" | rg -n 'uses:|with:|permissions:|persist-credentials|checkout@'

Repository: breezy-bays-labs/cute-dbt

Length of output: 12115


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=".github/workflows/ci.yml"

echo "== all permissions: occurrences =="
rg -n "^[[:space:]]*permissions:" "$file" || true

echo
echo "== all persist-credentials occurrences =="
rg -n "persist-credentials" "$file" || true

Repository: breezy-bays-labs/cute-dbt

Length of output: 147


Harden assets-manifest-gate permissions and checkout action pinning.

  • assets-manifest-gate uses actions/checkout@v4 without pinning to a full commit SHA.
  • No persist-credentials: false is set for checkout.
  • The workflow contains no permissions: block anywhere, so this job inherits broader token defaults.
Suggested patch
   assets-manifest-gate:
@@
     runs-on: ubuntu-latest
     timeout-minutes: 5
+    permissions:
+      contents: read
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@<FULL_LENGTH_COMMIT_SHA>
+        with:
+          persist-credentials: false
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 311-311: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 299-379: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 311-311: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 299 - 312, The assets-manifest-gate
job is using actions/checkout@v4 without a pinned commit, not setting
persist-credentials: false, and the workflow lacks an explicit least-privilege
permissions block; update the job so the checkout step references a full commit
SHA for actions/checkout, add persist-credentials: false to that checkout step,
and add a minimal permissions block (e.g., contents: read and any other exact
scopes needed) at the job (or top-level) to restrict the token; target the job
named assets-manifest-gate and the checkout step in the steps list when making
these changes.

Comment thread src/adapters/asset_embed.rs
Comment thread tests/assets_manifest.rs
Two findings from the CodeRabbit review on PR #26:

- `escape_label` mapped `"` to the HTML entity `&quot;`, but the Mermaid
  block is inlined into a `<pre>` element: the browser's HTML parser
  decodes `&quot;` back to `"` before Mermaid parses the `["..."]`
  label, breaking it. Switch to Mermaid's own `#quot;` escape — it
  carries no `&`, survives the HTML decode, and Mermaid resolves it to a
  literal quote. `& < >` keep their HTML entities; those guard the HTML
  layer (a raw `<` could close the `<pre>`).
- `assets_manifest.rs::walk_committed_assets` built relative paths with
  the platform separator; normalize to POSIX `/` so the disk walk
  matches MANIFEST.toml's forward-slash paths on every platform.

The third CodeRabbit finding — CI workflow hardening (scope
GITHUB_TOKEN, SHA-pin actions, persist-credentials: false) — is deferred
to #27: the new assets-manifest-gate job follows the existing
workflow-wide convention, so the fix belongs workflow-wide, not bolted
onto one job in isolation.

Quality: fmt, clippy pedantic -D warnings, nextest 189. /atdd: crap4rs
strict worst 10.0 (threshold 15); cargo-mutants 100 mutants, 87 caught,
13 unviable, 0 survivors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@cmbays

cmbays commented May 22, 2026

Copy link
Copy Markdown
Contributor Author

Bot-review dispositions

Thanks to @coderabbitai and gemini-code-assist — between them they caught a real defect. Dispositions for every finding, all in commits fa1d1c0 + 57a8591:

Finding Severity Disposition
gemini — node.name() interpolated unescaped into the Mermaid label (injection / syntax break) HIGH Fixed — added escape_label, applied to every CTE name.
CodeRabbit — escape_label used HTML &quot; for ", which Mermaid does not honour Major Fixed — the <pre> HTML parser decodes &quot; back to " before Mermaid sees the ["..."] label; switched to Mermaid's own #quot; escape, which carries no &, survives the HTML decode, and Mermaid resolves it. & < > keep HTML entities — those guard the HTML layer. Good catch; gemini flagged that the name needed escaping, CodeRabbit corrected how.
CodeRabbit — walk_committed_assets used platform path separators Minor Fixed — normalized to POSIX / so the disk walk matches MANIFEST.toml on every platform.
CodeRabbit — assets-manifest-gate lacks a permissions: block / SHA-pinned actions / persist-credentials: false Major Deferred to #27. The new job follows the workflow-wide convention — every job uses actions/checkout@v4 unpinned with no permissions: block. Hardening one job in isolation would leave it inconsistent with the other ~15; the correct fix scopes the token, SHA-pins, and disables credential persistence workflow-wide, which needs verifying that artifact upload/download and the crap4rs cargo install step still pass under a scoped token. Filed as #27 (type:chore, priority:soon).

All /atdd gates re-passed on 57a8591: crap4rs strict worst 10.0, cargo-mutants 100 mutants / 0 survivors, nextest 189.

@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@cmbays — thank you for the thorough disposition table; this is exactly the kind of structured close-out that makes a review useful after the fact.

On the two CodeRabbit fixes:

  • The #quot; correction is technically precise and the reasoning holds: because Mermaid labels are parsed inside a <pre> block, the browser's HTML decoder runs first and &quot; collapses back to " before Mermaid ever sees the ["…"] label syntax — whereas #quot; has no & and survives the HTML decode pass intact. I'll store that as a learning for future Mermaid-in-HTML reviews.
  • The POSIX-normalization fix for walk_committed_assets is the right call for cross-platform correctness.

On the deferred CI hardening (#27):

The rationale is sound. Hardening one job in isolation while the other ~15 remain unpinned and unpermissioned would give a false sense of security without actually narrowing the attack surface — and risks breaking artifact/cargo install steps under a tighter token scope. A workflow-wide pass is the correct unit of change.

Congratulations on the clean /atdd re-run — 0 mutant survivors and 189 nextest passes is a solid signal.

ʕ •ᴥ•ʔ 🎉


✏️ Learnings added
Learnt from: cmbays
URL: https://github.com/breezy-bays-labs/cute-dbt/pull/26

Timestamp: 2026-05-22T20:48:12.325Z
Learning: In Rust projects generating HTML that embeds Mermaid diagrams (e.g., via a `<pre class="mermaid">` block), do NOT use HTML entities like `&quot;` to escape double-quote characters inside Mermaid node labels (e.g., `["label"]` syntax). The browser HTML-decodes `&quot;` → `"` before Mermaid processes the label, breaking the label syntax. Use Mermaid's own `#quot;` escape instead, which carries no `&`, survives the HTML decode pass, and is resolved by Mermaid. The `&amp;`, `&lt;`, `&gt;` HTML entities are still correct for guarding `&`, `<`, `>` at the HTML layer since those characters do not appear in Mermaid label delimiters.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@cmbays
cmbays merged commit 51098fe into main May 22, 2026
18 checks passed
@cmbays
cmbays deleted the adapters-10-asset-inline branch May 22, 2026 20:52
cmbays added a commit that referenced this pull request May 23, 2026
asset_embed.rs (added in PR #26, merged after the branch was cut)
still imported JoinType and called edge.join_type(). After rebasing
onto main, update all references: JoinType → EdgeType, join_type() →
edge_type(), join_label → edge_label covering all 8 EdgeType variants
(From, Inner, Left, Right, Full, Cross, UnionAll, UnionDistinct).

Test: join_label_covers_every_join_kind →
      edge_label_covers_every_edge_kind (8 variants).
New test: mermaid_block_labels_from_and_union_edges.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

adapters: asset inlining infra + assets/MANIFEST.toml provenance

1 participant