Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: Records and manifest

Records and manifest

Stable identity

Jadpo knows a declaration or field by the name it was born with, so a rename never looks like something removed and something added. The identity registry holds one line for each thing that has been renamed since, mapping its name now to its born name, and nothing else: a line for every declaration would grow with every new action. Children follow their parent, so renaming a domain or an entity is one line.

Three things write the registry: jadpo rename, the jadpo domain commands, and promoting a function or type declared in a domain to shared/.

text
// Generated by Jadpo from renames and moves; update it with `jadpo rename`, `jadpo domain` or `jadpo fmt --layout`, never by hand.record identities 1entity Todo -> Taskfield Todo.priority -> importancesubscriber send_reminder -> notify_owner
  • One registry for data and code. Stored rows name code: outbox events, delivery records and schedule state in the system tables refer to events, subscribers and schedules. Renaming a subscriber must not orphan its pending deliveries, any more than renaming a field may lose its column.
  • Physical names never change. The table stays todo and the column priority. Migration snapshots hold the whole schema with physical names, so a rename made by hand shows as a removal and an addition, and jadpo migrate new refuses it, pointing you to jadpo rename (Tooling).
  • Inside a callable, branches and fault sites are numbered afresh in each build. Only declarations and fields need to be recognised across builds.
  • jadpo incident, path keys and the review all compare through this registry, so a rename reads as "renamed", never as "removed and added".

Keys

A key is the kind and the born name, in the registry's own form: action complete_todo, field Todo.title, function rounding.half_even (a library keeps its name in shared/). Names are unique across the project and across kinds (Names are unique), so the domain is a field of the node, not part of the key.

The exception is a function or type declared in a domain, whose name needs to be unique only within its domain. Its key carries the domain, whether it is public or not: type billing.Address, function billing.format_address. Its fields and variants follow it: field billing.Address.street.

Adding public, or a route starting to return the type, never changes a key. Promoting one to shared/ does. So when a type moves to shared/types/, the edits layout.promotion_required asks for add its registry line, type billing.Address -> Address, which jadpo fmt --layout writes. The key stays type billing.Address, and the move reads as a move, not as a removal and an addition. That is why the registry's header names jadpo fmt --layout beside jadpo rename and jadpo domain.

A field's, variant's or rule's line gives only its own new name (field Todo.priority -> importance), read back through its owner's line. Every other line gives the whole name now. The registry is database/identities.jadpo_record. Jadpo reads it once jadpo rename writes it; until then every born name is the name now.

A test's key is the file it sits beside and its sentence, with no path: test create_todo "rejects a blank title". Moving its domain keeps the key. Two tests with one sentence anywhere in the project are semantic.duplicate_declaration.

Changing what a key holds is a new manifest format.

Markdown for agents: /docs/stable-identity.md.Built from Jadpo main at a707efb.