Scrydon
Ontology

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:

  • main appears in the branch picker as the default.
  • main is read-only. You can browse, search, traverse — you cannot edit.
  • Every consumer (workflow tools, graph view, analyst) reads from main by 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:

  1. create(...) creates a draft branch from the current published revision.
  2. declare(...) adds validated schema upserts or retractions to that draft. One open proposal may target each schema kind and resource name.
  3. submit(...) moves a draft to in_review.
  4. publish(...) accepts only an in_review branch whose base is still current, applies its full authorized proposal set atomically, publishes a revision, and closes the branch as published.
  5. 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.
  6. archive(...) closes any non-archived branch as archived.

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:

  1. Validates the proposal against the current main — flags conflicts.
  2. Atomically replaces main's baseline with the proposal's baseline.
  3. Re-issues the version stamp on every binding, action type, and object type.
  4. Emits a structured event for downstream consumers.
  5. 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:

  1. Marks the proposal as archived in the catalog.
  2. Removes it from the active branch picker.
  3. 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.

RoleCan do
Workspace memberBrowse main and proposals allowed by policy and clearance
Eligible reviewerApprove or reject another person's proposal
Proposal author, including an administratorCannot approve or reject their own proposal
On this page

On this page