Where should a playground link point?

The decision behind this PR. Four candidate targets, scored on the four properties that actually matter.

Scorecard

Renders = a human sees the page, not its source. Origin = who serves the bytes. CSP = whether this project's Content-Security-Policy applies. Permanent = survives branch deletion and playground pruning.

TargetRendersOriginOur CSPPermanentVerdict
htmlpreview.github.io/?… yesthird partynoyes Rejected. Serves our HTML from an origin we do not control with none of our CSP. Was recommended in four places.
blob/<branch>/docs/… source onlyGitHubn/ano Rejected. Dies when the head branch is deleted on merge.
raw.githubusercontent… neverGitHubn/ayes Cannot work. GitHub forces text/plain deliberately, as an anti-XSS measure. Safe and therefore unusable.
blob/<SHA>/docs/… source onlyGitHubn/ayes Default for PR bodies. A SHA stays reachable via refs/pull/<N>/head forever. Trades rendering for not handing a third party our content.
orchestkit.yonyon.ai/lab/… yesoursyesyes The real answer, for playgrounds worth keeping. Requires publishing to the Lab.

Why there are two winners, not one

Tier 1 — ephemeral

docs/<branch-slug>/*.html

Attached to a PR to explain that PR. scripts/prune-playgrounds.sh archives these to the orphan playgrounds-archive branch and removes them from main once the branch is gone. They are meant to disappear.

→ link the SHA-pinned blob.

Tier 2 — curated

docs/site/public/lab/<slug>.html

Promoted deliberately, listed at /docs/showcase/lab, often with a case-study page. Served from our origin under the /lab CSP.

→ link the Lab URL.

The mistake this PR corrects is not "playgrounds are unpublished". It is that the guidance pointed at a proxy for tier 1, and never mentioned tier 2 existed.

Promoting to tier 2

1. add an entry to docs/site/lab-manifest.json
   { "slug": "...", "source": "docs/<dir>/<file>.html",
     "title": "...", "description": "...",
     "tags": ["..."], "date": "YYYY-MM-DD" }

2. node docs/site/scripts/generate-lab-data.mjs
   → copies the html into docs/site/public/lab/<slug>.html
   → regenerates lib/generated/lab-data.ts

The generator does the copy, so this is two steps rather than three. It also tolerates a pruned source by falling back to the committed public/lab copy, which is what makes tier 2 survive tier 1's deletion.