Builtin Library
README.md
world_vcs.engagement
The engagement state kept for each tracked install root and each tracked library: one JSON file <key>.json under STATE_DIR (/zero/source/agents/engagement/), in the world's synced agents folder, which an ignore file keeps out of the world's history. key is the asset guid of an install (kind = "asset") or the library's world guid (kind = "library"), and may hold letters, digits, _ and - only.
A RootState holds key, kind, root_path, installed_at, rated, silenced, an optional contribution (origin_world, branch, pr_number, status, and pull_pending, true from the write that settles the link as merged until the root is pulled again) and an optional owners, the ZeroMind account ids that own the unit, kept once they are read: for an asset, the account that published it and the account that owns the world it is published in; for a library, the account that owns the library's world. An asset's state also keeps owning_world, the guid of the world it is published in, once it is read with its owners; a library's world is its key. A file holding other fields as well reads as the state its known fields state, and owners that is not a non-empty list of non-empty strings, or owning_world that is not a non-empty string, reads as not read yet.
The rating reminders and unrated() count, name and list only the units to rate: tracked units the world holds that are not rated, that none of the caller's own accounts owns (the signed-in ZeroMind account and, for an agent account, the person it acts for), and that come from no world one of those accounts holds a role of contributor or above on (owns, is a member of at contributor or above, or maintains or owns the org of). A unit the caller's own account owns, or from such a world, is never reminded, so no reminder grants rating it. The worlds the caller holds a role on are the caller's alone, so the engagement keeps them in memory rather than in the shared state files; it reads them the first time an unrated unit the caller does not own needs them, and again once ROLE_REFRESH_S passed or the signed-in accounts changed. When they do not read, no unit is left out for a role.
read(key, fs?)answers theRootStatekept forkey, or nil. A file that is not valid JSON, or does not hold a state, is logged and answers nil.write(state, fs?)keepsstateunderstate.key, replacing an earlier one. It raises, naming the field, when a required field is missing or mistyped.list(fs?)answers every state kept, ordered by file name; a file that does not hold a state is logged and left out.remove(key, fs?)deletes the state kept forkey.
The turn-end rating reminder keeps one record per person whose engines posted it on the world, <person>.json under TURN_END_DIR (/zero/source/agents/engagement/turn_end/): the unrated roots it last named (roots) and when (at, seconds since the Unix epoch). The next engine on the world reads it, so an unchanged set is reminded again only once TURN_NUDGE_INTERVAL_S passed since any of that person's engines reminded it, and a changed set is reminded at the next turn end.
Each function takes an optional fs table of read, write, list and remove over full paths; it defaults to the virtual filesystem, where a write lands without firing the write watchers.
local Engagement = require("@builtin::modules.world_vcs.engagement")
Engagement.write({ key = guid, kind = "asset", root_path = "/deps/greeter", installed_at = os.time(), rated = false, silenced = false })
local state = Engagement.read(guid)