From 0a9145ab5c4a2afc7f076a8d2e721fc1d814dd38 Mon Sep 17 00:00:00 2001 From: Dan Wolfson Date: Sat, 10 Oct 2026 21:14:46 -0500 Subject: [PATCH 1/4] docs(issues): ISSUE-131 and ISSUE-133 released in 6.2.1 Signed-off-by: Dan Wolfson --- PYEGERIA_ISSUES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PYEGERIA_ISSUES.md b/PYEGERIA_ISSUES.md index 0321d252..582457e8 100644 --- a/PYEGERIA_ISSUES.md +++ b/PYEGERIA_ISSUES.md @@ -166,7 +166,7 @@ that the setting is debug-only and must not be used by applications that act on ### ISSUE-133: Egeria 6.2 returns a solution component's children as `nestedSolutionComponents`; one pyegeria formatter still reads only `subComponents` -**Layer:** pyegeria · **Status:** fixed in #439 (2026-10-10), pending merge · **Found:** 2026-10-10, reported by the Resource Explorer session +**Layer:** pyegeria · **Status:** fixed in #439, released in 6.2.1 (2026-10-10) · **Found:** 2026-10-10, reported by the Resource Explorer session (`SolutionArchitect.get_solution_component_by_guid` JSON on 6.2); confirmed from Egeria source. **What:** Egeria's REST element (`AttributedMetadataElement.java` ~387) carries child components as @@ -223,7 +223,7 @@ annotations); do not choose by majority or by what the code already sends. ### ISSUE-131: 13 `*_by_name` wrappers pass `metadata_element_type=`, but `_async_get_name_request` reads `metadata_element_type_name`, so the type filter is silently dropped -**Layer:** pyegeria · **Status:** fixed in #439 (2026-10-10), pending merge · **Found:** 2026-10-10, while building Resource Explorer's actor-graph lookups (`get_user_identities_by_name`, `get_actor_profiles_by_name`). +**Layer:** pyegeria · **Status:** fixed in #439, released in 6.2.1 (2026-10-10) · **Found:** 2026-10-10, while building Resource Explorer's actor-graph lookups (`get_user_identities_by_name`, `get_actor_profiles_by_name`). **What:** wrappers such as `ActorManager._async_get_user_identities_by_name` (`pyegeria/omvs/actor_manager.py` ~4195) build `params = {"metadata_element_type": metadata_element_type_name, ...}` and call `self._async_get_name_request(url, **params)`. The base method (`pyegeria/core/_server_client.py` ~6581) takes `metadata_element_type_name` and writes it to `"metadataElementTypeName"`, so the wrapper's key falls into `**kwargs` and never reaches the request body. The by-name searches run unfiltered by type. From 595c4c105d7ee3563a6c8dbaa897bfc10c816f0b Mon Sep 17 00:00:00 2001 From: Dan Wolfson Date: Sat, 10 Oct 2026 21:16:51 -0500 Subject: [PATCH 2/4] docs: http-clients folder rename; .http files are a reference, not ground truth - The .http collection folder is now pyegeria/http-clients (was "http clients"). Updated every doc reference, and made scripts/omvs_audit.py and test_metadata_expert_endpoint_contract.py look for the new name first (they pointed at a folder that no longer exists), falling back to the old one. - CLAUDE.md: the .http files are hand-maintained and can be wrong; confirm decision-critical details against Egeria's Java source (Resource class + DTO Jackson names). Corrected the ISSUE-62 note, which called cascadeDelete Egeria's real field name; it is cascadedDelete (ISSUE-132). Signed-off-by: Dan Wolfson --- .aiassistant/rules/pyegeria.md | 2 +- CLAUDE.md | 20 ++++++++++++++----- docs/developer_guide_pyegeria_textual.md | 2 +- omvs_audit_report.md | 2 +- pyegeria/core/README.md | 2 +- pyegeria/http_client_notes.md | 4 ++-- scripts/README.md | 2 +- scripts/omvs_audit.py | 9 ++++++--- .../test_metadata_expert_endpoint_contract.py | 9 +++++++-- 9 files changed, 35 insertions(+), 17 deletions(-) diff --git a/.aiassistant/rules/pyegeria.md b/.aiassistant/rules/pyegeria.md index ecbdd950..00f83545 100644 --- a/.aiassistant/rules/pyegeria.md +++ b/.aiassistant/rules/pyegeria.md @@ -8,7 +8,7 @@ Pyegeria is an Open Source python library supporting Egeria. There are 3 sub-pro 2. Hey_Egeria - Command line scripts to interact with Egeria accessible either standalone, and through a Click CLI. 3. Dr.Egeria - A markdown processor that allows Egeria commands to be written in markdown documents and then interpreted and executed by Dr.Egeria. -Raw sample HTTP requests can be seen in pyegeria/http clients - this is useful to see example payloads and URLs +Raw sample HTTP requests can be seen in pyegeria/http-clients - this is useful to see example payloads and URLs Always use signed commits. There are common patterns we try to follow across the different element types. location_arena.py is one good example but there are many others. Most of the common patterns use common helper functions in _server_client.py. diff --git a/CLAUDE.md b/CLAUDE.md index 0ec1bb38..f9165315 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -140,13 +140,23 @@ that's the complete change. ## Auditing the OMVS clients against the `.http` ground truth `scripts/omvs_audit.py` reconciles every `_async_*` method in `pyegeria/omvs/` -against the `.http` collections, which are the ground truth for URLs, verbs, +against the `.http` collections, which are the reference for URLs, verbs, and request-body classes. +**The `.http` files are not fully trustworthy.** They are maintained by hand, +can lag the server, and sometimes disagree with each other (e.g. half use +`cascadeDelete`, half `cascadedDelete`). When a decision depends on a detail +-- query parameter vs body field, or the exact JSON field name -- confirm it in +Egeria's Java source: the view service's `*Resource.java` Spring class +(`@RequestParam` vs `@RequestBody`) and the request DTO's getter/setter names +and Jackson annotations (`@JsonIgnoreProperties(ignoreUnknown=true)` means a +misspelled field is silently ignored by the server). A local checkout is at +`~/localGit/egeria-v6/egeria`. Checking this way found ISSUE-132. + ```bash -# pyegeria/http clients/ is GITIGNORED — absent in fresh worktrees. +# pyegeria/http-clients/ is GITIGNORED — absent in fresh worktrees. # Point the script at a checkout that has it: -export PYEGERIA_HTTP_DIR="/path/to/egeria-python/pyegeria/http clients" +export PYEGERIA_HTTP_DIR="/path/to/egeria-python/pyegeria/http-clients" python scripts/omvs_audit.py --quiet # full audit -> omvs_audit_report.md python scripts/omvs_audit.py --service location-arena # one service @@ -209,12 +219,12 @@ Changes to `pyegeria/` (SDK API, config, report formatting) can break both. - `_base_platform_client.py` → `_base_server_client.py` → `_server_client.py`: layered HTTP stack - `config.py`: Pydantic-settings config; precedence = explicit args > OS env > `.env` > `config.json` > defaults - `utils.py`: shared helpers (`body_slimmer`, `make_format_set_name_from_type`, etc.) -- **Gotcha — a request-body Pydantic model (`pyegeria/models/models.py`) missing a field silently drops it, not an error.** Every model inherits `PyegeriaModel`'s `extra='ignore'`, so a caller-supplied dict (or a raw no-body-provided construction in `_server_client.py`'s `validate_delete_*_request`-style helpers) with a field the model doesn't declare validates successfully and just vanishes before serialization — no exception, no warning. Confirmed live impact: `DeleteElementRequestBody` had neither `cascadeDelete` nor `deleteMethod` for a long time despite both being real, documented fields on the actual Egeria DTO (`.http` ground truth) — every caller passing `cascade_delete=True` through `_async_delete_element_request` had silently been sending it as unset (PYEGERIA_ISSUES.md ISSUE-62). When adding/using a request-body model, check its fields against the real body in `pyegeria/http clients/Egeria-api-*.http` rather than assuming "it validated without error" means the field will actually be sent. +- **Gotcha — a request-body Pydantic model (`pyegeria/models/models.py`) missing a field silently drops it, not an error.** Every model inherits `PyegeriaModel`'s `extra='ignore'`, so a caller-supplied dict (or a raw no-body-provided construction in `_server_client.py`'s `validate_delete_*_request`-style helpers) with a field the model doesn't declare validates successfully and just vanishes before serialization — no exception, no warning. Confirmed live impact: `DeleteElementRequestBody` had neither a cascade field nor `deleteMethod` for a long time — every caller passing `cascade_delete=True` through `_async_delete_element_request` had silently been sending it as unset (PYEGERIA_ISSUES.md ISSUE-62). The same thing happens on the server side: Egeria's DTOs ignore unknown fields too, so a misspelled name is dropped there. The ISSUE-62 fix chose `cascadeDelete` from the `.http` files, but Egeria's real field is `cascadedDelete` (`DeleteOptions.java`), so cascade still never reached the server (ISSUE-132, on hold for an Egeria fix). When adding/using a request-body model, check its fields against the Egeria Java DTO (or at least `pyegeria/http-clients/Egeria-api-*.http`, knowing it can be wrong) rather than assuming "it validated without error" means the field will actually be sent and read. **`pyegeria/omvs/`** — 40+ service-specific clients (one file per OMVS) - Every public method has an `_async_*` implementation and a sync wrapper calling `asyncio.get_event_loop().run_until_complete(...)`. - All public methods decorated with `@dynamic_catch`. -- Ground truth for API URLs and request bodies is in `pyegeria/http clients/Egeria-api-*.http` — check these files before constructing URLs. +- The reference for API URLs and request bodies is `pyegeria/http-clients/Egeria-api-*.http` — check these files before constructing URLs, and confirm anything decision-critical against Egeria's Java source (see "Auditing the OMVS clients" above). **`pyegeria/egeria_tech_client.py`** — `EgeriaTech` facade - Uses `__getattr__` to lazily proxy attribute access across all OMVS subclients; do not eagerly instantiate. diff --git a/docs/developer_guide_pyegeria_textual.md b/docs/developer_guide_pyegeria_textual.md index d22d359e..362462f2 100644 --- a/docs/developer_guide_pyegeria_textual.md +++ b/docs/developer_guide_pyegeria_textual.md @@ -307,7 +307,7 @@ pyegeria has hundreds of methods. To explore them: one method's parameters. - The source is organised one file per view service in `pyegeria/omvs/`. - The REST calls behind each method are recorded in `.http` files under - `pyegeria/http clients/`, which is useful when you need to see exactly what is sent. + `pyegeria/http-clients/`, which is useful when you need to see exactly what is sent. ### Ask only for the relationships you need: `graph_query_depth` diff --git a/omvs_audit_report.md b/omvs_audit_report.md index f93a2f1a..77aae337 100644 --- a/omvs_audit_report.md +++ b/omvs_audit_report.md @@ -1,6 +1,6 @@ # OMVS Audit Report -Ground truth: `pyegeria/http clients` (40 collections) +Ground truth: `pyegeria/http-clients` (40 collections) Subject: `pyegeria/omvs` (44 modules) | Result | Count | diff --git a/pyegeria/core/README.md b/pyegeria/core/README.md index 5f57cd3c..bcc3c4a9 100644 --- a/pyegeria/core/README.md +++ b/pyegeria/core/README.md @@ -24,6 +24,6 @@ builds on, plus shared config/exception/validation infrastructure. **Gotcha** (see the root `CLAUDE.md`): a request-body Pydantic model in `pyegeria/models/models.py` missing a field silently drops it rather than erroring, since every model inherits `PyegeriaModel`'s `extra='ignore'`. -Check a model's fields against the real body in `pyegeria/http clients/ +Check a model's fields against the real body in `pyegeria/http-clients/ Egeria-api-*.http` before assuming "it validated without error" means a field will actually be sent. diff --git a/pyegeria/http_client_notes.md b/pyegeria/http_client_notes.md index ab12c623..02f287be 100644 --- a/pyegeria/http_client_notes.md +++ b/pyegeria/http_client_notes.md @@ -1,6 +1,6 @@ -# Notes on pyegeria vs. the `http clients/` example collection +# Notes on pyegeria vs. the `http-clients/` example collection -The `pyegeria/http clients/*.http` files are periodically replaced wholesale with a fresh +The `pyegeria/http-clients/*.http` files are periodically replaced wholesale with a fresh copy from an Egeria distribution (`egeria-platform-*/assembly/opt/http-client-collections`), so any comments added directly inside those files get wiped out on the next copy. This file holds the same kind of note durably, outside that directory. diff --git a/scripts/README.md b/scripts/README.md index 69d61f42..758c9dbe 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -7,7 +7,7 @@ Standalone maintenance/audit scripts that aren't part of the installed package or the pytest suite. - `omvs_audit.py` — cross-checks every `_async_*` method in - `pyegeria/omvs/*.py` against its ground-truth `pyegeria/http clients/*.http` + `pyegeria/omvs/*.py` against its reference `pyegeria/http-clients/*.http` file (URL, HTTP verb, request-body class) and reports MISSING/VERB MISMATCH/PATH MISMATCH/BODY MISMATCH/ELSEWHERE/LINT findings (see `omvs_audit_report.md` at the repo root for the latest run's output). diff --git a/scripts/omvs_audit.py b/scripts/omvs_audit.py index c83e286a..b5b2fcda 100644 --- a/scripts/omvs_audit.py +++ b/scripts/omvs_audit.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Audit pyegeria's OMVS clients against the Egeria .http collections. -The .http files under ``pyegeria/http clients/`` are the ground truth for REST +The .http files under ``pyegeria/http-clients/`` are the ground truth for REST URLs, verbs, and request-body classes (see CLAUDE.md). This script reconciles every ``_async_*`` method in ``pyegeria/omvs/*.py`` against them and reports: @@ -30,7 +30,7 @@ Exit status is 1 when any confirmed defect (verb/path/body mismatch or lint) is found, so this can gate CI. -Note: ``pyegeria/http clients/`` is gitignored. It must be present locally or +Note: ``pyegeria/http-clients/`` is gitignored. It must be present locally or the audit cannot run - the script fails loudly rather than reporting a clean sheet against zero inputs. """ @@ -50,7 +50,10 @@ from collections import defaultdict from dataclasses import dataclass, field -HTTP_DIR = "pyegeria/http clients" +# The collection folder was renamed from "http clients" to "http-clients"; fall back to +# the old name for checkouts that still have it. +HTTP_DIR = next((d for d in ("pyegeria/http-clients", "pyegeria/http clients") if os.path.isdir(d)), + "pyegeria/http-clients") OMVS_DIR = "pyegeria/omvs" SERVER_CLIENT = "pyegeria/core/_server_client.py" BASE_PLATFORM_CLIENT = "pyegeria/core/_base_platform_client.py" diff --git a/tests/functional-tests/test_metadata_expert_endpoint_contract.py b/tests/functional-tests/test_metadata_expert_endpoint_contract.py index 038a1bf7..ca4a2786 100644 --- a/tests/functional-tests/test_metadata_expert_endpoint_contract.py +++ b/tests/functional-tests/test_metadata_expert_endpoint_contract.py @@ -6,7 +6,7 @@ This test compares URL templates built in `pyegeria/omvs/metadata_expert.py` with endpoint templates declared in -`pyegeria/http clients/Egeria-api-metadata-expert.http`. +`pyegeria/http-clients/Egeria-api-metadata-expert.http`. Behavior: - Path mismatches fail the test. @@ -22,7 +22,12 @@ ROOT = Path(__file__).resolve().parents[2] EXPERT_FILE = ROOT / "pyegeria" / "omvs" / "metadata_expert.py" -HTTP_CONTRACT_FILE = ROOT / "pyegeria" / "http clients" / "Egeria-api-metadata-expert.http" +# The collection folder was renamed from "http clients" to "http-clients"; fall back to the old name. +HTTP_CONTRACT_FILE = next( + (p for p in (ROOT / "pyegeria" / d / "Egeria-api-metadata-expert.http" for d in ("http-clients", "http clients")) + if p.exists()), + ROOT / "pyegeria" / "http-clients" / "Egeria-api-metadata-expert.http", +) # Optional tolerance: do not fail on query mismatches, only list them. TOLERATE_QUERY_MISMATCH = True From 1f24e4ec74e66d3c1c673bb8f4dd2f33eed423a1 Mon Sep 17 00:00:00 2001 From: Dan Wolfson Date: Sat, 10 Oct 2026 21:37:22 -0500 Subject: [PATCH 3/4] docs(issues): bring statuses up to date; log ISSUE-135 - ISSUE-121, 126, 127: released in 6.1.29. - ISSUE-117, 124, 125: reported to the Egeria team; their fix source (oak2026 fb3d6fce53) merged to Egeria main 2026-10-06 (odpi/egeria#9363), not yet re-tested. Same update note on 112 and 90 (fixed) and 102 and 108 (no fix made). - ISSUE-132: Egeria main checked 2026-10-10, no cascade change yet. - ISSUE-135 (new): 14 *_by_name wrappers required name despite accepting body; fixed in #445. Signed-off-by: Dan Wolfson --- PYEGERIA_ISSUES.md | 66 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/PYEGERIA_ISSUES.md b/PYEGERIA_ISSUES.md index 582457e8..5fb39c69 100644 --- a/PYEGERIA_ISSUES.md +++ b/PYEGERIA_ISSUES.md @@ -143,6 +143,41 @@ enough to track there too). --- +### ISSUE-135: 14 `*_by_name` wrappers required `name` even though they accept `body`, so a body-only call raised `TypeError` + +**Layer:** pyegeria · **Status:** fixed in #445 (2026-10-10), pending merge · **Found:** +2026-10-10, reported by the Resource Explorer session (`ActorManager.get_actor_profiles_by_name` on 6.1.15; still +present in 6.2.1). + +**What:** 14 of the 47 `*_by_name` wrappers declared their first argument (`name` or `filter_string`) with no +default, while also accepting `body`. A body-only call such as `get_actor_profiles_by_name(body={...})` raised +`TypeError`, while siblings such as `get_user_identities_by_name` default `name` to `None`. Affected: +`actor_manager` (actor profiles, actor roles), `asset_maker` (assets, software capabilities), `connection_maker` +(connections, connector types, endpoints), `data_designer` (data fields, data value specifications), +`data_discovery` (analysis reports), `product_manager` (governance action processes), `schema_maker` (schema types, +schema attributes) and `solution_architect` (concept model elements). + +**Workaround (before the fix):** pass a placeholder name with the body, e.g. `get_actor_profiles_by_name("*", body=...)`. +An explicit body is sent as given, and the name and the wrapper's other arguments are ignored. + +**Fix:** the first argument defaults to `None` in both the async and sync versions. `None` already meant "match +everything", like `"*"`, so name-only and name+body calls send exactly what they did before. +`_async_get_data_value_specifications_by_name` also gets the `classification_names=None` default its sync version +already had. Tests: `tests/micro-tests/test_issue_135_by_name_body_only.py`. + +**Behaviour to know (unchanged):** when a body is given, it is the whole request. The wrapper's default type filter +(e.g. `metadataElementTypeName: "ActorProfile"`) is not added to it, so a body without `metadataElementTypeName` +searches all types. + +**Related, not fixed (found while testing):** five `*_by_name` wrappers that already default `name` still mishandle +a body-only call: +- `SolutionArchitect.get_solution_roles_by_name`, `get_solution_blueprints_by_name`, `get_solution_components_by_name` + and `get_info_supply_chain_by_name` do `body["filter"] = name`, which overwrites the caller's filter (with `None` + when no name is given) and mutates the caller's dict. They also send paging as URL query parameters. +- `AutomatedCuration.get_engine_actions_by_name` rejects a missing `name` with `VALIDATION_ERROR_1`. + +--- + ### ISSUE-134: With `PYEGERIA_ENABLE_LOGGER_CATCH` on, `@dynamic_catch` turns every failure into a `None` return, indistinguishable from "nothing found" **Layer:** pyegeria · **Status:** open, not fixed · **Found:** 2026-10-10, reported by the Resource Explorer @@ -190,7 +225,7 @@ three dead `subComponents` fallbacks are removed. Micro-tests in `tests/micro-te ### ISSUE-132: `DeleteElementRequestBody` serializes the cascade flag as `cascadeDelete`; Egeria's field is `cascadedDelete` and unknown fields are ignored, so no pyegeria cascade delete has ever cascaded -**Layer:** pyegeria · **Status:** open, on hold: an Egeria fix for cascade delete is coming (owner, 2026-10-10). Wait +**Layer:** pyegeria · **Status:** open, on hold: an Egeria fix for cascade delete is coming (owner, 2026-10-10). Egeria `main` checked 2026-10-10 (head `af400039c2`, 2026-10-06): no cascade change yet. Wait for it, live-test cascade delete against it, then decide the pyegeria change; the fix below may change once the Egeria side lands. Confirmed from Egeria source, not yet live-tested · **Found:** 2026-10-10, while checking ISSUE-129's server contract against Egeria source instead of the `.http` files. @@ -319,8 +354,7 @@ overwriting would silently change callers who set it in the body. ### ISSUE-117: Cascade delete that takes the soft-delete (Memento) path fails partway with `OMAG-REPOSITORY-HANDLER-400-010` unless `forLineage=true` — leaves the asset live and an anchored element already soft-deleted -**Layer:** Egeria Server · **Status:** open, workaround known, not yet -reported upstream · **Found:** 2026-10-02, live test of Dr.Egeria's +**Layer:** Egeria Server · **Status:** open, workaround known; reported to the Egeria team (response 2026-10-05); Egeria fix merged to Egeria `main` 2026-10-06 (odpi/egeria#9363), not yet re-tested on a platform built from it · **Found:** 2026-10-02, live test of Dr.Egeria's Automation family (`Initiate Subscription` / `Cancel Subscription`, PR #414), cleaning up the throwaway destination data set afterwards. @@ -380,6 +414,8 @@ reproduction is to run a subscription process with a fresh asset as **Egeria team response, relayed 2026-10-05 (source `oak2026` fb3d6fce53; **fixes are in two unmerged PRs, so no build contains them, and nothing was tested against a live platform**):** valid. The cause is the `qualifiedName` rename *after* the Memento classification in `archiveBeanInRepository` (the re-read uses `forLineage=false`, so the Memento'd element is invisible and the first member, the Endpoint, fails 400-010). Also a silent defect: the top-level archived asset is never renamed. Fix: a two-pass archive (collect, then archive deepest-first, renaming before the Memento), internal reads with `forLineage=true`, the top-level asset renamed, and retries that finish a half-done archive. +**Update 2026-10-10:** the `oak2026` source (`fb3d6fce53`) is now in Egeria `main`, merged 2026-10-06 (odpi/egeria#9363), so a platform built from current `main` has the fix. Not yet re-tested. + --- ### ISSUE-112: `AutomatedCurationRESTServices.saveClientSideSecret`/`deleteClientSideSecret` return a plain success `VoidResponse` when the resolved connector isn't a `YAMLSecretsFileConnector` — no error, no write, no indication anything was skipped @@ -460,6 +496,8 @@ downstream investigation. **Egeria team response, relayed 2026-10-05 (source `oak2026` fb3d6fce53; **fixes are in two unmerged PRs, so no build contains them, and nothing was tested against a live platform**):** valid. A store whose connector cannot write secrets collections will get a 400 `OMAG-COMMON-400-034` naming the operation, asset and connector class; only `YAMLSecretsFileConnector` supports save and delete (`SecretsStoreConnector` gains `isSecretsCollectionUpdateSupported()`, others reject with `OCF-CONNECTOR-400-012`). +**Update 2026-10-10:** the `oak2026` source (`fb3d6fce53`) is now in Egeria `main`, merged 2026-10-06 (odpi/egeria#9363), so a platform built from current `main` has the fix. Not yet re-tested. + --- ### ISSUE-102: `MemberDataField.minCardinality` silently persists as `maxCardinality`'s value regardless of what's actually sent — server-side, confirmed via a raw request bypassing every pyegeria/Dr.Egeria layer @@ -544,6 +582,8 @@ fixable in this repo for that specific symptom. **Egeria team response, relayed 2026-10-05 (source `oak2026` fb3d6fce53; **fixes are in two unmerged PRs, so no build contains them, and nothing was tested against a live platform**):** NOT reproduced in Egeria (builder and converter round trip returns `position=3, min=1, max=5`; lower layers not traced). They asked for the exact request, the raw response and the read-back endpoint. Ours: request `NewRelationshipRequestBody` with `properties` `{class: MemberDataFieldProperties, position: 3, minCardinality: 1, maxCardinality: 5}` via `DataDesigner._async_link_member_data_field`; the original raw response was not captured. On the 2026-10-05 rebuilt platform it does not reproduce for us either (see the re-test above). +**Update 2026-10-10:** the `oak2026` source (`fb3d6fce53`) the team examined is now in Egeria `main` (merged 2026-10-06, odpi/egeria#9363). No fix was made for this issue; the team's questions above still stand. + --- ### ISSUE-95: No catalog template registered for the "Apache Kafka Server" technology type — `Create Kafka Server Element` (Asset Maker) fails with a 400 on `qs-view-server` @@ -654,6 +694,8 @@ read. Full draft: trellis session scratch `egeria-issue-engine-host-403-loop.md` **Egeria team response, relayed 2026-10-05 (source `oak2026` fb3d6fce53; **fixes are in two unmerged PRs, so no build contains them, and nothing was tested against a live platform**):** valid. `startMissedEngineActions` runs every 5 s per engine; `getActiveEngineActions` reads every action target and requester, so one target anchored to an element the engine's user cannot read (zone) throws, the outer `catch` ends the sweep, and newest-first paging brings the bad page back. The sweep is also unfiltered by engine, a likely contributor to the idle CPU (unmeasured). Fixes: unreadable actions filtered out, one-time error logging, anchor message argument order fixed, an engine-scoped sweep (new `.../governance-engines/{guid}/approved-engine-actions`), and anchor-refused search results filtered instead of logged as unauthorized. +**Update 2026-10-10:** the `oak2026` source (`fb3d6fce53`) is now in Egeria `main`, merged 2026-10-06 (odpi/egeria#9363), so a platform built from current `main` has the fix. Not yet re-tested. + --- ### ISSUE-38 (PY-18): `count_relationships_between_elements("Exception")` (276) disagrees with `ClassificationExplorer.get_relationships("Exception")` (55) @@ -1355,10 +1397,12 @@ into the entry now, so it isn't rediscovered from scratch later. **Egeria team response, relayed 2026-10-05 (source `oak2026` fb3d6fce53; **fixes are in two unmerged PRs, so no build contains them, and nothing was tested against a live platform**):** not validated; no cache found. Best lead: a client clock ahead of the server's, with `effectiveFrom` set from it (related-element queries silently hide a relationship whose `effectiveFrom` is later than the server's "now"). They need, for one link still missing at ~12 minutes: its `effectiveFrom` and `createTime`, the server clock then, and whether the loader sets `effectiveFrom`. **Our facts:** pyegeria sets no `effectiveFrom`/`effectiveTo`/`effectiveTime` by default (model defaults are `None`; no clock call is tied to any `effective*` field; Dr.Egeria forwards an "Effective From" only if typed). Host and container clocks agree within 1 s on 2026-10-05; the 2026-09-20 load's values are unavailable. +**Update 2026-10-10:** the `oak2026` source (`fb3d6fce53`) the team examined is now in Egeria `main` (merged 2026-10-06, odpi/egeria#9363). No fix was made for this issue; the team's questions above still stand. + ### ISSUE-126: `ProductManager` and `DigitalBusiness` never set `collection_command_root`, so every inherited `CollectionManager` method that uses it raises `AttributeError` -**Layer:** pyegeria · **Status:** fixed, merged to `main` in #429 (`68279835`) · **Found:** 2026-10-05, live cleanup of a throwaway data contract (PR #427's +**Layer:** pyegeria · **Status:** fixed in #429 (`68279835`), released in 6.1.29 · **Found:** 2026-10-05, live cleanup of a throwaway data contract (PR #427's live check). **Fix + scope (2026-10-05):** both constructors now call `CollectionManager.__init__`, as `GlossaryManager` @@ -1383,7 +1427,7 @@ pm.delete_collection(guid, cascade=True) ### ISSUE-127: `CollectionManager.delete_collection(cascade=True)` silently never sends `cascadeDelete` -- same shape as ISSUE-62 -**Layer:** pyegeria · **Status:** partly fixed in #429 (`68279835`); cascade still blocked by ISSUE-132 · **Found:** 2026-10-05, found by capturing the request body while diagnosing a +**Layer:** pyegeria · **Status:** partly fixed in #429 (`68279835`), released in 6.1.29; cascade still blocked by ISSUE-132 · **Found:** 2026-10-05, found by capturing the request body while diagnosing a failed cleanup. **Fix + scope (2026-10-05):** a scan of all 42 callers of `_async_delete_element_request` found exactly two @@ -1453,7 +1497,7 @@ queries, rendering "Not measured" instead of `0` (odpi/egeria-workspaces ### ISSUE-124: `updateTypeDef` (Metadata Expert `open-metadata-types/update`) can never succeed -- the server builds the patch without `updatedBy`, which the repository services require -**Layer:** Egeria Server (not pyegeria) · **Status:** open, not yet reported upstream · **Found:** +**Layer:** Egeria Server (not pyegeria) · **Status:** open; reported to the Egeria team (response 2026-10-05); Egeria fix merged to Egeria `main` 2026-10-06 (odpi/egeria#9363), not yet re-tested on a platform built from it · **Found:** 2026-10-05, live verification of `MetadataExpert.update_type_def` (PR #428). **What:** posting a valid `OpenMetadataTypeDefPatch` (type added through the API moments earlier, @@ -1480,11 +1524,13 @@ then deleted and verified gone. **Confirmed still present on the rebuilt platfor **Egeria team response, relayed 2026-10-05 (source `oak2026` fb3d6fce53; **fixes are in two unmerged PRs, so no build contains them, and nothing was tested against a live platform**):** valid, and `updateTime` was missing as well as `updatedBy` (our analysis was right but incomplete). `getTypeDefPatch` will take the user and set both; new `DynamicTypeFVT`. +**Update 2026-10-10:** the `oak2026` source (`fb3d6fce53`) is now in Egeria `main`, merged 2026-10-06 (odpi/egeria#9363), so a platform built from current `main` has the fix. Not yet re-tested. + --- ### ISSUE-125: `deleteEnumDef` answers 500 "unknown TypeDef" for an enum the server lists -- an enum added through the API cannot be removed -**Layer:** Egeria Server (not pyegeria) · **Status:** open, not yet reported upstream · **Found:** +**Layer:** Egeria Server (not pyegeria) · **Status:** open; reported to the Egeria team (response 2026-10-05); Egeria fix merged to Egeria `main` 2026-10-06 (odpi/egeria#9363), not yet re-tested on a platform built from it · **Found:** 2026-10-05, live verification of `MetadataExpert.delete_enum_def` (PR #428). **Left a stray type behind.** **What:** after `add_enum_def` (returned GUID `118441be-...`), `add_type_def` of an entity type using it, and a @@ -1513,6 +1559,8 @@ explains: the failure does not depend on what was loaded at startup. **Egeria team response, relayed 2026-10-05 (source `oak2026` fb3d6fce53; **fixes are in two unmerged PRs, so no build contains them, and nothing was tested against a live platform**):** valid; fix in source on `oak2026`, pending merge to `main`. +**Update 2026-10-10:** the `oak2026` source (`fb3d6fce53`) is now in Egeria `main`, merged 2026-10-06 (odpi/egeria#9363), so a platform built from current `main` has the fix. Not yet re-tested. + --- ### ISSUE-122: `AssetMaker.get_catalog_targets` / `get_catalog_target` send `metadataElementTypeName="CatalogTarget"` (a relationship type) — server rejects with OMAG-COMMON-400-019, surfaced as SERVER_ERROR_500 @@ -1588,9 +1636,7 @@ lacks `deleteMethod`, `permittedSynchronization`, `connectionName` and ### ISSUE-121: `core/mcp_adapter.py` writes the caller's user name and plaintext password to stderr and the log on every report call -**Layer:** pyegeria (credential leak in diagnostics) · **Status:** fixed on -branch `fix/issue-121-mcp-adapter-no-password-logging` (2026-10-05), pending -PR/merge · **Found:** 2026-10-03, read-only security sweep by the Resource +**Layer:** pyegeria (credential leak in diagnostics) · **Status:** fixed in #425, released in 6.1.29 · **Found:** 2026-10-03, read-only security sweep by the Resource Explorer coordinator session; no value was read or recorded. **Correction to the original report (2026-10-05, from reading the code):** From df70298ab31ec0628068a26e7d3d12d9abeec166 Mon Sep 17 00:00:00 2001 From: Dan Wolfson Date: Sat, 10 Oct 2026 21:46:09 -0500 Subject: [PATCH 4/4] docs(issues): ISSUE-135's remaining body-only gaps are fixed in #445 too Signed-off-by: Dan Wolfson --- PYEGERIA_ISSUES.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/PYEGERIA_ISSUES.md b/PYEGERIA_ISSUES.md index 5fb39c69..a402d324 100644 --- a/PYEGERIA_ISSUES.md +++ b/PYEGERIA_ISSUES.md @@ -169,12 +169,19 @@ already had. Tests: `tests/micro-tests/test_issue_135_by_name_body_only.py`. (e.g. `metadataElementTypeName: "ActorProfile"`) is not added to it, so a body without `metadataElementTypeName` searches all types. -**Related, not fixed (found while testing):** five `*_by_name` wrappers that already default `name` still mishandle -a body-only call: -- `SolutionArchitect.get_solution_roles_by_name`, `get_solution_blueprints_by_name`, `get_solution_components_by_name` - and `get_info_supply_chain_by_name` do `body["filter"] = name`, which overwrites the caller's filter (with `None` - when no name is given) and mutates the caller's dict. They also send paging as URL query parameters. -- `AutomatedCuration.get_engine_actions_by_name` rejects a missing `name` with `VALIDATION_ERROR_1`. +**Also fixed in #445 (found while testing):** five `*_by_name` wrappers that already defaulted `name` still +mishandled a body-only call: +- `SolutionArchitect.get_info_supply_chain_by_name`, `get_solution_blueprints_by_name`, + `get_solution_components_by_name` and `get_solution_roles_by_name` did `body["filter"] = name`, which overwrote + the caller's filter with `None` on a body-only call and mutated the caller's dict. They now copy the body and set + `filter` only when a name is given (a given name still wins). They also sent paging as URL query parameters, which + Egeria ignores: in Egeria source (`SolutionArchitectResource.java`, `ActorManagerResource.java`) the only query + parameter on these endpoints is `addImplementation`, on information supply chains. Paging now goes in the body, + without overriding values the body sets. +- `AutomatedCuration.get_engine_actions_by_name` rejected a missing `name` (`VALIDATION_ERROR_1`) even with a body, + contrary to its docstring. It now requires a name only when no body is given. It also passed its type filter under + the old `metadata_element_type` key; it was a 14th ISSUE-131 case that the original grep missed (single quotes), + already covered by the 6.2.1 helper fix, and now uses the canonical key. ---