Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
f75950f
WIP: add OntologyApprovalRule schema for release review rules
harshach Oct 22, 2026
a5dd249
WIP: record that ontology definition status is derived from releases
harshach Oct 22, 2026
f124425
WIP: add abstract, source, and deprecation fields to native classes
harshach Oct 22, 2026
c7a302e
Update generated TypeScript types and dereferenced schemas
github-actions[bot] Oct 22, 2026
c3357ef
Validate, project, and diff the class model fields
harshach Oct 22, 2026
df641ec
Cover the class model fields in integration tests and record the deci…
harshach Oct 22, 2026
f86721c
WIP: add abstract, source, and deprecation fields to native classes
harshach Oct 22, 2026
6b5163b
Validate, project, and diff the class model fields
harshach Oct 22, 2026
8a960a1
Cover the class model fields in integration tests and record the deci…
harshach Oct 22, 2026
e57ed09
Fix class model integration test assertions for wrapped SDK errors an…
harshach Oct 22, 2026
cbaaf62
Fixes #35981: Derive concept lifecycle status, ontology publication s…
harshach Oct 22, 2026
6132610
WIP: record that ontology definition status is derived from releases
harshach Oct 22, 2026
d21e133
Fixes #35981: Derive concept lifecycle status, ontology publication s…
harshach Oct 22, 2026
a9c9551
WIP: add approvalRule, reviewVotes and the release review read schemas
harshach Oct 23, 2026
63023bb
Decide ontology release reviews by the ontology's approval rule
harshach Oct 23, 2026
dde0008
Record votes only for ontology reviews and test the review read model
harshach Oct 23, 2026
2cb520f
Skip the reference delete for a definition that does not exist yet
harshach Oct 23, 2026
460408c
Keep the review task's own reviewers and declare approvalRule in the …
harshach Oct 23, 2026
57d6d4e
Fixes #35981: Cover property and ontology edits in the unpublished-ch…
harshach Oct 23, 2026
0e56fff
Fix review vote durability and authorized pagination
harshach Oct 23, 2026
4df6f6c
fix: persist workflow votes with terminal task decisions
harshach Oct 23, 2026
1dbf803
Fixes #35981: Clarify the derived publication status contract
harshach Oct 23, 2026
a49d4a7
test: assert ontology review approval rule round trips
harshach Oct 23, 2026
55c0778
test(ontology): cover property validation and grouped diff cursors
harshach Oct 23, 2026
f299086
test(ontology): reject release headers as captured definitions
harshach Oct 23, 2026
a6013a8
Merge main into ontology review rule branch for stacked integration
harshach Oct 25, 2026
358847e
Reconcile published ontology status history with verified local fixes
harshach Oct 25, 2026
50f6f0c
Reconcile published ontology class history with verified local fixes
harshach Oct 25, 2026
a823058
Merge review rules into ontology definition status stack
harshach Oct 25, 2026
3360180
Merge definition status and complete deprecated release summaries
harshach Oct 25, 2026
332a46c
Recheck review setup under the lock, list reviews by caller, vote per…
harshach Oct 26, 2026
ab51b62
Test ontology review votes through TaskWorkflowHandler.resolveTask
harshach Oct 26, 2026
5656111
Merge review rule fixes into ontology definition status
harshach Oct 26, 2026
ff88aa3
Merge ontology definition status into ontology class model
harshach Oct 26, 2026
57e3bc1
Merge review rule fixes into ontology definition status
harshach Oct 26, 2026
7e7f82a
Merge ontology definition status into ontology class model
harshach Oct 26, 2026
eaf8716
Merge main into ontology review rule
harshach Oct 27, 2026
f35e627
Merge review rule with main into ontology definition status
harshach Oct 27, 2026
f3e05a8
Merge definition status with main into ontology class model
harshach Oct 27, 2026
20e50e5
Keep release and member ID binds within one parameter budget in defin…
harshach Oct 27, 2026
eb95757
Merge definition status into class model
harshach Oct 27, 2026
00e5bb5
Test each ontology review view over stored tasks
harshach Oct 29, 2026
1690f63
List ontology reviews with the release each task is about
harshach Oct 29, 2026
e4cbfe2
Test that the review list never reads the caller's glossary approvals
harshach Oct 29, 2026
5b94592
List only the approval tasks that are about an ontology release
harshach Oct 29, 2026
422e9fa
Name the tasks in the glossary approval list test
harshach Oct 29, 2026
596f70e
Keep the review list test from registering a glossary repository
harshach Oct 29, 2026
97b1ead
Test that the review list drops a superseded review task
harshach Oct 29, 2026
64f21cc
Test that the review list reads its releases in one statement
harshach Oct 29, 2026
9a3059e
Merge review rule fixes into ontology definition status
harshach Oct 29, 2026
a91f9cb
Merge definition status fixes into class model
harshach Oct 29, 2026
964b3b7
Merge main into ontology review rule
harshach Oct 29, 2026
d63d512
Merge ontology review rule into ontology definition status
harshach Oct 29, 2026
fca4419
Merge main into ontology class model
harshach Oct 29, 2026
7d6de20
Merge main into definition status
harshach Oct 29, 2026
ae01b93
Record PR1's squash merge in definition status
harshach Oct 29, 2026
e112661
Merge definition status with main into class model
harshach Oct 29, 2026
9021493
Record the definition status squash merge in class model
harshach Oct 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Ontology definition status is derived from releases

