From a70e4e2c44d142cf9c7905ac6284523a9d430433 Mon Sep 17 00:00:00 2001 From: Dan Wolfson Date: Mon, 12 Oct 2026 21:51:52 -0500 Subject: [PATCH 1/2] docs(issues): log ISSUE-143 (PersonRoleAppointment relationship filter returns nothing) Signed-off-by: Dan Wolfson --- PYEGERIA_ISSUES.md | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/PYEGERIA_ISSUES.md b/PYEGERIA_ISSUES.md index ecd1cb46..73879d70 100644 --- a/PYEGERIA_ISSUES.md +++ b/PYEGERIA_ISSUES.md @@ -148,7 +148,7 @@ content was changed. The numbered section list above describes the # Open Issues -**At a glance** — 5 open pyegeria items, 7 awaiting re-test, 6 open Egeria Server issues. +**At a glance** — 5 open pyegeria items, 7 awaiting re-test, 7 open Egeria Server issues. **Open pyegeria items** - ISSUE-140: The executor charts any dict with two or more top-level numbers, regardless of the result's state @@ -167,6 +167,7 @@ content was changed. The numbered section list above describes the - ISSUE-38 (PY-18): `count_relationships_between_elements("Exception")` (276) disagrees with `ClassificationExplorer.get_relationships("Exception")` (55) **Open Egeria Server issues** +- ISSUE-143: `includeOnlyRelationships: ["PersonRoleAppointment"]` returns no relationships for a Person, although the unfiltered read has its role appointments - ISSUE-130: The YAML secrets store's user directory caches a user forever, so editing an existing user needs a platform restart - ISSUE-128: Retention cannot be set on Egeria 6.2: the server registers the Jackson subtype as `RetentionProperties.class` (typo), and pyegeria only allows `RetentionClassificationProperties` - ISSUE-108: newly created relationships stay invisible to related-element queries for up to ~20 minutes after creation @@ -1081,6 +1082,43 @@ enough to track there too). --- +### ISSUE-143: `includeOnlyRelationships: ["PersonRoleAppointment"]` returns no relationships for a Person, although the unfiltered read has its role appointments + +**Layer:** Egeria Server (not pyegeria) · **Status:** open, not yet reported to the Egeria team · **Found:** 2026-10-13, reported by the egeria-workspaces-fs Resource Browser session; reproduced read-only the same day. + +**What:** reading a Person with a `GetRequestBody` whose +`includeOnlyRelationships` is `["PersonRoleAppointment"]` returns the element +with no relationships at all. The same read with no filter returns 8 +`performsRoles` entries, each with relationship type `PersonRoleAppointment`. +Other filters on the same Person work. + +**Reproduction** (Person `10dc7da9-e9e1-471f-9afd-46a7ff414cb7`, Erin Overview, +as erinoverview on qs-view-server; +`ClassificationExplorer.get_element_by_guid(guid, graph_query_depth=1, +output_format="JSON", body={"class": "GetRequestBody", "graphQueryDepth": 1, +"includeOnlyRelationships": [...]})`): + +| Filter | Relationship keys returned | +|---|---| +| none | performsRoles 8, assignmentScope 15, requestedActions 11, contactDetails 1, userIdentities 1, contributionRecord 1 | +| `["ContactThrough"]` | contactDetails 1 | +| `["AssignmentScope"]` | assignmentScope 15 | +| `["PersonRoleAppointment"]` | none | + +A spy on the request confirmed pyegeria sends the body exactly as given, so +the filtering happens in Egeria. + +**Likely cause (not confirmed):** Egeria's relationship filter +(`OpenMetadataHandlerBase`, around line 478) keeps a relationship when +`propertyHelper.isTypeOf(rel, name)`, which should match. But `performsRoles` is +filled in a separate step (`OpenMetadataHandlerBase`, around line 1282), so the +role appointments may be dropped or never fetched once a filter is set. + +**Workaround:** read the Person without `includeOnlyRelationships` and take +`performsRoles` from the result. The Resource Browser already does this. + +--- + ### ISSUE-130: The YAML secrets store's user directory caches a user forever, so editing an existing user needs a platform restart **Layer:** Egeria server (`YAMLSecretsStoreConnector`) · **Status:** open, reported to the Egeria lead · **Found:** 2026-10-09, while adding Resource Explorer's own account (`resourceexplorernpa`). From c803954c2fb53058b76777f5abe4a3b9042db715 Mon Sep 17 00:00:00 2001 From: Dan Wolfson Date: Mon, 12 Oct 2026 21:59:17 -0500 Subject: [PATCH 2/2] docs: rewrite the reference data / valid metadata guide for the new Dr.Egeria families Replaces the August findings notes, which recommended plain ValidValueDefinitions (invisible to the Reference Data view's default finds), said valid metadata setup creates no element, and listed methods as missing that now exist. Adds the Dr.Egeria Reference Data and Valid Metadata commands, multi-value input, and behaviour verified live on 2026-10-13. Signed-off-by: Dan Wolfson --- docs/README.md | 2 +- ...ence-data-and-valid-metadata-mechanisms.md | 439 ++++++++++++------ 2 files changed, 286 insertions(+), 155 deletions(-) diff --git a/docs/README.md b/docs/README.md index 34b57147..cf9c3386 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,7 +14,7 @@ contributors who need more depth than the top-level `README.md`/`CLAUDE.md`/ | `my_profile_app_manual.md` | The My Profile App user manual — configuration, starting the app, change user, every screen and key, comments, feedback, return codes, known limitations, running the tests. | | `My-Egeria-Doc.md` | My Profile App reference guide — source layout, mixin structure, routing tables, Egeria calls and report specs per flow, flow and sequence diagrams. | | `output-formats-and-report-specs.md` | How `generate_output()`/report specs work: `FormatSet`/`Format`/`Column`/`ActionParameter` models, analytic functions, chart output formats. | -| `reference-data-and-valid-metadata-mechanisms.md` | Reference data (`ReferenceDataManager`) vs. valid metadata values — what each mechanism is for and when to use which. | +| `reference-data-and-valid-metadata-mechanisms.md` | Reference data (business value lists) vs. valid metadata values (allowed values of Egeria's own properties): the types, pyegeria methods, Dr.Egeria Reference Data and Valid Metadata families, and live-verified behaviour. | | `parameter_cleanup_plan.md` | Working notes from an in-progress parameter-naming/consistency audit across OMVS clients. | | `user_programming.md` | Notes on programmatic (non-CLI) use of pyegeria. | diff --git a/docs/reference-data-and-valid-metadata-mechanisms.md b/docs/reference-data-and-valid-metadata-mechanisms.md index 54ab2696..ab2605e1 100644 --- a/docs/reference-data-and-valid-metadata-mechanisms.md +++ b/docs/reference-data-and-valid-metadata-mechanisms.md @@ -1,165 +1,296 @@ -# Reference Data vs. Valid Metadata — the 3 "Create Valid Value" flavors, and Consistent/Specification Property mechanisms - -**Status: findings notes, written 2026-08-14 while designing Resource -Explorer's "measure definitions" (externalizing what data/interpretation -answers a Question, grounded in real standards like OpenSSF Scorecard) — -see `packages/resource-explorer/docs/survey-question-context-plan.md` in -the Trellis checkout for the consuming use case. Written here because the -findings are about pyegeria/Egeria itself, not Resource Explorer.** - -There are two *different* mechanisms in pyegeria that both create -"valid value"-shaped things, backed by two different Egeria OMVSes -(`reference-data` vs. `valid-metadata`), plus two more specific -relationship-style operations that are easy to conflate with the missing -`SpecificationPropertyAssignment`/`ReferenceValueAssignment` gap noted in -the Trellis doc above. Documented here so the distinction doesn't get lost -before the pending pyegeria work (adding a `ValidValuesAssignment` / -`ReferenceValueAssignment` method, fixing `link_valid_value_definition()`) -gets picked up. - -## The 3 flavors of "Create Valid Value" - -### 1. `ReferenceDataManager.create_valid_value_definition(body)` - -Creates a **first-class, standalone `ValidValueDefinition` entity** — -real domain reference data (e.g. country codes, our own repo-maintenance- -activity tiers). It has its own GUID, can be searched, can have -relationships (`ValidValueMember`, `ExternalReferenceLink`, etc.), and is -what https://egeria-project.org/types/5/0545-Reference-Data/ documents as -`ValidValueDefinition`/`ReferenceDataSet`/`ReferenceDataValue`. +# Reference Data and Valid Metadata + +Egeria has two separate mechanisms for "allowed values". They are served by +different view services, wrapped by different pyegeria clients, and authored +by different Dr.Egeria families. Both store their values as subtypes of +`ValidValueDefinition`, which is why the generic phrase "valid values" causes +confusion. This guide uses two specific terms: + +| | **Reference data** | **Valid metadata values** | +|---|---|---| +| What it governs | Your business value lists: order statuses, country codes, contact types | The allowed values of Egeria's own properties, e.g. `fileType`, `deployedImplementationType`, `projectHealth` on `Project` | +| Egeria view service | Reference Data (`/api/open-metadata/reference-data`) | Valid Metadata (`/api/open-metadata/valid-metadata`) | +| pyegeria client | `ReferenceDataManager` (`pyegeria/omvs/reference_data.py`) | `ValidMetadataManager` (`pyegeria/omvs/valid_metadata.py`) | +| Dr.Egeria family | Reference Data | Valid Metadata | +| Stored as | `ReferenceDataSet` and `ReferenceDataValue` elements | `ValidMetadataValue` elements, built by the server | +| How a value is identified | Its own qualified name and GUID | The property name, plus optional type name and map name | +| How values are grouped | `ReferenceDataSet` → `ValidValueMember` → `ReferenceDataValue` | Implicitly, per (property, type) | + +Use **reference data** when the value is a business-meaningful thing that +should be catalogued, cited, linked and organised into sets. Use **valid +metadata values** when you are constraining what an open metadata property +may hold. Dr.Egeria validates its own "Valid Value"-style attributes against +this registry, so a new valid metadata value is accepted by Dr.Egeria +straight away. + +Behaviour described as "verified" below was checked against a live +qs-view-server on 2026-10-13. + +--- + +## Reference data + +### Types + +All of these are in Egeria's model 0545: + +- `ValidValueDefinition` — the base type. Properties: `preferredValue`, + `dataType`, `usage`, `scope`, `namespacePath`, `isCaseSensitive`, `ordinal`, + plus `contentStatus` from `AuthoredReferenceable`. +- `ReferenceDataValue` — a single business value. Subtype of + `ValidValueDefinition`. +- `ReferenceDataSet` — a named list of values. Subtype of `ReferenceDataValue`. +- `ValidMetadataValue` and `SpecificationPropertyValue` are the other + `ValidValueDefinition` subtypes. They belong to the Valid Metadata side. + +`ValidValueSet` is a 5.x name. It is not a 6.x type. + +Relationships, with the properties each carries: + +| Relationship | Ends | Properties | +|---|---|---| +| `ValidValueMember` | set (end 1) → member (end 2) | `isDefaultValue`, `ordinal` | +| `ValidValuesAssignment` | element → set | `strictRequirement` | +| `ReferenceValueAssignment` | element → value | `attributeName`, `confidence`, `steward`, `stewardTypeName`, `stewardPropertyName`, `notes` | +| `ValidValueAssociation` | value ↔ value | `associationName`, `associationType`, `additionalProperties` | +| `ConsistentValidValues` | value ↔ value | none | +| `ValidValuesMapping` | value ↔ value | `associationDescription`, `confidence`, `steward*`, `notes` | +| `ValidValuesImplementation` | value → implementing element | `symbolicName`, `implementationValue`, `additionalValues` | + +### Create sets and values as the subtypes, not plain definitions + +Pass `ReferenceDataSetProperties` or `ReferenceDataValueProperties` as the +properties class. `create_valid_value_definition` creates exactly that subtype +(verified). + +**Do not create plain `ValidValueDefinition`s for business data.** The +Reference Data view service builds its handler with a default type of +`ReferenceDataValue` (Egeria `ReferenceDataInstance.java:65-69`). So +`find_valid_value_definitions` and `get_valid_value_definitions_by_name` +without `metadata_element_type` do not return plain `ValidValueDefinition` +elements (verified). If you must read them, pass +`metadata_element_type="ValidValueDefinition"`. Note that this also sweeps in +every `ValidMetadataValue` on the server, which is several hundred. + +Egeria's own Coco Pharmaceuticals content follows this shape. For example, +`ReferenceDataSet::ContactType` has 8 `ReferenceDataValue` members, each linked +with `isDefaultValue` and `ordinal`. ```python -body = { - "class": "NewElementRequestBody", - "isOwnAnchor": True, - "properties": { - "class": "ValidValueDefinitionProperties", - "qualifiedName": "...", "displayName": "...", "description": "...", - "namespacePath": "...", "usage": "...", "dataType": "...", - "scope": "...", "preferredValue": "...", "isCaseSensitive": False, - }, -} -guid = client.create_valid_value_definition(body) +from pyegeria import EgeriaTech + +client = EgeriaTech("qs-view-server", "https://localhost:9443", "erinoverview", "secret") +client.create_egeria_bearer_token("erinoverview", "secret") + +set_guid = client.create_valid_value_definition({ + "class": "NewElementRequestBody", "isOwnAnchor": True, + "properties": {"class": "ReferenceDataSetProperties", + "qualifiedName": "ReferenceDataSet::OrderStatus", "displayName": "Order Status", + "contentStatus": "DRAFT"}}) +value_guid = client.create_valid_value_definition({ + "class": "NewElementRequestBody", "isOwnAnchor": True, + "properties": {"class": "ReferenceDataValueProperties", + "qualifiedName": "ReferenceDataSet::OrderStatus::PENDING", "displayName": "Pending", + "preferredValue": "PENDING"}}) +client.link_valid_value_definition(set_guid, value_guid, { # ValidValueMember + "class": "NewRelationshipRequestBody", + "properties": {"class": "ValidValueMemberProperties", "isDefaultValue": True, "ordinal": 1}}) ``` -This is the one to use when the valid value is a real, business-meaningful -piece of domain reference data that should itself be catalogable, citable -(via `ExternalReferenceLink`), and organizable into sets. - -### 2. `ReferenceDataManager.create_valid_value_definition_from_template(body)` - -Same entity type as #1, but instantiated from an existing -`ValidValueDefinition` used as a template (`TemplateRequestBody` — template -GUID + property overrides). Not otherwise different in kind from #1; just -a different creation path when a similar value already exists to clone -from. - -### 3. `ValidMetadataManager.setup_valid_metadata_value(property_name, type_name, body)` - -**A completely different mechanism** — this does *not* create a -standalone entity at all. It registers what values are **valid for a -specific open-metadata TYPE's PROPERTY**, i.e. it's Egeria's own type- -system extensibility feature (this is what backs `TechnologyType`, a -`ValidMetadataValue` specialization for `deployedImplementationType` -values). Keyed by `(property_name, type_name)`, stored as metadata *about -the property itself*, not as a separately GUID-addressable thing you'd -link other elements to. Sibling methods: `setup_valid_metadata_map_name` / -`setup_valid_metadata_map_value` for map-shaped properties (name→value -pairs), `clear_valid_metadata_value` / `clear_valid_metadata_map_name` / -`clear_valid_metadata_map_value` to remove, `validate_metadata_value` / -`validate_metadata_map_name` / `validate_metadata_map_value` to check -whether a value is currently valid, `get_valid_metadata_value(s)` / -`get_valid_metadata_map_name` / `get_valid_metadata_map_value` to read. +### Behaviour worth knowing -```python -body = { - "displayName": "", "description": "", "preferredValue": "", - "dataType": "", "isCaseSensitive": False, "isDeprecated": False, - "additionalProperties": {"colour": "purple"}, -} -client.setup_valid_metadata_value(property_name="deployedImplementationType", - type_name="SoftwareServer", body=body) +- **Re-linking is an upsert.** Linking the same set and member again updates + the existing `ValidValueMember` (e.g. a new `ordinal`) rather than adding a + second one (verified). Re-running a script or document is safe. +- **Listing a set's members:** the Reference Data service has no "members" + call. Use + `get_related_metadata_elements(set_guid, "ValidValueMember", {"class": "ResultsRequestBody"}, starting_at_end=1)`. + Each item's `element` is the member, and `relationshipProperties.propertiesAsStrings` + holds `isDefaultValue` and `ordinal`. +- **Updates:** `update_valid_value_definition` with `"mergeUpdate": True` + changes only the properties you send (verified). +- **Deletes:** `delete_valid_value_definition` by GUID. Cascade does not reach + the server today (ISSUE-132), so delete members you no longer need + explicitly. +- **The sync wrapper name:** `link_valid_value_definition` / + `detach_valid_value_definition` are the sync wrappers for the member link + (`_async_link_valid_value_member`). + +### pyegeria methods (`ReferenceDataManager`) + +| Operation | Method | +|---|---| +| Create, from template, update, delete | `create_valid_value_definition`, `create_valid_value_definition_from_template`, `update_valid_value_definition`, `delete_valid_value_definition` | +| Find, by name, by GUID | `find_valid_value_definitions`, `get_valid_value_definitions_by_name`, `get_valid_value_definition_by_guid` | +| Member | `link_valid_value_definition` / `detach_valid_value_definition` | +| Assign a set to an element | `link_valid_values_assignment` / `detach_valid_values_assignment` | +| Tag an element with a value | `link_reference_value_assignment` / `detach_reference_value_assignment` | +| Associated, consistent, mapped | `link_associated_valid_values`, `link_consistent_valid_values`, `link_mapped_valid_values` (and `detach_*`) | +| Implementation | `link_valid_value_implementation` / `detach_valid_value_implementation`, `update_valid_value_implementation`, `detach_valid_value_implementation_by_id` | + +### Dr.Egeria: the Reference Data family + +| Command | Does | +|---|---| +| `Create Reference Data Set` | Creates or updates a `ReferenceDataSet`, and its members (see below) | +| `Create Reference Data Value` | Creates or updates a `ReferenceDataValue`; `In Reference Data Set` adds it to a set, with `Is Default Member` and `Member Ordinal` | +| `Link`/`Detach Valid Value Member` | `ValidValueMember` (`Valid Value Set`, `Member Value`) | +| `Link`/`Detach Consistent Valid Values` | `ConsistentValidValues` (`Valid Value 1`, `Valid Value 2`) | +| `Link`/`Detach Associated Valid Values` | `ValidValueAssociation` | +| `Link`/`Detach Mapped Valid Values` | `ValidValuesMapping` | +| `Link`/`Detach Valid Value Implementation` | `ValidValuesImplementation` (`Valid Value`, `Implementation Element`) | +| `Link`/`Detach Element to Valid Values` | `ValidValuesAssignment`, with `Strict Requirement` (default true) | +| `Link`/`Detach Reference Value Assignment` | `ReferenceValueAssignment`, with Attribute Name, Confidence, Steward, Notes | + +`Link Question to Valid Values` (Glossary) and `Link Data Field to Valid +Values` (Data Designer) are contextual forms of `ValidValuesAssignment`. They +live in their own families. + +A set's members can be given three ways, in one `Create Reference Data Set`: + +- `Members` — existing values, by name or GUID. +- `Values` — new values, one per line. This is a **Line List**: only new + lines separate entries, so `Washington, D.C.` stays one value. +- `Value Table` — new values with their own properties, as a markdown + **Table**. Columns: Value (required), Display Name, Description, Usage, + Data Type, Is Case Sensitive, Default, Ordinal. Write a literal pipe as `\|`. + +```markdown +## Create Reference Data Set +### Display Name +Order Status + +### Value Table +| Value | Display Name | Description | Default | Ordinal | +|-----------|--------------|---------------------|---------|---------| +| PENDING | Pending | Order received | true | 1 | +| SHIPPED | Shipped | Left the warehouse | | 2 | ``` -**Use #1/#2 when the value needs to be its own catalogable, linkable, -citable metadata element** (our measure-definition use case). **Use #3 -when you're constraining what a specific open-metadata property can -legally hold** — a type-system-level concern, not a domain-reference-data -one. - -## `set_consistent_metadata_values` — the file-type/file-suffix example - -`ValidMetadataManager.set_consistent_metadata_values(property_name1, -type_name1, map_name1, preferred_value1, property_name2, type_name2, -map_name2, preferred_value2)` is real and dedicated — backs the -`ConsistentValidValues` relationship from the Reference Data types page. -It cross-references two **`ValidMetadataValue`** entries (flavor #3 above, -not flavor #1's `ValidValueDefinition`) as required to co-occur — e.g. -"file type = Python Source" (`property_name="fileType"`) should be -consistent with "file suffix = .py" (`property_name="fileExtension"`). -Both values must already exist via `setup_valid_metadata_value`/ -`setup_valid_metadata_map_value` before linking them consistent — this -operates entirely within the type-property system (#3), not on standalone -`ValidValueDefinition` elements (#1/#2). `get_consistent_metadata_values` -is the read side. - -**Practical implication**: if Resource Explorer (or anything else) ever -wants "these two properties' values must agree" validation — e.g. file -classification's type/suffix pairing — this is the real, already-built -mechanism, and it's a type-property-level concern (flavor #3), not -something to route through `ValidValueDefinition`/`ValidValueMember`. - -## Correction: `SpecificationPropertyAssignment`-shaped functionality -**does** have a dedicated method — just not one matching that literal name, -and it may not fit our use case - -Confirmed via `ValidMetadataManager`: `setup_specification_property( -element_guid, body)` / `delete_specification_property(...)` / -`find_specification_property(...)` / `get_specification_property_by_type` -/ `_by_name` / `_by_guid` / `get_specification_property_types` — a real, -dedicated CRUD set. This attaches a "specification property" to an -element, with two documented payload shapes: +Rules: + +- An inline value is named `::`. The set's + qualified name is derived as usual, with the local prefix and version, e.g. + `Coco Pharmaceuticals::ReferenceDataSet::Order Status::1.0::PENDING`. So + re-running a document finds the value and updates it rather than creating a + duplicate (verified). +- When any of the three attributes is given, the set's membership is made to + match. Listed values are linked; changed defaults or ordinals are updated in + place. Members no longer listed are **unlinked, never deleted**, since other + sets or fields may use them. When none of the three is given, an update + leaves membership alone. +- Ordinal comes from the `Ordinal` column, or from list position. `Default + Member` names the default when you use `Values`. +- To link values across sets in a portable document, give them unique display + names with `Create Reference Data Value`. An inline value's display name is + just its value, which may repeat across sets. +- There are no Delete commands in Dr.Egeria (no family has them). Use the SDK. + +Report specs `Reference-Data-Set-DrE-Basic/Advanced` and +`Reference-Data-Value-DrE-Basic/Advanced` work with `View Report`. + +--- + +## Valid metadata values + +### What they are + +`ValidMetadataManager.setup_valid_metadata_value(property_name, type_name, body)` +registers a value as valid for an open metadata property, optionally for one +type only. The server builds a `ValidMetadataValue` element for it, with a +qualified name like `Egeria:ValidMetadataValue::-`. You +address it by property, type and value, never by GUID. `TechnologyType` (the +values of `deployedImplementationType`) is a specialisation of this. + +Siblings: `setup_valid_metadata_map_name` / `setup_valid_metadata_map_value` +for map-valued properties; `clear_valid_metadata_value` / +`clear_valid_metadata_map_name` / `clear_valid_metadata_map_value`; +`validate_metadata_value` (and map forms); `get_valid_metadata_value(s)` (and +map forms). `get_valid_metadata_values` has no `asOfTime` (ISSUE-18, an +Egeria limit). ```python -# ReplacementAttribute — a customizable attribute a template exposes -{ - "class": "ReplacementAttribute", - "name": "...", "description": "...", "datatype": "...", - "example": "...", "required": False, - "otherPropertyValues": {"property1": "propertyValue1"}, -} - -# SupportedTemplate — declares what open-metadata type a template produces -{ - "class": "SupportedTemplate", - "name": "...", "description": "...", - "openMetadataTypeName": "...", "required": False, - "otherPropertyValues": {"property1": "propertyValue1"}, -} +client.valid_metadata.setup_valid_metadata_value( + "projectHealth", "Project", + {"displayName": "At Risk", "description": "Slipping; needs attention", "preferredValue": "At Risk"}) ``` -Both documented shapes are specifically about **template/connector -configuration** (what a template can be customized with, what type a -template instantiates) — not the generic "attach an interpretation -`ValidValueDefinition` to an arbitrary Annotation Type's property" shape -the Trellis measure-definitions work actually needs. **This needs a live -check before assuming it covers our case** — worth confirming against a -real server whether `setup_specification_property` accepts other -`class` values beyond the two documented ones, or whether the still- -missing `SpecificationPropertyAssignment` relationship (per the Reference -Data types page) is a genuinely separate thing pyegeria doesn't expose -yet. Flagging this now specifically so it doesn't get assumed-solved and -skipped when the pending pyegeria work happens. - -## Summary table - -| Mechanism | Entity created? | Keyed by | pyegeria class | Real/dedicated? | -|---|---|---|---|---| -| `create_valid_value_definition` | Yes — standalone `ValidValueDefinition` | qualifiedName | `ReferenceDataManager` | ✅ | -| `create_valid_value_definition_from_template` | Yes — same, from template | qualifiedName | `ReferenceDataManager` | ✅ | -| `setup_valid_metadata_value` | No — property-level metadata | `(property_name, type_name)` | `ValidMetadataManager` | ✅ | -| `set_consistent_metadata_values` | No — relates two property-level values | `(property_name, type_name)` pairs | `ValidMetadataManager` | ✅ | -| `setup_specification_property` | Attaches to an existing element | `element_guid` + `class` (2 known shapes) | `ValidMetadataManager` | ✅ for template use cases; unconfirmed for general use | -| `link_valid_value_definition` (ValidValueMember) | Relates two `ValidValueDefinition`s | vv_set_guid + vv_member_guid | `ReferenceDataManager` | ⚠️ documented body fails client-side validation — real bug, see Trellis doc | -| `ValidValuesAssignment` (Question → measure set) | — | — | — | ❌ no dedicated method yet | -| `ReferenceValueAssignment` (tag a result) | — | — | — | ❌ no dedicated method yet | +Omit `type_name` (pass `None`) to make a value valid for the property on every +type. pyegeria omits the query parameter in that case (ISSUE-82). + +### Behaviour worth knowing + +- **Re-running setup is safe.** Setting up the same value again does not + duplicate it (verified). +- **Setup also creates a per-property container** + (`Egeria:ValidMetadataValue::-`), and clearing the values + does not remove it. To remove it, find it with + `find_valid_value_definitions(, metadata_element_type="ValidMetadataValue")` + and delete it by GUID. +- **Clearing:** in the 2026-10-13 live check, the first + `clear_valid_metadata_value` calls returned an error, yet the values were gone + afterwards. A repeat call answered "not found" (`OPEN-METADATA-400-011`). Read + the values back rather than trusting the response. +- **Consistent values:** `set_consistent_metadata_values(property1, type1, + map1, value1, property2, type2, map2, value2)` says two valid metadata values + go together — e.g. `fileType` "Python Source" with `fileExtension` ".py". + Both must already be set up. `get_consistent_metadata_values` reads them. + +### Specification properties + +`SpecificationPropertyValue` is the third `ValidValueDefinition` subtype. It +describes a template's or connector's configuration: placeholders, replacement +attributes, supported templates, action targets, guards. + +- `setup_specification_property(element_guid, body)`, + `delete_specification_property`, `find_specification_property`, + `get_specification_property_by_type` / `_by_name` / `_by_guid`, + `get_specification_property_types`. +- `link_specification_property` / `detach_specification_property` create + and remove the `SpecificationPropertyAssignment` relationship (with + `propertyName`) between an element and a valid value. + +### Dr.Egeria: the Valid Metadata family + +| Command | Does | +|---|---| +| `Setup`/`Clear Valid Metadata Value` | One value for a property (and optional type) | +| `Setup`/`Clear Valid Metadata Map Name` | A valid name for a map-valued property | +| `Setup`/`Clear Valid Metadata Map Value` | A valid value for a name in a map-valued property | +| `Set Consistent Metadata Values` | Two values that go together | +| `Link`/`Detach Specification Property Assignment` | `SpecificationPropertyAssignment` | + +`Setup Valid Metadata Value` also accepts a `Metadata Value Table`, to set up +several values for one property in one command: + +```markdown +## Setup Valid Metadata Value +### Metadata Property Name +projectHealth + +### Type Name +Project + +### Metadata Value Table +| Preferred Value | Display Name | Description | +|-----------------|--------------|---------------------------| +| On Track | On Track | Progressing to plan | +| At Risk | At Risk | Slipping; needs attention | +``` + +These commands were part of the Reference Data family until 2026-10-13. +Their names did not change when they moved. + +--- + +## Summary + +| You want to… | Use | +|---|---| +| Publish a business code list | Reference data: `Create Reference Data Set` with `Values` or `Value Table` | +| Say which code list a field or question uses | `Link Element to Valid Values` / `Link Data Field to Valid Values` / `Link Question to Valid Values` | +| Tag an element with one code | `Link Reference Value Assignment` | +| Relate codes in two lists | `Link Mapped Valid Values` (same meaning), `Link Associated Valid Values` (named relation), `Link Consistent Valid Values` (used together) | +| Record how a system stores a code | `Link Valid Value Implementation` | +| Allow a new value for an Egeria property | Valid metadata: `Setup Valid Metadata Value` | +| Say two Egeria property values go together | `Set Consistent Metadata Values` |