Skip to content

Persistence (graph-backed)

Every entry created via create_entry for a type defined here lands as a node in the world graph (the same graph the host’s Cypher / schema-projector / proposition-recall tools talk to). Two consequences worth knowing when writing a realm:

  • The entry’s name is the host’s headline for it. The host picks a single field per type to use as the node name for rendering — first title, then name, then summary if any exists. Add at least one of those if you want list / Cypher output to be human-readable.
  • The host can add an implicit edge to the acting human principal’s AssistantUser node. The compatibility default is (entry)-[:OWNED_BY]->(principal) — fine for most human-authored types. Service principals have no implicit anchor. When the predicate reads more naturally in the other direction, declare a userAnchor: on the type:
types/movies.yml
- name: MovieRating
description: "The user's score for a Movie."
userAnchor:
predicate: RATED # uppercase; stored uppercase
direction: from-user # `principal -[RATED]-> rating` (default is `from-entry`)
properties:
imdbId: "IMDb id of the rated Movie."
rating:
type: int
description: "1–10."
Field Default Notes
predicate OWNED_BY Cypher-style relationship name. Required when the key is declared. Stored uppercase.
direction from-entry from-entry → (entry)-[:PREDICATE]->(principal). from-user → (principal)-[:PREDICATE]->(entry). Pick whichever reads naturally.
(sentinel) — Set userAnchor: false to opt the type out of the implicit edge entirely (reference data, type registries, etc.).

create_entry accepts an optional relations: array so a realm’s skill can wire the new entry to another entry that already exists in the host-bound visibility scope. The host emits each requested edge on save; if any target can’t be found in that scope, the whole create is refused (no orphan node, no orphan edge). A cross-context relation requires an explicit policy-authorized bridge. Example shape, taken from the movie realm’s rate-movie skill:

// inside execute_javascript / execute_python, via the repository tool:
create_entry({
type: "MovieRating",
data: { imdbId: "tt0113277", title: "Heat", rating: 9 },
relations: [
{ predicate: "OF", to: { type: "Movie", imdbId: "tt0113277" } }
]
})
// Resulting graph: (User)-[:RATED]->(MovieRating)-[:OF]->(Movie)
// - The RATED edge comes from `MovieRating.userAnchor` (implicit).
// - The OF edge comes from `relations:` (explicit, from the skill).

Each relation is {predicate, to: {type, ...keyProps}} — to.type names the target’s type, and the remaining to.* fields are the key properties the host MATCHes against on target nodes in the same host-bound visibility scope. Cross-context matching is never implicit. Use this pattern any time a realm’s typed records form a small connected graph (rating → movie, comment → ticket, note → contact, etc.) — the same graph is then walkable by Cypher and feeds the recall path automatically.