- **Status:** Accepted
- **Revisions:** v1 2026-10-21 (initial); v2 2026-10-23 (clarify publication response and working-change counts)
- **Revisions:** v1 2026-10-21 (initial); v2 2026-10-23 (clarify publication response and working-change counts); v3 2026-10-25 (separate deprecation counts at stack integration)
- **Deciders:** Harsha
- **Guard:** `OntologyDefinitionStatusResolverTest`, `OntologyDerivedStatusStorageTest`, `IndependentOntologyStatusIT`
- **Related:** ADR:2026-10-14-ontology-reviews-bind-workflow-tasks-to-revisions, ADR:2026-10-14-ontology-releases-seal-canonical-sql-members, #35981
Expand Down Expand Up @@ -59,3 +59,18 @@ reads for the governed-content comparison.

Clarify the existing response names and stage vocabulary, the complete working-change count, and the
writes that affect derived status. This amendment changes no API or stored data.

## Amendment v3, 2026-10-25

Release change summaries partition the default-base diff rows into added, changed, removed and
deprecated counts. Newly deprecating an existing concept or property counts only as deprecated,
even when its other governed fields also change. Adding an already deprecated definition counts
as added. Editing a definition that was already deprecated, or clearing its flag, counts as
changed. Removing a deprecated definition counts as removed.

New captures always store all four counts, including zero. The schema leaves `deprecated` optional
with no default. A historical summary without this bucket has an unavailable total; readers must
not infer zero. Existing captures are immutable and receive no backfill.

`OntologyReleaseComparisonTest.summaryPartitionsDeprecationsAndOtherChangesWithoutDoubleCounting`
and `unchangedAndNewClosuresHaveAnExplicitZeroDeprecationCount` guard the partition and explicit zero.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Native classes record abstraction, source, and deprecation as standard RDF annotations

- **Status:** Accepted
- **Revisions:** v1 2026-10-22 (initial)
- **Deciders:** Harsha
- **Guard:** `OntologyReleaseProjectionTest`, `NativeOntologyRdfImporterTest`, `OntologyStructureValidatorTest`, `OntologyReleaseComparisonTest`, `IndependentOntologyClassModelIT`, `NativeOntologyMemoryIT`
- **Related:** #35988, ADR:2026-10-14-ontology-definitions-have-independent-entity-storage

## Context

Ontology Studio authors classes that have no direct instances, cite the standard their definition
comes from, and retire in favor of a successor. Native concepts and properties had no fields for
these facts, so a release export could not state them, and a release diff showed a retirement as
an ordinary change. The Studio also lists a new class as one change row with its parents and
property count, which the flat working diff cannot supply.

## Decision

