Builtin Library
README.md
world_vcs.publishReminders
Tells the agents building in a world, without being asked, what keeps their work from being published: changes that are uncommitted or commits that are unpushed, a world still marked as a draft, and a world with no description or no cover image. Each is an engine notice addressed to every caller, naming the counts or the missing fields and the call that puts it right, read by a person in the editor's notification bell as its notices.world.* catalog sentence, and withdrawn once the state it reports is gone.
UNSAVED,DRAFTandPRESENTATIONare the three agent-facing sentences; their varying values (uncommitted,unpushed,intended,missing) ride as params.MESSAGESmaps each to its catalog key.new(ops)answers the reminders overops(now,counts,presentation,post(actionable, stored, or riding the agent's work),withdraw, and the optionalafterTurnEnd,recallandkeep):activity()says an agent is at work now and posts what a turn end held for it,idle()says no agent is at work now,tick()runs the rules that hold while one works,turnEnded()runs the turn-end rule for every notice, thenafterTurnEnd, whose error is logged and stays inside the turn end, andmoved()says a verb that moves the world's unpublished work landed (a step of publishing: a stage, a commit, a push; or a verb that rewrites the working tree or the branch: a discard, a checkout, a merge or its abort, a pull, a stash or its apply, a reset, a restore from the trash): a standing unpublished-work notice is read again then, withdrawn once nothing is unpublished and posted again with the counts the verb left otherwise (riding the work while an agent is at work, stored when none is). Every read of the counts that a step landed during is read again before anything is posted from it. Over the live engineafterTurnEndisworld_vcs.engagement'sturnEnded, which reminds the agent of the installs it has not rated. Withrecallandkeep, what the reminders told is kept in a record each time it changes and read back at their first call and at every turn end, so reminders made over the same record go on from what the last ones told.worlds(make)keeps the reminders of each world an engine authors:get(guid)answers the onesmakemade for that world the first time it was asked for, so a world swapped away from and back to keeps what it was told.moved(guid?)tells every remindersworldskeeps for the worldguid(the world this engine authors when omitted) that a verb that moves the world's unpublished work landed.world_vcscalls it as each such verb lands, before the verb answers: the steps of publishingworld.add,world.add_all,world.commitandworld.push, and the verbs that rewrite the working tree or the branch,world.discard,world.discardFile,world.discardAll,world.revertUpdate,world.checkout,world.checkoutPaths,world.checkoutSide,world.resolvePullConflict,world.merge,world.mergeAbort,world.pull,world.stash,world.stashApply,world.stashPop,world.resetandworld.restore(sozm restore,zm reset,zm stash,zm checkout,zm mergeandzm pullreach it through them). The live reminders call it as a sealed commit lands too. So an agent that pushes, commits or discards in a tool call reads, with the request after that call, the world as the call left it: nothing about unpublished work after a push that published everything, or a discard that took back every change.turns()answers where agents' turns end:dotbot(event, now)takes one of DotBot's turn events and answers whether it starts a tool call, andpoll(newestCall, now, epochS)answers whether an agent is at work, whether a turn ended since the last poll, and whether the work is an open DotBot turn. A DotBot turn ends at itsendevent whose reason iscompleted; any other caller's turn ends once its tool calls go quiet forQUIET_S(__presence.newestTurnlessCall, which leaves out DotBot's calls, its host's looks at the notices between turns included).presentationOf(record)reads a world record as its release: draft, intended visibility, description, cover, and whether the reader edits it.driver(worlds, turns)answers the live driver's two entries:poll(guid, newestCall, now, epochS), one read everyTICK_Sof who is at work, anddotbot(guid, event, now), one of DotBot's turn events. While a DotBot turn is open the reminders speak at its tool calls, since the model request after a tool call reads the notices inside that turn, and a poll posts nothing.uncommittedOf(status)counts the changes aworld.vcsStatusanswer holds for a commit to take: each changed path once and each differing install, leaving out a file listed only because its references moved (its bytes are the branch head's), aszm statusdoes.engineOps()answers the operations over this engine: the counts fromworld.vcsStatus(uncommittedOf) andworld_vcs.__unpushedCommitCount, the world record from ZeroMind, notices addressed to every caller, and the record of what was told as<person>.jsonunderRECORD_DIR(/zero/source/agents/publish_reminders/), in the world's synced agents folder, which stays out of the world's history.start()runs the reminders over the live engine, once per engine, on the world an editor is bound to, and hears each sealed commit that lands (moved).world_vcs.installOpenBackfillcalls it as a world becomes ready.
The cadence: unpublished work is told while an agent works, after UNSAVED_INTERVAL_S of it and then at most every UNSAVED_INTERVAL_S, only when the counts moved; a draft world and a missing description or cover are told after the push that leaves them standing; and at a turn end every notice whose state holds is told, repeated only when what it reports changed. A turn end posts a notice actionable, waking an idle agent, only the first time it tells that state; a change to a notice an earlier turn end woke the agent for, while it stood since, is held and posted at the agent's next work, without waking it. Unpublished work that is only commits the agent holds (nothing uncommitted, every unpushed commit made after the reminders read the world with nothing unpublished, as after a push) is told at the turn end as a stored notice that is not actionable: the agent reads it with its next turn and a person sees it in the notification bell, each further commit held refreshes it the same way, and uncommitted work beyond the held commits wakes the agent at its turn end. A push clears it. Every rule but the turn end posts at a moment an agent at work reads what is posted with what it does next (an MCP caller's tool call, a tool call of an open DotBot turn), so what it posts rides that work. Once no agent has been at work for UNSAVED_INTERVAL_S, the reminders read neither the world's status nor its ZeroMind record.
The next engine on a world goes on from what the last one told: it reads the record of the person it acts for, so a finding no engine's turn end has seen change is not told again, a change a turn end held for the agent's next work is posted there, and a state gone (which removes it from the record) is told again when it comes back.
local Reminders = require("@builtin::modules.world_vcs.publishReminders")
local r = Reminders.new(Reminders.engineOps())
r:turnEnded()