Relationship rules
Cross-field rules the registry enforces beyond what the manifest Lexicon can express.
Rules the Lexicon cannot express, enforced at publish time. Paths use JSON Pointer with [] for every element. They are declared as data in FEED_PACKAGE_MANIFEST_RELATIONSHIPS and walked by one checker in the registry; this table is rendered from the same declaration.
| Rule | Description |
|---|---|
capture.routes[].id is unique | Route ids are unique within a package; a route with a feed is pinned into installs and provenance under that id. |
capture.logins[].id is unique | Login ids are unique so a route selects exactly one session requirement. |
capture.bindings[].id is unique | Binding aliases are unique so a route selects exactly one pinned binding. |
capture.hooks.exports[].name is unique | Each capture-hook export declares its capabilities once. |
capture.routes[].feed.explore.targets[].id is unique | Explore target ids are unique across every feed in the package. |
focus[].id is unique | Focus policy ids are unique within a package. |
capture.routes[].login names a capture.logins[].id | A route that needs a signed-in session names a declared login. |
capture.routes[].binding names a capture.bindings[].id | A route names a declared, pinned binding; the binding, through its extractor engine, decides what the page becomes. |
capture.routes[].on[].hook names a capture.hooks.exports[].name | A lifecycle point attaches a hook that appears in capture.hooks.exports, so its capabilities are declared. A hook with no exports entry would run with an empty import table. |
focus[].feeds[] names a capture.routes[].id | A Focus policy activates when the feed on one of the named routes is followed. |
capture.routes[].detailOf.record names a transform.records[] (by pin name) | An item route is the detail of a record type the transform may emit. |
render.root names a transform.records[] (by pin name) | The Activity root is one of the record types the transform may emit. |
capture.hooks.file names a files[] | The capture-hook module ships in the package. |
transform.hooks.file names a files[] | The transform module ships in the package. |
render.surfaces.compact names a files[] | The compact surface template ships in the package. |
render.surfaces.expanded names a files[] | The expanded surface template ships in the package. |
Still in code
These read beyond the document, so they stay as checks in the registry: every capture.hooks.exports[].name is exported by the module; a route that declares on requires capture.hooks; a follow feed's schedule.runOn is among its route's runsOn; Explore target URLs match the feed's route; a binding's engine decides what its route may be (a collection needs a transform-feeding engine and urls; a reader or media binding needs an item reached through detailOf or offered as a feed; engines that never open the page reject login, load, ready, on and scroll); transform.input is the one def the transform-feeding bindings emit unless declared; the transform exports normalize when a binding emits a different def; a first-party app.fruitful.binding.* vendor matches the canonical manifest.