# The manifest

`jadpo check` writes one manifest for your project,
`build/manifest.json`, whether the project has errors or not. It is the
compiler's graph as versioned JSON: every declaration and field with its
stable identity, source file and lines, content digest, `///`
description, calls, reads, writes, events and failures. It also holds the
routes, schedules, subscribers, connections and their hosts, policy
grants, personal fields, thresholds, the control flow that path numbers
are decoded against, and each deployable's build id.

```json
{
  "format": 2,
  "source": { "commit": "8d113e6", "modified": false },
  "compiler": "0.4.0",
  "deployables": { "api": { "target": "wasm", "build": "b_9a1f03c6d2e4" } },
  "nodes": [
    {
      "id": "action complete_todo",
      "kind": "action",
      "domain": "planning",
      "file": "domains/planning/actions/complete_todo.jadpo",
      "lines": [4, 22],
      "digest": "9f2c41d0",
      "calls": ["Todo.get", "Todo.update"],
      "fails": ["TodoNotFound", "TodoMutationConflict"]
    }
  ]
}
```

**Every report is a view of it.** The permissions, personal-data,
network, database and query reports, the catalogues, OpenAPI and the
monitoring rules are all made from the manifest, so they can't disagree
with each other.

**A build id is a digest** of everything that decides a deployable's
behaviour: the source it reaches, the compiler version, the target and
the locked packages. The same build id means the same build. The source
is the deployable's program as it is compiled from what it reaches: its
Rust and its plan, with its name and its stores' migrations. So a change
to what only another deployable reaches, or to a test, leaves its id
alone ([design notes](https://github.com/jadpo-dev/jadpo/blob/main/docs/language/notes/18-records-and-manifest.md), "What a build id
digests"). A project with errors builds nothing, so the manifest gives
its deployables no `build`.

**The format.** The JSON is canonical: sorted, with relative paths and no
timestamps. The `format` number changes only when a field is removed or
changes meaning; additions keep the number. Manifests are never stored,
so no tool ever reads an old format. `jadpo help --json` documents the
schema, with every node and edge kind and whether it is built yet.

**Its size doesn't matter**, because it is never shipped. An agent asks
for one node with `jadpo inspect <name> --json` rather than reading the
whole file.

## What a node holds

The manifest is at `format` 2, with `compiler`, `errors` and `nodes`. A
node has `id`, `kind`, `name`, `file`, `lines` and `digest`. Where they
apply, it also has:

- `domain`, `parent`, `public` and `doc`;
- a type's `base`, `rules` and `failure`;
- a field's `type`;
- a callable's `signature`;
- an action's or fixture's `isolation`, `read_committed` or
  `repeatable_read` ([Isolation levels](all-or-nothing-actions-and-concurrent-changes.md#isolation-levels));
- its edges, as sorted lists by kind: `calls`, `uses`, and `raises` for
  the failures that can leave a callable (the `fails` above).

The build stamp is in `source`, `deployables` and their build ids.

Other parts of the language add their own nodes:

- **Integrations, identity, configuration, jobs and events** add a node
  for each connection, package, resource, operation, capability mapping,
  host and lock line, each kind of caller, sign-in method, way of signing
  in and route the runtime answers itself, each setting, the locale set,
  the rate limits, and each schedule and subscriber. Their edges are
  `emits`, `subscribes`, `runs` and `provides`.
- **[Policy](policy.md)** adds a `grant` node for each list an
  entity's `policy:` writes, and a `field_restriction` for each field's
  own policy (`serverOnly`, or `who`: each effect's list). It adds a
  `tenancy` for each entity that belongs to the tenant, and an
  `action_exception` for each line under root `policy { actions: }`.
  `grants` edges go to what each decides, and `scopes` edges go from each
  tenancy to its entity.
- **[Prompts](prompts-as-files.md)** each add a `prompt` node,
  placed at its `.prompt` file, with its type as its parent and its
  `version`: its name and the first 8 hex characters of a SHA-256 over
  its two files, `answer_question@864ad76b`.

Which parts of the language have nodes so far is in
[What is built](records-and-manifest-built.md).
