Branches & proposals
The ontology schema is versioned — main is read-only, edits go through proposals that are reviewed and either published or archived.
The ontology schema is versioned. There is one canonical published baseline — main — and every edit happens on a proposal branch that gets reviewed before it merges.
Why versioned
The schema is consumed by workflows, agents, the graph view, the analyst, and any custom UI. A schema change that breaks a workflow's expected property type is exactly the kind of change you want to see in review before it ships. Proposals give you that review without slowing down day-to-day work.
main
main is the published baseline. From the workbench:
mainappears in the branch picker as the default.mainis read-only. You can browse, search, traverse — you cannot edit.- Every consumer (workflow tools, graph view, analyst) reads from
mainby default.
Proposals
A proposal is a branch off main with a name like proposal/add-customer-tier or proposal/rename-account-status. Proposals can:
- Add new object types, link types, action types, bindings.
- Modify existing types (change a property type, add a property, change identity rules).
- Remove types (with a migration path).
- Update bindings (re-map columns, switch source tables).
The workbench shows the diff between the proposal and main. A reviewer can see exactly which types changed and how.
The kernel also supports a focused non-branch proposal for one schema resource. It is either an
upsert with a fully validated schema payload or a retract pinned to the exact live assertion it
would close. For an upsert, an omitted or null expectedAssertionId means “create only” and fails
if the resource already exists; a string means “replace exactly this reviewed assertion” and fails
if that assertion is no longer the sole current owner. A retract is likewise never resolved by
name alone. These stale-owner checks run again in the publishing transaction. Approving one of
these proposals publishes an immutable revision atomically; rejecting it records the decision
without changing the published schema.
Proposal reads are clearance-filtered. A proposal cannot be used to lower the classification of a schema change: approval retains the proposal marking, and a retraction also retains the target's marking and provenance.
The kernel SDK exposes client.proposals.list(...) and client.proposals.get(...) for these
clearance-filtered records. Lists support status, schema-kind, cursor, and limit selectors; branch
proposals are deliberately excluded from this generic surface. Their durable association is the
exact branch ID recorded by branch.declare, and they are exposed only through the branch view.
Kernel branch lifecycle
The kernel represents a review branch as a governed object pinned to the published revision that
was current when the branch was created. client.branches exposes the complete lifecycle:
create(...)creates adraftbranch from the current published revision.declare(...)adds validated schema upserts or retractions to that draft. One open proposal may target each schema kind and resource name.submit(...)moves a draft toin_review.publish(...)accepts only anin_reviewbranch whose base is still current, applies its full authorized proposal set atomically, publishes a revision, and closes the branch aspublished.rebase(...)moves a draft's base to the current published revision when its proposals do not intersect published changes. Conflicts are reported instead of resolved implicitly.archive(...)closes any non-archived branch asarchived.
client.branches.list(...), .get(...), and .manifest(...) provide clearance-filtered reads.
The manifest call returns the branch overlay without changing main. Schema-read methods accept a
branch selector instead of revisionId; supplying both is invalid.
Every lifecycle call above is a kernel action: it appends to the assertion ledger and returns a
receipt, while the row list(...), .get(...) and .manifest(...) read is materialised afterwards
by the current-state projector. So create(...) followed immediately by get(...) on the new
extensions.branchId normally answers NOT_FOUND — the branch exists, the projection has not
caught up. Poll the read until it appears, bounded by a deadline you choose, and treat NOT_FOUND
and PROJECTION_LAGGING alike as "ask again" only inside that bounded wait: outside one, NOT_FOUND
also means the caller's clearance does not dominate the row's marking.
Lifecycle
┌─────────┐ propose ┌──────────────┐
│ main │ ─────────────▶│ proposal │
└─────────┘ └──────────────┘
▲ │
│ publish (replaces main) │ review
└─────────────────────────────┘
│
▼ archive (discarded)
[end]What "publish" does
Publishing a proposal:
- Validates the proposal against the current
main— flags conflicts. - Atomically replaces
main's baseline with the proposal's baseline. - Re-issues the version stamp on every binding, action type, and object type.
- Emits a structured event for downstream consumers.
- Records an audit event with the actor, the proposal, and the published changes.
After publish, the proposal branch is closed. Future edits start from the new main.
What "archive" does
Archiving a proposal:
- Marks the proposal as archived in the catalog.
- Removes it from the active branch picker.
- Records an audit event.
Archived proposals are retained for compliance and audit but do not appear in normal browsing. Archive is terminal; continuing the work requires a new branch from the appropriate published revision.
Concurrent edits
Multiple proposals can be in flight at the same time. The publish step does a conflict check — if a second proposal touches a type that a first proposal already published, the second proposal's reviewer sees the conflict and decides how to resolve it.
Authorisation
Publishing or rejecting a proposal requires independent review. The person who authored a proposal cannot decide it, even if that person is a workspace or organisation administrator. An eligible different reviewer may decide it according to the workspace policy. This separation applies to both approval and rejection; automation receives no generic fallback around it.
| Role | Can do |
|---|---|
| Workspace member | Browse main and proposals allowed by policy and clearance |
| Eligible reviewer | Approve or reject another person's proposal |
| Proposal author, including an administrator | Cannot approve or reject their own proposal |
Related
- Concepts → Branches — where branches fit in the five layers.
- Audit logging — every publish and archive is logged.
- Authoring SDK → Ontologies — packs ship on
mainby default; pack updates land via proposals.