From 9db0f222eb1a3ab1328bc63b6fae1e6148e7a314 Mon Sep 17 00:00:00 2001 From: Yernat Yestekov <2068106+doublewhy@users.noreply.github.com> Date: Sat, 10 Oct 2026 11:44:06 -0700 Subject: [PATCH 1/2] fix(kits): release four kits with an open compute substrate application-api-service, postgresql-database, reverse-proxy-api-gateway and smtp-imap-mail-service each get a 1.1.0 release whose compute-substrate constraint is posture: open with no domain, so the backend chooses the substrate (#413). Their 1.0.0 releases, which declare an exact virtual-machine substrate, stay published unchanged. - Each 1.1.0 release is cut from 1.0.0: version, released_at and posture: open are the only authored differences, and README.md, assets/integration.md, assets/seed.yaml and tests/composition.yaml are byte-identical to 1.0.0. - associated-artifacts.json is derived from the 1.0.0 manifest: manifest_version, created_at and source, checksums and sizes from the new bytes, the canonical SDL parent digest and the set digest. load_kit_release() verifies each release. - tests/test_kit_compute_substrate.py checks that every compute node of the four newest releases declares an open compute substrate, and that planning them with both declared parameter sets, where no virtual machine is offered, reports no compute-substrate diagnostic. RAES 6.0.1 still reports realization.authority-bound-unavailable for each kit's runtime-collection parameter (OpenRAE/rae#1481), so the test asserts that the plan is not valid and that this is its only diagnostic. - tests/test_published_kits.py counts releases instead of kits (EXPECTED_RELEASE_COUNT = 50 for 46 kits) and composes each module at its own version. The manual author walkthrough expects 50 entries. Refs #413 --- .../1.1.0/README.md | 7 + .../1.1.0/assets/integration.md | 15 ++ .../1.1.0/assets/seed.yaml | 22 ++ .../1.1.0/associated-artifacts.json | 113 ++++++++++ .../1.1.0/kit.yaml | 49 +++++ .../1.1.0/module.sdl.yaml | 110 ++++++++++ .../1.1.0/tests/composition.yaml | 9 + .../1.1.0/README.md | 7 + .../1.1.0/assets/integration.md | 15 ++ .../1.1.0/assets/seed.yaml | 25 +++ .../1.1.0/associated-artifacts.json | 113 ++++++++++ .../1.1.0/kit.yaml | 49 +++++ .../1.1.0/module.sdl.yaml | 132 ++++++++++++ .../1.1.0/tests/composition.yaml | 9 + .../1.1.0/README.md | 7 + .../1.1.0/assets/integration.md | 15 ++ .../1.1.0/assets/seed.yaml | 21 ++ .../1.1.0/associated-artifacts.json | 113 ++++++++++ .../1.1.0/kit.yaml | 53 +++++ .../1.1.0/module.sdl.yaml | 114 ++++++++++ .../1.1.0/tests/composition.yaml | 9 + .../1.1.0/README.md | 7 + .../1.1.0/assets/integration.md | 15 ++ .../1.1.0/assets/seed.yaml | 22 ++ .../1.1.0/associated-artifacts.json | 113 ++++++++++ .../1.1.0/kit.yaml | 49 +++++ .../1.1.0/module.sdl.yaml | 117 +++++++++++ .../1.1.0/tests/composition.yaml | 9 + tests/test_kit_compute_substrate.py | 194 ++++++++++++++++++ tests/test_published_kits.py | 6 +- tests_integration/kit_author_walkthrough.py | 2 +- 31 files changed, 1537 insertions(+), 4 deletions(-) create mode 100644 kits/infrastructure.application-api-service/1.1.0/README.md create mode 100644 kits/infrastructure.application-api-service/1.1.0/assets/integration.md create mode 100644 kits/infrastructure.application-api-service/1.1.0/assets/seed.yaml create mode 100644 kits/infrastructure.application-api-service/1.1.0/associated-artifacts.json create mode 100644 kits/infrastructure.application-api-service/1.1.0/kit.yaml create mode 100644 kits/infrastructure.application-api-service/1.1.0/module.sdl.yaml create mode 100644 kits/infrastructure.application-api-service/1.1.0/tests/composition.yaml create mode 100644 kits/infrastructure.postgresql-database/1.1.0/README.md create mode 100644 kits/infrastructure.postgresql-database/1.1.0/assets/integration.md create mode 100644 kits/infrastructure.postgresql-database/1.1.0/assets/seed.yaml create mode 100644 kits/infrastructure.postgresql-database/1.1.0/associated-artifacts.json create mode 100644 kits/infrastructure.postgresql-database/1.1.0/kit.yaml create mode 100644 kits/infrastructure.postgresql-database/1.1.0/module.sdl.yaml create mode 100644 kits/infrastructure.postgresql-database/1.1.0/tests/composition.yaml create mode 100644 kits/infrastructure.reverse-proxy-api-gateway/1.1.0/README.md create mode 100644 kits/infrastructure.reverse-proxy-api-gateway/1.1.0/assets/integration.md create mode 100644 kits/infrastructure.reverse-proxy-api-gateway/1.1.0/assets/seed.yaml create mode 100644 kits/infrastructure.reverse-proxy-api-gateway/1.1.0/associated-artifacts.json create mode 100644 kits/infrastructure.reverse-proxy-api-gateway/1.1.0/kit.yaml create mode 100644 kits/infrastructure.reverse-proxy-api-gateway/1.1.0/module.sdl.yaml create mode 100644 kits/infrastructure.reverse-proxy-api-gateway/1.1.0/tests/composition.yaml create mode 100644 kits/infrastructure.smtp-imap-mail-service/1.1.0/README.md create mode 100644 kits/infrastructure.smtp-imap-mail-service/1.1.0/assets/integration.md create mode 100644 kits/infrastructure.smtp-imap-mail-service/1.1.0/assets/seed.yaml create mode 100644 kits/infrastructure.smtp-imap-mail-service/1.1.0/associated-artifacts.json create mode 100644 kits/infrastructure.smtp-imap-mail-service/1.1.0/kit.yaml create mode 100644 kits/infrastructure.smtp-imap-mail-service/1.1.0/module.sdl.yaml create mode 100644 kits/infrastructure.smtp-imap-mail-service/1.1.0/tests/composition.yaml create mode 100644 tests/test_kit_compute_substrate.py diff --git a/kits/infrastructure.application-api-service/1.1.0/README.md b/kits/infrastructure.application-api-service/1.1.0/README.md new file mode 100644 index 0000000..7675b72 --- /dev/null +++ b/kits/infrastructure.application-api-service/1.1.0/README.md @@ -0,0 +1,7 @@ +# Application/API service + +Reusable application/api service with domain-specific configuration, declared service surfaces, seeded objects, and pack-local integration material. + +The release includes a RAES module, explicit service and identity surfaces, benign seed inventory, planning estimates, component-inventory inputs, integration guidance, and composition tests. + +It is authoring content, not a runtime plugin, scenario narrative, backend qualification, or evidence claim. diff --git a/kits/infrastructure.application-api-service/1.1.0/assets/integration.md b/kits/infrastructure.application-api-service/1.1.0/assets/integration.md new file mode 100644 index 0000000..fdf6a2f --- /dev/null +++ b/kits/infrastructure.application-api-service/1.1.0/assets/integration.md @@ -0,0 +1,15 @@ +# Application/API service integration material + +Author parameter: `api_base_path` (default `/api`). + +## Exported RAES declarations + +- `nodes.application` +- `content.seed_inventory` +- `accounts.application_service` + +## Composition notes + +- No mandatory external authoring prerequisite; connect exported surfaces at the pack composition root as needed. +- Keep credentials and runtime-selected endpoints outside kit parameters and seed assets. +- Validate the completed ordinary pack after adding pack-level relationships. diff --git a/kits/infrastructure.application-api-service/1.1.0/assets/seed.yaml b/kits/infrastructure.application-api-service/1.1.0/assets/seed.yaml new file mode 100644 index 0000000..17c4ff0 --- /dev/null +++ b/kits/infrastructure.application-api-service/1.1.0/assets/seed.yaml @@ -0,0 +1,22 @@ +schema_version: environment-kit-seed/v1 +kit: infrastructure.application-api-service +configuration: + api_base_path: /api + deployment_profile: standard + service_label: application-api-service +declared_objects: +- id: api_routes + kind: infrastructure-seed + sensitivity: non-secret +- id: health_route + kind: infrastructure-seed + sensitivity: non-secret +- id: seed_records + kind: infrastructure-seed + sensitivity: non-secret +- id: service_account + kind: infrastructure-seed + sensitivity: non-secret +integration_requirements: +- No mandatory external authoring prerequisite; connect exported surfaces at the pack + composition root as needed. diff --git a/kits/infrastructure.application-api-service/1.1.0/associated-artifacts.json b/kits/infrastructure.application-api-service/1.1.0/associated-artifacts.json new file mode 100644 index 0000000..5729189 --- /dev/null +++ b/kits/infrastructure.application-api-service/1.1.0/associated-artifacts.json @@ -0,0 +1,113 @@ +{ + "schema_version": "associated-artifact-manifest/v1", + "manifest_id": "infrastructure.application-api-service-associated-artifacts", + "manifest_version": "1.1.0", + "canonicalization_profile": "associated-artifact-set/v1", + "scope": "scenario", + "parent_ref": { + "ref_kind": "scenario-snapshot", + "ref_id": "application-api-service", + "ref_version": null, + "ref_digest": "sha256:7a1862b94da049003de43ed8261dd29cb3d35de793ca707d38a6ff3582584ccf", + "ref_path": null + }, + "artifacts": { + "readme": { + "artifact_id": "readme", + "role": "documentation", + "media_type": "text/markdown", + "uri": "raes-environment-kit:/README.md", + "checksum": { + "algorithm": "sha256", + "value": "e601eec18bf601b1426a61ee43794c4173ab3673641e6f23740a0b1fec9ce7f4" + }, + "size_bytes": 479, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.application-api-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "integration-material": { + "artifact_id": "integration-material", + "role": "operator-guide", + "media_type": "text/markdown", + "uri": "raes-environment-kit:/assets/integration.md", + "checksum": { + "algorithm": "sha256", + "value": "0b5b6dea0cfa31296c5a41a23a57ed19143f5da2fc6657b6a5a14640a45b8ef4" + }, + "size_bytes": 519, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.application-api-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "seed-profile": { + "artifact_id": "seed-profile", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/assets/seed.yaml", + "checksum": { + "algorithm": "sha256", + "value": "f327d3afd9a2a5bc0852d65bdc7a3af18db5d803fdfeeffe325930b9fcc3522a" + }, + "size_bytes": 646, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.application-api-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "kit-manifest": { + "artifact_id": "kit-manifest", + "role": "manifest", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/kit.yaml", + "checksum": { + "algorithm": "sha256", + "value": "edf2a18513d11f760826a3667b81d042c2d37bd0cddf6cb95444a9516f9e198a" + }, + "size_bytes": 1698, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.application-api-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "module": { + "artifact_id": "module", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/module.sdl.yaml", + "checksum": { + "algorithm": "sha256", + "value": "f22658a0f96cc0db8fef64ea253406235394f6524d8b0d1a0154b4a5007768ab" + }, + "size_bytes": 2896, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.application-api-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "composition-tests": { + "artifact_id": "composition-tests", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/tests/composition.yaml", + "checksum": { + "algorithm": "sha256", + "value": "733c5117c59c5d2dbf7cfeb0a25594f989dd1ad8f22bdfeee760ea43223cc066" + }, + "size_bytes": 248, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.application-api-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + } + }, + "set_digest": "sha256:8e34aa86384f20b90d7610a93406488b83a601a6c8a2f2d230f5a50cf4e72750" +} diff --git a/kits/infrastructure.application-api-service/1.1.0/kit.yaml b/kits/infrastructure.application-api-service/1.1.0/kit.yaml new file mode 100644 index 0000000..95fdd1f --- /dev/null +++ b/kits/infrastructure.application-api-service/1.1.0/kit.yaml @@ -0,0 +1,49 @@ +schema_version: environment-pack-kit/v1 +id: infrastructure.application-api-service +version: 1.1.0 +title: Application/API service +summary: Reusable application/api service with domain-specific configuration, declared + service surfaces, seeded objects, and pack-local integration material. +concern: network-shared +released_at: '2026-10-09T00:00:00Z' +module: + path: module.sdl.yaml +assets: +- source: assets/integration.md + target: assets/kits/application-api-service/integration.md + visibility: operator + artifact_id: integration-material +- source: assets/seed.yaml + target: assets/kits/application-api-service/seed.yaml + visibility: operator + artifact_id: seed-profile +resources: + cpu_cores: 2 + memory_mib: 2048 + storage_mib: 4096 + notes: Planning estimates only; realization sizing remains backend-owned. +prerequisites: [] +limitations: +- Declares static infrastructure, seeded state, and integration surfaces only. +- Does not claim launch, readiness, traffic attachment, credential delivery, or runtime + evidence. +- No mandatory external authoring prerequisite; connect exported surfaces at the pack + composition root as needed. +license: + expression: MIT + redistribution: open + attribution: OpenRAE contributors +tests: +- path: tests/composition.yaml + kind: validate +- path: tests/composition.yaml + kind: parameter-variation +- path: tests/composition.yaml + kind: multi-kit +component_inventory: +- scope: unresolved + authority: raes-source + ref: /nodes/application/source + description: RAES carries the declared application-service stable source; immutable + artifact selection remains unresolved until pack publication. +associated_artifact_manifest: associated-artifacts.json diff --git a/kits/infrastructure.application-api-service/1.1.0/module.sdl.yaml b/kits/infrastructure.application-api-service/1.1.0/module.sdl.yaml new file mode 100644 index 0000000..bd99e50 --- /dev/null +++ b/kits/infrastructure.application-api-service/1.1.0/module.sdl.yaml @@ -0,0 +1,110 @@ +name: application-api-service +version: 1.1.0 +description: Reusable static infrastructure for Application/API service. Configures + api_base_path through the kit parameter contract. +module: + id: infrastructure/application-api-service + version: 1.1.0 + parameters: + - deployment_profile + - service_label + - api_base_path + exports: + nodes: + - application + content: + - seed_inventory + accounts: + - application_service + description: Composable Application/API service infrastructure module. +variables: + deployment_profile: + type: string + default: standard + allowed_values: + - compact + - standard + service_label: + type: string + default: application-api-service + api_base_path: + type: string + default: /api +nodes: + application: + type: compute + description: '${deployment_profile} profile for ${service_label} (Application/API + service). Configuration: ${api_base_path}.' + source: + name: application-service + version: stable + resources: + cpu: 2 + ram: 2 GiB + services: + - port: 8080 + protocol: tcp + name: http + description: Declared http service surface. + runtime: + applications: + - application_id: application_surface + service: http + protocol: http + name: Application surface + routes: + - route_id: primary + path: ${api_base_path} + methods: + - GET + responses: + - status_code: 200 + description: Declared primary response. + - route_id: health + path: /health + methods: + - GET + responses: + - status_code: 200 + description: Declared health response. +content: + seed_inventory: + type: dataset + target: application + description: Benign infrastructure seed inventory for ${api_base_path}. + items: + - name: api_routes + display_name: Api Routes + tags: + - infrastructure + - seed + description: Declared api routes for this reusable service. + - name: health_route + display_name: Health Route + tags: + - infrastructure + - seed + description: Declared health route for this reusable service. + - name: seed_records + display_name: Seed Records + tags: + - infrastructure + - seed + description: Declared seed records for this reusable service. + - name: service_account + display_name: Service Account + tags: + - infrastructure + - seed + description: Declared service account for this reusable service. +accounts: + application_service: + username: application-service + node: application + password_strength: strong + description: Declared environment account; credential delivery remains backend-owned. +realization: + constraints: + - field_pointer: /nodes/application + concern: compute-substrate + posture: open diff --git a/kits/infrastructure.application-api-service/1.1.0/tests/composition.yaml b/kits/infrastructure.application-api-service/1.1.0/tests/composition.yaml new file mode 100644 index 0000000..5e5cc75 --- /dev/null +++ b/kits/infrastructure.application-api-service/1.1.0/tests/composition.yaml @@ -0,0 +1,9 @@ +default: + deployment_profile: standard + service_label: application-api-service + api_base_path: /api +variation: + deployment_profile: compact + service_label: application-api-service-alternate + api_base_path: /v2 +multi_kit_group: network-shared diff --git a/kits/infrastructure.postgresql-database/1.1.0/README.md b/kits/infrastructure.postgresql-database/1.1.0/README.md new file mode 100644 index 0000000..a61f7db --- /dev/null +++ b/kits/infrastructure.postgresql-database/1.1.0/README.md @@ -0,0 +1,7 @@ +# PostgreSQL database + +Reusable postgresql database with domain-specific configuration, declared service surfaces, seeded objects, and pack-local integration material. + +The release includes a RAES module, explicit service and identity surfaces, benign seed inventory, planning estimates, component-inventory inputs, integration guidance, and composition tests. + +It is authoring content, not a runtime plugin, scenario narrative, backend qualification, or evidence claim. diff --git a/kits/infrastructure.postgresql-database/1.1.0/assets/integration.md b/kits/infrastructure.postgresql-database/1.1.0/assets/integration.md new file mode 100644 index 0000000..e3e84c0 --- /dev/null +++ b/kits/infrastructure.postgresql-database/1.1.0/assets/integration.md @@ -0,0 +1,15 @@ +# PostgreSQL database integration material + +Author parameter: `database_name` (default `environment`). + +## Exported RAES declarations + +- `nodes.database` +- `content.seed_inventory` +- `accounts.database_operator` + +## Composition notes + +- No mandatory external authoring prerequisite; connect exported surfaces at the pack composition root as needed. +- Keep credentials and runtime-selected endpoints outside kit parameters and seed assets. +- Validate the completed ordinary pack after adding pack-level relationships. diff --git a/kits/infrastructure.postgresql-database/1.1.0/assets/seed.yaml b/kits/infrastructure.postgresql-database/1.1.0/assets/seed.yaml new file mode 100644 index 0000000..7ca5a2c --- /dev/null +++ b/kits/infrastructure.postgresql-database/1.1.0/assets/seed.yaml @@ -0,0 +1,25 @@ +schema_version: environment-kit-seed/v1 +kit: infrastructure.postgresql-database +configuration: + database_name: environment + deployment_profile: standard + service_label: postgresql-database +declared_objects: +- id: database + kind: infrastructure-seed + sensitivity: non-secret +- id: schemas + kind: infrastructure-seed + sensitivity: non-secret +- id: tables + kind: infrastructure-seed + sensitivity: non-secret +- id: roles + kind: infrastructure-seed + sensitivity: non-secret +- id: seed_rows + kind: infrastructure-seed + sensitivity: non-secret +integration_requirements: +- No mandatory external authoring prerequisite; connect exported surfaces at the pack + composition root as needed. diff --git a/kits/infrastructure.postgresql-database/1.1.0/associated-artifacts.json b/kits/infrastructure.postgresql-database/1.1.0/associated-artifacts.json new file mode 100644 index 0000000..a06c660 --- /dev/null +++ b/kits/infrastructure.postgresql-database/1.1.0/associated-artifacts.json @@ -0,0 +1,113 @@ +{ + "schema_version": "associated-artifact-manifest/v1", + "manifest_id": "infrastructure.postgresql-database-associated-artifacts", + "manifest_version": "1.1.0", + "canonicalization_profile": "associated-artifact-set/v1", + "scope": "scenario", + "parent_ref": { + "ref_kind": "scenario-snapshot", + "ref_id": "postgresql-database", + "ref_version": null, + "ref_digest": "sha256:b2c919d72ed02f0fcb7ca868a7d969744799ec1e7786acf01c6d082c4a9b7c92", + "ref_path": null + }, + "artifacts": { + "readme": { + "artifact_id": "readme", + "role": "documentation", + "media_type": "text/markdown", + "uri": "raes-environment-kit:/README.md", + "checksum": { + "algorithm": "sha256", + "value": "e0cf28cee157dd0b3598fb41600e34afa6d6b94c154ac848e8026c83fa1c6fd4" + }, + "size_bytes": 471, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.postgresql-database@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "integration-material": { + "artifact_id": "integration-material", + "role": "operator-guide", + "media_type": "text/markdown", + "uri": "raes-environment-kit:/assets/integration.md", + "checksum": { + "algorithm": "sha256", + "value": "43a67d897338c70b24a436168050353000af12a3c96a9088da8554a6487d5041" + }, + "size_bytes": 517, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.postgresql-database@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "seed-profile": { + "artifact_id": "seed-profile", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/assets/seed.yaml", + "checksum": { + "algorithm": "sha256", + "value": "d72b09f43718d0252c106def535251eb7dc2dc448eca64e5ef60bab172431a56" + }, + "size_bytes": 692, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.postgresql-database@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "kit-manifest": { + "artifact_id": "kit-manifest", + "role": "manifest", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/kit.yaml", + "checksum": { + "algorithm": "sha256", + "value": "ec01c58b3ee55524c2dbcc5b1c4cc4768d8047f2d260b14e21bb45f8a7c41b55" + }, + "size_bytes": 1661, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.postgresql-database@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "module": { + "artifact_id": "module", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/module.sdl.yaml", + "checksum": { + "algorithm": "sha256", + "value": "41d3bd9a72ef50b58664b7c922c704702bc42283c8c263ab4f19a4452f1a35b9" + }, + "size_bytes": 3439, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.postgresql-database@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "composition-tests": { + "artifact_id": "composition-tests", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/tests/composition.yaml", + "checksum": { + "algorithm": "sha256", + "value": "753c8345cdefa6e071a0d2674fe500350b196dc99552bdf5af2df30e30742038" + }, + "size_bytes": 252, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.postgresql-database@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + } + }, + "set_digest": "sha256:49b321895e9fc2cb7635f98a227daaeb6475c1aab125716667df6c95614c6917" +} diff --git a/kits/infrastructure.postgresql-database/1.1.0/kit.yaml b/kits/infrastructure.postgresql-database/1.1.0/kit.yaml new file mode 100644 index 0000000..c847fb6 --- /dev/null +++ b/kits/infrastructure.postgresql-database/1.1.0/kit.yaml @@ -0,0 +1,49 @@ +schema_version: environment-pack-kit/v1 +id: infrastructure.postgresql-database +version: 1.1.0 +title: PostgreSQL database +summary: Reusable postgresql database with domain-specific configuration, declared + service surfaces, seeded objects, and pack-local integration material. +concern: data-workflow +released_at: '2026-10-09T00:00:00Z' +module: + path: module.sdl.yaml +assets: +- source: assets/integration.md + target: assets/kits/postgresql-database/integration.md + visibility: operator + artifact_id: integration-material +- source: assets/seed.yaml + target: assets/kits/postgresql-database/seed.yaml + visibility: operator + artifact_id: seed-profile +resources: + cpu_cores: 2 + memory_mib: 2048 + storage_mib: 4096 + notes: Planning estimates only; realization sizing remains backend-owned. +prerequisites: [] +limitations: +- Declares static infrastructure, seeded state, and integration surfaces only. +- Does not claim launch, readiness, traffic attachment, credential delivery, or runtime + evidence. +- No mandatory external authoring prerequisite; connect exported surfaces at the pack + composition root as needed. +license: + expression: MIT + redistribution: open + attribution: OpenRAE contributors +tests: +- path: tests/composition.yaml + kind: validate +- path: tests/composition.yaml + kind: parameter-variation +- path: tests/composition.yaml + kind: multi-kit +component_inventory: +- scope: unresolved + authority: raes-source + ref: /nodes/database/source + description: RAES carries the declared postgresql 17 source; immutable artifact + selection remains unresolved until pack publication. +associated_artifact_manifest: associated-artifacts.json diff --git a/kits/infrastructure.postgresql-database/1.1.0/module.sdl.yaml b/kits/infrastructure.postgresql-database/1.1.0/module.sdl.yaml new file mode 100644 index 0000000..0d01c0c --- /dev/null +++ b/kits/infrastructure.postgresql-database/1.1.0/module.sdl.yaml @@ -0,0 +1,132 @@ +name: postgresql-database +version: 1.1.0 +description: Reusable static infrastructure for PostgreSQL database. Configures database_name + through the kit parameter contract. +module: + id: infrastructure/postgresql-database + version: 1.1.0 + parameters: + - deployment_profile + - service_label + - database_name + exports: + nodes: + - database + content: + - seed_inventory + accounts: + - database_operator + description: Composable PostgreSQL database infrastructure module. +variables: + deployment_profile: + type: string + default: standard + allowed_values: + - compact + - standard + service_label: + type: string + default: postgresql-database + database_name: + type: string + default: environment +nodes: + database: + type: compute + description: '${deployment_profile} profile for ${service_label} (PostgreSQL database). + Configuration: ${database_name}.' + source: + name: postgresql + version: '17' + resources: + cpu: 2 + ram: 2 GiB + services: + - port: 5432 + protocol: tcp + name: postgresql + description: Declared postgresql service surface. + runtime: + database_services: + - database_service_id: postgresql_service + service: postgresql + engine: postgresql + protocol: postgresql + version: '17' + databases: + - database_id: application_database + name: ${database_name} + origin: scenario + schemas: + - schema_id: application_schema + name: application + tables: + - table_id: records_table + name: records + - table_id: audit_table + name: audit_log + roles: + - role_id: application_role + name: application + role_type: application + can_login: true + - role_id: operator_role + name: operator + role_type: admin + can_login: true + grants: + - grantee_role_ref: application_role + object_type: table + object_ref: records_table + privileges: + - SELECT + - INSERT + - UPDATE + with_grant_option: false +content: + seed_inventory: + type: dataset + target: database + description: Benign infrastructure seed inventory for ${database_name}. + items: + - name: database + display_name: Database + tags: + - infrastructure + - seed + description: Declared database for this reusable service. + - name: schemas + display_name: Schemas + tags: + - infrastructure + - seed + description: Declared schemas for this reusable service. + - name: tables + display_name: Tables + tags: + - infrastructure + - seed + description: Declared tables for this reusable service. + - name: roles + display_name: Roles + tags: + - infrastructure + - seed + description: Declared roles for this reusable service. + - name: seed_rows + display_name: Seed Rows + tags: + - infrastructure + - seed + description: Declared seed rows for this reusable service. +accounts: + database_operator: + username: db-operator + node: database + password_strength: strong + description: Declared environment account; credential delivery remains backend-owned. +realization: + constraints: + - field_pointer: /nodes/database + concern: compute-substrate + posture: open diff --git a/kits/infrastructure.postgresql-database/1.1.0/tests/composition.yaml b/kits/infrastructure.postgresql-database/1.1.0/tests/composition.yaml new file mode 100644 index 0000000..458e1b3 --- /dev/null +++ b/kits/infrastructure.postgresql-database/1.1.0/tests/composition.yaml @@ -0,0 +1,9 @@ +default: + deployment_profile: standard + service_label: postgresql-database + database_name: environment +variation: + deployment_profile: compact + service_label: postgresql-database-alternate + database_name: analytics +multi_kit_group: data-workflow diff --git a/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/README.md b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/README.md new file mode 100644 index 0000000..bf8f65b --- /dev/null +++ b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/README.md @@ -0,0 +1,7 @@ +# Reverse proxy/API gateway + +Reusable reverse proxy/api gateway with domain-specific configuration, declared service surfaces, seeded objects, and pack-local integration material. + +The release includes a RAES module, explicit service and identity surfaces, benign seed inventory, planning estimates, component-inventory inputs, integration guidance, and composition tests. + +It is authoring content, not a runtime plugin, scenario narrative, backend qualification, or evidence claim. diff --git a/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/assets/integration.md b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/assets/integration.md new file mode 100644 index 0000000..90f0738 --- /dev/null +++ b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/assets/integration.md @@ -0,0 +1,15 @@ +# Reverse proxy/API gateway integration material + +Author parameter: `route_prefix` (default `/`). + +## Exported RAES declarations + +- `nodes.gateway` +- `content.seed_inventory` +- `accounts.gateway_operator` + +## Composition notes + +- Add pack-level proxy-upstream relationships to imported application services. +- Keep credentials and runtime-selected endpoints outside kit parameters and seed assets. +- Validate the completed ordinary pack after adding pack-level relationships. diff --git a/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/assets/seed.yaml b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/assets/seed.yaml new file mode 100644 index 0000000..fa9ca31 --- /dev/null +++ b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/assets/seed.yaml @@ -0,0 +1,21 @@ +schema_version: environment-kit-seed/v1 +kit: infrastructure.reverse-proxy-api-gateway +configuration: + route_prefix: / + deployment_profile: standard + service_label: reverse-proxy-api-gateway +declared_objects: +- id: listener_routes + kind: infrastructure-seed + sensitivity: non-secret +- id: upstream_bindings + kind: infrastructure-seed + sensitivity: non-secret +- id: tls_termination + kind: infrastructure-seed + sensitivity: non-secret +- id: request_limits + kind: infrastructure-seed + sensitivity: non-secret +integration_requirements: +- Add pack-level proxy-upstream relationships to imported application services. diff --git a/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/associated-artifacts.json b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/associated-artifacts.json new file mode 100644 index 0000000..df5e687 --- /dev/null +++ b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/associated-artifacts.json @@ -0,0 +1,113 @@ +{ + "schema_version": "associated-artifact-manifest/v1", + "manifest_id": "infrastructure.reverse-proxy-api-gateway-associated-artifacts", + "manifest_version": "1.1.0", + "canonicalization_profile": "associated-artifact-set/v1", + "scope": "scenario", + "parent_ref": { + "ref_kind": "scenario-snapshot", + "ref_id": "reverse-proxy-api-gateway", + "ref_version": null, + "ref_digest": "sha256:2774e1bc278253b2ef6a3436ba66a859e702f7a9c1d99b3cdf225360a84402a1", + "ref_path": null + }, + "artifacts": { + "readme": { + "artifact_id": "readme", + "role": "documentation", + "media_type": "text/markdown", + "uri": "raes-environment-kit:/README.md", + "checksum": { + "algorithm": "sha256", + "value": "a09b545a81d7e0b99dd1aa7203bb7ba6b5ec83d00921e90d59494358982bf7ce" + }, + "size_bytes": 483, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.reverse-proxy-api-gateway@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "integration-material": { + "artifact_id": "integration-material", + "role": "operator-guide", + "media_type": "text/markdown", + "uri": "raes-environment-kit:/assets/integration.md", + "checksum": { + "algorithm": "sha256", + "value": "8a4ff5e48b4c3b3af3c1d84848da68a500ac975dd6ea51de631538b0a9243f2d" + }, + "size_bytes": 476, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.reverse-proxy-api-gateway@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "seed-profile": { + "artifact_id": "seed-profile", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/assets/seed.yaml", + "checksum": { + "algorithm": "sha256", + "value": "6a767ce02a3fba64f7425e78b9248dbb7ba5670a40124614ea616a457d7d6ee6" + }, + "size_bytes": 622, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.reverse-proxy-api-gateway@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "kit-manifest": { + "artifact_id": "kit-manifest", + "role": "manifest", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/kit.yaml", + "checksum": { + "algorithm": "sha256", + "value": "78a8a035bcf871cc1808bab5db7eeb41bbc63fa42c53290c649a9d9d2715e23f" + }, + "size_bytes": 1809, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.reverse-proxy-api-gateway@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "module": { + "artifact_id": "module", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/module.sdl.yaml", + "checksum": { + "algorithm": "sha256", + "value": "0118744c80b0f8457425c3b531f0b6a00c719c97a6fe818e62f0895c6fc7f428" + }, + "size_bytes": 2986, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.reverse-proxy-api-gateway@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "composition-tests": { + "artifact_id": "composition-tests", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/tests/composition.yaml", + "checksum": { + "algorithm": "sha256", + "value": "96f6b575fa5f0c5f4c23d7a3de39cb51441d56bd88e509f00a16c9d0cc1488e5" + }, + "size_bytes": 253, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.reverse-proxy-api-gateway@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + } + }, + "set_digest": "sha256:e123b899a0f956b135cf735cbd3f271d23e6225c8219d2b627d83aa704c9cf32" +} diff --git a/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/kit.yaml b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/kit.yaml new file mode 100644 index 0000000..3f08f82 --- /dev/null +++ b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/kit.yaml @@ -0,0 +1,53 @@ +schema_version: environment-pack-kit/v1 +id: infrastructure.reverse-proxy-api-gateway +version: 1.1.0 +title: Reverse proxy/API gateway +summary: Reusable reverse proxy/api gateway with domain-specific configuration, declared + service surfaces, seeded objects, and pack-local integration material. +concern: network-shared +released_at: '2026-10-09T00:00:00Z' +module: + path: module.sdl.yaml +assets: +- source: assets/integration.md + target: assets/kits/reverse-proxy-api-gateway/integration.md + visibility: operator + artifact_id: integration-material +- source: assets/seed.yaml + target: assets/kits/reverse-proxy-api-gateway/seed.yaml + visibility: operator + artifact_id: seed-profile +resources: + cpu_cores: 2 + memory_mib: 2048 + storage_mib: 4096 + notes: Planning estimates only; realization sizing remains backend-owned. +prerequisites: +- kind: external + id: upstream-application + version: raes-3.2 + description: Add pack-level proxy-upstream relationships to imported application + services. +limitations: +- Declares static infrastructure, seeded state, and integration surfaces only. +- Does not claim launch, readiness, traffic attachment, credential delivery, or runtime + evidence. +- Add pack-level proxy-upstream relationships to imported application services. +license: + expression: MIT + redistribution: open + attribution: OpenRAE contributors +tests: +- path: tests/composition.yaml + kind: validate +- path: tests/composition.yaml + kind: parameter-variation +- path: tests/composition.yaml + kind: multi-kit +component_inventory: +- scope: unresolved + authority: raes-source + ref: /nodes/gateway/source + description: RAES carries the declared traefik 3 source; immutable artifact selection + remains unresolved until pack publication. +associated_artifact_manifest: associated-artifacts.json diff --git a/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/module.sdl.yaml b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/module.sdl.yaml new file mode 100644 index 0000000..6f26ea2 --- /dev/null +++ b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/module.sdl.yaml @@ -0,0 +1,114 @@ +name: reverse-proxy-api-gateway +version: 1.1.0 +description: Reusable static infrastructure for Reverse proxy/API gateway. Configures + route_prefix through the kit parameter contract. +module: + id: infrastructure/reverse-proxy-api-gateway + version: 1.1.0 + parameters: + - deployment_profile + - service_label + - route_prefix + exports: + nodes: + - gateway + content: + - seed_inventory + accounts: + - gateway_operator + description: Composable Reverse proxy/API gateway infrastructure module. +variables: + deployment_profile: + type: string + default: standard + allowed_values: + - compact + - standard + service_label: + type: string + default: reverse-proxy-api-gateway + route_prefix: + type: string + default: / +nodes: + gateway: + type: compute + description: '${deployment_profile} profile for ${service_label} (Reverse proxy/API + gateway). Configuration: ${route_prefix}.' + source: + name: traefik + version: '3' + resources: + cpu: 2 + ram: 2 GiB + services: + - port: 80 + protocol: tcp + name: http + description: Declared http service surface. + - port: 443 + protocol: tcp + name: https + description: Declared https service surface. + runtime: + applications: + - application_id: gateway_surface + service: http + protocol: http + name: Gateway surface + routes: + - route_id: primary + path: ${route_prefix} + methods: + - GET + responses: + - status_code: 200 + description: Declared primary response. + - route_id: health + path: /health + methods: + - GET + responses: + - status_code: 200 + description: Declared health response. +content: + seed_inventory: + type: dataset + target: gateway + description: Benign infrastructure seed inventory for ${route_prefix}. + items: + - name: listener_routes + display_name: Listener Routes + tags: + - infrastructure + - seed + description: Declared listener routes for this reusable service. + - name: upstream_bindings + display_name: Upstream Bindings + tags: + - infrastructure + - seed + description: Declared upstream bindings for this reusable service. + - name: tls_termination + display_name: Tls Termination + tags: + - infrastructure + - seed + description: Declared tls termination for this reusable service. + - name: request_limits + display_name: Request Limits + tags: + - infrastructure + - seed + description: Declared request limits for this reusable service. +accounts: + gateway_operator: + username: gateway-operator + node: gateway + password_strength: strong + description: Declared environment account; credential delivery remains backend-owned. +realization: + constraints: + - field_pointer: /nodes/gateway + concern: compute-substrate + posture: open diff --git a/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/tests/composition.yaml b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/tests/composition.yaml new file mode 100644 index 0000000..e0245a1 --- /dev/null +++ b/kits/infrastructure.reverse-proxy-api-gateway/1.1.0/tests/composition.yaml @@ -0,0 +1,9 @@ +default: + deployment_profile: standard + service_label: reverse-proxy-api-gateway + route_prefix: / +variation: + deployment_profile: compact + service_label: reverse-proxy-api-gateway-alternate + route_prefix: /services +multi_kit_group: network-shared diff --git a/kits/infrastructure.smtp-imap-mail-service/1.1.0/README.md b/kits/infrastructure.smtp-imap-mail-service/1.1.0/README.md new file mode 100644 index 0000000..e88e6de --- /dev/null +++ b/kits/infrastructure.smtp-imap-mail-service/1.1.0/README.md @@ -0,0 +1,7 @@ +# SMTP/IMAP mail service + +Reusable smtp/imap mail service with domain-specific configuration, declared service surfaces, seeded objects, and pack-local integration material. + +The release includes a RAES module, explicit service and identity surfaces, benign seed inventory, planning estimates, component-inventory inputs, integration guidance, and composition tests. + +It is authoring content, not a runtime plugin, scenario narrative, backend qualification, or evidence claim. diff --git a/kits/infrastructure.smtp-imap-mail-service/1.1.0/assets/integration.md b/kits/infrastructure.smtp-imap-mail-service/1.1.0/assets/integration.md new file mode 100644 index 0000000..cefd1f1 --- /dev/null +++ b/kits/infrastructure.smtp-imap-mail-service/1.1.0/assets/integration.md @@ -0,0 +1,15 @@ +# SMTP/IMAP mail service integration material + +Author parameter: `mail_domain` (default `environment.test`). + +## Exported RAES declarations + +- `nodes.mail` +- `content.seed_inventory` +- `accounts.mail_operator` + +## Composition notes + +- No mandatory external authoring prerequisite; connect exported surfaces at the pack composition root as needed. +- Keep credentials and runtime-selected endpoints outside kit parameters and seed assets. +- Validate the completed ordinary pack after adding pack-level relationships. diff --git a/kits/infrastructure.smtp-imap-mail-service/1.1.0/assets/seed.yaml b/kits/infrastructure.smtp-imap-mail-service/1.1.0/assets/seed.yaml new file mode 100644 index 0000000..9cebeae --- /dev/null +++ b/kits/infrastructure.smtp-imap-mail-service/1.1.0/assets/seed.yaml @@ -0,0 +1,22 @@ +schema_version: environment-kit-seed/v1 +kit: infrastructure.smtp-imap-mail-service +configuration: + mail_domain: environment.test + deployment_profile: standard + service_label: smtp-imap-mail-service +declared_objects: +- id: mail_domain + kind: infrastructure-seed + sensitivity: non-secret +- id: mailboxes + kind: infrastructure-seed + sensitivity: non-secret +- id: aliases + kind: infrastructure-seed + sensitivity: non-secret +- id: seed_messages + kind: infrastructure-seed + sensitivity: non-secret +integration_requirements: +- No mandatory external authoring prerequisite; connect exported surfaces at the pack + composition root as needed. diff --git a/kits/infrastructure.smtp-imap-mail-service/1.1.0/associated-artifacts.json b/kits/infrastructure.smtp-imap-mail-service/1.1.0/associated-artifacts.json new file mode 100644 index 0000000..f5a9236 --- /dev/null +++ b/kits/infrastructure.smtp-imap-mail-service/1.1.0/associated-artifacts.json @@ -0,0 +1,113 @@ +{ + "schema_version": "associated-artifact-manifest/v1", + "manifest_id": "infrastructure.smtp-imap-mail-service-associated-artifacts", + "manifest_version": "1.1.0", + "canonicalization_profile": "associated-artifact-set/v1", + "scope": "scenario", + "parent_ref": { + "ref_kind": "scenario-snapshot", + "ref_id": "smtp-imap-mail-service", + "ref_version": null, + "ref_digest": "sha256:bc3ca325e7034a2fab52160c5310c761202b67dbbae4f5d4e703acbf694fabd9", + "ref_path": null + }, + "artifacts": { + "readme": { + "artifact_id": "readme", + "role": "documentation", + "media_type": "text/markdown", + "uri": "raes-environment-kit:/README.md", + "checksum": { + "algorithm": "sha256", + "value": "d5ca58ea7130283318c6a3b7685dc711ebf805b0e3433b9d37feba90ee513c38" + }, + "size_bytes": 477, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.smtp-imap-mail-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "integration-material": { + "artifact_id": "integration-material", + "role": "operator-guide", + "media_type": "text/markdown", + "uri": "raes-environment-kit:/assets/integration.md", + "checksum": { + "algorithm": "sha256", + "value": "5370704a583607c25e92e340af96d060a8613df9bb2422e09cfce0c9694c237f" + }, + "size_bytes": 515, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.smtp-imap-mail-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "seed-profile": { + "artifact_id": "seed-profile", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/assets/seed.yaml", + "checksum": { + "algorithm": "sha256", + "value": "373971e0ebc64634f4b5c61f6303e7d2d9db6e42c38a59d1342355ac996b0da0" + }, + "size_bytes": 645, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.smtp-imap-mail-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "kit-manifest": { + "artifact_id": "kit-manifest", + "role": "manifest", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/kit.yaml", + "checksum": { + "algorithm": "sha256", + "value": "0732e62be6a1d7ae7a482db2a3ca859df8ac53404e919379e5708ce3c00745c2" + }, + "size_bytes": 1678, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.smtp-imap-mail-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "module": { + "artifact_id": "module", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/module.sdl.yaml", + "checksum": { + "algorithm": "sha256", + "value": "d905a7c06a2b010a17f8ebff3333c148404747ce84548a6a99092162e0be265f" + }, + "size_bytes": 3090, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.smtp-imap-mail-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + }, + "composition-tests": { + "artifact_id": "composition-tests", + "role": "configuration", + "media_type": "application/yaml", + "uri": "raes-environment-kit:/tests/composition.yaml", + "checksum": { + "algorithm": "sha256", + "value": "d70f4fd395197c38a5b9ffdf68b71a6f9feca59059ed073e3c3fc1409b82d5f6" + }, + "size_bytes": 265, + "created_at": "2026-10-09T00:00:00Z", + "source": "infrastructure.smtp-imap-mail-service@1.1.0", + "satisfies_refs": [], + "sensitivity": "public", + "description": null + } + }, + "set_digest": "sha256:456a050aa35924b00ea91f80d5212a375f833464c312e90ee08fd4513ccb7bee" +} diff --git a/kits/infrastructure.smtp-imap-mail-service/1.1.0/kit.yaml b/kits/infrastructure.smtp-imap-mail-service/1.1.0/kit.yaml new file mode 100644 index 0000000..d4346d8 --- /dev/null +++ b/kits/infrastructure.smtp-imap-mail-service/1.1.0/kit.yaml @@ -0,0 +1,49 @@ +schema_version: environment-pack-kit/v1 +id: infrastructure.smtp-imap-mail-service +version: 1.1.0 +title: SMTP/IMAP mail service +summary: Reusable smtp/imap mail service with domain-specific configuration, declared + service surfaces, seeded objects, and pack-local integration material. +concern: network-shared +released_at: '2026-10-09T00:00:00Z' +module: + path: module.sdl.yaml +assets: +- source: assets/integration.md + target: assets/kits/smtp-imap-mail-service/integration.md + visibility: operator + artifact_id: integration-material +- source: assets/seed.yaml + target: assets/kits/smtp-imap-mail-service/seed.yaml + visibility: operator + artifact_id: seed-profile +resources: + cpu_cores: 2 + memory_mib: 2048 + storage_mib: 4096 + notes: Planning estimates only; realization sizing remains backend-owned. +prerequisites: [] +limitations: +- Declares static infrastructure, seeded state, and integration surfaces only. +- Does not claim launch, readiness, traffic attachment, credential delivery, or runtime + evidence. +- No mandatory external authoring prerequisite; connect exported surfaces at the pack + composition root as needed. +license: + expression: MIT + redistribution: open + attribution: OpenRAE contributors +tests: +- path: tests/composition.yaml + kind: validate +- path: tests/composition.yaml + kind: parameter-variation +- path: tests/composition.yaml + kind: multi-kit +component_inventory: +- scope: unresolved + authority: raes-source + ref: /nodes/mail/source + description: RAES carries the declared mail-server stable source; immutable artifact + selection remains unresolved until pack publication. +associated_artifact_manifest: associated-artifacts.json diff --git a/kits/infrastructure.smtp-imap-mail-service/1.1.0/module.sdl.yaml b/kits/infrastructure.smtp-imap-mail-service/1.1.0/module.sdl.yaml new file mode 100644 index 0000000..ae36324 --- /dev/null +++ b/kits/infrastructure.smtp-imap-mail-service/1.1.0/module.sdl.yaml @@ -0,0 +1,117 @@ +name: smtp-imap-mail-service +version: 1.1.0 +description: Reusable static infrastructure for SMTP/IMAP mail service. Configures + mail_domain through the kit parameter contract. +module: + id: infrastructure/smtp-imap-mail-service + version: 1.1.0 + parameters: + - deployment_profile + - service_label + - mail_domain + exports: + nodes: + - mail + content: + - seed_inventory + accounts: + - mail_operator + description: Composable SMTP/IMAP mail service infrastructure module. +variables: + deployment_profile: + type: string + default: standard + allowed_values: + - compact + - standard + service_label: + type: string + default: smtp-imap-mail-service + mail_domain: + type: string + default: environment.test +nodes: + mail: + type: compute + description: '${deployment_profile} profile for ${service_label} (SMTP/IMAP mail + service). Configuration: ${mail_domain}.' + source: + name: mail-server + version: stable + resources: + cpu: 2 + ram: 2 GiB + services: + - port: 25 + protocol: tcp + name: smtp + description: Declared smtp service surface. + - port: 143 + protocol: tcp + name: imap + description: Declared imap service surface. + runtime: + mail_services: + - mail_service_id: environment_mail + service: smtp + engine: postfix-dovecot + listeners: + - listener_id: smtp_listener + service: smtp + protocol: smtp + tls_mode: starttls-available + - listener_id: imap_listener + service: imap + protocol: imap + tls_mode: starttls-available + domains: + - domain_id: primary_domain + name: ${mail_domain} + mailboxes: + - mailbox_id: operator_mailbox + address: operator@environment.test + domain_ref: primary_domain + - mailbox_id: service_mailbox + address: service@environment.test + domain_ref: primary_domain +content: + seed_inventory: + type: dataset + target: mail + description: Benign infrastructure seed inventory for ${mail_domain}. + items: + - name: mail_domain + display_name: Mail Domain + tags: + - infrastructure + - seed + description: Declared mail domain for this reusable service. + - name: mailboxes + display_name: Mailboxes + tags: + - infrastructure + - seed + description: Declared mailboxes for this reusable service. + - name: aliases + display_name: Aliases + tags: + - infrastructure + - seed + description: Declared aliases for this reusable service. + - name: seed_messages + display_name: Seed Messages + tags: + - infrastructure + - seed + description: Declared seed messages for this reusable service. +accounts: + mail_operator: + username: mail-operator + node: mail + password_strength: strong + description: Declared environment account; credential delivery remains backend-owned. +realization: + constraints: + - field_pointer: /nodes/mail + concern: compute-substrate + posture: open diff --git a/kits/infrastructure.smtp-imap-mail-service/1.1.0/tests/composition.yaml b/kits/infrastructure.smtp-imap-mail-service/1.1.0/tests/composition.yaml new file mode 100644 index 0000000..305a51d --- /dev/null +++ b/kits/infrastructure.smtp-imap-mail-service/1.1.0/tests/composition.yaml @@ -0,0 +1,9 @@ +default: + deployment_profile: standard + service_label: smtp-imap-mail-service + mail_domain: environment.test +variation: + deployment_profile: compact + service_label: smtp-imap-mail-service-alternate + mail_domain: alternate.test +multi_kit_group: network-shared diff --git a/tests/test_kit_compute_substrate.py b/tests/test_kit_compute_substrate.py new file mode 100644 index 0000000..d4ddb5a --- /dev/null +++ b/tests/test_kit_compute_substrate.py @@ -0,0 +1,194 @@ +"""Four runtime-collection kits leave the compute substrate open (#413). + +The newest release of each kit in ``RUNTIME_COLLECTION_KITS`` declares an open +compute-substrate constraint on every compute node, so the backend chooses the +substrate. Planning it against a manifest whose realization envelope offers +in-process emulation, not a virtual machine, therefore reports no +``realization.compute-substrate-*`` diagnostic. The 1.0.0 releases declare an +exact virtual-machine substrate and fail there with +``realization.compute-substrate-not-admitted``. + +The manifest is the RAES stub manifest with its in-process realization +envelope, plus exact and constrained support, with an observation capability, +for every RAES realization concern. RAES's own planner tests declare support the +same way (``_fixture`` in ``test_issue_1200_mixed_runtime_constraints.py``). The +manifest judges what the kit demands, not what a particular backend supports, +and claims no backend behavior. + +Each of these kits puts a ``${parameter}`` inside a node runtime collection. +RAES 6.0.1 cannot retain typed authority for a configurable string parameter +there (OpenRAE/rae#1481), so planning still reports +``realization.authority-bound-unavailable`` and the plan is not valid (#414). +The planning test asserts that the plan is not valid and that this is the only +diagnostic left. +""" + +from __future__ import annotations + +import shutil +import tempfile +import unittest +from dataclasses import replace +from pathlib import Path + +import yaml +from packaging.version import Version +from raes import parse_sdl_file +from raes_backend_protocols.capabilities import BackendManifest +from raes_backend_stubs.stubs import create_stub_manifest +from raes_contracts.apparatus import RealizationObservationCapability +from raes_contracts.vocabulary import ObservationStrength, RealizationVerificationScope +from raes_processor.compiler import compile_scenario_runtime_model +from raes_processor.planner import plan +from raes_processor.semantics.realization_concerns import realization_concern_descriptors + + +ROOT = Path(__file__).resolve().parents[1] +RUNTIME_COLLECTION_KITS = frozenset( + { + "infrastructure.application-api-service", + "infrastructure.postgresql-database", + "infrastructure.reverse-proxy-api-gateway", + "infrastructure.smtp-imap-mail-service", + } +) +OPEN = {"concern": "compute-substrate", "posture": "open"} +AUTHORITY_BOUND_UNAVAILABLE = "realization.authority-bound-unavailable" + + +def _declaring_manifest() -> BackendManifest: + """Return the stub manifest declaring every RAES realization concern.""" + + stub = create_stub_manifest(with_realization_envelope=True) + kinds = frozenset( + descriptor.concern_kind for descriptor in realization_concern_descriptors() + ) + observed = RealizationObservationCapability( + verification_scope=RealizationVerificationScope.CONFIGURATION, + observation_strength=ObservationStrength.GUEST_OBSERVED, + ) + return replace( + stub, + realization_support=tuple( + replace( + declaration, + supported_exact_requirement_kinds=( + declaration.supported_exact_requirement_kinds | kinds + ), + supported_constraint_kinds=declaration.supported_constraint_kinds | kinds, + observation_capabilities={ + **declaration.observation_capabilities, + **dict.fromkeys(kinds, observed), + }, + ) + for declaration in stub.realization_support + ), + ) + + +MANIFEST = _declaring_manifest() + + +def _newest_releases() -> list[Path]: + """Return the newest release directory of every published kit.""" + + newest: dict[str, Path] = {} + for manifest in ROOT.glob("kits/*/*/kit.yaml"): + release = manifest.parent + current = newest.get(release.parent.name) + if current is None or Version(release.name) > Version(current.name): + newest[release.parent.name] = release + return [newest[kit] for kit in sorted(newest)] + + +def _runtime_collection_releases() -> list[Path]: + return [ + release + for release in _newest_releases() + if release.parent.name in RUNTIME_COLLECTION_KITS + ] + + +def _module(release: Path) -> dict: + return yaml.safe_load((release / "module.sdl.yaml").read_text(encoding="utf-8")) + + +def _substrates(module: dict) -> dict[str, dict]: + """Map each node pointer to its compute-substrate constraint.""" + + return { + constraint["field_pointer"]: { + key: value for key, value in constraint.items() if key != "field_pointer" + } + for constraint in module.get("realization", {}).get("constraints", []) + if constraint["concern"] == "compute-substrate" + } + + +def _on_every_compute_node(module: dict, constraint: dict) -> dict[str, dict]: + return { + f"/nodes/{name}": constraint + for name, node in module["nodes"].items() + if node["type"] != "switch" + } + + +def _plan_release(release: Path, version: str, parameters: dict) -> tuple[bool, set[str]]: + """Compose one release with ``parameters``, plan it, and return the result.""" + + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + shutil.copy2(release / "module.sdl.yaml", root / "module.sdl.yaml") + document = { + "name": "composition", + "imports": [ + { + "source": "local:module.sdl.yaml", + "namespace": "subject", + "version": version, + "parameters": parameters, + } + ], + } + (root / "scenario.sdl.yaml").write_text( + yaml.safe_dump(document, sort_keys=False), encoding="utf-8" + ) + scenario = parse_sdl_file(root / "scenario.sdl.yaml", migration_policy="accept") + model = compile_scenario_runtime_model(scenario, parameters={}) + execution = plan(model, MANIFEST) + codes = {diagnostic.code for diagnostic in (*model.diagnostics, *execution.diagnostics)} + return execution.is_valid, codes + + +class KitComputeSubstrateTests(unittest.TestCase): + def test_runtime_collection_kits_leave_the_compute_substrate_open(self) -> None: + releases = _runtime_collection_releases() + self.assertEqual( + {release.parent.name for release in releases}, RUNTIME_COLLECTION_KITS + ) + for release in releases: + module = _module(release) + with self.subTest(kit=release.parent.name, version=release.name): + self.assertEqual(_substrates(module), _on_every_compute_node(module, OPEN)) + + def test_runtime_collection_kits_plan_without_a_compute_substrate_diagnostic( + self, + ) -> None: + for release in _runtime_collection_releases(): + module = _module(release) + cases = yaml.safe_load( + (release / "tests/composition.yaml").read_text(encoding="utf-8") + ) + for case in ("default", "variation"): + with self.subTest(kit=release.parent.name, version=release.name, case=case): + is_valid, codes = _plan_release( + release, module["module"]["version"], cases[case] + ) + self.assertFalse(is_valid) + # OpenRAE/rae#1481: the runtime-collection parameter has no + # authority bound under RAES 6.0.1. + self.assertEqual(codes, {AUTHORITY_BOUND_UNAVAILABLE}) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_published_kits.py b/tests/test_published_kits.py index 25f30cc..5280862 100644 --- a/tests/test_published_kits.py +++ b/tests/test_published_kits.py @@ -14,7 +14,7 @@ ROOT = Path(__file__).resolve().parents[1] -EXPECTED_KIT_COUNT = 46 +EXPECTED_RELEASE_COUNT = 50 ISSUE_225_KITS = { "certificate-authority": ( @@ -99,7 +99,7 @@ def test_all_releases_are_discoverable_and_deterministic(self) -> None: first = build_kit_catalog((source,)) second = build_kit_catalog((source,)) self.assertEqual(first, second) - self.assertEqual(len(first["entries"]), EXPECTED_KIT_COUNT) + self.assertEqual(len(first["entries"]), EXPECTED_RELEASE_COUNT) def test_every_release_composes_with_two_parameter_sets(self) -> None: for manifest in sorted(ROOT.glob("kits/*/*/kit.yaml")): @@ -141,7 +141,7 @@ def test_every_release_composes_with_two_parameter_sets(self) -> None: { "source": "local:module.sdl.yaml", "namespace": "subject", - "version": "1.0.0", + "version": module["module"]["version"], "parameters": cases[name], } ], diff --git a/tests_integration/kit_author_walkthrough.py b/tests_integration/kit_author_walkthrough.py index 96cd0ec..c337950 100644 --- a/tests_integration/kit_author_walkthrough.py +++ b/tests_integration/kit_author_walkthrough.py @@ -130,7 +130,7 @@ def _walk(result: Result, catalog: Path, revision: str, workspace: Path) -> None listed = _kit(["list", *_source(catalog, revision), "--json"]) result.command("catalog listed", listed) entries = _json(listed) - result.check("all releases are discoverable", isinstance(entries, list) and len(entries) == 46) + result.check("all releases are discoverable", isinstance(entries, list) and len(entries) == 50) searched = _kit(["search", *_source(catalog, revision), "domain controller", "--json"]) result.command("catalog searched", searched) result.check("search returns identity infrastructure", bool(_json(searched))) From 7dc33462b5ea058cb6da0ef30c76b0250866f27d Mon Sep 17 00:00:00 2001 From: Brad Edwards Date: Sun, 11 Oct 2026 02:01:34 +0200 Subject: [PATCH 2/2] test(kits): cover custom parameters without requiring an upstream failure --- tests/test_kit_compute_substrate.py | 31 +++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/tests/test_kit_compute_substrate.py b/tests/test_kit_compute_substrate.py index d4ddb5a..1a84447 100644 --- a/tests/test_kit_compute_substrate.py +++ b/tests/test_kit_compute_substrate.py @@ -19,8 +19,9 @@ RAES 6.0.1 cannot retain typed authority for a configurable string parameter there (OpenRAE/rae#1481), so planning still reports ``realization.authority-bound-unavailable`` and the plan is not valid (#414). -The planning test asserts that the plan is not valid and that this is the only -diagnostic left. +The planning test permits this known diagnostic. It rejects all other +diagnostics and does not require the upstream failure to persist. Each kit is +also composed with a custom value outside its default and variation values. """ from __future__ import annotations @@ -54,6 +55,12 @@ ) OPEN = {"concern": "compute-substrate", "posture": "open"} AUTHORITY_BOUND_UNAVAILABLE = "realization.authority-bound-unavailable" +CUSTOM_PARAMETERS = { + "infrastructure.application-api-service": {"api_base_path": "/custom/v3"}, + "infrastructure.postgresql-database": {"database_name": "customer_data"}, + "infrastructure.reverse-proxy-api-gateway": {"route_prefix": "/team/api"}, + "infrastructure.smtp-imap-mail-service": {"mail_domain": "example.test"}, +} def _declaring_manifest() -> BackendManifest: @@ -133,8 +140,8 @@ def _on_every_compute_node(module: dict, constraint: dict) -> dict[str, dict]: } -def _plan_release(release: Path, version: str, parameters: dict) -> tuple[bool, set[str]]: - """Compose one release with ``parameters``, plan it, and return the result.""" +def _plan_release(release: Path, version: str, parameters: dict) -> set[str]: + """Compose one release with ``parameters`` and return planning diagnostics.""" with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) @@ -157,7 +164,7 @@ def _plan_release(release: Path, version: str, parameters: dict) -> tuple[bool, model = compile_scenario_runtime_model(scenario, parameters={}) execution = plan(model, MANIFEST) codes = {diagnostic.code for diagnostic in (*model.diagnostics, *execution.diagnostics)} - return execution.is_valid, codes + return codes class KitComputeSubstrateTests(unittest.TestCase): @@ -179,15 +186,19 @@ def test_runtime_collection_kits_plan_without_a_compute_substrate_diagnostic( cases = yaml.safe_load( (release / "tests/composition.yaml").read_text(encoding="utf-8") ) - for case in ("default", "variation"): + cases["custom"] = { + **cases["default"], + **CUSTOM_PARAMETERS[release.parent.name], + } + for case in ("default", "variation", "custom"): with self.subTest(kit=release.parent.name, version=release.name, case=case): - is_valid, codes = _plan_release( + codes = _plan_release( release, module["module"]["version"], cases[case] ) - self.assertFalse(is_valid) # OpenRAE/rae#1481: the runtime-collection parameter has no - # authority bound under RAES 6.0.1. - self.assertEqual(codes, {AUTHORITY_BOUND_UNAVAILABLE}) + # authority bound under RAES 6.0.1. Permit that diagnostic + # without requiring the upstream failure to persist. + self.assertFalse(codes - {AUTHORITY_BOUND_UNAVAILABLE}, codes) if __name__ == "__main__":