- Concepts carry `abstract`, `definitionSource`, `deprecated`, and `replacedBy`. Properties carry
`deprecated` and `replacedBy`. `abstract` and `deprecated` default to false. The class layer stays
on the ontology.
- `replacedBy` names another definition of the same kind in the same ontology, never the definition
itself. The reference index records it with the role `REPLACED_BY`, so deleting the replacement is
refused like any other dangling reference.
- Releases project the fields as `om:abstract true`, `dct:source <iri>`, `owl:deprecated true`, and
`dct:isReplacedBy <iri>`, where `om:` is `https://open-metadata.org/ontology/`. OWL has no
abstract-class construct, so `om:abstract` is an annotation property. False and absent values
project nothing. Native import reads the same four predicates and requires `xsd:boolean` values
and IRIs.
- A data enumeration needs at least two allowed values. An empty list means no enumeration. The
schema states this as `not: {minItems: 1, maxItems: 1}`, because `minItems: 2` would reject the
empty default. `OntologyPropertyRepository` enforces it on every write, with the message
`An enumeration needs at least two allowed values`. A one-value enumeration stored before this
rule stays editable until its values change.
- A member whose `deprecated` turned true diffs as `DEPRECATED` in release and working diffs.
Clearing the flag, or editing a deprecated member, is `CHANGED`.
- `GET /ontologies/{id}/working/diff?groupBy=concept` returns `groups` and an empty `data`. A group
names a concept, its own change type or `CHANGED` when only its axioms or properties changed, the
labels of its named `SUBCLASS_OF` parents, the count of properties whose domain includes it, and
its member changes. An axiom joins its subject. A property joins the first concept in its domain
that this ontology declares. A change that belongs to no concept, such as the ontology root or an
axiom about an external subject, forms a group without a concept, so the groups cover every
working change. Groups sort by label and then IRI, and concept-less groups come last. Paging
counts groups. The cursor is bound to the working and activation revisions like the plain cursor,
and uses its own prefix, so neither cursor is accepted by the other view.

## Consequences

Other OWL tools can read the exported deprecation and source. Releases captured before this change
compare unchanged, because both sides of a comparison read the new fields with their defaults.
Clients that read grouped changes must handle a group without a concept. Grouping reads the same
working content and active release as the plain diff and adds no queries.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.openmetadata.it.bootstrap.SharedEntities;
import org.openmetadata.it.util.SdkClients;
import org.openmetadata.it.util.TestNamespace;
import org.openmetadata.schema.api.data.ActivateOntologyRelease;
import org.openmetadata.schema.api.data.CaptureOntologyRelease;
import org.openmetadata.schema.api.data.CreateOntology;
import org.openmetadata.schema.api.data.CreateOntologyConcept;
Expand All @@ -24,6 +25,7 @@
import org.openmetadata.schema.type.TaskCategory;
import org.openmetadata.schema.type.TaskEntityType;
import org.openmetadata.schema.type.TaskResolutionType;
import org.openmetadata.service.Entity;

abstract class BaseOntologyApprovalIT {
@AfterEach
Expand Down Expand Up @@ -54,6 +56,22 @@ protected static OntologyRelease capture(Ontology ontology) {
.withExpectedWorkingRevision(service.state(ontology.getId()).getWorkingRevision()));
}

protected static OntologyRelease activate(TestNamespace ns, Ontology ontology) {
final OntologyRelease release = capture(ontology);
final var task = submit(ns, Entity.ONTOLOGY_RELEASE, release.getFullyQualifiedName());
SdkClients.user1Client()
.tasks()
.resolve(task.getId().toString(), decision(TaskResolutionType.Approved));
SdkClients.adminClient()
.ontologies()
.activate(
ontology.getId(),
new ActivateOntologyRelease()
.withReleaseId(release.getId())
.withExpectedActivationRevision(0L));
return release;
}

protected static Ontology createOntology(TestNamespace ns, String name) {
Ontology ontology =
SdkClients.adminClient().ontologies().create(request(ns).withName(ns.prefix(name)));
Expand Down
Loading
Loading