Consolidated work list. Update status when items start or finish.
Status: open · in-progress · done · deferred
🟠 High Priority — Missing/absent catalog templates crash or silently proceed in _async_get_template_guid_for_technology_type callers — needs discussion
Status: open (partial fix landed 2026-07-27) Added: 2026-07-27
tests/scenario-tests/test_automated_curation_scenarios.py::scenario_manage_client_side_secrets crashed with a bare KeyError: 0 calling create_secrets_store_element_from_template. Root cause: _async_get_template_guid_for_technology_type() (pyegeria/omvs/automated_curation.py:4476, shared by 13 create_X_element_from_template methods — Kafka, CSV, PostgreSQL x2, File System Directory, 6x Unity Catalog, YAML File Secrets Collection) blindly indexed details.get("catalogTemplates", {})[0] with a wrong default ({} instead of []), turning a missing/empty catalogTemplates into a confusing KeyError instead of a clear error.
Fixed: the indexing bug itself — now raises a clear PyegeriaException naming the technology type and stating no catalog template is registered, instead of crashing opaquely.
Live-checked all 13 call sites against qs-view-server (2026-07-27) — two real gaps found, need a decision on each:
YAML File Secrets Collection— technology type exists (it's a real, standard Egeria type perDeployedImplementationType.javain egeria core) but has zero catalog templates registered on this server (catalogTemplates: []). This is a server-side sample-data/archive gap, not a pyegeria bug —create_secrets_store_element_from_templatecannot work at all against this server until the template is loaded. Confirm which archive/sample-data load is supposed to seed this template, and whether it's missing from the quickstart setup or was never added upstream.Apache Kafka Server— technology type is not registered at all on this server (_async_get_tech_type_detailreturnsNO_ELEMENTS_FOUND)._async_get_template_guid_for_technology_typealready handles this branch gracefully (returnsNone, no crash) — but every caller (e.g.create_kafka_server_element_from_template) then proceeds to build aTemplateRequestBodywithtemplateGUID: None, whichbody_slimmerwill likely strip, sending a request silently missing a required field — masking the real problem behind a probably-confusing downstream 400 from the server instead of failing fast client-side. Needs a decision: should_async_get_template_guid_for_technology_typereturningNonecause the 13 callers to raise immediately (consistent with the empty-catalogTemplates case above), rather than let each one send a doomed request?
All other 10 call sites (CSV Data File, PostgreSQL Server, PostgreSQL Relational Database, File System Directory, and all 6 Unity Catalog * types) checked clean — tech type found, exactly one catalog template registered, no issue.
Status: open (partially resolved 2026-07-27) Added: 2026-07-02
tests/functional-tests/test_comments.py originally had 9 failing tests, all AttributeError on pyegeria.core._server_client.ServerClient. Root cause turned out to be test bugs, not missing SDK methods — the file was written by copy-pasting a note_logs test file and missed several renames:
- 7 tests patched
async_Xwhen the real method is_async_X(this repo's documented convention: private_async_*impl + public sync wrapper) — simple naming typo. test_remove_comment_from_element_sync_calls_asynccalledclient.remove_note_log(...)instead ofclient.remove_comment_from_element(...), with a stale fake signature (extraelement_guidparam the real method doesn't have).test_get_attached_comments_sync_calls_asynccalledclient.get_attached_note_logs(...)instead ofclient.get_attached_comments(...), with wrong fake param names/order.test_find_comments_sync_calls_asynccalledclient.find_note_logs(...)instead ofclient.find_comments(...).test_get_comment_by_guid_sync_calls_asynchad a fake signature with a nonexistentelement_typeparam instead of the realgraph_query_depth.test_update_comment_sync_calls_asyncasserted a return value ({"status": "OK"}) thatupdate_comment()'s sync wrapper never actually propagates (matches_async_update_comment's own-> Nonecontract) — assertion was just wrong.
All 8 of the above are now fixed in tests/functional-tests/test_comments.py; pytest tests/functional-tests/test_comments.py passes.
Still open: test_add_comment_reply_sync_calls_async is marked @pytest.mark.skip — add_comment_reply has no _async_* method on ServerClient, and Egeria's feedback-manager REST API (Egeria-api-feedback-manager.http) has no distinct comment-reply endpoint either; replies appear to just be regular comments attached via addCommentToElement, not a separate mechanism. Needs a product decision: implement real reply support (if Egeria core actually has one this reference file is missing), or delete the test.
Status: open Added: 2026-07-02
The new Produced Guards attribute (Action Author family, on Governance Action Type Base bundle — used by Create Governance Action Type / Create Governance Action Process Step) is a Simple List of strings with no valid_values constraint. Unlike Domain Identifier-style Enum attributes (which list every allowed value in valid_values, e.g. ALL;DATA;PRIVACY;...), guard names are process-author-defined labels rather than a fixed global enum, so there's no universal list to seed it with today.
Future validation idea: once real governance action processes exist with real guard names in use, consider whether Produced Guards values should be validated against something more specific than free text — e.g. cross-checked against the Guard/Next Governance Action Process Step relationship attributes actually declared in the same process, so a typo'd guard name that never matches a real transition gets caught at validate time instead of silently producing a dead-end step. Not blocking Phase 1 or Phase 2 — flagging so it isn't forgotten once there's real usage data to design the check against.
Status: open Added: 2026-07-02
47 of the failures across tests/dr-egeria-command-tests/dr_test_*.md (validate mode) are all the same root cause: Referenced element 'X' ... not found, where X is a specific named element from a "SalesForecast" demo scenario (a pipeline, a master collection, an agreement, glossary terms, a governance zone) plus a couple of similar campaigns ("Clinical Trials Management", "Sustainability"). Confirmed directly against the live server (localhost:9443) that zero SalesForecast elements currently exist — client.find_collections('SalesForecast') returns "No elements found".
This means the Create commands that would establish this baseline dataset are scattered across several of the dr_test_*.md files rather than living together, and nothing has actually run them in --process mode against this server (or the server was reset since they last were). Every Link/Attach/Detach/Unlink command elsewhere that references one of those named elements by qualified name fails to resolve it.
Fix: collect up the Create commands that establish the SalesForecast baseline (and the couple of campaign elements), work out the correct dependency order, and either (a) run them once in --process mode against whichever server these fixtures are meant to run against, or (b) consolidate them into a dedicated seed file that run_dr_tests.py (or a setup step before it) runs first. Not blocking Action Author Phase 1/2 — pre-existing gap, unrelated to those commands.
Status: fixed (2026-07-31) Added: 2026-07-08
Running dr_egeria <100+ command file> --process against localhost:9443 (e.g. the generated dr-egeria-help-*.md, ~100+ commands) took ~1h20m end to end and started failing every remaining command with HTTP 401 partway through — the bearer token created at the start of the run expired before the run finished, and nothing re-authenticates or refreshes it mid-batch. Confirmed directly in logs/pyegeria.log: the "Create Risk" term's _async_create_element_body_request call at 23:12:14 got a 401 (Client error '401' for url .../glossary-manager/glossaries/terms), as did every command after it in that run (~6+ trailing Solution Architect Link commands all failed the same way). Re-running the single "Create Risk" term in isolation (a few seconds) succeeded immediately with the same credentials — confirming it's a token-lifetime/duration issue, not a bad request or bad credentials.
Fixed: option (b) implemented, but in pyegeria core (_async_make_request in pyegeria/core/_base_server_client.py) rather than the v2 dispatcher loop — so it fixes every caller of any pyegeria client, not just Dr.Egeria's batch pipeline. On a 401, if the client holds stored credentials, it now transparently re-authenticates via _async_create_egeria_bearer_token() and retries the original request exactly once before surfacing a failure. Also fixed a bug in _async_create_egeria_bearer_token() itself found while implementing this: it was sending the token-refresh request with the stale/expired Authorization header still attached, which got that request itself rejected with 401 — silently defeating both this new auto-retry and the pre-existing manual "call this if your token expired" use case. See PYEGERIA_ISSUES.md ISSUE-7 for full detail; live-verified end-to-end against qs-view-server.
🟠 High Priority — Egeria server silently overwrites SolutionLinkingWire instead of creating a parallel relationship
Status: open (client-side warning added; server-side behavior not fixable from egeria-python) Added: 2026-07-09
Issuing two Link Solution Components Dr.Egeria commands with the same ordered (Component1, Component2) pair but different Labels does not create two parallel SolutionLinkingWire relationships — the second call silently overwrites the first's properties (including label) in place. Discovered because sample-data/egeria-inbox/dr-egeria-inbox/solution-design.md was missing exactly one relationship on the live server (DataHub -> Finance | expenses) after processing, while a same-direction sibling link (DataHub -> Finance | new-orders) survived.
Confirmed with a controlled repro (two throwaway components, two same-direction Link Solution Components calls) and verified two independent ways: the wiredTo convenience summary field, and the generic get_related_elements relationship query — both show only one relationship, carrying the second call's properties. Reversing direction between two calls (C→D then D→C) correctly produces two distinct relationships, so it's specifically the ordered pair that collapses, not direction in general.
Checked the Egeria core Java handler (SolutionComponentHandler.linkSolutionLinkingWire → openMetadataClient.createRelatedElementsInStore) — no find-first/update logic visible at that layer, so the collapse happens deeper in the server/repository stack. Also checked the live SolutionLinkingWire relationship type definition directly (get_all_relationship_defs): both endDef1/endDef2 declare attributeCardinality: "ANY_NUMBER", meaning the type system itself permits multiple relationships between the same pair — so this looks like a REST/view-service handler bug (an unwanted idempotent "find matching relationship, update it" pattern) rather than a fundamental repository constraint. Nothing to fix in pyegeria or dr_egeria's Python code for the write path itself — the request sent is exactly what was asked for.
Mitigation added 2026-07-09: the user extended Link Solution Components with a One Way attribute (bool, default True) as a workaround — set One Way: False to express a bidirectional flow with a single command instead of issuing two same-direction commands. SolutionLinkProcessor.apply_changes() in md_processing/v2/solution_architect.py now also pre-checks for an existing same-direction wire before creating a new one and surfaces a WARNING-status "Existing Wire Overwrite" result if a call is about to silently clobber an existing relationship — so this is no longer a silent, undetectable data-loss surprise, but the underlying overwrite behavior itself is still present.
Fix (if ever pursued upstream): report/fix in Egeria core so the attach REST handler for SolutionLinkingWire creates a new relationship instance per call (matching the type system's ANY_NUMBER cardinality) rather than upserting by ordered end-GUID pair. Out of scope for egeria-python to fix directly.
Status: open Added: 2026-07-24
Running pytest broadly enough to sweep in examples/ (rather than scoping to tests/ per this repo's convention) surfaces two pre-existing collection errors, unrelated to any Dr.Egeria/glossary work:
examples/extract_attribute_test.py:13— a stray trailing/afterif zones and isinstance(zones, list):is a plainSyntaxError, so the file can't even be parsed.examples/test_jacquard_data_sets.pyandexamples/test_jacquard_data_sets_scenarios.py— bothfrom examples.jacquard_data_sets import JacquardDataSets, which fails withModuleNotFoundError: No module named 'examples'(no__init__.py/path setup makesexamplesimportable as a package).
Neither breaks pytest tests/, so day-to-day test runs are unaffected — this only bites if examples/ is included in the collection path.
Fix: remove the stray / in extract_attribute_test.py:13; either add examples/__init__.py (and confirm examples is on sys.path/rootdir-relative import works) or change the two Jacquard test imports to a path that resolves without treating examples as a package.
Status: open Added: 2026-07-24
pyegeria/view/_output_format_models.py (lines 164, 172, 221, 238, 275) still uses Pydantic v1-style @root_validator(pre=True) and @validator(...) decorators. These emit PydanticDeprecatedSince20 warnings on every collection/import that touches this module (visible in pytest output) — they still work today (v2 keeps them as deprecated shims) but are slated for removal in a future Pydantic major version. Not urgent — no functional bug, and the project's Pydantic version (2.12.3) is current — but the warning noise will become a hard break eventually.
Fix: migrate @root_validator(pre=True) → @model_validator(mode="before") and @validator(...) → @field_validator(...) for each of the 5 flagged validators in _output_format_models.py, then re-run pytest -m unit to confirm the warnings are gone and behavior is unchanged.
🟠 High Priority — Forward references to elements later in the same Dr.Egeria file don't actually resolve
Status: done (fixed 2026-08-02) Added: 2026-08-01
Context: investigating a user report that Sub-Projects on Create Project
(and variants: Campaign/Task/Personal Project/Study Project) was "being
ignored." The wiring itself is correct and works (fixed 2026-07-08, commit
71202ef) — live-verified end-to-end for both plain Create Project and
Create Campaign, both correctly created ProjectHierarchy relationships.
The actual bug: it only works when every referenced sub-project is already
created or listed earlier in the same file. If the parent project is
listed before its children — a very natural way to write a Dr.Egeria
doc — the reference silently failed to resolve. (A related, smaller bug —
list-style reference resolution silently dropping unresolvable items with
zero error, instead of reporting them like single-value references already
did — was fixed same day, see md_processing/v2/processors.py's Step 7
list-resolution loop. That fix alone turns "silently ignored" into "clearly
reported: Execution blocked: Referenced element(s) [...] not found," so
users at least get an actionable error now.)
Root cause (why true forward-reference support is a bigger job):
Dr.Egeria processes commands strictly sequentially in --process mode. By
the time command N runs, commands 1..N-1 have already fully executed —
so a backward reference (child listed before parent) never needs the
"planned" placeholder mechanism at all; it just finds the real,
already-created GUID via cache/live-lookup. The "planned" mechanism
(context["planned_elements"], populated incrementally as each command
executes) only helps a forward reference if the referenced name is
already registered by the time the referencing command's own resolution
step runs — which is never true for command K > N referenced by command N,
since command K hasn't executed yet. There's already a well-built "resolve
planned GUIDs right before applying changes" step in the code (~line
557-610 in processors.py) that correctly detects a still-unresolved
planned item and blocks with a clear "Prerequisite element ... was not
successfully created" error — but it can only help if the item was
recognized as planned in the first place, which requires it to already be
in planned_elements, which requires its own command to have executed.
Real fix would require a two-phase batch design:
- A pre-scan pass over the whole batch (before any command executes) to
register every Create/Update-verb command's target name into
planned_elementsupfront — so forward references are recognized as "planned" rather than "not found at all." - Defer the actual relationship-sync API calls (e.g.
_sync_sub_projects'sadd_fn/remove_fn) for any reference still showing a(Planned:...)placeholder until after the full batch has executed and the referenced element genuinely exists — not just "recognized as planned." - Error handling for the case where the referenced element's own command later fails (e.g. the forward-referenced child project itself fails to create) — the deferred relationship-sync needs to surface a clear error in that case too, not fail silently or crash.
This is a genuine architectural change to the core dispatch pipeline
(md_processing/v2/dispatcher.py, processors.py), affecting every
list-style and single-value reference attribute across every command
family — not scoped to Sub-Projects. Deferred pending a scoping discussion;
not started.
Workaround for users today: list every element a command will
reference before the command that references it, in file order (e.g.
create sub-projects first, then the parent project that lists them under
Sub-Projects). This is exactly what the newly-added blocking error
message will now tell you to do if you get it wrong.
Bonus finding while validating the Tier 1 fix: the same silent-drop bug
was independently reproduced (pre-existing, unrelated to Sub-Projects) in
two of the regression fixtures under tests/dr-egeria-command-tests/:
dr_test_glossary.md's GL-08 scenario ("member of multiple glossaries") referencesGlossary::CRM::Domain::1.0as a second glossary membership, but no such glossary is ever actually created anywhere in the file — the term was silently only added to one glossary instead of two.dr_test_products_good.md'sLink Agreement to Actorscenario references actor<jane.smith@example.com>, which was never created — same root cause as the already-tracked "SalesForecast regression fixtures need a baseline seed sequence" entry above.
Both now correctly fail with a clear blocking error instead of silently
"succeeding." Not fixed as part of this entry — the fixtures themselves
need either a missing Create Glossary/actor block added, or the stale
reference corrected.
Fixed 2026-08-02: implemented the two-phase batch design described
above, smaller in scope than originally framed — none of the 11
relationship-establishing call sites across project.py/
solution_architect.py/glossary.py/data_designer.py/governance.py/
collection_manager_processor.py needed to change; the entire mechanism
lives in dispatcher.py and processors.py:
V2Dispatcher.prescan_batch_target_qns()walks the full batch once before execution, deriving each Create/Update command's own qualified name (reusing the realderive_qualified_name(), byte-identical to the later real parse) plus its raw Display Name (a forward reference is typically typed as the display name, matching how a backward reference already resolves viafind_key_with_value()).dispatch_batch()now runs in rounds: a command whose reference is recognized as a legitimate batch target but not yet resolvable is deferred (not failed) and retried next round; stops when nothing's deferred, or forces one final round (treating anything still unresolved as a genuine, final failure) once a round makes zero progress.- Two "flavors" of command, discriminated automatically by whether
derive_qualified_name()returns non-empty: embedded (Create Projectetc.) always creates its own element immediately regardless of unresolved embedded references, so same-round dependents aren't falsely blocked; standalone (Link Project Hierarchyetc., the whole command is the relationship) defers the entire command. - Also fixed a genuine multi-level-chain bug found during design (grandparent→parent→child
forward-reference chains failed one level too early without a
context["final_round"]guard on the existing "resolve Planned GUIDs" gate), and a pre-existing silent-success bug inSolutionLinkProcessor.apply_changes()(unresolvedid1/id2returnedraw_blockwithout setting an error, soexecute()reported"success"on a silently-skipped link).
Live-verified against qs-view-server: a parent-before-child Sub-Projects
forward reference now resolves and creates the real ProjectHierarchy
relationship. New test coverage: tests/micro-tests/test_dispatcher_forward_references.py.
Backward-compatibility confirmed byte-for-byte via all 12 dr_test_*.md
regression fixtures (identical SCORE lines before/after). Full design
history and validated rationale in the session that implemented this — see
git history around 2026-08-02 for md_processing/v2/dispatcher.py and
md_processing/v2/processors.py.
The two bonus fixtures noted above (dr_test_glossary.md GL-08,
dr_test_products_good.md Agreement-to-Actor) are still open — not
forward-reference cases (nothing in either file ever creates the referenced
element), so this fix doesn't change their outcome. Still need a decision:
add the missing block, or correct the stale reference.
🟡 Medium Priority — Parent ID/Parent Relationship Type Name silently dropped on Update (fixed); Anchor ID/Anchor Scope ID cannot be changed post-creation (confirmed architectural constraint, not a bug)
Status: done (Parent Relationship fixed 2026-08-02); Anchor — confirmed not fixable, no further action planned Added: 2026-08-02
Context: also fixed in passing: set_create_body() looked up the
attribute under the wrong key, 'Anchor Scope GUID', when the compact
spec's actual attribute name is 'Anchor Scope ID' — silently broke
anchorScopeGUID even on Create, independent of the Update-time gap
below. Corrected the key name.
set_create_body() bakes Anchor ID/Parent ID/Anchor Scope ID (+ Parent Relationship Type Name/Parent Relationship Attributes/
Parent at End1) into Create's NewElementRequestBody as a shortcut —
Egeria's create endpoint bundles "create the element" and "establish this
one relationship/anchor" into a single call. set_update_body() has no
equivalent fields at all (confirmed: Egeria's real UpdateElementRequestBody
Java class has only a properties field — no anchor/parent slot exists on
the update endpoint). Since the compact spec marks these attributes
inUpdate: True, they were being resolved to real GUIDs on Update
commands and then silently discarded — parsed, resolved, never sent
anywhere.
Parent ID / Parent Relationship Type Name — fixed. The relationship
these fields represent (an ordinary Egeria relationship, e.g.
ProjectHierarchy) can be established explicitly post-creation, the same
way a standalone Link X command would. Added
AsyncBaseCommandProcessor._sync_parent_relationship() (one generic method,
called from execute() after apply_changes() succeeds, for both Create
and Update) using MetadataExpert's generic relationship calls
(_async_create_related_elements/_async_get_all_related_elements/
_async_delete_related_elements — any Egeria relationship type, not just
ones with a dedicated OMVS wrapper). Live-verified against qs-view-server:
creates the relationship on Update, idempotent on repeat (checked via direct
GUID comparison), and correctly re-parents (old relationship removed, new
one created) when Parent ID changes.
Fixing this surfaced three independent, pre-existing pyegeria bugs (all fixed as part of this same pass, since they directly blocked verifying the above):
validate_new_related_elements_request()(pyegeria/core/_server_client.py) used the wrongTypeAdapter(_new_relationship_request_adapter, for an unrelated model) instead of the already-defined-but-unused_new_related_elements_request_adapter.NewRelatedElementsRequestBody(pyegeria/models/models.py) had field names (relationship_type_name/end_1_guid/end_2_guid) that don't match the real Java DTO (typeName/metadataElement1GUID/metadataElement2GUID, confirmed againstframeworkservices/omf/rest/NewRelatedElementsRequestBody.java) — the server silently ignored the wrong field names rather than erroring._async_get_all_related_elements()(pyegeria/omvs/metadata_expert.py) returns a dict ({"startingElement":..., "elementList":[...], "mermaidGraph":...}), not a list, andelementListentries use a different, lower-level shape (type.typeName/relationshipGUID/element.elementGUID) than domain-specific calls likeProjectManager._async_get_project_by_guid()'smanagedProjectsfield.
Anchor ID / Anchor Scope ID — investigated, confirmed NOT fixable the same
way; no code change made. Anchoring is implemented as a classification
("Anchors"/AnchorsProperties: anchorGUID, anchorTypeName,
anchorDomainName, anchorScopeGUIDs, zoneMembership), not a
relationship, so the relationship-based fix above doesn't apply. Tried the
obvious equivalent — MetadataExpert._async_reclassify_metadata_element()
with an updated anchorGUID — and it succeeds at the API level but does
not establish real anchor semantics: live-tested twice (two independent
throwaway-element pairs), reclassifying one element's Anchors to point at
another, then deleting the "anchor" with cascade=True — the reclassified
element survived both times and had to be deleted independently, proving no
real cascade-delete relationship was established. Traced into
OpenMetadataAPIAnchorHandler.java: anchorGUID maintenance there is wired
into specific entity-creation flows (schema types, attributes,
connections, comments, ratings, etc.), not into any generic post-creation
reclassify path. This reads as an intentional constraint — anchoring
governs lifecycle/security/visibility scope, which is the kind of thing
that's reasonable to keep immutable after creation for governance reasons,
unlike an ordinary Parent relationship. Recommendation: leave Anchor ID/Anchor Scope ID's current Update-time silent-no-op behavior as-is.
If this needs revisiting, the next step would be finding whichever
repository-services-level operation (if any) actually re-evaluates an
entity's anchor after creation — not found via the generic MetadataExpert
API surface in this investigation.
🟢 Low Priority — Confidentiality/Confidence/Criticality/Retention/Impact classifications were completely unwired (all five now fixed and working)
Status: done — all five classifications, including Retention (fixed server-side 2026-08-03) Added: 2026-08-02
Context: per dwolfson — unlike Anchor ID (confirmed immutable-by-design, see
entry above), Confidentiality/Retention/Criticality/Confidence genuinely need
to be changeable over an element's lifetime. Investigating this found these
five "0422 Governed Data Classifications" attributes (Confidentiality Classification, Confidence Classification, Criticality Classification,
Retention Classification, Impact Classification — all style: "Valid Value", inUpdate: true, present on every family via the shared bundle)
were not wired into any processor at all — not Create, not Update. Parsed
and validated by AttributeFirstParser, then silently discarded; a bigger gap
than the Parent/Anchor case, which at least worked on Create.
Fixed: added AsyncBaseCommandProcessor._sync_governance_classifications()
(md_processing/v2/processors.py), called from execute() alongside
_sync_zone_membership/_sync_parent_relationship for both Create and
Update. Uses classification_manager's (ClassificationExplorer) dedicated
_async_set_X_classification/_async_clear_X_classification methods.
Found and worked around a systemic, previously-unknown bug across ALL FIVE
of pyegeria's own classification methods while implementing this: both
classification_explorer.py's docstrings and the compact spec's attribute
descriptions document the "level" property uniformly (and wrongly) as
levelIdentifier (Retention: basisIdentifier, Impact:
severityIdentifier). Confirmed live that calling set_confidentiality_ classification with the documented levelIdentifier field returns no
error but the classification silently fails to attach at all. Cross-checked
each real Java class
(frameworks/openmetadata/properties/governance/*Properties.java) and
confirmed live, round-trip, that the real field names are:
confidentialityLevel, confidenceLevel, criticalityLevel,
severityLevel (Impact), and retentionBasis (Retention — matches its
docstring, unlike the other four). Verified end-to-end: set on Create,
re-set to a different value on Update (confirmed idempotent — Egeria
reclassifies in place, same as _sync_zone_membership's existing
established pattern), values read back correctly via direct element fetch
for Confidentiality/Confidence/Criticality/Impact.
Retention Classification — was a separate server-side gap, confirmed fixed 2026-08-03.
Every attempt to set Retention was previously rejected server-side:
OMRS-REPOSITORY-400-028 A property called statusIdentifier has been proposed for a metadata instance of category ClassificationDef and type Retention; it is not supported for this type, even though the outgoing
request never included that field (confirmed via a wire-body dump at the
time) — an Egeria core / ClassificationDef type-registration gap, not a
pyegeria or Dr.Egeria issue.
Re-verified live 2026-08-03 per dwolfson's report that the Egeria bug was fixed — confirmed:
the same call (RetentionClassificationProperties / retentionBasis, this
codebase's class name and field were already correct) now succeeds, with
the server correctly auto-populating a statusIdentifier default (0) on
its own, no error. Verified end-to-end through the real Dr.Egeria pipeline
(Create Project with Retention Classification: PROJECT_LIFETIME) and via
direct element fetch showing retentionBasis: 2 persisted correctly.
Caught in the process: a "fix" documented here on 2026-08-02 was never actually committed.
This entry previously claimed the client-side class name had been corrected
to "RetentionProperties" (the real Java properties class's simple name).
That change was never actually present in the committed code — and, more
importantly, it would have been wrong: live testing today showed the
server's own Jackson deserializer error lists its exact registered subtype
IDs, and it recognizes "RetentionClassificationProperties", not
"RetentionProperties" — sending the latter gets rejected outright as an
unrecognized type ID, before ever reaching the (now-fixed)
ClassificationDef-registration check. The original class name in
pyegeria/omvs/classification_explorer.py's _async_set_retention_classification
was correct all along; left unchanged (confirmed via a full revert-and-retest
in this session).
Also fixed in passing: pyegeria/omvs/classification_explorer.py's
docstrings for these five _async_set_X_classification methods are stale
(still show the wrong "level" field names) — not corrected as part of this
pass since they're documentation only (the actual behavior is determined by
whatever the caller passes, not by the docstring), but worth a follow-up
cleanup so future users don't fall into the same "no error, but silently
did nothing" trap this session found for Confidentiality.