/** * Learn — the two tracks, and the host allowlist that turns a pasted link into * an iframe source. * * **Two tracks, and they are not the same kind of thing.** `supply` and * `demand` are CONCEPT material: how this market actually works, taught to the * GTM team that runs that side. `platform` is PIG itself — onboarding, feature * walkthroughs, demos. The distinction is load-bearing rather than cosmetic, * because the access code unlocks exactly one of them. * * **Only the platform track may be visible to a code-holder.** Someone holding * the share code has no account and no principal; they may see how the product * works, because that is a sales asset. They may not see how we source and * price capacity. This predicate is enforced three times on purpose — here, in * the API write path, and in a database CHECK constraint — because a concept * video becoming anon-visible through a mistake in a form is the failure that * matters, and a UI-only rule does not survive an API caller. * * **The allowlist is the whole XSS surface of the feature.** A learn resource * is a URL somebody pasted, and it ends up as an `iframe src`. So a pasted URL * is never stored as a source and never rendered as one: it is resolved * through the table below into a *provider* and an *external id*, and every * embed URL is rebuilt from a hardcoded template and a pattern-checked id. * Anything the table does not match is rejected at the write path, so a row * that cannot be rendered safely cannot exist. * * Adding a provider is one row here plus one host in the proxy's `frame-src` * (see `LEARN_FRAME_SRC_HOSTS`). Do not add a row whose URL shape has not been * checked against the running service — the id extraction is what decides * whether a hostile path becomes a trusted embed. * * **One provider is not an iframe at all.** `pig` is video PIG serves itself, * from `/media/learn/…` on this origin, rendered in a native `