You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
mojulo orient — the shell's initialize. An MCP client is handed the server instructions at
connect (what mojulo is, the five paradigms, "call forward_context when unsure"), and the host
injects them into the agent's context for free. A shell caller (npx mojulo call … in an agent's
box with no MCP client) never sends initialize, so nothing told it to orient, and every body it
read — forward_context, a pack unveil, a vocab card — was written in MCP call grammar with no
translation to the bin. The local tool ledger showed the gap: sessions driven through mojulo call
called forward_context once in a month and never first, while the Grok shell run that piped
JSON-RPC frames into the same bin oriented before minting. mojulo orient prints the same preamble
byte for byte, the packs mechanic (the CLI listing is the packs shape), and a CLI addendum that
translates the grammar (tool({…}) → mojulo call tool --json, pack_x({tool,args}) → mojulo pack_x tool), points at mojulo call forward_context, and names MOJULO_HOST (the ids
come from the host registry) and MOJULO_SURFACE=box, the two env vars that stand in for clientInfo. All three blocks live in server.js; the CLI still authors no orientation prose of
its own beyond a one-line footer on mojulo tools and the usage line. orient is one more
reserved word on the bin. Both READMEs, AGENTS.md and CLAUDE.md name it; the box paragraph now
tells the operator to have the agent run it first.
Recorded stopping point. Surface-aware grammar lines inside forward_context and the pack
unveils (a surface field on the CLI context rather than branching on the cli session id) were
considered and left out: the pointer alone may be enough, and that change opens the orientation
bodies' own pins.
Clouds
A cloud deck over any world that has fog boxes. The 2026-09-17 smoke-and-cloud spike found that
a lit, Worley-eroded deck composited through the existing effects[] overlay reads as cumulus with
lit tops and shaded troughs, and recommended it as a clouds setting; nothing had been wired since.
Now clouds: true (or a tuning object) on a kind whose registry descriptor declares fogBoxes
(fractal-city, edifices, subway-station, controllable) adds a deck layer to the live /world
page. Two modes, chosen by the operator because the frame budget is theirs. undershot (the default)
is one plane intersection per pixel, no march: coverage and erosion sampled where the view ray meets
the deck's base (camera below) or top (camera above), slab depth turned into alpha, lit by the sun
transmitted through the slab plus a normalised phase lobe and a ground-to-sky ambient, faded toward
the horizon. { mode: 'full' } is the spike's round-3 composite: a volumetric march over the band
with a sun light-march, dual-lobe Henyey-Greenstein, powder and ambient, and when base is set low
enough that a solid crosses the band, clipped behind it by the same box occluder the fog uses.
Tuning: base, top (default: the band starts above the tallest occluder box, so nothing solid
crosses it), coverage 0..1, sun (defaults to the
world's light.toLight), color, density, scale, drift, maxDist, fade, steps. The layer
publishes its band as meta.base / meta.top so cameras and walk eyes can stay out of it. A bad
tuning object throws by name, so compose_world's render check refuses the mint instead of storing
a page that fails. Absent ⇒ zero bytes; stills and engine exports ignore it, like fog. lib/graph/effects/effects-clouds.js (composeCloudDeck) is fog's sibling; the shared GLSL the
spike wrote inline (trilinear value noise, fbm, Worley, Henyey-Greenstein, the light march, the
energy rules) is now lib/graph/effects/volume-lib.js for the next effect to reuse. compose_world
with base city stores clouds beside fog; the city card documents it.
Painted landscapes take the deck too. A registry descriptor can now say clouds: true instead of
declaring fogBoxes: the kind has no solids to clip, and the band clears the mesh's tallest vertex
instead (the deck composer's new floor, which every deck also honours beside its boxes). The painted-landscape kind declares it, create_painted_landscape and compose_world with base painted-landscape store clouds, and the landscape card documents it. The ?render=raymarch
backend returns before the channel layer and carries no deck, like every other channel.
Library
The Library is a folder list, not a gallery./library no longer renders anything: the
split-view preview pane, the per-shelf rooms (board, wall, cast, masonry, rows) and the turntable
tiles of the full folder view are gone from the page. A left rail lists All sketches, Unfiled and
every folder, then the shelves with their whole-store counts; the body is one table (name with its
plan/research tags, kind, minted date, ref) with open / move / delete on hover; a strip under the
table shows the focused row's facts and actions (rename in place, open the detail page in a new
tab, SVG/PNG download where the kind has a still form, move, delete) and turns into the bulk bar
when rows are checked. The Name, Kind and Minted headers sort: newest first by default, a column's
first click sorts the way it reads (names A to Z, kinds grouped, dates newest first), a second
flips it, ties break newest first, and the choice is remembered per browser. Seeing a sketch is what /sketches/<ref> is for. The shelf model,
the sketch APIs and the beats gallery are untouched; components/LibraryBrowser.jsx is the new
body and SketchGallery now exports its folder modals, download links and icons so the two share
them. New library.* strings in every locale.
The dashboard stops serving stale rows. Two causes, both fixed. Recency was mint time only: sketches had no edit timestamp, so a recipe iterated in place with update_sketch or edit_solid never rose on the bench or in a strip. A sketches.updated_at column (idempotent
migration, backfilled from created_at) is stamped on mint, retitle and recipe edit, never on a
folder move or bucket pin; SketchRepository.recent() and newestByBucket() order by last touched,
so /api/home's head and /api/home/floor's strips and "picked up recently" follow what was
actually just touched. Rows carry updatedAt beside createdAt. And the floor's two SWR reads had
focus revalidation switched off, so a tab left open while the agent worked never refreshed: they now
re-read on focus and every thirty seconds while visible, keeping the previous rows until the new
ones land. The floor's cards, hero and swatches are unchanged. The library keeps its mint-time
order; its Minted column is honest about what it sorts.
The floor's 3D zone names the workshop's real contexts, and the bench is gone. Two shelves
join the shelf model. turntables is the illustration bucket's css3d-turntable and subway-station kinds: live scenes the viewport orbits, and by far the commonest thing in that
bucket, which the Images shelf had been hiding on the 2D side of the floor. views is the object
bucket minus the solids (workbench, scad, assembler, the polygomer's manji-tree): the
scientific and educational studies, orbited and read, never printed. Models is now the solids alone,
Images is what is left after characters and turntables, and Scenes is labelled Worlds. The 3D zone
reads worlds · turntables · models · views · characters · materials; the 2D zone is unchanged; the
front door's zone counts follow. The floor's bench (the live hero frame and "picked up recently")
is removed: the head is still what ?ref= and the empty-workshop check read, but nothing on the
floor mounts a live frame any more. The six per-room "open the … board" links collapse to one
"Open in the library" string. Shelf and zone tests re-pinned; every locale re-minted.
Docs
README and npm README name every box that has run mojulo. The agent-box tier now lists the
hosts that have installed the package in their throwaway Linux box and driven it to a mint and an
export: the Claude app (macOS, Windows, web, iOS; Claude Code on the web is that app), ChatGPT
work mode with Codex, Grok chat, and Meta Muse (iOS, web, macOS app, one session across all
three). The
Quickstart splits the box comment by what the box has: an MCP client (init with defaults) or a
shell only (npx mojulo call). The package.json description carries the same list. The
"verified on" sentence in both READMEs says which platform verified what, instead of folding the
box runs into a Linux CI clause.
A who-ran-it-where matrix under "Where it runs" in both READMEs: agents down, environments
across (macOS, Windows, the web agent's Linux box), a green tick for a persistent install on the
operator's machine and a blue tick for an ephemeral box run (the same glyph, two colours: docs/images/tick-green.svg and tick-blue.svg, inline images because markdown cannot colour
text; the npm README points at the raw GitHub URLs), blank for not yet verified. Cells come from
the recorded runs: Claude Code and the Claude app on macOS and Windows, Codex, Grok Build and
Hermes Agent on macOS, and the box runs above. One row per vendor: Codex sits in the ChatGPT row, Grok Build and
Grok chat share a row, and Claude Code on the web is the Claude app's box. There is no Linux
column: a Linux run is the box.