The project manifest

The project manifest, a write-once file of defaults the editors read on load.

project.json sits at the root of every project. It records the project's name and description and names the workflow and world the Workflow Editor should preselect.

The important thing to understand about this file: it is written once and then only read. The scaffold that creates your project writes it, and nothing writes it again. The platform reads it for defaults and never updates it. The gateway's manifest reader is explicitly read-only.

That has a consequence worth internalizing before you go looking for a bug: the authoritative record of your project's name, description, and archived state lives in the cloud database, not in this file. Renaming or archiving a project updates that record and leaves project.json untouched.

Example

{
  "name": "plate-prep",
  "description": "Plate preparation runs.",
  "created_at": "2026-05-16T02:52:57.244Z",
  "updated_at": "2026-05-16T02:52:57.244Z",
  "archived": false,
  "active_workflow": "plate_prep_v2",
  "active_world": "bench_layout"
}

Note that created_at and updated_at are identical. They will stay identical for the life of the project, because nothing rewrites the file.

Fields

The scaffold writes exactly these seven keys.

FieldTypeDescription
namestringThe project's display name. 1–128 characters; must be unique among your projects.
descriptionstringFree-text description. May be empty.
created_atstring (RFC 3339 with milliseconds)When the scaffold ran.
updated_atstring (RFC 3339 with milliseconds)Set to the same value as created_at and never changed.
archivedbooleanWritten as false and never flipped. Archive state is tracked in the cloud record, not here.
active_workflowstring | nullThe workflow_id (filename without .json) the Workflow Editor preselects. null if none.
active_worldstring | nullThe world id (folder name under worlds/) the Workflow Editor preselects. null if none.

name carries no character-set restriction, only a 1–128 character length bound. Hyphens are fine. This is a looser rule than the one for skills, workflows, worlds, and objects, whose names must match ^[a-z_][a-z0-9_-]{0,63}$.

How active_workflow and active_world resolve

Both are validated when read, not when written. The gateway checks that workflows/<active_workflow>.json is a file and that worlds/<active_world>/ is a directory. If either is missing, it returns no default and the editor falls back to the first item in the list.

It does not repair the file. A stale active_workflow naming a workflow you deleted stays in project.json indefinitely and is ignored on every read. Nothing breaks, and nothing cleans it up.

The Workflow Editor treats these as the middle tier of a three-step preference: an explicit choice you navigated with wins, then the project.json default, then the first workflow in the list.

📝

Opening a different workflow or world does not rewrite active_workflow or active_world. There is no write path for these fields anywhere in the app, the IDE, or the CLI. If you want to change the preselected default, edit this file by hand and commit it.

What updates the cloud record instead

These commands change the project record in the cloud. None of them touch project.json.

ActionWhat it changes
zeon project rename <project> <new-name>The cloud record's name. <project> is the project id or its current name.
zeon project archive <project>Sets archived_at on the cloud record, which hides the project from the default list.

The cloud record also holds a project_id, the project's real identity. The name in this file is a display label; the id is what the sync service actually keys on.

Because the record and the file are separate, they can disagree. After zeon project rename, the cloud knows the new name and project.json still has the old one. That is expected, and nothing reconciles them.

Editing it by hand

This is the normal way to change any of these values, and it is safe. Treat it as an ordinary JSON edit: change the file, then commit and push it like any other file.

The common edits are repointing active_workflow or active_world, or setting them to null for a clean slate. Those two keys are the only ones the platform reads back from this file for an ordinary project.

Changing name or description here has no visible effect; nothing reads them. Use zeon project rename <project> <new-name> to change the name you actually see.

When the file is wrong

If project.json is missing or contains malformed JSON, the gateway treats it as an empty manifest: no configured defaults, and the editors fall back to first-in-list. It fails quietly rather than blocking you from opening the project.

See also


Did this page help you?