---
title: "world"
description: "The world namespace — the engine's Luau API reference for world."
section: "API Reference"
slug: "api-world"
canonical: "https://origozero.ai/docs/api-world"
updated: "2026-09-06T10:26:33.171450838+00:00"
tags: ["api", "reference"]
---

# world

The `world` namespace — 119 functions.

## globals/world/add {#globals-world-add}

```lua
world.add(path: string, opts: AddOpts?)
```

Stage one path's manifest row, expanding to the full asset
family if the path lives inside a composite asset. Idempotent
at (stage, manifest_row). Pass `{ force = true }` to bypass
the `.zmignore` / `.gitignore` gate — same intent as
`git add -f`. Without force, attempts to stage an ignored
path (or a path whose `.refs` points at an ignored dep)
error.
`{ stage = "<name>" }` stages into one of the caller's own staging
areas instead of the shared default one, so a commit naming that area
freezes these paths and leaves every other caller's staged.

**Parameters**

- `path` `string` — The path to stage. Must be a non-empty string.
- `opts` `AddOpts` _(optional)_ — Optional `{ force: boolean?, stage: string? }`. Defaults to
`{ force = false }` on the default staging area.

```lua
world.add("/source/foo.luau")
world.add("/source/scene_dirty/entities/42.json", { force = true })
world.add("/source/fauna.module", { stage = "fauna" })
```

## globals/world/add_all {#globals-world-add-all}

```lua
world.add_all(opts: StageOpts?) -> { string }
```

Stage the dirty manifest rows this caller can claim, skipping
any path that matches `.zmignore` / `.gitignore`. Paths that match
an ignore pattern are silently skipped — `world.add(path, {
force = true })` is the explicit way to override the gate
for an individual path. Rows still flagged conflicted by
`world.pullAsset` are held back too — resolve them (edit +
`world.add(path)`, or `world.resolvePullConflict`) and re-run.
A path another staging area holds is held back as well: the
working tree is one per branch and staging areas are not, so a
path some other caller has already selected for a commit of its
own belongs to that caller until it commits or hands it over.
`world.add(path)` names a path deliberately and takes it either
way, which is how a claim is handed over — and a path this area
already holds stays staged here, whoever else holds it too.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
stage into. Omitted, the call stages into the shared default area.

**Returns** `{ string }` — The paths that were held back — those another staging area holds, then the conflicted ones. Empty when none were.

```lua
world.add_all()
world.add_all({ stage = "fauna" })
```

## globals/world/affirm {#globals-world-affirm}

```lua
world.affirm(token: string)
```

Consume an XXX-XXX-XXX-style affirmation token returned by
a destructive op surface (e.g. `vfs.remove`). The destruction
commits atomically with the pending-row delete; the token is
one-shot. Errors verbatim on expiry / wrong-user.

**Parameters**

- `token` `string` — The affirmation token.

```lua
world.affirm("ABC-DEF-GHI")
```

## globals/world/args {#globals-world-args}

```lua
world.args -> any
```

**Returns** `any`

## globals/world/assetInstallable {#globals-world-assetinstallable}

```lua
world.assetInstallable(opts: AssetInstallableOpts) -> AssetInstallableReport
```

Report whether one published asset can be installed on its own,
without raising. `world.previewInstall` plans a real install and
raises when the closure will not resolve; this answers the prior
question — does this guid name something ZeroMind will hand over by
itself — as a verdict a caller can branch on. Content that ships
inside a larger library (a module inside a package, a material
inside a system) carries its own published identity, so the answer
is per asset rather than per library. Reads only.

**Parameters**

- `opts` `AssetInstallableOpts` — `{ guid }` names the asset; `ref` pins a commit-id instead
of the latest.

**Returns** `AssetInstallableReport` — An `AssetInstallableReport` — `installable`, a `verdict`, a one-line `detail`, and the closure's `nodes` / `tree_children` / `deps` shape when one resolved.

```lua
world.assetInstallable({ guid = asset.guid("@builtin::materials.neon") })
```

## globals/world/avatar_default_edit {#globals-world-avatar-default-edit}

```lua
world.avatar_default_edit -> any
```

**Returns** `any`

## globals/world/avatar_default_play {#globals-world-avatar-default-play}

```lua
world.avatar_default_play -> any
```

**Returns** `any`

## globals/world/awaitOutgoingSync {#globals-world-awaitoutgoingsync}

```lua
world.awaitOutgoingSync()
```

Wait until every `/source` write this session made has reached
the branch it was written against. Raises naming the paths that did
not land. `add` / `commit` / `push` / `checkout` / `merge` / `pull`
already wait on their own; call this before rebinding after a burst
of writes, which `world.checkout` and `world.swap` refuse over.

**Returns** Nothing. Raises when a write did not land.

```lua
world.awaitOutgoingSync() ; world.checkout("main")
```

## globals/world/branches {#globals-world-branches}

```lua
world.branches() -> { { branch: string, commit_id: string, current: boolean } }
```

Every branch this world has, with the commit each one's head
names and which one this session is on — `git branch --list`. Sorted
by name. A branch exists for everyone in the world; which one you are
on is yours alone, so `current` is true for at most one row here and
says nothing about where anybody else is.

**Returns** `{ { branch: string, commit_id: string, current: boolean } }` — Array of `{ branch, commit_id, current }`.

```lua
for _, b in ipairs(world.branches()) do print(b.branch, b.commit_id) end
```

## globals/world/camera_default_edit {#globals-world-camera-default-edit}

```lua
world.camera_default_edit -> any
```

**Returns** `any`

## globals/world/camera_default_play {#globals-world-camera-default-play}

```lua
world.camera_default_play -> any
```

**Returns** `any`

## globals/world/checkUpdates {#globals-world-checkupdates}

```lua
world.checkUpdates() -> { UpdateReport }
```

Discover upstream changes for every asset this world has
pulled. Read-only — makes no local mutation and no VCS write.
Each locally-pulled row identifies its own origin asset via
`origin_asset_guid` (recorded as that entry's own asset guid at
pull time — see `world.installAsset`). For every distinct
origin asset among the pulled rows, this re-resolves that
asset's latest transitive closure and compares each returned
entry's checksum against the matching local row's recorded
`origin_checksum`.

**Returns** `{ UpdateReport }` — An array of `UpdateReport`, one per re-resolved origin asset whose closure produced at least one changed entry. Empty when every pulled row is already current. A root whose closure can't be re-resolved (e.g. the origin world is unreachable) is silently skipped rather than aborting the whole scan.

```lua
local reports = world.checkUpdates()
```

## globals/world/checkout {#globals-world-checkout}

```lua
world.checkout(branch: string) -> string
```

Switch this session to another branch — `git checkout <branch>`.
The branch must already exist (create one with `world.createBranch`).
The tree is replaced by the branch's own content. Which branch this
session is on is this session's alone; the branch itself is shared,
so others may be on the one you move onto.
Uncommitted work is not at risk: it already has its row on the
branch it was written against and is in the tree again when you
check that branch out.
Returns only once the branch's content has landed, so `world.head`,
`world.log`, `world.commit` and the VFS all target the new branch
immediately afterwards.

**Parameters**

- `branch` `string` — The branch to switch to.

**Returns** `string` — The branch now checked out.

```lua
world.checkout("feature")
```

## globals/world/commit {#globals-world-commit}

```lua
world.commit(message: string, opts: CommitOpts?) -> string
```

Open-or-resume a staging area, set the message, and materialise
the commit. Commits ONLY what's already staged via `world.add` /
`world.add_all` — git semantics, not `git commit -a`. The reducer
auto-deletes the stage row on success so a subsequent
`world.commit` opens a fresh one.

`{ stage = "<name>" }` materialises one of the caller's own staging
areas, so the commit carries the paths staged under that name and
leaves every other caller's staged. When a commit from another
caller has landed since the area was opened, this brings the area
onto the branch head there is now and commits it there.

Pre-flight `.zmignore` refs gate: every staged source's
aggregated deps (via `asset.deps`, which recurses composite
asset folders) are checked against the live ignore set. If
any dep target's path is currently ignored AND the dep target
is not itself in the stage, the commit is refused. This
mirrors the closure invariant — a commit whose deps can't
resolve cleanly shouldn't land. Force-staging the dep
alongside (`world.add(dep, { force = true })`) makes the
ignored dep satisfy the gate.

**Parameters**

