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..1a84447 --- /dev/null +++ b/tests/test_kit_compute_substrate.py @@ -0,0 +1,205 @@ +"""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 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 + +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" +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: + """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) -> set[str]: + """Compose one release with ``parameters`` and return planning diagnostics.""" + + 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 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") + ) + 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): + codes = _plan_release( + release, module["module"]["version"], cases[case] + ) + # OpenRAE/rae#1481: the runtime-collection parameter has no + # 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__": + 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)))