Engines, bindings, and packages
Three layers with different owners, different rates of change, and different trust.
"Extractor" used to mean two things at once, which hid a real split. Reading a page is platform work that changes rarely and must be trusted. Knowing what to read on one site is package data that changes whenever the site does. Schema 3 separates them.
Engine: how a page is read
An engine is Fruitful code. dom@1 runs CSS selectors over a browser snapshot. reader@1 hands the snapshot to the platform reader and emits a webDocument. media@1 runs the video and audio pipeline on a URL. rss@1 and http@1 will read fetched bodies once their runtimes land. Engines are versioned in their id; a package cannot add one.
Binding: what to read on this site
A binding is a package of data that configures one engine for one site: for dom@1, an entry selector and its fields. It declares emits, the Lexicon def its output conforms to, so the extract is validated before the transform sees it. No package code runs during extraction, which is why a binding can be reviewed by reading it.
First-party bindings wrap the engines that need no site-specific data. app.fruitful.binding.reader is reader@1 with nothing else. They are seeded into every registry and are only ever pinned.
Package: how records come from a site
The Feed Package pins bindings (by alias), Lexicons (by version range), and a transform, and declares routes, presentation, and Focus. It is the immutable contract for one kind of page. It changes when the product's needs change, or when the site changes enough that selectors and transform must move together.
Why the split holds
- Rules follow the engine, not the alias. A document is required exactly when the engine takes one. A collection needs a transform-feeding engine and
urls. Engines that never open the page rejectlogin,load,ready,on, andscroll. These are the same checks for every package because they are properties of the engine. - Trust is proportional to code. Engines are reviewed once, as platform. Bindings are data. The transform is the only package code on the record path, and it runs with no capabilities.
- Versions move independently. A site redesign bumps a binding. A new field in the product bumps a Lexicon and the transform. The Feed Package pins ranges so compatible releases resolve without a republish.
Reference: Extractor engines, Binding package.