Skip to content

feat(platform): custom_metadata checksum concurrency control + enrich_sdk_metadata toggle [PYSDK-130][PYSDK-147]#691

Merged
arne-aignx merged 5 commits into
mainfrom
feat/PYSDK-130-147-custom-metadata
Jul 9, 2026
Merged

feat(platform): custom_metadata checksum concurrency control + enrich_sdk_metadata toggle [PYSDK-130][PYSDK-147]#691
arne-aignx merged 5 commits into
mainfrom
feat/PYSDK-130-147-custom-metadata

Conversation

@arne-aignx

@arne-aignx arne-aignx commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

🛡️ Implements PYSDK-130 and PYSDK-147 (both tracked under VPTHP-44) following CC-SOP-01 Change Control, part of our ISO 13485-certified QMS | Ketryx Project

Supersedes the stale draft #632 (rebased onto current main).

Summary

Two logical commits extending custom-metadata updates on Run.update_custom_metadata() / Run.update_item_custom_metadata() (platform), their four service wrappers, and the update-metadata / update-item-metadata / dump-metadata / dump-item-metadata CLI commands. Both parameters are keyword-only and fully backward compatible.

[PYSDK-130] Optimistic concurrency control

  • Adds optional custom_metadata_checksum: str | None to both platform methods, forwarded verbatim on CustomMetadataUpdateRequest. The server rejects a stale write with HTTP 412.
  • Introduces ConcurrencyConflictError(ValueError) in platform/_exceptions.py (exported from aignostics.platform); the service layer maps HTTP 412 → ConcurrencyConflictError. Subclassing ValueError keeps existing except ValueError callers working.
  • CLI: --checksum on the update commands (exit code 3 on conflict); --show-checksum on the dump commands emits {"custom_metadata": {...}, "custom_metadata_checksum": "..."}.
  • GUI metadata editor forwards the checksum and surfaces the conflict instead of silently overwriting.

[PYSDK-147] enrich_sdk_metadata toggle

  • Adds optional enrich_sdk_metadata: bool = True to both platform methods. Default preserves current behaviour (merge auto-generated SDK tracking context into the sdk field + schema-validate).
  • With enrich_sdk_metadata=False, the SDK skips both the merge and validation and forwards custom_metadata verbatim — enabling round-tripping a previously read sdk field unchanged.
  • CLI: --enrich-sdk-metadata / --no-enrich-sdk-metadata on both update commands.

Combined read → modify → write loop

aignostics application run dump-metadata RUN_ID --show-checksum --pretty
# edit the JSON locally
aignostics application run update-metadata RUN_ID "$(cat edited.json)" \
  --checksum <checksum-from-step-1> --no-enrich-sdk-metadata

Test plan

  • make lint (ruff, pyright, mypy) — clean
  • uv run pytest -m unit tests/aignostics/application tests/aignostics/platform — 590 passed
  • CI matrix green

🤖 Generated with Claude Code

arne-aignx and others added 2 commits July 9, 2026 08:12
…rror [PYSDK-130]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…YSDK-147]

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@arne-aignx arne-aignx requested a review from a team as a code owner July 9, 2026 07:11
@arne-aignx arne-aignx added the skip:test:long_running Skip long-running tests (≥5min) label Jul 9, 2026
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.23077% with 3 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...application/_gui/_page_application_run_describe.py 33.33% 2 Missing ⚠️
src/aignostics/application/_service.py 90.90% 0 Missing and 1 partial ⚠️

❗ There is a different number of reports uploaded between BASE (baa7e91) and HEAD (3f1a6a4). Click for more details.

HEAD has 8 uploads less than BASE
Flag BASE (baa7e91) HEAD (3f1a6a4)
9 1
Files with missing lines Coverage Δ
src/aignostics/application/_cli.py 75.45% <100.00%> (-4.19%) ⬇️
src/aignostics/platform/__init__.py 100.00% <100.00%> (ø)
src/aignostics/platform/_exceptions.py 100.00% <100.00%> (ø)
src/aignostics/platform/resources/runs.py 84.82% <100.00%> (-0.59%) ⬇️
src/aignostics/application/_service.py 55.61% <90.90%> (-10.44%) ⬇️
...application/_gui/_page_application_run_describe.py 35.72% <33.33%> (-34.87%) ⬇️

... and 20 files with indirect coverage changes

arne-aignx and others added 3 commits July 9, 2026 10:15
…a [PYSDK-130][PYSDK-147]

Update the platform and application Software Item Specs to document the new
update_custom_metadata / update_item_custom_metadata parameters
(custom_metadata_checksum, enrich_sdk_metadata), the run dump/update-metadata
CLI flags, and ConcurrencyConflictError. Keeps the SIS in sync with the
implementation per CC-SOP-01.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eability [PYSDK-130][PYSDK-147]

Author a fresh software requirement SWR-APPLICATION-2-17 (Update Run and Item
Custom Metadata After Creation, parent SHR-APPLICATION-2) covering post-creation
custom-metadata updates with optimistic-concurrency checksum and the
enrich_sdk_metadata toggle.

Add test case TC-APPLICATION-CLI-07 verifying the behaviour and wire full
traceability:
- SIS -> SWR: itemFulfills SWR-APPLICATION-2-17 in SPEC-APPLICATION-SERVICE and
  SPEC_PLATFORM_SERVICE
- SWR -> SHR: itemHasParent SHR-APPLICATION-2
- TC -> SIS/SWR: @tests tags on every scenario

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…7 scenarios [PYSDK-130][PYSDK-147]

Add record_property("tested-item-id", ...) traceability from the pytest tests
to the TC-APPLICATION-CLI-07 test-case scenarios, SWR-APPLICATION-2-17, and the
platform/application SIS.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@arne-aignx arne-aignx force-pushed the feat/PYSDK-130-147-custom-metadata branch from 7bd6b68 to 3f1a6a4 Compare July 9, 2026 08:47
@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@arne-aignx arne-aignx merged commit bebc642 into main Jul 9, 2026
40 of 45 checks passed
@arne-aignx arne-aignx deleted the feat/PYSDK-130-147-custom-metadata branch July 9, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip:test:long_running Skip long-running tests (≥5min)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants