Machine formats and JSON reports
01Every command can answer in JSON for scripts and agents. This page lists the documents, their schemas and the envelope fields that every document carries.
vibe list --json --path hello-vibe
{
"ok": true,
"command": "list",
"project": "<TMP>/work/hello-vibe",
"count": 1,
"packages": [
{
"kind": "flow",
"name": "wal",
"version": "1.0.0",
"bridge": false,
"authors": [
"Oleg Chirukhin"
],
"source_url": "file:///<TMP>/registry/org.vibevm.world/wal/v1.0.0",
"content_hash": "sha256:58eccc204df7e63e78e8d15f9416b6fd528e786b74d9e0e5e2fcb859716ea0d0",
"boot_snippet": null,
"files_written": []
}
]
}
One rule for every format
03Anything a foreign parser reads, a report a script parses, a file another language writes, a manifest a browser fetches, is described by a schema and registered in one inventory. The Rust types and the TypeScript types are generated from the schema, never written by hand, so the two sides cannot drift. An unregistered format is not merely discouraged: it cannot be expressed in the type system that writes it.
04 quote from the specification
16. JTD + codegen for wire contracts
05 spec: The format registry
4.1 The format registry.formats/REGISTRY.tomlinventories every surface a foreign parser reads: id, epoch, schema path, recoverable-or-not, independent-parser count, sunset date, golden-corpus path. From it theFormatIdenum is generated, and all wire I/O goes throughwire::publish(FormatId, …)/wire::load(FormatId, …)— an unregistered format is inexpressible in the type system, not merely discouraged. An unnumbered format is a format that will be broken without anyone noticing.
06The schemas are JSON Typedef documents under schemas/ in the source tree. The registry is formats/REGISTRY.toml. For each format it records the epoch, the schema, whether the format can be rebuilt from other state, and how many parsers read it. It also names a corpus of golden documents that a build compares against.
07 spec: A format's policy is computed, not chosen
A format's policy is computed, not chosen, from
two axes: is it recoverable without a human, and how many independent parsers
exist. Recoverable + one parser → hard gate + silent rebuild (lockfile,
caches). Recoverable + many parsers → epochs, parallel publication, generated
clients, narrow projection (catalog, CLI JSON). Unrecoverable + one parser →
epoch-in-file + codemod (configs). Unrecoverable + many parsers is the worst
quadrant — minimise it, epoch it, migrate it by bot (vibe.toml is the only
resident, and creating a new format in this quadrant requires an explicit
owner decision recorded in the format registry).
The envelope
08A --json document is one JSON object per command, or a stream of objects for commands that report in stages, such as an install. Every object carries ok, the command that produced it, and the report fields the schema names; when the caller identified itself with --invoked-by, the object carries invoked_by, and under --unattended it carries unattended: true.
The documents
| Command | Document | Schema |
|---|---|---|
vibe init --json |
the scaffold report | init_report.jtd.json |
vibe install --json |
the plan, then the report | install_plan.jtd.json, install_report.jtd.json |
vibe update --json |
the update report | update_report.jtd.json |
vibe uninstall --json |
the removal report | uninstall_report.jtd.json |
vibe reinstall --json |
the regeneration report | reinstall_report.jtd.json |
vibe list --json |
the installed packages | list_report.jtd.json |
vibe registry publish --json, vibe registry sync --json |
the publish and sync reports | registry_publish_report.jtd.json, registry_sync_report.jtd.json |
vibe extensions --json, vibe extensions analyze --json |
the extension registry and the lane analysis | extensions_report.jtd.json, extensions_analyze.jtd.json |
the lifecycle verbs with --json |
the plan, the report, the state and the parked tasks | lifecycle_plan.jtd.json, lifecycle_report.jtd.json, lifecycle_state.jtd.json, lifecycle_tasks.jtd.json |
vibe deploy, vibe deployments --json |
the deploy intent, the receipts, the inverse plan and the checkpoints | deploy_intent.jtd.json, deploy_receipt.jtd.json |
vibe requirements --json |
the requirements report | requirements_report.jtd.json |
vibe tree --json |
the package tree | a JSON Schema document, package-tree.schema.v1.json |
vibe doc manifest --json, vibe doc todo --format json, vibe doc surface --record |
the page manifest of a documentation package, the maintenance queue, the surface snapshot of a version and the diff of two | doc_manifest.jtd.json, doc_todo.jtd.json, doc_surface.jtd.json, doc_surface_diff.jtd.json |
10The fields of every schema in the table, generated from the schema files in the order above:
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32The documents of the index server, the scrape contract and plan, the compiler trace and the native ABI have schemas of their own in the same folder; the registry lists all of them.
Edge cases and rules
33A document that no schema describes is a defect, not a feature; the campaign that wrote this manual filed the ones it found in the product's backlog, and the examples on these pages mark such documents as unchecked rather than passed.
34Formats carry an epoch; while the product is not yet public, an incompatible change of a format is free and unmigrated, and the registry says so. A published format changes only with a break note and, where needed, a migration.
35 spec: vibe.toml is the most expensive format…
6.2 vibe.toml is the most expensive format in the
system — authored, unrecoverable, resident in foreign repositories, and an
external surface de facto because agents read files, not APIs. It is the one
place we honestly pay the stability tax: an epoch marker in the file,
introduced before first publication (absence ≠ "assume 1"; absence is the
distinct pre-epoch state, interpreted by a heuristic exactly once in history);
strictness with did-you-mean hints in our namespace (in a hand-written file an
unknown key is a typo and the author is present — the asymmetry with the
machine-written catalog is principled, not inconsistent); a named reserve
section we never touch; a generated projection as the published copy, so
foreign tools read a recoverable artifact while the hand-written original
remains our internal concern; migration by codemod + bot PR; and a minimal
surface — every new manifest key is a years-long obligation and requires a
break note, a codemod, and generated documentation.
36Raw parsing with shell tools counts as a parser: the registry assumes someone pipes a report into a JSON tool, and treats the format accordingly.
37 spec: Foreign curl | jq will happen…
Foreign curl | jq will happen regardless of
generated clients, and there will never be a signal of it (raw files in git
give no telemetry, by design). The honest posture: assume raw parsing exists,
keep the narrow gate genuinely boring, and treat any change to it at the
highest severity class.