Skip to content

feat: convention contract — authored config/limits, release as pure artifact - #170

Merged
rorybyrne merged 1 commit into
mainfrom
feat/convention-contract-authored-config
Jul 22, 2026
Merged

feat: convention contract — authored config/limits, release as pure artifact#170
rorybyrne merged 1 commit into
mainfrom
feat/convention-contract-authored-config

Conversation

@rorybyrne

Copy link
Copy Markdown
Contributor

What

Restructure the convention deploy contract so a component's authored config/limits live on the component and its build release is a pure artifact {image, digest, source_ref}. Make the ingester symmetric with hooks (nested release).

  • DeployConventionRelease{image, digest, source_ref} (drops config/limits).
  • DeployConventionHook gains config/limits.
  • New DeployConventionIngester — symmetric, with a nested release.

Internals unchanged (by design)

This is an edge-DTO-only change. The internal OciConfig/IngesterDefinition, the versioned immutable HookRelease, the hooks/hook_releases tables, and the OOM memory-escalation path are all untouched: to_deploy()/to_definition() re-gather authored config/limits (from the component) with the built image (from the release) into the existing runtime. No migration. Adds an optional source_ref to IngesterDefinition for build-provenance parity with hooks.

Contract coupling

Pairs with the osa-py producer change. Breaking pair — deploy together (every deploy-edge DTO is extra="forbid", so old body ⇄ new server both 422).

Tests

1558 unit+contract pass. Added test_deploy_convention_dto.py (12 tests: pure release, rejects config/limits in release, re-gather mapping, ingester symmetry, optional-field omission). Verified an osa deploy body and the cloud-path (release-less manifest + injected releases) both validate against the new DTO.

🤖 Generated with Claude Code

…rtifact

Move a hook's authored config/limits out of its build `release` and onto
the hook itself; `release` becomes a pure build artifact {image, digest,
source_ref}. Make the ingester symmetric with hooks (nested `release`).

Edge DTOs only — the internal OciConfig/IngesterDefinition and the
versioned HookRelease are unchanged: to_deploy()/to_definition() re-gather
authored config/limits (from the component) with the built image (from the
release) into the existing runtime. No migration; OOM memory-escalation
untouched. Adds an optional source_ref to IngesterDefinition for build
provenance parity with hooks.

Pairs with the osa-py producer change — deploy them together.

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

Copy link
Copy Markdown
Contributor Author

⚠️ Breaking pair with the osa-py producer change: opensciencearchive/osa-py#13. Deploy together. (Cloud side: opensciencearchive/cloud#71.)

