Fruitful Docs
Reference

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.

RuleDescription
capture.routes[].id is uniqueRoute ids are unique within a package; a route with a feed is pinned into installs and provenance under that id.
capture.logins[].id is uniqueLogin ids are unique so a route selects exactly one session requirement.
capture.bindings[].id is uniqueBinding aliases are unique so a route selects exactly one pinned binding.
capture.hooks.exports[].name is uniqueEach capture-hook export declares its capabilities once.
capture.routes[].feed.explore.targets[].id is uniqueExplore target ids are unique across every feed in the package.
focus[].id is uniqueFocus policy ids are unique within a package.
capture.routes[].login names a capture.logins[].idA route that needs a signed-in session names a declared login.
capture.routes[].binding names a capture.bindings[].idA 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[].nameA 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[].idA 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.

On this page