- `message` `string` — The commit message.
- `opts` `CommitOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
materialise. Omitted, the commit materialises the shared default
area.

**Returns** `string` — The newly-allocated commit id (ULID string).

```lua
local id = world.commit("feat: ship widget")
local id = world.commit("fauna: the swallow colony", { stage = "fauna" })
```

## globals/world/conflicts {#globals-world-conflicts}

```lua
world.conflicts() -> { ConflictEntry }
```

List every locally-pulled row currently flagged conflicted —
the findable surface `world.pullAsset` leaves behind on an
unresolved merge. Read-only.

**Returns** `{ ConflictEntry }` — An array of `ConflictEntry`, one per conflicted row. Empty when nothing is conflicted.

```lua
local list = world.conflicts()
```

## globals/world/connectedUsers {#globals-world-connectedusers}

```lua
world.connectedUsers -> any
```

**Returns** `any`

## globals/world/contentRequirements {#globals-world-contentrequirements}

```lua
world.contentRequirements(scope: { string }?) -> { { asset: string, typeName: string, detail: string } }
```

List the world's unmet content requirements: user-authored assets
whose type-declared content constraints are not yet satisfied (an
empty README, a `.metadata` with no description or tags — the
empty-skeleton state a fresh create emits for the author to fill).
The same walk `world.push` gates on: push refuses while this list is
non-empty, and `world.publishBlockers` reports it as the `content`
class beside the other two. Empty list = every checked asset meets
its type's contract.

**Parameters**

- `scope` `{ string }` _(optional)_ — Asset paths to restrict the check to — pass a status read's
dirty + staged paths to check only content that would actually
publish (a per-file path matches its containing asset; each path
resolves directly, with no world enumeration). Omit for the
full-world walk the push gate performs.

**Returns** `{ { asset: string, typeName: string, detail: string } }` — Array of `{ asset, typeName, detail }` requirement rows.

```lua
for _, r in ipairs(world.contentRequirements()) do print(r.asset, r.detail) end
```

## globals/world/contribute {#globals-world-contribute}

```lua
world.contribute(opts: ContributeOpts?) -> { ContributeOutcome }
```

Send improvements to installed content back upstream — `git
subtree push` ending in a pull request. For each targeted origin
world: the diverging subtree is remapped to the origin's canonical
paths, three-way merged against the origin's CURRENT content
(regions the origin also changed become local conflicts to
resolve first), pushed as a `contrib/<id>` branch in the origin
world, and opened as a pull request there. With `merge` (the
default) the pull request is merged immediately when authorized —
a refusal leaves it open and reported, never a failure. After a
merge, the local fork re-pulls so its origin pins advance and the
asset no longer reads as ahead.

**Parameters**

- `opts` `ContributeOpts` _(optional)_ — Optional `ContributeOpts` — `targets` (origin world guids;
default all ahead), `merge` (default true), `title`,
`description`, `dryRun`.

**Returns** `{ ContributeOutcome }` — Array of `ContributeOutcome`, one per targeted origin.

```lua
local r = world.contribute({})
```

## globals/world/createBranch {#globals-world-createbranch}

```lua
world.createBranch(name: string, fromCommit: string?)
```

Create a branch — `git branch <name> [<start>]`. The branch
starts at `fromCommit` (defaults to the session branch's HEAD)
and gets its own working tree, materialized from that commit.
The session stays on its current branch; move onto it with
`world.checkout("<branch>")` (`git checkout`).

**Parameters**

- `name` `string` — The new branch name.
- `fromCommit` `string` _(optional)_ — Commit id to start at. Defaults to `world.head()`.

```lua
world.createBranch("feature")
```

## globals/world/deleteBranch {#globals-world-deletebranch}

```lua
world.deleteBranch(branch: string)
```

Delete a branch — `git branch -D <name>`. Drops the branch and
the working tree it owns; its commits are left alone, since deleting
a branch is dropping the name and the tree under it, not rewriting
history. Uncommitted work on that branch goes with it and is NOT
recoverable from trash, so the call refuses the first time and
returns the affirmation needed to go through with it — affirm with
`world.affirm(<token>)`. Refuses the branch this session is on
(check out another first) and the world's last branch.

**Parameters**

- `branch` `string` — The branch to delete.

```lua
world.deleteBranch("feature")
```

## globals/world/diff {#globals-world-diff}

```lua
world.diff(...: string) -> any
```

Mirror `git diff`'s CLI arg shape. Returns per-file diffs
by default; pass `--stat` for summary stats, `--name-only` for
just paths. Positional commit ids drive the two sources;
`--staged` pivots to staged-vs-HEAD. `--`-separated args
scope the diff to specific paths. `--stage=<name>` reads one of the
caller's own staging areas in place of the shared default one.

**Parameters**

- `...` `string` — Variadic string args: flags, commit ids, `--`, path filters.

**Returns** `any` — Array of `DiffFile` tables (or string-list for `--name-only`).

```lua
local files = world.diff()
local files = world.diff("--staged")
local files = world.diff("abc", "def")
local names = world.diff("--name-only")
local files = world.diff("--staged", "--stage=fauna")
```

## globals/world/discard {#globals-world-discard}

```lua
world.discard(opts: StageOpts?)
```

Drop a staging area without committing. Live manifest dirty flags
are preserved so the user can re-stage later. No-op if the area
doesn't exist.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
drop. Omitted, the call drops the shared default area.

```lua
world.discard()
world.discard({ stage = "fauna" })
```

## globals/world/discardFile {#globals-world-discardfile}

```lua
world.discardFile(path: string)
```

Discard one file's unstaged working edits, taking its content
back to what it was staged or committed as — the
`git restore <path>` shape. The stage is the baseline when the
path is staged, the last commit when it is not, and where it is
neither there is nothing to come back to, so the path goes away.
Staging is left exactly as it was; `world.unstage` is the verb
that changes it. One shot: a path that reverts to a committed
version snapshots the discarded bytes to trash first, so that
case is recoverable via `world.restore(<handle>)`. Errors when
the path is not dirty (nothing to discard).

**Parameters**

- `path` `string` — The VFS path whose unstaged edits to discard.

```lua
world.discardFile("/source/foo.luau")
```

## globals/world/fetch {#globals-world-fetch}

```lua
world.fetch(branch: string?) -> FetchResult
```

Update the `origin/<branch>` remote-tracking ref — `git fetch`.
Mirrors the world's ZeroMind branch head into the local commit
history (no working-tree change) and reports how the session
branch relates to it: `behind` origin commits to pull, `ahead`
local commits to push, `diverged` when both. A stale installed
pin or out-of-band ZeroMind change shows up here as `behind` —
reconcile with `world.pull()`.

**Parameters**

- `branch` `string` _(optional)_ — Remote branch to fetch. Defaults to the session branch.

**Returns** `FetchResult` — A `FetchResult` table.

```lua
local f = world.fetch()
```

## globals/world/forkLive {#globals-world-forklive}

```lua
world.forkLive(opts: { source: string, sourceBranch: string?, maxBatches: number? }) -> number
```

Seed THIS (empty) world's live content from another world by
copying its whole manifest as clean **Pulled** rows — the
in-engine half of "fork a world". Provenance is preserved: each
row points at the content's ORIGINAL owner (a fork of a
fork-of-A still points at A), so the fork never claims to have
authored what it pulled. The copy runs server-side in bounded
batches (idempotent + resumable), looping until the source is
fully mirrored. Pair with `world.add_all()` + `world.commit()` +
`world.push()` to publish the fork.

**Parameters**

- `opts` `{ source: string, sourceBranch: string?, maxBatches: number? }` — `{ source, sourceBranch?, maxBatches? }` — `source` is the
source world GUID; branches default to `"main"`; `maxBatches`
caps the batch loop (default 60 ⇒ up to ~120k entries).

**Returns** `number` — The number of pulled (dirty) rows now staged-pending on the fork.

```lua
world.forkLive({ source = "e89aa92e-4c1f-460e-acd8-73859dd3a346" })
```

## globals/world/forkStatus {#globals-world-forkstatus}

```lua
world.forkStatus() -> { ForkStatus }
```

Per-asset "ahead of origin" report — the fork analogue of git
status against an upstream. Every installed (pulled) row whose
content diverges from its pinned origin is listed, partitioned by
the TRUE origin world it was pulled from (nested dependencies
carry the world that authored them, not the intermediary they
arrived through). This is information for judgment: decide
whether a change belongs upstream, then `world.contribute`.

**Returns** `{ ForkStatus }` — Array of `ForkStatus` partitions.

```lua
for _, f in ipairs(world.forkStatus()) do print(f.origin_world, #f.entries) end
```

## globals/world/head {#globals-world-head}

```lua
world.head() -> string?
```

Return the current branch HEAD commit id, or nil if the
branch has no commits yet.

**Returns** `string?` — The commit id string, or nil.

```lua
local id = world.head()
```

## globals/world/installAsset {#globals-world-installasset}

```lua
world.installAsset(opts: InstallAssetOpts) -> InstallAssetResult
```

Install a published asset into this world, pulling the asset and
every dependency it closes over and writing them into the source tree.
Reports what it wrote so a caller can tell a fresh install from a no-op.

**Parameters**

- `opts` `InstallAssetOpts` — `{ guid }` names the root asset to install; `ref` pins a specific
commit-id instead of the latest.

**Returns** `InstallAssetResult` — `{ assets_written, blobs_downloaded, root_guid, root_path, root_version, deps }`.

```lua
local r = world.installAsset({ guid = assetGuid })
```

## globals/world/installLibrary {#globals-world-installlibrary}

```lua
world.installLibrary(opts: InstallLibraryOpts) -> InstallLibraryResult
```

Declarative cross-world dependency. Writes a single marker
file at `/source/libs/@<name>` whose body is the
`zero/world-import/v1` JSON. The next commit ships it as one
regular manifest entry; ZM's import-derivation pass at
finalize-time decodes the marker and stamps the new commit's
`imports[]`. Unmodified library content never ships in the
importing world's tree — it's fetched from the source world
on demand by the engine's library resolver.

**Parameters**

- `opts` `InstallLibraryOpts` — See `InstallLibraryOpts`. `opts.world` is the upstream
world's guid (required). `opts.commit` is the upstream
commit_id to pin (optional; resolves `opts.ref` or `main` if
omitted). `opts.as` is the local library name (defaults to
the upstream world's slug). `opts.ref` is the human-meaningful
ref recorded in the marker.

**Returns** `InstallLibraryResult` summarising the install.

```lua
world.installLibrary({ world = "guid", as = "combat" })
```

## globals/world/installedAssets {#globals-world-installedassets}

```lua
world.installedAssets() -> { InstalledAsset }
```

Every asset this world carries from ZeroMind, keyed by the
published guid it was pulled from. The read that answers "what is
actually in this world" by identity rather than by path — an
installed asset's local name can be chosen by the installer, so a
path is not the thing to check a pull against.

**Returns** `{ InstalledAsset }` — An array of `InstalledAsset` sorted by local path, one per pulled row carrying a published guid.

```lua
for _, a in ipairs(world.installedAssets()) do print(a.asset_guid, a.path) end
```

## globals/world/list {#globals-world-list}

```lua
world.list() -> { WorldEntry }
```

List every world the authenticated user has access to.
Calls the spacetime `list_my_worlds` procedure which wraps
ZeroMind's `GET /v1/me/worlds`. Flattens each entry to one
record per world with the role promoted to a top-level field.

**Returns** `{ WorldEntry }` — Array of `WorldEntry` records.

```lua
local worlds = world.list()
```

## globals/world/log {#globals-world-log}

```lua
world.log(opts: LogOpts?) -> { CommitRow }
```

Return the commit log for the current branch, newest first.
Pass `opts.path` to get the per-path history (`git log -- <path>`):
only the commits that touched that file, newest-first.

**Parameters**

- `opts` `LogOpts` _(optional)_ — Optional. `opts.limit` caps the number of commits
(default 50, 0 = all). `opts.path` scopes the log to one file.

**Returns** `{ CommitRow }` — Array of `CommitRow` tables.

```lua
local commits = world.log({ limit = 20 })
local touched = world.log({ path = "/source/foo.luau" })
```

## globals/world/merge {#globals-world-merge}

```lua
world.merge(sourceBranch: string) -> MergeResult
```

Merge another branch into the session branch — `git merge
<source>`. The merge runs locally in the world's SpacetimeDB clone
and is abortable with `world.mergeAbort`; nothing reaches ZeroMind
until the result is pushed. Requires a clean working tree (commit
or stash first — that is also what makes abort exact). Clean →
a two-parent merge commit lands on the session branch and the
merged content appears in the working tree. Conflicts → git-style
markers are projected into each conflicting text file, the
cleanly-merged remainder is applied as working-tree changes, and
`world.vcsStatus().unmerged` lists what needs attention: resolve
each path (edit out the markers / rewrite / remove the file),
then `world.add` + `world.commit` — that commit records the merge
(second parent = the source head) and clears the unmerged set.

**Parameters**

- `sourceBranch` `string` — The branch to merge in.

**Returns** `MergeResult` — A `MergeResult` — `status` is `clean` (with `commit`), `conflicts` (with `conflicts`), or `up_to_date`.

```lua
local r = world.merge("feature")
```

## globals/world/mergeAbort {#globals-world-mergeabort}

```lua
world.mergeAbort()
```

Abort the in-progress merge — `git merge --abort`. Clears the
unmerged set and restores the working tree to the pre-merge state
(the target head's committed content; the branch head never moved
during a conflicted merge). Errors when no merge is in progress.

```lua
world.mergeAbort()
```

## globals/world/offLoaded {#globals-world-offloaded}

```lua
world.offLoaded(handle: number) -> boolean
```

Stop a callback registered with `world.onLoaded` from running.

**Parameters**

- `handle` `number` — The handle `world.onLoaded` returned.

**Returns** `boolean` — `true` when the handle matched a registered callback.

```lua
world.offLoaded(h)
```

## globals/world/offSaved {#globals-world-offsaved}

```lua
world.offSaved(handle: number) -> boolean
```

Stop a callback registered with `world.onSaved` from running.

**Parameters**

- `handle` `number` — The handle `world.onSaved` returned.

**Returns** `boolean` — `true` when the handle matched a registered callback.

```lua
world.offSaved(h)
```

## globals/world/offUnloaded {#globals-world-offunloaded}

```lua
world.offUnloaded(handle: number) -> boolean
```

Stop a callback registered with `world.onUnloaded` from running.

**Parameters**

- `handle` `number` — The handle `world.onUnloaded` returned.

**Returns** `boolean` — `true` when the handle matched a registered callback.

```lua
world.offUnloaded(h)
```

## globals/world/onLoaded {#globals-world-onloaded}

```lua
world.onLoaded(cb: (...any) -> ()) -> number
```

Register a callback to run after a world finishes loading.

**Parameters**

- `cb` `(...any) -> ()` — Called when the event fires, with whatever the event supplies.

**Returns** `number` — Handle for `world.offLoaded`.

```lua
local h = world.onLoaded(function() log.info("loaded") end)
```

## globals/world/onSaved {#globals-world-onsaved}

```lua
world.onSaved(cb: (...any) -> ()) -> number
```

Register a callback to run after a world is saved.

**Parameters**

- `cb` `(...any) -> ()` — Called when the event fires, with whatever the event supplies.

**Returns** `number` — Handle for `world.offSaved`.

```lua
local h = world.onSaved(function() log.info("saved") end)
```

## globals/world/onUnloaded {#globals-world-onunloaded}

```lua
world.onUnloaded(cb: (...any) -> ()) -> number
```

Register a callback to run after a world is unloaded.

**Parameters**

- `cb` `(...any) -> ()` — Called when the event fires, with whatever the event supplies.

**Returns** `number` — Handle for `world.offUnloaded`.

```lua
local h = world.onUnloaded(function() log.info("unloaded") end)
```

## globals/world/prConflicts {#globals-world-prconflicts}

```lua
world.prConflicts(worldGuid: string?, number: number) -> any
```

Read a pull request's conflicts — what stands between it and a
merge. Returns the mergeability verdict, the merge base, both
heads, and one entry per conflicting path. A conflicting TEXT path
carries `marked_text`: the same `<<<<<<<` / `=======` / `>>>>>>>`
rendering a merge leaves in the working tree, with the source and
target sides laid against their common ancestor. Resolve a path by
writing the settled bytes back to it and committing on the source
branch; the pull request re-analyses on the next read. A binary
path carries the two sides' hashes and no text — pick a side.
A mergeable pull request returns an empty conflict list.

**Parameters**

- `worldGuid` `string` _(optional)_ — The world the pull request lives in. Defaults to the
bound world.
- `number` `number` — The pull request number.

**Returns** `any` — Decoded ZeroMind conflicts response.

```lua
local c = world.prConflicts(nil, 3)
for _, m in ipairs(world.prConflicts(originGuid, 3).markers) do print(m.path, m.marked_text) end
```

## globals/world/prList {#globals-world-prlist}

```lua
world.prList(worldGuid: string?, number: number?) -> any
```

**Parameters**

- `worldGuid` `string` _(optional)_
- `number` `number` _(optional)_

**Returns** `any`

## globals/world/prMerge {#globals-world-prmerge}

```lua
world.prMerge(worldGuid: string, number: number, strategy: string?) -> any
```

Merge a pull request — the agent-side merge button.

**Parameters**

- `worldGuid` `string` — The world the pull request lives in.
- `number` `number` — The pull request number.
- `strategy` `string` _(optional)_ — `merge` (default), `squash`, or `fast_forward`.

**Returns** `any` — Decoded ZeroMind merge response.

```lua
world.prMerge(originGuid, 3)
```

## globals/world/prOpen {#globals-world-propen}

```lua
world.prOpen(opts: PrOpenOpts) -> any
```

List a world's pull requests, or fetch one.
Open a pull request — `gh pr create`. Proposes the work on one
`(world, branch)` pair to another. Defaults make the common cases one
argument: from a fork, the target is the world it was forked from, so
`world.prOpen({ title = "..." })` proposes your work upstream. In an
ordinary world the target is the same world, so you get a
branch → `main` pull request.
The PR lives in — and is numbered by — the world it targets, exactly
as a forge numbers pull requests on the upstream repository. That is
also where `world.prList` finds it.

**Parameters**

- `opts` `PrOpenOpts` — `title` (required), plus `description`, `sourceWorld`,
`sourceBranch`, `targetWorld`, `targetBranch` to address any leg
explicitly.

**Returns** `any` — Decoded ZeroMind response. The decoded ZeroMind pull request.

```lua
local prs = world.prList()
world.prOpen({ title = "fix the door hinge" })
world.prOpen({ title = "port the fix", targetWorld = otherGuid })
```

## globals/world/prView {#globals-world-prview}

```lua
world.prView(worldGuid: string?, number: number) -> any
```

Read one pull request in full — `gh pr view`. Returns the record
plus a LIVE re-analysis against the current branch heads: `mergeability`
(`clean` / `conflicts` / `fast_forwardable` / `up_to_date` /
`unrelated`), `conflict_count`, and `diff` — every path the request
adds, modifies or deletes with its checksums. Read this before merging:
it is what tells you WHAT the request changes.

**Parameters**

- `worldGuid` `string` _(optional)_ — The world the pull request lives in (its target world).
Defaults to the session world.
- `number` `number` — The pull request number.

**Returns** `any` — The decoded pull request view.

```lua
world.prView(nil, 1)
```

## globals/world/previewInstall {#globals-world-previewinstall}

```lua
world.previewInstall(opts: InstallAssetOpts) -> PreviewResult
```

Preview what installing an asset WOULD write, without writing
anything. Fetches + decodes the closure and plans placement (the
same helpers `world.installAsset` uses), returning a flat node
list plus rollup totals. A truncated closure is reported (not
raised) so a caller can surface it and block import.

**Parameters**

- `opts` `InstallAssetOpts` — `{ guid, at?, ref? }` — same shape as installAsset.

**Returns** `PreviewResult` — nodes + totals + a truncated flag.

```lua
world.previewInstall({ guid = "..." })
```

## globals/world/publishBlockers {#globals-world-publishblockers}

```lua
world.publishBlockers() -> { PublishBlockerClass }
```

List every reason `world.push` would refuse to publish this
world, as one entry per blocker class: script errors in user
content, assets that don't meet their type's content requirements,
and asset references that can't be statically pinned. Each class
carries the same `title` the refusal prints, one `items` entry per
offending subject (an asset identity, or a `<path>:<line>` site),
and the single `remedy` covering that class. This is the account
`world.push` composes its refusal from, so it names the same
blockers with no push attempted — and in full, where a refusal
bounds how many of a class it prints. Empty list = the world
publishes. `zm status` prints this list.

**Returns** `{ PublishBlockerClass }` — Array of `PublishBlockerClass` entries, empty when nothing blocks.

```lua
for _, c in ipairs(world.publishBlockers()) do
for _, i in ipairs(c.items) do print(c.kind, i.subject, i.detail) end
end
```

## globals/world/pull {#globals-world-pull}

```lua
world.pull(branch: string?) -> PullResult
```

Fetch and reconcile with origin — `git pull`. Strictly behind →
fast-forward (the branch head moves to the origin mirror, no merge
commit). Diverged → three-way merge of the origin mirror, with the
same conflict/marker/resolve flow as `world.merge` (resolve the
unmerged paths, then `world.add` + `world.commit`; abortable with
`world.mergeAbort`). Requires a clean working tree.

**Parameters**

- `branch` `string` _(optional)_ — Remote branch to pull. Defaults to the session branch.

**Returns** `PullResult` — A `PullResult` table.

```lua
local r = world.pull()
```

## globals/world/pullAsset {#globals-world-pullasset}

```lua
world.pullAsset(opts: PullAssetOpts?) -> PullAssetResult
```

Pull upstream changes into a previously-installed asset,
three-way reconciling each entry against local edits. Re-resolves
the root's transitive closure at `opts.ref` (default latest),
then for every entry decides `fast_forward` / `noop` / `converged`
/ `merge` from `(row.origin_checksum, localChecksum,
entry.checksum)` (`M.__reconcileDecision`):

- `noop` — upstream hasn't moved; skipped.
- `fast_forward` / `converged` — the entry's latest text is
written to the local path and the row's origin pointer
advances. Binary and composite entries can't be content-synced
through this call's only cross-world read primitive (text
only), so a non-text entry with a real upstream change is
surfaced as a conflict instead of silently going stale.
- `merge` (text entries) — a three-way `vcs.merge3` runs over
(base, local, theirs); a clean result is written and the
origin pointer advances, a conflicted result is written WITH
markers and the row is flagged conflicted (base + theirs
checksums recorded for `world.resolvePullConflict`).
- `merge` (binary / composite entries) — no text merge is
possible; flagged conflicted with the structured base/theirs
checksums (no marker write).

Closure drift: an entry the original install never landed is
pulled fresh (added). A locally-pulled row nested under the
root's own directory whose origin entry disappeared from the
closure is removed when clean (pruned), or flagged conflicted
when it carries local edits.

**Parameters**

- `opts` `PullAssetOpts` _(optional)_ — See `PullAssetOpts`. `opts.guid` or `opts.path` is
required; `opts.ref` pins the re-resolve to a specific upstream
commit (defaults to latest finalized).

**Returns** `PullAssetResult` summarising what merged, conflicted, was pruned, and was newly added.

```lua
world.pullAsset({ guid = "..." })
```

## globals/world/push {#globals-world-push}

```lua
world.push(commitId: string?) -> (string?, string)
```

Publish the current branch to ZeroMind. The no-argument form
is a git `merge --squash` push: EVERY unpushed commit on the
branch collapses into a SINGLE ZeroMind commit (latest content
per path, parented on the branch's current remote HEAD). Because
only the merged final state's bytes are uploaded, a superseded or
lost intermediate-commit blob can never break the push — this is
what makes a churn-heavy world publishable. The local commit
history is preserved as the editing journal; on success every
squashed commit shares the one remote commit id. The explicit
`commitId` form still pushes that single commit verbatim via
`publish_commit` (advanced / chain-replay use; its parent must
already be on the remote).

**Parameters**

- `commitId` `string` _(optional)_ — Optional. A single commit to push verbatim. Omit for
the squash push of the whole unpushed stack (the normal path).

**Returns** `(string?, string)` — Two values: the ZeroMind-allocated commit id, and the verdict. `"published"` with the new commit id when this call published; `"already-published"` when ZeroMind already carries what this call would have published — the state a push asks for, so it returns rather than raising. That verdict carries the commit's existing ZeroMind id when the publish names one (the single-commit form), and a nil id when it names none (the whole-stack form, which reports a chain). A squash whose merged final state carries `dep.unresolved` problems takes the slow path inside the same call: the engine re-resolves each pending literal against its live asset index and submits the resolutions to the publish procedure, which completes the push. A reference literal that still resolves to nothing is published with the asset holding it and stays a problem recorded on that asset, while a dep pin the squash severed raises instead; either way the engine names each one with its path, line, reference and reason. A publish ZeroMind refuses raises naming the condition and the command that clears it — a branch that moved under this push names `world.pull()`.

```lua
local zmId = world.push()
local zmId, verdict = world.push()
world.push("01HABC...")
```

## globals/world/reset {#globals-world-reset}

```lua
world.reset(targetCommitId: string) -> string?
```

Rewind HEAD to `targetCommitId` in one shot. Non-destructive
— orphaned commits stay in storage and each becomes a trash
entry the user can `world.restore` (in chain order) to re-attach
the branch. Errors when `targetCommitId` is not an ancestor of
HEAD. Returns a summary of what was rewound.

**Parameters**

- `targetCommitId` `string` — The commit id to rewind to.

**Returns** `string?` — A summary message: the target plus the list of commits rewound past.

```lua
world.reset("01HABC...")
```

## globals/world/resolveConflict {#globals-world-resolveconflict}

```lua
world.resolveConflict(path: string, mode: string, content: string?) -> ResolveResult
```

Resolve one conflicted `/source` record, one path at a time.
`mode` is `merge` | `apply` | `take-local` | `take-backend` |
`discard`. `merge` returns `{ merged, clean }` and mutates nothing
— a clean merge can be finalized with `apply`, and a conflicted one
carries `<<<<<<< / ======= / >>>>>>>` markers to edit first. `apply`
writes the finalized `content` to `/source`; `take-local` writes the
retained local bytes; `take-backend` / `discard` keep the backend
head. Errors when the record is absent, a `merge` has no common
ancestor or hits binary content, or a write fails.

**Parameters**

- `path` `string` — Canonical `/source` path of the conflicted record.
- `mode` `string` — One of merge | apply | take-local | take-backend | discard.
- `content` `string` _(optional)_ — Finalized bytes for `apply` mode.

**Returns** `ResolveResult`

```lua
world.resolveConflict("/zero/source/foo.luau", "take-local")
local r = world.resolveConflict(p, "merge"); if r.clean then world.resolveConflict(p, "apply", r.merged) end
```

## globals/world/resolvePullConflict {#globals-world-resolvepullconflict}

```lua
world.resolvePullConflict(path: string, choice: string)
```

Resolve a conflicted row. A TEXT conflict is one where the file
currently contains conflict markers (`world.pullAsset` writes
markers only for a text three-way merge that didn't resolve
cleanly); a BINARY/composite conflict has no markers — the local
bytes were left untouched.

`choice = "theirs"` fetches clean upstream text by content hash
(`conflict_theirs_blob_sha256` — path/rename-independent, since
blobs are content-addressed) and overwrites the local file with it
before clearing the flag. It errors, refusing to guess, when the
row records no theirs blob (a binary/composite conflict — a text
blob read can't address theirs for those; keep `"ours"` or
re-install the asset instead).

`choice = "ours"` keeps the local side. When the file carries
conflict markers, the local side is reconstructed from them (the
marker writers put ours first, so dropping each block's base and
theirs sections restores your bytes exactly) and written back;
a marker-free file is kept as-is. Either way the flag clears.

Either way, staging the resolved file (`world.add`) is the normal
git-add path once this returns — this call only clears the
manifest-level flag and (for `"theirs"`) the file content.

**Parameters**

- `path` `string` — The conflicted row's local VFS path.
- `choice` `string` — `"ours"` or `"theirs"`.

```lua
world.resolvePullConflict("/source/combat/rules.luau", "theirs")
```

## globals/world/restore {#globals-world-restore}

```lua
world.restore(handle: any?)
```

Restore one trash entry by row_id. Errors verbatim on
handler-not-yet-implemented / world-mismatch.

**Parameters**

- `handle` `any` _(optional)_ — The trash row id. May be a number or a numeric string.

```lua
world.restore(42)
```

## globals/world/show {#globals-world-show}

```lua
world.show(...: string) -> any
```

Mirror `git show`'s CLI arg shape. Default returns commit
metadata + full diff vs parent. `world.show("commit:/path")`
returns just the bytes. Flags: `--stat`, `--name-only`.

**Parameters**

- `...` `string` — Variadic string args: commit id, optional path, optional flags.

**Returns** `any` — Either a `ShowResult` table or a string (for `commit:/path`).

```lua
local r = world.show("abc123")
local r = world.show("--stat", "abc123")
local bytes = world.show("abc123:/foo.luau")
```

## globals/world/startup_scene {#globals-world-startup-scene}

```lua
world.startup_scene -> any
```

**Returns** `any`

## globals/world/stash {#globals-world-stash}

```lua
world.stash(label: string?)
```

Save the caller's current pending dirty + staged state on
the active (world, branch) into a stash row. `label` is
optional free-form text. Non-destructive — dirty + staged
state is preserved on disk.

**Parameters**

- `label` `string` _(optional)_ — Optional. Free-form text label for the stash.

```lua
world.stash("wip widget refactor")
```

## globals/world/stashDrop {#globals-world-stashdrop}

```lua
world.stashDrop(handle: any?)
```

Request an affirmation token to drop a stash. Always
errors — successful mint surfaces the token as `affirmation
required: zm affirm <token>`. The agent runs `zm affirm
<token>` to actually drop; restoration via `world.restore()`
reappears the stash under a new row_id.

**Parameters**

- `handle` `any` _(optional)_ — The stash row id. May be a number or numeric string.

```lua
world.stashDrop(7)
```

## globals/world/stashPop {#globals-world-stashpop}

```lua
world.stashPop(handle: any?) -> StashSnapshot
```

Author-only. Pop the stash row (deletes it server-side)
and return the decoded snapshot. The caller is responsible
for re-applying the snapshot to disk via the normal write
paths (so ACL gates fire on every restored path).

**Parameters**

- `handle` `any` _(optional)_ — The stash row id. May be a number or numeric string.

**Returns** `StashSnapshot` containing `dirty` + `staged` entries.

```lua
local snap = world.stashPop(7)
```

## globals/world/stashes {#globals-world-stashes}

```lua
world.stashes() -> { StashRow }
```

List every stash row in the world. Anyone with read access
sees every stash; the per-row `author_hex` makes it clear
which entries the caller can pop / drop themselves.

**Returns** `{ StashRow }` — Array of `StashRow` tables.

```lua
local rows = world.stashes()
```

## globals/world/status {#globals-world-status}

```lua
world.status -> any
```

**Returns** `any`

## globals/world/status_text {#globals-world-status-text}

```lua
world.status_text -> any
```

**Returns** `any`

## globals/world/syncStatus {#globals-world-syncstatus}

```lua
world.syncStatus() -> SyncStatus
```

Read the durable-sync status: `{ subscribed, content_synced,
progress, pending_writes, unsaved_writes, uploads_abandoned,
conflicts, binding }`. `conflicts` maps each conflicted `/source`
path to `{ base_sha, local_sha, backend_sha, isBinary }`.
`unsaved_writes` lists the `/source` paths this session wrote that
the server does not hold, and `uploads_abandoned` counts the uploads
the queue stopped carrying — read those two to tell a queue working
through a backlog from one that gave content up, which
`pending_writes` alone reads the same for. `binding` names which
world holds `/source` — `bound`, `unbound`, `binding`,
`session_only`, or `unclassified` before the boot has decided — and,
when an authorization attempt is on record,
which attempt is running and what the last one answered. Read
`binding` to tell a world that is still coming from one that was
never asked for: `subscribed` answers `false` for both. Synchronous.

**Returns** `SyncStatus`

```lua
local s = world.syncStatus(); print(s.pending_writes)
local s = world.syncStatus(); for _, p in ipairs(s.unsaved_writes) do print(p) end
local s = world.syncStatus(); if s.binding.awaiting_world then print(s.binding.state, s.binding.attempt) end
```

## globals/world/trash {#globals-world-trash}

```lua
world.trash() -> { TrashRow }
```

List trash entries for the world. Anyone with read access
to the world can list trash — recovery is a shared safety net,
not a privacy boundary. The handle (`row_id`) feeds back into
`world.restore`.

**Returns** `{ TrashRow }` — Array of `TrashRow` tables.

```lua
local rows = world.trash()
```

## globals/world/uninstallLibrary {#globals-world-uninstalllibrary}

```lua
world.uninstallLibrary(name: string) -> string
```

Delete the library marker file. `name` accepts `"@combat"`
or `"combat"` (the leading `@` is the convention carried by
the on-disk path).

**Parameters**

- `name` `string` — The library name, with or without the leading `@`.

**Returns** `string` — The marker path that was removed.

```lua
world.uninstallLibrary("@combat")
```

## globals/world/unstage {#globals-world-unstage}

```lua
world.unstage(path: string, opts: StageOpts?)
```

Remove a path from the staging area. Live manifest dirty
state is untouched.

**Parameters**

- `path` `string` — The path to unstage.
- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area the
path was staged into. Omitted, the call acts on the shared default
area.

```lua
world.unstage("/source/foo.luau")
world.unstage("/source/foo.luau", { stage = "fauna" })
```

## globals/world/vcsStatus {#globals-world-vcsstatus}

```lua
world.vcsStatus(opts: StageOpts?) -> StatusResult
```

Return the working-tree VCS status: dirty paths, staged
entries, ignored paths, untracked paths, and any unmerged ones.
An untracked path is one with no committed version behind it, and
it appears in `dirty` as well — `git add .` picks up new files too.
Named `vcsStatus` (not `status`) because `world.status()` is the
runtime-snapshot accessor owned by `world_status.module`; the
source-control surface keeps its own VCS-specific name so the
two never shadow each other.
Each `dirty[i].dirtied_by` is the identity of the most recent
writer; `dirty_since_micros` is the microsecond timestamp of the
first write of the current dirty run. `local_identity` is this
session's own writer identity in that same namespace — compare
the two to tell your own writes from another account's.
`claimed_by_other_stages` names the paths some other staging area
holds and which area holds each — the grain that tells two callers
apart when they share one writer identity, and the set
`world.add_all` holds back.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area whose
staged set to report. The dirty, ignored and untracked sets are the
world's working tree and read the same whichever area is named.

**Returns** `StatusResult` — A `StatusResult` table.

```lua
local s = world.vcsStatus()
local s = world.vcsStatus({ stage = "fauna" })
```

## typed/builtin//modules/world_sync/world/resolveConflict {#typed-builtin-modules-world-sync-world-resolveconflict}

```lua
world.resolveConflict(path: string, mode: string, content: string?) -> ResolveResult
```

Resolve one conflicted `/source` record, one path at a time.
`mode` is `merge` | `apply` | `take-local` | `take-backend` |
`discard`. `merge` returns `{ merged, clean }` and mutates nothing
— a clean merge can be finalized with `apply`, and a conflicted one
carries `<<<<<<< / ======= / >>>>>>>` markers to edit first. `apply`
writes the finalized `content` to `/source`; `take-local` writes the
retained local bytes; `take-backend` / `discard` keep the backend
head. Errors when the record is absent, a `merge` has no common
ancestor or hits binary content, or a write fails.

**Parameters**

- `path` `string` — Canonical `/source` path of the conflicted record.
- `mode` `string` — One of merge | apply | take-local | take-backend | discard.
- `content` `string` _(optional)_ — Finalized bytes for `apply` mode.

**Returns** `ResolveResult`

```lua
world.resolveConflict("/zero/source/foo.luau", "take-local")
local r = world.resolveConflict(p, "merge"); if r.clean then world.resolveConflict(p, "apply", r.merged) end
```

## typed/builtin//modules/world_sync/world/syncStatus {#typed-builtin-modules-world-sync-world-syncstatus}

```lua
world.syncStatus() -> SyncStatus
```

Read the durable-sync status: `{ subscribed, content_synced,
progress, pending_writes, unsaved_writes, uploads_abandoned,
conflicts, binding }`. `conflicts` maps each conflicted `/source`
path to `{ base_sha, local_sha, backend_sha, isBinary }`.
`unsaved_writes` lists the `/source` paths this session wrote that
the server does not hold, and `uploads_abandoned` counts the uploads
the queue stopped carrying — read those two to tell a queue working
through a backlog from one that gave content up, which
`pending_writes` alone reads the same for. `binding` names which
world holds `/source` — `bound`, `unbound`, `binding`,
`session_only`, or `unclassified` before the boot has decided — and,
when an authorization attempt is on record,
which attempt is running and what the last one answered. Read
`binding` to tell a world that is still coming from one that was
never asked for: `subscribed` answers `false` for both. Synchronous.

**Returns** `SyncStatus`

```lua
local s = world.syncStatus(); print(s.pending_writes)
local s = world.syncStatus(); for _, p in ipairs(s.unsaved_writes) do print(p) end
local s = world.syncStatus(); if s.binding.awaiting_world then print(s.binding.state, s.binding.attempt) end
```

## typed/builtin//modules/world_vcs/world/add {#typed-builtin-modules-world-vcs-world-add}

```lua
world.add(path: string, opts: AddOpts?)
```

Stage one path's manifest row, expanding to the full asset
family if the path lives inside a composite asset. Idempotent
at (stage, manifest_row). Pass `{ force = true }` to bypass
the `.zmignore` / `.gitignore` gate — same intent as
`git add -f`. Without force, attempts to stage an ignored
path (or a path whose `.refs` points at an ignored dep)
error.
`{ stage = "<name>" }` stages into one of the caller's own staging
areas instead of the shared default one, so a commit naming that area
freezes these paths and leaves every other caller's staged.

**Parameters**

- `path` `string` — The path to stage. Must be a non-empty string.
- `opts` `AddOpts` _(optional)_ — Optional `{ force: boolean?, stage: string? }`. Defaults to
`{ force = false }` on the default staging area.

```lua
world.add("/source/foo.luau")
world.add("/source/scene_dirty/entities/42.json", { force = true })
world.add("/source/fauna.module", { stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/add_all {#typed-builtin-modules-world-vcs-world-add-all}

```lua
world.add_all(opts: StageOpts?) -> { string }
```

Stage the dirty manifest rows this caller can claim, skipping
any path that matches `.zmignore` / `.gitignore`. Paths that match
an ignore pattern are silently skipped — `world.add(path, {
force = true })` is the explicit way to override the gate
for an individual path. Rows still flagged conflicted by
`world.pullAsset` are held back too — resolve them (edit +
`world.add(path)`, or `world.resolvePullConflict`) and re-run.
A path another staging area holds is held back as well: the
working tree is one per branch and staging areas are not, so a
path some other caller has already selected for a commit of its
own belongs to that caller until it commits or hands it over.
`world.add(path)` names a path deliberately and takes it either
way, which is how a claim is handed over — and a path this area
already holds stays staged here, whoever else holds it too.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
stage into. Omitted, the call stages into the shared default area.

**Returns** `{ string }` — The paths that were held back — those another staging area holds, then the conflicted ones. Empty when none were.

```lua
world.add_all()
world.add_all({ stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/affirm {#typed-builtin-modules-world-vcs-world-affirm}

```lua
world.affirm(token: string)
```

Consume an XXX-XXX-XXX-style affirmation token returned by
a destructive op surface (e.g. `vfs.remove`). The destruction
commits atomically with the pending-row delete; the token is
one-shot. Errors verbatim on expiry / wrong-user.

**Parameters**

- `token` `string` — The affirmation token.

```lua
world.affirm("ABC-DEF-GHI")
```

## typed/builtin//modules/world_vcs/world/assetInstallable {#typed-builtin-modules-world-vcs-world-assetinstallable}

```lua
world.assetInstallable(opts: AssetInstallableOpts) -> AssetInstallableReport
```

Report whether one published asset can be installed on its own,
without raising. `world.previewInstall` plans a real install and
raises when the closure will not resolve; this answers the prior
question — does this guid name something ZeroMind will hand over by
itself — as a verdict a caller can branch on. Content that ships
inside a larger library (a module inside a package, a material
inside a system) carries its own published identity, so the answer
is per asset rather than per library. Reads only.

**Parameters**

- `opts` `AssetInstallableOpts` — `{ guid }` names the asset; `ref` pins a commit-id instead
of the latest.

**Returns** `AssetInstallableReport` — An `AssetInstallableReport` — `installable`, a `verdict`, a one-line `detail`, and the closure's `nodes` / `tree_children` / `deps` shape when one resolved.

```lua
world.assetInstallable({ guid = asset.guid("@builtin::materials.neon") })
```

## typed/builtin//modules/world_vcs/world/awaitOutgoingSync {#typed-builtin-modules-world-vcs-world-awaitoutgoingsync}

```lua
world.awaitOutgoingSync()
```

Wait until every `/source` write this session made has reached
the branch it was written against. Raises naming the paths that did
not land. `add` / `commit` / `push` / `checkout` / `merge` / `pull`
already wait on their own; call this before rebinding after a burst
of writes, which `world.checkout` and `world.swap` refuse over.

**Returns** Nothing. Raises when a write did not land.

```lua
world.awaitOutgoingSync() ; world.checkout("main")
```

## typed/builtin//modules/world_vcs/world/branches {#typed-builtin-modules-world-vcs-world-branches}

```lua
world.branches() -> { { branch: string, commit_id: string, current: boolean } }
```

Every branch this world has, with the commit each one's head
names and which one this session is on — `git branch --list`. Sorted
by name. A branch exists for everyone in the world; which one you are
on is yours alone, so `current` is true for at most one row here and
says nothing about where anybody else is.

**Returns** `{ { branch: string, commit_id: string, current: boolean } }` — Array of `{ branch, commit_id, current }`.

```lua
for _, b in ipairs(world.branches()) do print(b.branch, b.commit_id) end
```

## typed/builtin//modules/world_vcs/world/checkUpdates {#typed-builtin-modules-world-vcs-world-checkupdates}

```lua
world.checkUpdates() -> { UpdateReport }
```

Discover upstream changes for every asset this world has
pulled. Read-only — makes no local mutation and no VCS write.
Each locally-pulled row identifies its own origin asset via
`origin_asset_guid` (recorded as that entry's own asset guid at
pull time — see `world.installAsset`). For every distinct
origin asset among the pulled rows, this re-resolves that
asset's latest transitive closure and compares each returned
entry's checksum against the matching local row's recorded
`origin_checksum`.

**Returns** `{ UpdateReport }` — An array of `UpdateReport`, one per re-resolved origin asset whose closure produced at least one changed entry. Empty when every pulled row is already current. A root whose closure can't be re-resolved (e.g. the origin world is unreachable) is silently skipped rather than aborting the whole scan.

```lua
local reports = world.checkUpdates()
```

## typed/builtin//modules/world_vcs/world/checkout {#typed-builtin-modules-world-vcs-world-checkout}

```lua
world.checkout(branch: string) -> string
```

Switch this session to another branch — `git checkout <branch>`.
The branch must already exist (create one with `world.createBranch`).
The tree is replaced by the branch's own content. Which branch this
session is on is this session's alone; the branch itself is shared,
so others may be on the one you move onto.
Uncommitted work is not at risk: it already has its row on the
branch it was written against and is in the tree again when you
check that branch out.
Returns only once the branch's content has landed, so `world.head`,
`world.log`, `world.commit` and the VFS all target the new branch
immediately afterwards.

**Parameters**

- `branch` `string` — The branch to switch to.

**Returns** `string` — The branch now checked out.

```lua
world.checkout("feature")
```

## typed/builtin//modules/world_vcs/world/commit {#typed-builtin-modules-world-vcs-world-commit}

```lua
world.commit(message: string, opts: CommitOpts?) -> string
```

Open-or-resume a staging area, set the message, and materialise
the commit. Commits ONLY what's already staged via `world.add` /
`world.add_all` — git semantics, not `git commit -a`. The reducer
auto-deletes the stage row on success so a subsequent
`world.commit` opens a fresh one.

`{ stage = "<name>" }` materialises one of the caller's own staging
areas, so the commit carries the paths staged under that name and
leaves every other caller's staged. When a commit from another
caller has landed since the area was opened, this brings the area
onto the branch head there is now and commits it there.

Pre-flight `.zmignore` refs gate: every staged source's
aggregated deps (via `asset.deps`, which recurses composite
asset folders) are checked against the live ignore set. If
any dep target's path is currently ignored AND the dep target
is not itself in the stage, the commit is refused. This
mirrors the closure invariant — a commit whose deps can't
resolve cleanly shouldn't land. Force-staging the dep
alongside (`world.add(dep, { force = true })`) makes the
ignored dep satisfy the gate.

**Parameters**

- `message` `string` — The commit message.
- `opts` `CommitOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
materialise. Omitted, the commit materialises the shared default
area.

**Returns** `string` — The newly-allocated commit id (ULID string).

```lua
local id = world.commit("feat: ship widget")
local id = world.commit("fauna: the swallow colony", { stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/conflicts {#typed-builtin-modules-world-vcs-world-conflicts}

```lua
world.conflicts() -> { ConflictEntry }
```

List every locally-pulled row currently flagged conflicted —
the findable surface `world.pullAsset` leaves behind on an
unresolved merge. Read-only.

**Returns** `{ ConflictEntry }` — An array of `ConflictEntry`, one per conflicted row. Empty when nothing is conflicted.

```lua
local list = world.conflicts()
```

## typed/builtin//modules/world_vcs/world/contentRequirements {#typed-builtin-modules-world-vcs-world-contentrequirements}

```lua
world.contentRequirements(scope: { string }?) -> { { asset: string, typeName: string, detail: string } }
```

List the world's unmet content requirements: user-authored assets
whose type-declared content constraints are not yet satisfied (an
empty README, a `.metadata` with no description or tags — the
empty-skeleton state a fresh create emits for the author to fill).
The same walk `world.push` gates on: push refuses while this list is
non-empty, and `world.publishBlockers` reports it as the `content`
class beside the other two. Empty list = every checked asset meets
its type's contract.

**Parameters**

- `scope` `{ string }` _(optional)_ — Asset paths to restrict the check to — pass a status read's
dirty + staged paths to check only content that would actually
publish (a per-file path matches its containing asset; each path
resolves directly, with no world enumeration). Omit for the
full-world walk the push gate performs.

**Returns** `{ { asset: string, typeName: string, detail: string } }` — Array of `{ asset, typeName, detail }` requirement rows.

```lua
for _, r in ipairs(world.contentRequirements()) do print(r.asset, r.detail) end
```

## typed/builtin//modules/world_vcs/world/contribute {#typed-builtin-modules-world-vcs-world-contribute}

```lua
world.contribute(opts: ContributeOpts?) -> { ContributeOutcome }
```

Send improvements to installed content back upstream — `git
subtree push` ending in a pull request. For each targeted origin
world: the diverging subtree is remapped to the origin's canonical
paths, three-way merged against the origin's CURRENT content
(regions the origin also changed become local conflicts to
resolve first), pushed as a `contrib/<id>` branch in the origin
world, and opened as a pull request there. With `merge` (the
default) the pull request is merged immediately when authorized —
a refusal leaves it open and reported, never a failure. After a
merge, the local fork re-pulls so its origin pins advance and the
asset no longer reads as ahead.

**Parameters**

- `opts` `ContributeOpts` _(optional)_ — Optional `ContributeOpts` — `targets` (origin world guids;
default all ahead), `merge` (default true), `title`,
`description`, `dryRun`.

**Returns** `{ ContributeOutcome }` — Array of `ContributeOutcome`, one per targeted origin.

```lua
local r = world.contribute({})
```

## typed/builtin//modules/world_vcs/world/createBranch {#typed-builtin-modules-world-vcs-world-createbranch}

```lua
world.createBranch(name: string, fromCommit: string?)
```

Create a branch — `git branch <name> [<start>]`. The branch
starts at `fromCommit` (defaults to the session branch's HEAD)
and gets its own working tree, materialized from that commit.
The session stays on its current branch; move onto it with
`world.checkout("<branch>")` (`git checkout`).

**Parameters**

- `name` `string` — The new branch name.
- `fromCommit` `string` _(optional)_ — Commit id to start at. Defaults to `world.head()`.

```lua
world.createBranch("feature")
```

## typed/builtin//modules/world_vcs/world/deleteBranch {#typed-builtin-modules-world-vcs-world-deletebranch}

```lua
world.deleteBranch(branch: string)
```

Delete a branch — `git branch -D <name>`. Drops the branch and
the working tree it owns; its commits are left alone, since deleting
a branch is dropping the name and the tree under it, not rewriting
history. Uncommitted work on that branch goes with it and is NOT
recoverable from trash, so the call refuses the first time and
returns the affirmation needed to go through with it — affirm with
`world.affirm(<token>)`. Refuses the branch this session is on
(check out another first) and the world's last branch.

**Parameters**

- `branch` `string` — The branch to delete.

```lua
world.deleteBranch("feature")
```

## typed/builtin//modules/world_vcs/world/diff {#typed-builtin-modules-world-vcs-world-diff}

```lua
world.diff(...: string) -> any
```

Mirror `git diff`'s CLI arg shape. Returns per-file diffs
by default; pass `--stat` for summary stats, `--name-only` for
just paths. Positional commit ids drive the two sources;
`--staged` pivots to staged-vs-HEAD. `--`-separated args
scope the diff to specific paths. `--stage=<name>` reads one of the
caller's own staging areas in place of the shared default one.

**Parameters**

- `...` `string` — Variadic string args: flags, commit ids, `--`, path filters.

**Returns** `any` — Array of `DiffFile` tables (or string-list for `--name-only`).

```lua
local files = world.diff()
local files = world.diff("--staged")
local files = world.diff("abc", "def")
local names = world.diff("--name-only")
local files = world.diff("--staged", "--stage=fauna")
```

## typed/builtin//modules/world_vcs/world/discard {#typed-builtin-modules-world-vcs-world-discard}

```lua
world.discard(opts: StageOpts?)
```

Drop a staging area without committing. Live manifest dirty flags
are preserved so the user can re-stage later. No-op if the area
doesn't exist.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
drop. Omitted, the call drops the shared default area.

```lua
world.discard()
world.discard({ stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/discardFile {#typed-builtin-modules-world-vcs-world-discardfile}

```lua
world.discardFile(path: string)
```

Discard one file's unstaged working edits, taking its content
back to what it was staged or committed as — the
`git restore <path>` shape. The stage is the baseline when the
path is staged, the last commit when it is not, and where it is
neither there is nothing to come back to, so the path goes away.
Staging is left exactly as it was; `world.unstage` is the verb
that changes it. One shot: a path that reverts to a committed
version snapshots the discarded bytes to trash first, so that
case is recoverable via `world.restore(<handle>)`. Errors when
the path is not dirty (nothing to discard).

**Parameters**

- `path` `string` — The VFS path whose unstaged edits to discard.

```lua
world.discardFile("/source/foo.luau")
```

## typed/builtin//modules/world_vcs/world/fetch {#typed-builtin-modules-world-vcs-world-fetch}

```lua
world.fetch(branch: string?) -> FetchResult
```

Update the `origin/<branch>` remote-tracking ref — `git fetch`.
Mirrors the world's ZeroMind branch head into the local commit
history (no working-tree change) and reports how the session
branch relates to it: `behind` origin commits to pull, `ahead`
local commits to push, `diverged` when both. A stale installed
pin or out-of-band ZeroMind change shows up here as `behind` —
reconcile with `world.pull()`.

**Parameters**

- `branch` `string` _(optional)_ — Remote branch to fetch. Defaults to the session branch.

**Returns** `FetchResult` — A `FetchResult` table.

```lua
local f = world.fetch()
```

## typed/builtin//modules/world_vcs/world/forkLive {#typed-builtin-modules-world-vcs-world-forklive}

```lua
world.forkLive(opts: { source: string, sourceBranch: string?, maxBatches: number? }) -> number
```

Seed THIS (empty) world's live content from another world by
copying its whole manifest as clean **Pulled** rows — the
in-engine half of "fork a world". Provenance is preserved: each
row points at the content's ORIGINAL owner (a fork of a
fork-of-A still points at A), so the fork never claims to have
authored what it pulled. The copy runs server-side in bounded
batches (idempotent + resumable), looping until the source is
fully mirrored. Pair with `world.add_all()` + `world.commit()` +
`world.push()` to publish the fork.

**Parameters**

- `opts` `{ source: string, sourceBranch: string?, maxBatches: number? }` — `{ source, sourceBranch?, maxBatches? }` — `source` is the
source world GUID; branches default to `"main"`; `maxBatches`
caps the batch loop (default 60 ⇒ up to ~120k entries).

**Returns** `number` — The number of pulled (dirty) rows now staged-pending on the fork.

```lua
world.forkLive({ source = "e89aa92e-4c1f-460e-acd8-73859dd3a346" })
```

## typed/builtin//modules/world_vcs/world/forkStatus {#typed-builtin-modules-world-vcs-world-forkstatus}

```lua
world.forkStatus() -> { ForkStatus }
```

Per-asset "ahead of origin" report — the fork analogue of git
status against an upstream. Every installed (pulled) row whose
content diverges from its pinned origin is listed, partitioned by
the TRUE origin world it was pulled from (nested dependencies
carry the world that authored them, not the intermediary they
arrived through). This is information for judgment: decide
whether a change belongs upstream, then `world.contribute`.

**Returns** `{ ForkStatus }` — Array of `ForkStatus` partitions.

```lua
for _, f in ipairs(world.forkStatus()) do print(f.origin_world, #f.entries) end
```

## typed/builtin//modules/world_vcs/world/head {#typed-builtin-modules-world-vcs-world-head}

```lua
world.head() -> string?
```

Return the current branch HEAD commit id, or nil if the
branch has no commits yet.

**Returns** `string?` — The commit id string, or nil.

```lua
local id = world.head()
```

## typed/builtin//modules/world_vcs/world/installAsset {#typed-builtin-modules-world-vcs-world-installasset}

```lua
world.installAsset(opts: InstallAssetOpts) -> InstallAssetResult
```

Install a published asset into this world, pulling the asset and
every dependency it closes over and writing them into the source tree.
Reports what it wrote so a caller can tell a fresh install from a no-op.

**Parameters**

- `opts` `InstallAssetOpts` — `{ guid }` names the root asset to install; `ref` pins a specific
commit-id instead of the latest.

**Returns** `InstallAssetResult` — `{ assets_written, blobs_downloaded, root_guid, root_path, root_version, deps }`.

```lua
local r = world.installAsset({ guid = assetGuid })
```

## typed/builtin//modules/world_vcs/world/installLibrary {#typed-builtin-modules-world-vcs-world-installlibrary}

```lua
world.installLibrary(opts: InstallLibraryOpts) -> InstallLibraryResult
```

Declarative cross-world dependency. Writes a single marker
file at `/source/libs/@<name>` whose body is the
`zero/world-import/v1` JSON. The next commit ships it as one
regular manifest entry; ZM's import-derivation pass at
finalize-time decodes the marker and stamps the new commit's
`imports[]`. Unmodified library content never ships in the
importing world's tree — it's fetched from the source world
on demand by the engine's library resolver.

**Parameters**

- `opts` `InstallLibraryOpts` — See `InstallLibraryOpts`. `opts.world` is the upstream
world's guid (required). `opts.commit` is the upstream
commit_id to pin (optional; resolves `opts.ref` or `main` if
omitted). `opts.as` is the local library name (defaults to
the upstream world's slug). `opts.ref` is the human-meaningful
ref recorded in the marker.

**Returns** `InstallLibraryResult` summarising the install.

```lua
world.installLibrary({ world = "guid", as = "combat" })
```

## typed/builtin//modules/world_vcs/world/installedAssets {#typed-builtin-modules-world-vcs-world-installedassets}

```lua
world.installedAssets() -> { InstalledAsset }
```

Every asset this world carries from ZeroMind, keyed by the
published guid it was pulled from. The read that answers "what is
actually in this world" by identity rather than by path — an
installed asset's local name can be chosen by the installer, so a
path is not the thing to check a pull against.

**Returns** `{ InstalledAsset }` — An array of `InstalledAsset` sorted by local path, one per pulled row carrying a published guid.

```lua
for _, a in ipairs(world.installedAssets()) do print(a.asset_guid, a.path) end
```

## typed/builtin//modules/world_vcs/world/list {#typed-builtin-modules-world-vcs-world-list}

```lua
world.list() -> { WorldEntry }
```

List every world the authenticated user has access to.
Calls the spacetime `list_my_worlds` procedure which wraps
ZeroMind's `GET /v1/me/worlds`. Flattens each entry to one
record per world with the role promoted to a top-level field.

## typed/builtin//modules/world_vcs/world/log {#typed-builtin-modules-world-vcs-world-log}

```lua
world.log(opts: LogOpts?) -> { CommitRow }
```

Return the commit log for the current branch, newest first.
Pass `opts.path` to get the per-path history (`git log -- <path>`):
only the commits that touched that file, newest-first.

**Parameters**

- `opts` `LogOpts` _(optional)_ — Optional. `opts.limit` caps the number of commits
(default 50, 0 = all). `opts.path` scopes the log to one file.

**Returns** `{ CommitRow }` — Array of `CommitRow` tables.

```lua
local commits = world.log({ limit = 20 })
local touched = world.log({ path = "/source/foo.luau" })
```

## typed/builtin//modules/world_vcs/world/merge {#typed-builtin-modules-world-vcs-world-merge}

```lua
world.merge(sourceBranch: string) -> MergeResult
```

Merge another branch into the session branch — `git merge
<source>`. The merge runs locally in the world's SpacetimeDB clone
and is abortable with `world.mergeAbort`; nothing reaches ZeroMind
until the result is pushed. Requires a clean working tree (commit
or stash first — that is also what makes abort exact). Clean →
a two-parent merge commit lands on the session branch and the
merged content appears in the working tree. Conflicts → git-style
markers are projected into each conflicting text file, the
cleanly-merged remainder is applied as working-tree changes, and
`world.vcsStatus().unmerged` lists what needs attention: resolve
each path (edit out the markers / rewrite / remove the file),
then `world.add` + `world.commit` — that commit records the merge
(second parent = the source head) and clears the unmerged set.

**Parameters**

- `sourceBranch` `string` — The branch to merge in.

**Returns** `MergeResult` — A `MergeResult` — `status` is `clean` (with `commit`), `conflicts` (with `conflicts`), or `up_to_date`.

```lua
local r = world.merge("feature")
```

## typed/builtin//modules/world_vcs/world/mergeAbort {#typed-builtin-modules-world-vcs-world-mergeabort}

```lua
world.mergeAbort()
```

Abort the in-progress merge — `git merge --abort`. Clears the
unmerged set and restores the working tree to the pre-merge state
(the target head's committed content; the branch head never moved
during a conflicted merge). Errors when no merge is in progress.

```lua
world.mergeAbort()
```

## typed/builtin//modules/world_vcs/world/prConflicts {#typed-builtin-modules-world-vcs-world-prconflicts}

```lua
world.prConflicts(worldGuid: string?, number: number) -> any
```

Read a pull request's conflicts — what stands between it and a
merge. Returns the mergeability verdict, the merge base, both
heads, and one entry per conflicting path. A conflicting TEXT path
carries `marked_text`: the same `<<<<<<<` / `=======` / `>>>>>>>`
rendering a merge leaves in the working tree, with the source and
target sides laid against their common ancestor. Resolve a path by
writing the settled bytes back to it and committing on the source
branch; the pull request re-analyses on the next read. A binary
path carries the two sides' hashes and no text — pick a side.
A mergeable pull request returns an empty conflict list.

**Parameters**

- `worldGuid` `string` _(optional)_ — The world the pull request lives in. Defaults to the
bound world.
- `number` `number` — The pull request number.

**Returns** `any` — Decoded ZeroMind conflicts response.

```lua
local c = world.prConflicts(nil, 3)
for _, m in ipairs(world.prConflicts(originGuid, 3).markers) do print(m.path, m.marked_text) end
```

## typed/builtin//modules/world_vcs/world/prList {#typed-builtin-modules-world-vcs-world-prlist}

```lua
world.prList(worldGuid: string?, number: number?) -> any
```

**Parameters**

- `worldGuid` `string` _(optional)_
- `number` `number` _(optional)_

**Returns** `any`

## typed/builtin//modules/world_vcs/world/prMerge {#typed-builtin-modules-world-vcs-world-prmerge}

```lua
world.prMerge(worldGuid: string, number: number, strategy: string?) -> any
```

Merge a pull request — the agent-side merge button.

**Parameters**

- `worldGuid` `string` — The world the pull request lives in.
- `number` `number` — The pull request number.
- `strategy` `string` _(optional)_ — `merge` (default), `squash`, or `fast_forward`.

**Returns** `any` — Decoded ZeroMind merge response.

```lua
world.prMerge(originGuid, 3)
```

## typed/builtin//modules/world_vcs/world/prOpen {#typed-builtin-modules-world-vcs-world-propen}

```lua
world.prOpen(opts: PrOpenOpts) -> any
```

List a world's pull requests, or fetch one.
Open a pull request — `gh pr create`. Proposes the work on one
`(world, branch)` pair to another. Defaults make the common cases one
argument: from a fork, the target is the world it was forked from, so
`world.prOpen({ title = "..." })` proposes your work upstream. In an
ordinary world the target is the same world, so you get a
branch → `main` pull request.
The PR lives in — and is numbered by — the world it targets, exactly
as a forge numbers pull requests on the upstream repository. That is
also where `world.prList` finds it.

**Parameters**

- `opts` `PrOpenOpts` — `title` (required), plus `description`, `sourceWorld`,
`sourceBranch`, `targetWorld`, `targetBranch` to address any leg
explicitly.

**Returns** `any` — Decoded ZeroMind response. The decoded ZeroMind pull request.

```lua
local prs = world.prList()
world.prOpen({ title = "fix the door hinge" })
world.prOpen({ title = "port the fix", targetWorld = otherGuid })
```

## typed/builtin//modules/world_vcs/world/prView {#typed-builtin-modules-world-vcs-world-prview}

```lua
world.prView(worldGuid: string?, number: number) -> any
```

Read one pull request in full — `gh pr view`. Returns the record
plus a LIVE re-analysis against the current branch heads: `mergeability`
(`clean` / `conflicts` / `fast_forwardable` / `up_to_date` /
`unrelated`), `conflict_count`, and `diff` — every path the request
adds, modifies or deletes with its checksums. Read this before merging:
it is what tells you WHAT the request changes.

**Parameters**

- `worldGuid` `string` _(optional)_ — The world the pull request lives in (its target world).
Defaults to the session world.
- `number` `number` — The pull request number.

**Returns** `any` — The decoded pull request view.

```lua
world.prView(nil, 1)
```

## typed/builtin//modules/world_vcs/world/previewInstall {#typed-builtin-modules-world-vcs-world-previewinstall}

```lua
world.previewInstall(opts: InstallAssetOpts) -> PreviewResult
```

Preview what installing an asset WOULD write, without writing
anything. Fetches + decodes the closure and plans placement (the
same helpers `world.installAsset` uses), returning a flat node
list plus rollup totals. A truncated closure is reported (not
raised) so a caller can surface it and block import.

**Parameters**

- `opts` `InstallAssetOpts` — `{ guid, at?, ref? }` — same shape as installAsset.

**Returns** `PreviewResult` — nodes + totals + a truncated flag.

```lua
world.previewInstall({ guid = "..." })
```

## typed/builtin//modules/world_vcs/world/publishBlockers {#typed-builtin-modules-world-vcs-world-publishblockers}

```lua
world.publishBlockers() -> { PublishBlockerClass }
```

List every reason `world.push` would refuse to publish this
world, as one entry per blocker class: script errors in user
content, assets that don't meet their type's content requirements,
and asset references that can't be statically pinned. Each class
carries the same `title` the refusal prints, one `items` entry per
offending subject (an asset identity, or a `<path>:<line>` site),
and the single `remedy` covering that class. This is the account
`world.push` composes its refusal from, so it names the same
blockers with no push attempted — and in full, where a refusal
bounds how many of a class it prints. Empty list = the world
publishes. `zm status` prints this list.

**Returns** `{ PublishBlockerClass }` — Array of `PublishBlockerClass` entries, empty when nothing blocks.

```lua
for _, c in ipairs(world.publishBlockers()) do
for _, i in ipairs(c.items) do print(c.kind, i.subject, i.detail) end
end
```

## typed/builtin//modules/world_vcs/world/pull {#typed-builtin-modules-world-vcs-world-pull}

```lua
world.pull(branch: string?) -> PullResult
```

Fetch and reconcile with origin — `git pull`. Strictly behind →
fast-forward (the branch head moves to the origin mirror, no merge
commit). Diverged → three-way merge of the origin mirror, with the
same conflict/marker/resolve flow as `world.merge` (resolve the
unmerged paths, then `world.add` + `world.commit`; abortable with
`world.mergeAbort`). Requires a clean working tree.

**Parameters**

- `branch` `string` _(optional)_ — Remote branch to pull. Defaults to the session branch.

**Returns** `PullResult` — A `PullResult` table.

```lua
local r = world.pull()
```

## typed/builtin//modules/world_vcs/world/pullAsset {#typed-builtin-modules-world-vcs-world-pullasset}

```lua
world.pullAsset(opts: PullAssetOpts?) -> PullAssetResult
```

Pull upstream changes into a previously-installed asset,
three-way reconciling each entry against local edits. Re-resolves
the root's transitive closure at `opts.ref` (default latest),
then for every entry decides `fast_forward` / `noop` / `converged`
/ `merge` from `(row.origin_checksum, localChecksum,
entry.checksum)` (`M.__reconcileDecision`):

- `noop` — upstream hasn't moved; skipped.
- `fast_forward` / `converged` — the entry's latest text is
written to the local path and the row's origin pointer
advances. Binary and composite entries can't be content-synced
through this call's only cross-world read primitive (text
only), so a non-text entry with a real upstream change is
surfaced as a conflict instead of silently going stale.
- `merge` (text entries) — a three-way `vcs.merge3` runs over
(base, local, theirs); a clean result is written and the
origin pointer advances, a conflicted result is written WITH
markers and the row is flagged conflicted (base + theirs
checksums recorded for `world.resolvePullConflict`).
- `merge` (binary / composite entries) — no text merge is
possible; flagged conflicted with the structured base/theirs
checksums (no marker write).

Closure drift: an entry the original install never landed is
pulled fresh (added). A locally-pulled row nested under the
root's own directory whose origin entry disappeared from the
closure is removed when clean (pruned), or flagged conflicted
when it carries local edits.

**Parameters**

- `opts` `PullAssetOpts` _(optional)_ — See `PullAssetOpts`. `opts.guid` or `opts.path` is
required; `opts.ref` pins the re-resolve to a specific upstream
commit (defaults to latest finalized).

**Returns** `PullAssetResult` summarising what merged, conflicted, was pruned, and was newly added.

```lua
world.pullAsset({ guid = "..." })
```

## typed/builtin//modules/world_vcs/world/push {#typed-builtin-modules-world-vcs-world-push}

```lua
world.push(commitId: string?) -> (string?, string)
```

Publish the current branch to ZeroMind. The no-argument form
is a git `merge --squash` push: EVERY unpushed commit on the
branch collapses into a SINGLE ZeroMind commit (latest content
per path, parented on the branch's current remote HEAD). Because
only the merged final state's bytes are uploaded, a superseded or
lost intermediate-commit blob can never break the push — this is
what makes a churn-heavy world publishable. The local commit
history is preserved as the editing journal; on success every
squashed commit shares the one remote commit id. The explicit
`commitId` form still pushes that single commit verbatim via
`publish_commit` (advanced / chain-replay use; its parent must
already be on the remote).

**Parameters**

- `commitId` `string` _(optional)_ — Optional. A single commit to push verbatim. Omit for
the squash push of the whole unpushed stack (the normal path).

**Returns** `(string?, string)` — Two values: the ZeroMind-allocated commit id, and the verdict. `"published"` with the new commit id when this call published; `"already-published"` when ZeroMind already carries what this call would have published — the state a push asks for, so it returns rather than raising. That verdict carries the commit's existing ZeroMind id when the publish names one (the single-commit form), and a nil id when it names none (the whole-stack form, which reports a chain). A squash whose merged final state carries `dep.unresolved` problems takes the slow path inside the same call: the engine re-resolves each pending literal against its live asset index and submits the resolutions to the publish procedure, which completes the push. A reference literal that still resolves to nothing is published with the asset holding it and stays a problem recorded on that asset, while a dep pin the squash severed raises instead; either way the engine names each one with its path, line, reference and reason. A publish ZeroMind refuses raises naming the condition and the command that clears it — a branch that moved under this push names `world.pull()`.

```lua
local zmId = world.push()
local zmId, verdict = world.push()
world.push("01HABC...")
```

## typed/builtin//modules/world_vcs/world/reset {#typed-builtin-modules-world-vcs-world-reset}

```lua
world.reset(targetCommitId: string) -> string?
```

Rewind HEAD to `targetCommitId` in one shot. Non-destructive
— orphaned commits stay in storage and each becomes a trash
entry the user can `world.restore` (in chain order) to re-attach
the branch. Errors when `targetCommitId` is not an ancestor of
HEAD. Returns a summary of what was rewound.

**Parameters**

- `targetCommitId` `string` — The commit id to rewind to.

**Returns** `string?` — A summary message: the target plus the list of commits rewound past.

```lua
world.reset("01HABC...")
```

## typed/builtin//modules/world_vcs/world/resolvePullConflict {#typed-builtin-modules-world-vcs-world-resolvepullconflict}

```lua
world.resolvePullConflict(path: string, choice: string)
```

Resolve a conflicted row. A TEXT conflict is one where the file
currently contains conflict markers (`world.pullAsset` writes
markers only for a text three-way merge that didn't resolve
cleanly); a BINARY/composite conflict has no markers — the local
bytes were left untouched.

`choice = "theirs"` fetches clean upstream text by content hash
(`conflict_theirs_blob_sha256` — path/rename-independent, since
blobs are content-addressed) and overwrites the local file with it
before clearing the flag. It errors, refusing to guess, when the
row records no theirs blob (a binary/composite conflict — a text
blob read can't address theirs for those; keep `"ours"` or
re-install the asset instead).

`choice = "ours"` keeps the local side. When the file carries
conflict markers, the local side is reconstructed from them (the
marker writers put ours first, so dropping each block's base and
theirs sections restores your bytes exactly) and written back;
a marker-free file is kept as-is. Either way the flag clears.

Either way, staging the resolved file (`world.add`) is the normal
git-add path once this returns — this call only clears the
manifest-level flag and (for `"theirs"`) the file content.

**Parameters**

- `path` `string` — The conflicted row's local VFS path.
- `choice` `string` — `"ours"` or `"theirs"`.

```lua
world.resolvePullConflict("/source/combat/rules.luau", "theirs")
```

## typed/builtin//modules/world_vcs/world/restore {#typed-builtin-modules-world-vcs-world-restore}

```lua
world.restore(handle: any?)
```

Restore one trash entry by row_id. Errors verbatim on
handler-not-yet-implemented / world-mismatch.

**Parameters**

- `handle` `any` _(optional)_ — The trash row id. May be a number or a numeric string.

```lua
world.restore(42)
```

## typed/builtin//modules/world_vcs/world/show {#typed-builtin-modules-world-vcs-world-show}

```lua
world.show(...: string) -> any
```

Mirror `git show`'s CLI arg shape. Default returns commit
metadata + full diff vs parent. `world.show("commit:/path")`
returns just the bytes. Flags: `--stat`, `--name-only`.

**Parameters**

- `...` `string` — Variadic string args: commit id, optional path, optional flags.

**Returns** `any` — Either a `ShowResult` table or a string (for `commit:/path`).

```lua
local r = world.show("abc123")
local r = world.show("--stat", "abc123")
local bytes = world.show("abc123:/foo.luau")
```

## typed/builtin//modules/world_vcs/world/stash {#typed-builtin-modules-world-vcs-world-stash}

```lua
world.stash(label: string?)
```

Save the caller's current pending dirty + staged state on
the active (world, branch) into a stash row. `label` is
optional free-form text. Non-destructive — dirty + staged
state is preserved on disk.

**Parameters**

- `label` `string` _(optional)_ — Optional. Free-form text label for the stash.

```lua
world.stash("wip widget refactor")
```

## typed/builtin//modules/world_vcs/world/stashDrop {#typed-builtin-modules-world-vcs-world-stashdrop}

```lua
world.stashDrop(handle: any?)
```

Request an affirmation token to drop a stash. Always
errors — successful mint surfaces the token as `affirmation
required: zm affirm <token>`. The agent runs `zm affirm
<token>` to actually drop; restoration via `world.restore()`
reappears the stash under a new row_id.

**Parameters**

- `handle` `any` _(optional)_ — The stash row id. May be a number or numeric string.

```lua
world.stashDrop(7)
```

## typed/builtin//modules/world_vcs/world/stashPop {#typed-builtin-modules-world-vcs-world-stashpop}

```lua
world.stashPop(handle: any?) -> StashSnapshot
```

Author-only. Pop the stash row (deletes it server-side)
and return the decoded snapshot. The caller is responsible
for re-applying the snapshot to disk via the normal write
paths (so ACL gates fire on every restored path).

**Parameters**

- `handle` `any` _(optional)_ — The stash row id. May be a number or numeric string.

**Returns** `StashSnapshot` containing `dirty` + `staged` entries.

```lua
local snap = world.stashPop(7)
```

## typed/builtin//modules/world_vcs/world/stashes {#typed-builtin-modules-world-vcs-world-stashes}

```lua
world.stashes() -> { StashRow }
```

List every stash row in the world. Anyone with read access
sees every stash; the per-row `author_hex` makes it clear
which entries the caller can pop / drop themselves.

**Returns** `{ StashRow }` — Array of `StashRow` tables.

```lua
local rows = world.stashes()
```

## typed/builtin//modules/world_vcs/world/trash {#typed-builtin-modules-world-vcs-world-trash}

```lua
world.trash() -> { TrashRow }
```

List trash entries for the world. Anyone with read access
to the world can list trash — recovery is a shared safety net,
not a privacy boundary. The handle (`row_id`) feeds back into
`world.restore`.

**Returns** `{ TrashRow }` — Array of `TrashRow` tables.

```lua
local rows = world.trash()
```

## typed/builtin//modules/world_vcs/world/uninstallLibrary {#typed-builtin-modules-world-vcs-world-uninstalllibrary}

```lua
world.uninstallLibrary(name: string) -> string
```

Delete the library marker file. `name` accepts `"@combat"`
or `"combat"` (the leading `@` is the convention carried by
the on-disk path).

**Parameters**

- `name` `string` — The library name, with or without the leading `@`.

**Returns** `string` — The marker path that was removed.

```lua
world.uninstallLibrary("@combat")
```

## typed/builtin//modules/world_vcs/world/unstage {#typed-builtin-modules-world-vcs-world-unstage}

```lua
world.unstage(path: string, opts: StageOpts?)
```

Remove a path from the staging area. Live manifest dirty
state is untouched.

**Parameters**

- `path` `string` — The path to unstage.
- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area the
path was staged into. Omitted, the call acts on the shared default
area.

```lua
world.unstage("/source/foo.luau")
world.unstage("/source/foo.luau", { stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/vcsStatus {#typed-builtin-modules-world-vcs-world-vcsstatus}

```lua
world.vcsStatus(opts: StageOpts?) -> StatusResult
```

Return the working-tree VCS status: dirty paths, staged
entries, ignored paths, untracked paths, and any unmerged ones.
An untracked path is one with no committed version behind it, and
it appears in `dirty` as well — `git add .` picks up new files too.
Named `vcsStatus` (not `status`) because `world.status()` is the
runtime-snapshot accessor owned by `world_status.module`; the
source-control surface keeps its own VCS-specific name so the
two never shadow each other.
Each `dirty[i].dirtied_by` is the identity of the most recent
writer; `dirty_since_micros` is the microsecond timestamp of the
first write of the current dirty run. `local_identity` is this
session's own writer identity in that same namespace — compare
the two to tell your own writes from another account's.
`claimed_by_other_stages` names the paths some other staging area
holds and which area holds each — the grain that tells two callers
apart when they share one writer identity, and the set
`world.add_all` holds back.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area whose
staged set to report. The dirty, ignored and untracked sets are the
world's working tree and read the same whichever area is named.

**Returns** `StatusResult` — A `StatusResult` table.

```lua
local s = world.vcsStatus()
local s = world.vcsStatus({ stage = "fauna" })
```
