# HTML presentation failure-recovery corpus

This corpus contains five small, reviewable failure/fix pairs used by the Slidesfly article
“HTML presentation not working after publishing.” Executable source is stored as `.txt` so the
Slidesfly app origin never serves these intentionally broken fixtures as runnable HTML or
JavaScript.

## Recorded cases

| Case | Failing condition | Fixed condition | Deterministic evidence |
| --- | --- | --- | --- |
| `missing-asset` | HTML requests a packaged file that is absent | The referenced SVG is included at the same relative path | Chrome text state plus asset HTTP status |
| `wrong-base-path` | A root-relative URL escapes the deployed subdirectory | The URL is relative to the deck entry point | Chrome text state plus requested URL and HTTP status |
| `csp-inline-script` | `script-src 'self'` blocks an inline script | The script becomes a same-origin file without weakening CSP | Chrome text state plus runtime HTTP status |
| `remote-runtime` | A single-file upload loads a remote script | The required runtime is inlined | Current `scanHtmlUpload` return value |
| `zip-root` | `index.html` is nested under `dist/` | `index.html` is at the archive root | Current `extractDeckZip` error or extracted paths |

The complete observations and fixture SHA-256 values are in [`results.json`](results.json).

## Reproduce the three browser cases

From the repository root, create a temporary directory. Copy each `.html.txt` file to the indicated
`index.html` path and each asset/runtime `.txt` file to its real extension:

```text
<temporary-root>/missing/failing/index.html
<temporary-root>/missing/fixed/index.html
<temporary-root>/missing/fixed/assets/chart.svg
<temporary-root>/base/failing/deck/index.html
<temporary-root>/base/failing/deck/assets/chart.svg
<temporary-root>/base/fixed/deck/index.html
<temporary-root>/base/fixed/deck/assets/chart.svg
<temporary-root>/csp/failing/index.html
<temporary-root>/csp/fixed/index.html
<temporary-root>/csp/fixed/runtime.js
```

Serve the temporary root without changing any source bytes:

```bash
python3 -m http.server 3142 --bind 127.0.0.1 --directory <temporary-root>
```

Open these URLs in a clean Chrome profile and read the `#result` text while observing the Network
panel:

```text
http://127.0.0.1:3142/missing/failing/index.html
http://127.0.0.1:3142/missing/fixed/index.html
http://127.0.0.1:3142/base/failing/deck/index.html
http://127.0.0.1:3142/base/fixed/deck/index.html
http://127.0.0.1:3142/csp/failing/index.html
http://127.0.0.1:3142/csp/fixed/index.html
```

The failing and fixed missing-asset HTML intentionally differ only in the document title; the
repair is the presence of `assets/chart.svg`. The two base-path packages contain the same asset;
the repair is the URL in HTML. The CSP repair moves code into `runtime.js` and keeps the policy
unchanged.

## Reproduce the upload-policy cases

The repository quality test
`apps/web/lib/blog/failure-recovery-quality.test.ts` reads the public fixture sources and calls the
current product functions directly:

- `scanHtmlUpload` must reject the remote-runtime failing source and accept the inlined source.
- `extractDeckZip` must reject in-memory entries under `dist/` and accept the same entry names at
  the archive root.

Run it from the repository root:

```bash
pnpm --filter @slidesfly/web exec vitest run lib/blog/failure-recovery-quality.test.ts
```

## Evidence boundary

This is a local, deterministic diagnostic corpus, not a performance benchmark, security
certification, framework-compatibility claim, or production publish. No public deployment, viewer
event, account mutation, or third-party request was created while recording it. A passing fixture
does not prove that every slide, plugin, media format, browser, or hosting policy will work.
