Vancetope 0.3.0 is out 🎉

Vancetope 0.3.0 is tagged and pushed — 369 commits since 0.2.0.

0.2.0 consolidated how the agents behave. 0.3.0 grows the surface, in three directions at once, and the thread that connects them is the same one that has run through Vance from the start: everything is a document, and an agent can touch it. A running app is a document. A file someone else owns is a document, mounted. A question in the inbox is a document with a lifecycle.

Apps that are documents

Bistromath is an application runtime where a view is a document ($meta.kind: app-view) and the behaviour lives in main.js, running sandboxed in a null-origin iframe. The program is the centre; data access is a capability underneath, not the other way around. Programs reach the project through vance.rest — the real REST controllers, no second API cut down for the sandbox — plus five libraries (core@1/api@1/db@1/fmt@1/ui@1) and lifecycle hooks in the onApp* namespace.

Apps are built by agents, via the app-builder recipe — and because a guest can’t do authenticated HTTP on its own, governance is enforced entirely in the client. The default is forbidden; an app gets its freedom through an approval request in the inbox, and the proposal is frozen while it waits. A running app can do what the user can do — nothing more, nothing the user didn’t ask for.

Foreign files, read like your own

Jaglan mounts files that live somewhere else under _ext/<mount>/<path> so they’re read with doc_read, embeds, WebDAV and the Cortex like any project document. Two protocols ship: local (a read-only directory on the brain’s host, confined) and ode (a foreign application as the source). The interesting invariant is that the bytes are never copied — a mounted document is a Mongo row without a storageId, and the missing handle is the mark of content that lives elsewhere. A read is a pass-through, every time.

The hard part wasn’t reading. It was listing: a listing is complete, there’s no cursor on the wire, and a cut at 5000 entries per folder prevents a single page from deleting everything behind it. The folder tree loads per level instead of the whole project, and a failed refresh is finally visible instead of silent.

The inbox becomes a thing

Maximegalon is the entity behind the inbox — an Anliegen with at most one decision plus the path to it. Three independent axes (answered/archived at the thread, read at the readable unit) instead of a status enum, because “read but unanswered” would otherwise need a PENDING_READ that nobody wants to maintain. The badge counts only the unread, an answer resolves by being read, a reminder is a contribution instead of a loop. Agents can read the inbox and contribute to a thread; a “Diskussion” tab in Cortex shows the threads to the open document.

An agentic user loop

Trillian runs two sessions: a control session owned by a human, and a user-loop owned by a headless service account. The Nature decides what a wakeup is worth — Nature-A adam is the first persistent Trillian with a journal, reflection, and a worker that pauses on a question instead of ending. Asking gets its own tool and its own engine; the heartbeat adopts loops that fell out of the schedule.

Placement, runs, and the operator’s view

  • Cluster placement is centralized with labels and selectors, a placement round runs on demand instead of on a tick, demand/drain/”waiting for a pod” are visible in the UI, and lifecycleType is an operator concern (/internal, anus, read-only in the UI).
  • Run view at /runs shows the instances of all runtimes — Magrathea runs, plan-shaped think-processes, Compose runs — under one surface, with control and a project picker. Addressing is <source>:<nativeId>; without the prefix, a 32-hex run id and a Mongo id aren’t tellable apart.

Everything else

  • Centauri — Mastodon as the first FREEFORM feed source, its own addon, publishedAt derived from the Snowflake-Id because created_at is not the stream order.
  • Project & user maintenanceproject delete|rename and user delete|rename in anus, via a *DataHandler SPI per entity. Drain first, typed confirmation, handler idempotency, and a drift test plus a runtime sonde.
  • Kitsode as a kit source, credentials in kits, overwriteSecrets, and project:<name> turning a project into a kit source.
  • vance-workflow document kind with a flow renderer and a start button on the document in Cortex; agent_task drives and terminates engines that don’t do it themselves.
  • Selection reference — what a message meant survives the turn, as selectionRef (label + at least one address) persisted per message.
  • Links app (app: links) and inter-links — a link can point at a place in an app (vance:/<folder>/_app.yaml?entry=<handle>), late-bound.
  • Foot remote control per project, a light-LLM REST route, and workers spawned from the web.
  • DocumentsIf-Match on the content PUT (optional, 412 on mismatch) against the silent last-writer-wins.

Worth knowing before you upgrade

0.3.0 is a minor bump below 1.0, so it’s allowed to break. The client stack moved (Spring Boot 4.1.1, langchain4j 1.19, Anthropic 2.57, Milton 4.2), and Cortex/Chat/Inbox/Documents/Landing became one cluster — switching between them no longer reloads the page and keeps the WebSocket. The full list is in the changelog.

Try it

  • Get started — the Docker stack, a couple of commands, a few minutes.
  • Bring your own model — Vancetope ships no model; you connect your own.
  • Something broken? Discussions or an issue. Still early, still rough, still real.

Onward to 0.4. 🚀

🎉 more confetti