Appearance
Versioning and change requests
A model is versioned like code (ADR-0008): immutable revisions, branches, object-level diffs, change requests with automatic checks, approvals, three-way merges and SemVer releases.
Revisions and branches
- A revision is an immutable model document with a content hash, one or two parents, an author and a message. Commits carry the branch head they expect (
expectedHeadRevisionId); if someone else committed first you get409. - Branches are created from a branch head (default
main) or any revision.mainis protected: direct commits are refused unless the model allows them and the caller is an Owner. - Keel's own branches:
keel/proposals-{run}(generation),keel/drift-{id}(rename fixes after drift),keel/metric-{name}-{id}(a metric drafted from the assistant). - Working copies: in the workspace, your edits autosave to a private draft per model, branch and user (versioned, with ETag/If-Match; a stale save is
412). Committing a draft rebases it automatically when the branch moved and the merge is clean, otherwise409 Modeling.WorkingCopyOutdatedlists the conflicting paths.
Diff
Diffs are object by object — entities, dimensions, measures, hierarchies, segments, joins, metrics — with property-level detail (GET …/diff?base=&head=). The diff of identical revisions is empty and swapping base and head swaps added and removed. A rename shows as a removal plus an addition.
Change requests
A change request proposes merging a branch into main (or another branch). The checks run when it opens and on :checks, and are stamped with the heads they ran against:
| Check | Outcome |
|---|---|
| Validation | Errors block |
| Breaking changes vs. the latest release, with consumers (serving query log, last 30 days; exports) | Blocks until acknowledged (:acknowledge) |
| Data quality behind changed metrics | Warning only |
| Governance: changes to certified metrics | Needs an approval from someone who can govern |
Reviews (:review) approve, request changes or comment. A model setting fixes the number of approvals (default 1). Authors can't approve their own request unless they can govern.
Merge
A three-way merge per object: an object changed on one side takes that side; conflicts are listed per object and an explicit resolution wins. A merge after either head moved returns 409 Modeling.ChecksOutdated; of two concurrent merges the loser gets 409 Modeling.BranchMoved. Merge revisions have two parents; history follows first parents.
Known gap
Conflicts in the web workspace are reported (409 with the paths) but there is no side-by-side conflict-resolution UI yet.
Releases
A release tags a main revision with a SemVer version and notes. The suggested bump comes from the diff against the previous release: removed or redefined metrics, dimensions or measures → major; additions → minor; documentation only → patch. A rollback publishes an earlier release's revision as a new release. Serving endpoints pin a release or follow the latest; exports, lineage and the assistant read releases.