@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Complexity Health
. 83% 0
application 100% 0
application.api 100% 0
application.api.mcp 80% 0
application.api.mcp.tools 89% 0
application.api.rest 76% 0
application.api.v1 88% 0
application.api.v1.routes 68% 0
application.api.v1.routes.data 93% 0
application.api.v1.routes.data.serializers 99% 0
application.event 100% 0
application.workflow 95% 0
domain 100% 0
domain.auth 100% 0
domain.auth.command 90% 0
domain.auth.event 100% 0
domain.auth.model 93% 0
domain.auth.port 99% 0
domain.auth.query 93% 0
domain.auth.service 91% 0
domain.auth.util 100% 0
domain.auth.util.di 79% 0
domain.curation 100% 0
domain.curation.adapter 100% 0
domain.curation.command 100% 0
domain.curation.event 100% 0
domain.curation.model 100% 0
domain.curation.port 100% 0
domain.curation.query 100% 0
domain.curation.service 100% 0
domain.data 100% 0
domain.data.model 97% 0
domain.data.port 100% 0
domain.data.query 93% 0
domain.data.service 84% 0
domain.data.util 100% 0
domain.data.util.di 89% 0
domain.deposition 100% 0
domain.deposition.adapter 100% 0
domain.deposition.command 91% 0
domain.deposition.event 100% 0
domain.deposition.model 94% 0
domain.deposition.port 100% 0
domain.deposition.query 86% 0
domain.deposition.service 97% 0
domain.deposition.util.di 94% 0
domain.feature 100% 0
domain.feature.event 0% 0
domain.feature.model 0% 0
domain.feature.port 100% 0
domain.feature.service 97% 0
domain.feature.util 100% 0
domain.feature.util.di 100% 0
domain.ingest 100% 0
domain.ingest.command 79% 0
domain.ingest.event 100% 0
domain.ingest.model 100% 0
domain.ingest.port 100% 0
domain.ingest.query 100% 0
domain.ingest.service 99% 0
domain.metadata 100% 0
domain.metadata.event 100% 0
domain.metadata.handler 100% 0
domain.metadata.model 0% 0
domain.metadata.port 100% 0
domain.metadata.service 93% 0
domain.metadata.util 100% 0
domain.metadata.util.di 100% 0
domain.record 100% 0
domain.record.adapter 100% 0
domain.record.command 100% 0
domain.record.event 100% 0
domain.record.model 100% 0
domain.record.port 100% 0
domain.record.query 100% 0
domain.record.service 66% 0
domain.semantics 100% 0
domain.semantics.command 94% 0
domain.semantics.event 100% 0
domain.semantics.handler 100% 0
domain.semantics.model 100% 0
domain.semantics.port 100% 0
domain.semantics.query 90% 0
domain.semantics.service 100% 0
domain.semantics.util 100% 0
domain.semantics.util.di 93% 0
domain.shared 94% 0
domain.shared.authorization 86% 0
domain.shared.model 92% 0
domain.shared.port 100% 0
domain.validation 100% 0
domain.validation.adapter 100% 0
domain.validation.command 98% 0
domain.validation.event 100% 0
domain.validation.model 97% 0
domain.validation.port 100% 0
domain.validation.query 100% 0
domain.validation.service 91% 0
domain.validation.util.di 94% 0
infrastructure 80% 0
infrastructure.auth 56% 0
infrastructure.data 35% 0
infrastructure.event 79% 0
infrastructure.http 92% 0
infrastructure.ingest 85% 0
infrastructure.k8s 77% 0
infrastructure.messaging 100% 0
infrastructure.oci 55% 0
infrastructure.persistence 69% 0
infrastructure.persistence.adapter 78% 0
infrastructure.persistence.mappers 62% 0
infrastructure.persistence.repository 38% 0
infrastructure.s3 39% 0
infrastructure.storage 100% 0
infrastructure.telemetry 100% 0
sdk 100% 0
util 100% 0
util.di 71% 0
Summary 80% (9690 / 12077) 0

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR separates authored component settings from built release artifacts. The main changes are:

  • Moves hook config and limits outside the nested release.
  • Adds a symmetric deploy DTO with a nested ingester release.
  • Reassembles edge DTOs into the existing internal runtime models.
  • Adds optional ingester build provenance through source_ref.
  • Adds contract tests for validation, defaults, and mapping.

Confidence Score: 5/5

This looks safe to merge with the paired producer deployment.

  • No blocking issues found in the changed code.
  • Hook and ingester fields are preserved when converted to internal models.
  • Existing stored ingesters remain compatible because source_ref is optional.
  • The old wire format is intentionally rejected and the rollout dependency is documented.

T-Rex T-Rex Logs

What T-Rex did

  • The initial validation on HEAD^ rejected the component-level hook config/limits and nested ingester release fields.
  • The updated HEAD accepted and mapped the representative payload, and the probe ended with PROBE_RESULT=PASS.
  • The targeted pytest run completed with 17 passed in 0.23s.
  • Artifacts from the run were captured to support verification of the validation and test results.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
server/osa/domain/deposition/command/create_convention.py Defines the revised hook and ingester edge DTOs and maps them into the unchanged internal models.
server/osa/domain/shared/model/source.py Adds optional source_ref provenance to ingester definitions while preserving old stored data.
server/tests/unit/domain/deposition/test_deploy_convention_dto.py Covers strict release validation, component mapping, defaults, and optional fields.
server/tests/unit/domain/deposition/test_deploy_convention_handler.py Updates the handler fixture to use hook-level configuration.
server/uv.lock Updates the editable project version to 0.0.6.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
P[Deploy payload] --> H[Hook DTO]
P --> I[Ingester DTO]
H --> HC[Authored config and limits]
H --> HR[Release artifact]
HC --> HD[HookDeploy]
HR --> HD
I --> IC[Authored config, limits, schedule]
I --> IR[Release artifact]
IC --> ID[IngesterDefinition]
IR --> ID
HD --> S[Convention service]
ID --> S
Loading

Reviews (1): Last reviewed commit: "feat: convention contract — authored con..." | Re-trigger Greptile

@rorybyrne
rorybyrne merged commit 99c92a0 into main Jul 22, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant