# ADR-001: No Subresource Integrity (SRI) on docs-site CDN scripts

- **Status:** Accepted
- **Date:** 2026-07-01
- **Tracking:** Genesis NOJS-207

## Context

The documentation site loads the framework from always-latest CDN endpoints
without `integrity`/`crossorigin` attributes:

- `docs/index.html` and `docs/404.html` load
  `https://cdn.no-js.dev/` and `https://cdn-elements.no-js.dev/`
  (jsDelivr-backed, serving the latest tagged release — the URL is unpinned).
- The same pages load a Google Fonts stylesheet, also without SRI.

Two properties of this setup conflict with SRI:

1. **Unpinned URLs.** SRI requires a fixed hash of the exact bytes served. The
   CDN endpoints intentionally serve the latest release, so any fixed hash
   would break the docs site on every release until the HTML was updated.
2. **Dev-server rewrite.** `docs/dev-server.js` rewrites `cdn.no-js.dev` to
   the local build on the fly for local docs testing. An `integrity`
   attribute in the HTML would fail against the rewritten local bytes and
   break that workflow.

The Google Fonts stylesheet cannot practically carry SRI at all: Google serves
UA-specific CSS, so the response bytes vary per browser. Omitting SRI there is
the industry-accepted norm.

## Decision

**Accept the risk of loading unpinned, non-SRI CDN scripts on the docs site.**
No `integrity` attributes will be added; the URLs stay unpinned.

Rationale:

- The always-latest CDN endpoint **is the product being demonstrated**. The
  docs site dogfoods the exact `<script src="https://cdn.no-js.dev/">` snippet
  users are told to copy. Pinning the docs would stop exercising that path.
- The docs site is static content: no user accounts, sessions, credentials, or
  user data. The realistic blast radius of a compromised CDN response is
  defacement or drive-by content injection on a documentation page — serious,
  but bounded, and the same compromise (of the GitHub release or jsDelivr)
  would equally affect every downstream user regardless of what the docs do.

Compensating controls (existing, not invented):

- `cdn.no-js.dev` / `cdn-elements.no-js.dev` DNS and the jsDelivr source
  (GitHub releases on protected `main`, tag-driven) are controlled by the
  maintainer; releases require PR + merge + tag, limiting who can change the
  served bytes.
- The dev-server rewrite means local docs testing runs against the local
  build, so a poisoned CDN would not silently contaminate development.

## Consequences

### Negative (explicit)

- **No integrity guarantee:** a compromise of jsDelivr, the GitHub release
  artifacts, or the `cdn.no-js.dev` DNS records lets an attacker execute
  arbitrary script on the docs site. SRI would have detected byte tampering
  (though not a malicious-but-validly-hashed release).
- **No CSP-style backstop is added by this ADR** — the acceptance is of the
  full risk, not a mitigated version of it.
- Automated security scanners will continue to flag the missing SRI; this ADR
  is the canonical answer to those findings.

### Positive

- Docs always demonstrate the current release with zero release-time HTML
  churn; no risk of shipping a stale or mismatched hash.
- Local docs testing via the dev-server rewrite keeps working unchanged.

## Alternatives Considered

### Option A — Pin to versioned jsDelivr URLs + SRI (rejected)

Reference exact versions (e.g. `cdn.jsdelivr.net/gh/no-js-dev/nojs@vX.Y.Z/...`)
with `integrity` hashes, regenerated by a new release step.

Rejected because:

- **Release burden:** every release must regenerate two hashes and edit two
  HTML files; a missed step ships a broken or stale docs site.
- **Stale-pin risk:** the docs would demonstrate an old version whenever the
  pin lags, undermining the dogfooding goal.
- **Dev-server conflict:** the local-rewrite workflow would need integrity
  stripping or per-environment HTML, adding tooling for a static site.

### Google Fonts SRI (not applicable)

UA-varying CSS makes a fixed hash impossible; accepted as-is.
