# Breadth-Test Corpus — Rendering Manifest v0.1

**The rendering stage is part of the frozen apparatus, not a neutral pass-through.** The synthetic S2 corpus was born as clean markdown; the real 13-document corpus is fetched HTML that must be rendered to plain text before ingestion, and that rendering stage can itself produce artifacts (boilerplate leakage, flattened tables, dropped code) that would masquerade as "real-prose properties" in the eventual census if left unexamined. This document records the rendering apparatus and the per-document sanity check, per the operator's 2026-08-20 rider, before the full run.

## Apparatus

`trafilatura` **2.2.0**, installed into `ngramdb/.venv` for this task. Settings: `include_comments=False, include_tables=True, favor_precision=True`. Script: `scratch/extract_breadth_corpus.py`.

**`favor_precision`, not `favor_recall`:** a first pass with `favor_recall=True` leaked nav/footer/CTA boilerplate on the two marketing-CMS-hosted blog posts — GitLab 2017 ("Duo Agent Platform delivers 400% ROI" at the head, "Start building faster today" at the tail) and Twilio 2013 ("Resource Center" / "Ahoy — Twilio's developer community hub" at the tail). `favor_precision` cleans both with negligible content loss elsewhere (Cloudflare 3000→2974 words, GitLab-2017 3747→2876 words spot-checked against the raw source — no real paragraphs dropped, only chrome). Applied uniformly to all 8 HTML-sourced documents, not selected per-document. Twilio's tail still carried a residual "Related Posts / Related Resources" block past `favor_precision`; fixed with one named, manual trim at the verified true end of the article prose ("...all the steps that follow.") rather than a further blind parameter search — recorded as `MANUAL_TRIM_AFTER` in the script, not a silent edit.

The 5 already-clean-markdown documents (Ory Hydra design doc, 4 Backstage ADRs) are copied as-is — no rendering stage applies.

## Per-document sanity check (head/tail eyeball against the raw source, post-render)

| # | File | Head clean? | Tail clean? | Note |
|---|---|---|---|---|
| 1 | 01_cloudflare_outage_2025-11-18.md | yes | yes | Starts at "On 18 November 2025..."; ends at the real incident timeline table. |
| 2 | 02_gitlab_db_outage_postmortem_2017-01-31.md | yes | yes | Was leaking marketing chrome under favor_recall; clean under favor_precision. One small residual: a few sentences near the true tail read as an unrelated embedded FAQ snippet (merge-request/pipeline troubleshooting text) that doesn't belong to the outage narrative — flagged, not scrubbed further; low-impact (~5 sentences out of 2,876 words). |
| 3 | 03_gitlab_issue_17057.md | yes | yes | Issue-template body only (see comment-scope note below). |
| 4 | 04_gitlab_issue_18490.md | yes | yes | Issue-template body only. |
| 5 | 05_gitlab_issue_18596.md | yes | yes | Issue-template body only. |
| 6 | 06_gitlab_issue_15999.md | yes | yes | Issue-template body only. |
| 7 | 07_aws_s3_disruption_2017-02-28.md | yes | yes | Clean at both ends, no rendering issue found. |
| 8 | 08_ory_hydra_flow_cache_design_doc.md | yes | yes | Copied as-is, no rendering stage. |
| 9 | 09_backstage_adr002_default_catalog_file_format.md | yes | yes | Copied as-is (YAML front matter is genuine source content, not chrome). |
| 10 | 10_backstage_adr005_catalog_core_entities.md | yes | yes | Copied as-is. |
| 11 | 11_backstage_adr009_entity_references.md | yes | yes | Copied as-is. |
| 12 | 12_backstage_adr011_plugin_package_structure.md | yes | yes | Copied as-is. |
| 13 | 13_twilio_billing_postmortem_2013.md | yes | yes | Cleaned via `favor_precision` + manual trim; tail now ends at genuine article close. |

## GitLab issue-tracker rendering scope — issue body only, no comments (deliberate, uniform)

All 4 GitLab issue-tracker documents (#17057, #18490, #18596, #15999) render **the issue description/body only — zero comments** — and this is structural, not incidental. GitLab's issue page is a Vue SPA: the comment/discussion thread is not present in the server-rendered HTML at all, it loads via a separate async API call (confirmed on #17057's raw fetch: `data-notes-path=".../noteable/issue/137365573/notes"`, `prerenderedNotesCount: 10` — ten comments exist on that issue, none present in the bytes a plain `curl` receives). Since all 4 documents were fetched the same way (plain `curl`, no JS execution), this scope is uniform across the sub-genre by construction, not a per-document accident. Recorded as the sub-genre definition: **issue-tracker incident review = issue body/description text, never discussion/comment threads**, for `breadth-test-analysis-amendments-v0_1.md`'s Amendment 2.

## Word-count correction — supersedes finding #0's raw-fetch numbers for analysis purposes

`breadth-test-corpus-frozen-v0_1.md`'s word counts (and breadth finding #0) were computed by tag-stripping the **full raw page**, chrome included — a rougher proxy, flagged as such at the time. The rendered/clean counts below are what actually feeds the ingest pipeline and are the more honest basis for any real-vs-synthetic length comparison:

| # | File | Frozen-manifest word count (raw, chrome-inclusive) | Rendered word count (clean, ingestion input) |
|---|---|---|---|
| 1 | Cloudflare | 4,549 | 2,974 |
| 2 | GitLab 2017 | 4,395 | 2,876 |
| 3 | GitLab #17057 | 904 | 935 |
| 4 | GitLab #18490 | 327 | 213 |
| 5 | GitLab #18596 | 375 | 254 |
| 6 | GitLab #15999 | 1,197 | 1,140 |
| 7 | AWS S3 | 1,927 | 905 |
| 8 | Ory Hydra | 751 | 751 |
| 9 | Backstage ADR002 | 1,293 | 1,293 |
| 10 | Backstage ADR005 | 519 | 519 |
| 11 | Backstage ADR009 | 362 | 362 |
| 12 | Backstage ADR011 | 509 | 509 |
| 13 | Twilio | 4,402 | 1,172 |

**Corrected breadth finding #0**, clean-text basis: n=13, min=213, max=2974, mean=1069.5, median=905 (sorted: 213, 254, 362, 509, 519, 751, 905, 935, 1140, 1172, 1293, 2876, 2974) — vs. the synthetic S2 band of 742–2041 (mean 1285, median ≈1389, n=18). The corrected picture is a real but less extreme divergence than the raw-count version reported: only 2 of 13 (Cloudflare, GitLab-2017, both blog postmortems) exceed the S2 max, by roughly 40% rather than 2×; the short end (issue-tracker items and short ADRs) is unchanged and remains the more pronounced deviation — 6 of 13 documents sit below the S2 minimum. This is the number that should be cited in `breadth-test-findings-v0_1.md`'s comparison table, not the raw-fetch figure.

**What did not change:** the frozen manifest's SHA-256 hashes, URLs, and liveness verification remain the corpus's identity of record (that's about the fetched artifact, not the rendering), so `breadth-test-corpus-frozen-v0_1.md` is not re-frozen or re-hashed. Only the word-count figures feeding the length-norm analysis are corrected here, via this rendering manifest.
