Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/development/kits-integration-runbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ every checked-in kit release and representative multi-kit composition.

## What it proves

- A minimal pack can list, search, and inspect the complete initial 38-kit
- A minimal pack can list, search, and inspect the complete 46-kit
collection.
- Preview is side-effect free and exposes ordinary files, topology, assumptions,
dependencies, and RAES lock changes without parameter values.
Expand Down
110 changes: 110 additions & 0 deletions docs/development/missing-infrastructure-kits-preflight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Missing infrastructure kits preflight

Issue #225 adds eight first-party infrastructure kit releases. This note fixes
their architecture boundary before content is authored; it does not implement
the releases or prescribe an implementation sequence. Existing ADRs
[0009](../decisions/adrs/0009-scenario-packs-subordinate-to-aces.md),
[0035](../decisions/adrs/0035-compose-catalog-kits-through-raes-and-transactional-pack-projections.md),
and [0036](../decisions/adrs/0036-publish-first-party-content-with-env-packs.md)
already govern the change. No new ADR or schema version is needed.

## Release boundary

Add exactly eight independently versioned `1.0.0` releases under `kits/`. Use
capability-oriented kit and module identities; the named implementation belongs
in the RAES node `source`, not in another product-specific manifest field.
`concern` remains a discovery aid, not a semantic or deployment classification.

| Kit identity | RAES source | Existing concern | Domain variation seam | Declared service boundary |
| --- | --- | --- | --- | --- |
| `infrastructure.certificate-authority` | `step-ca` | `identity-domain` | authority name | HTTPS CA API, normally `9000/tcp` for the selected source release |
| `infrastructure.dhcp-ipam-service` | `kea` | `network-shared` | address pool or subnet | server-side DHCP surfaces (`67/udp`, and `547/udp` only when DHCPv6 is declared) |
| `infrastructure.secrets-store` | `openbao` | `policy-operations` | non-secret mount or namespace name | client API `8200/tcp`; cluster `8201/tcp` only if the module actually declares clustering |
| `infrastructure.message-broker` | `rabbitmq` | `data-workflow` | virtual host | AMQP `5672/tcp`; management `15672/tcp` only if that plugin is part of the declared surface |
| `infrastructure.cache-key-value-store` | `valkey` | `data-workflow` | key prefix or cache profile | client service `6379/tcp` |
| `infrastructure.firewall-nat` | `nftables` | `network-shared` | ruleset name | no invented listener; filtering/NAT policy ports are seeded state, not node services |
| `infrastructure.ldap-directory` | `openldap` | `identity-domain` | directory suffix | LDAP `389/tcp`; LDAPS `636/tcp` only when the TLS surface is declared |
| `infrastructure.container-orchestration` | `k3s` | `data-workflow` | cluster name | author-facing API `6443/tcp`; node/overlay ports only when corresponding topology is modeled |

The numeric surfaces above are guardrails, not permission to copy every port an
upstream deployment might use. Confirm the selected source release and declare
only stable, author-relevant listeners. A RAES node service is a scenario-visible
service, not a Docker host publish, firewall opening, process bind address, or
complete vendor firewall matrix. In particular, `nftables` has no application
listener of its own; adding SSH or a fake management port would misdescribe it.

Every module retains the collection's established shared parameters
`deployment_profile` and `service_label`, plus the domain seam above. It exports
its node and `content.seed_inventory`, with other RAES declarations only where
the exact RAES 5.0.0 public contract supports the meaning. Generic LDAP must not
copy Active Directory forests, profiles, or controller relationships merely to
look like the existing AD kits. Relationships between DHCP/DNS, CA/consumers,
broker/clients, cache/applications, firewall/protected nodes, LDAP/members, or
k3s/workloads belong at the consuming pack root.

Seed inventories describe at least three useful, benign objects such as policy
names, pools, queues, exchanges, cache policies, directory containers, or
cluster namespaces. They contain no private keys, bootstrap tokens, unseal
material, RabbitMQ credentials, LDAP bind passwords, kubeconfigs, environment
variable coordinates, signed URLs, or example values that resemble live
secrets. A certificate name or secret-engine mount is acceptable metadata; a
certificate authority private key or stored secret value is not.

The existing
[`infrastructure.reverse-proxy-api-gateway`](../../kits/infrastructure.reverse-proxy-api-gateway/1.0.0/module.sdl.yaml)
already covers the load-balancer boundary: it declares a Traefik source,
HTTP/HTTPS services, route and upstream-binding seed objects, and an explicit
pack-root upstream relationship. Do not add a duplicate load-balancer kit.
A future demonstrated L4-only or algorithm-specific need should first test
whether it is a compatible new release/parameter of that kit; a product synonym
is not a separate reusable unit.

## Contracts and cross-cutting layers

The releases are ordinary inputs to the existing RAES-subordinate pack tooling;
they require no new controller, DTO, service, repository, persistence
store, exception family, logger, catalog registry, or workflow.

| Layer and canonical incumbent | Required guardrail |
| --- | --- |
| Carrier and schema: `src/raes_env_packs/resources/schemas/kit.schema.yaml`, `validate_kit_document()` | Keep `environment-pack-kit/v1` closed. Reuse its existing concern enum, resources, prerequisites, limitations, license, tests, component inventory, and associated-artifact pointer. Do not add product, port, seed, or runtime fields to the manifest. |
| Semantic authority: exact `raes==5.0.0`, `parse_sdl()`, `canonical_sdl_digest()` | Nodes, sources, services, parameters, exports, accounts, identity declarations, relationships, content and realization constraints are ordinary RAES SDL. Do not restate their schema or accept RAES-invalid vocabulary locally. |
| Infrastructure admission: `_validate_raw_module()` and `_verify_infrastructure_only()` | No agents, actions, behavior, conditions, objectives, injects, events, scripts, stories, workflows, scoring, telemetry, oracle, or runtime lifecycle semantics. Seed names are not a loophole for behavior. |
| Input and filesystem safety: `KitLimits`, strict YAML/JSON readers, `_pack_fs`, `_authoring_safety.admit_members()` | Preserve duplicate-key rejection, bounded nodes/depth/aliases/bytes/members, canonical relative paths, no links or special files, no sensitive filenames, and unchanged-inventory checks. All assets stay below the four safe non-executable destinations. |
| Secret and environment admission: `_secret_shape_violations()`, `_secret_parameter_name()`, `_normalize_parameters()`, `kit_cli._parameters()`, `AuthoringSession.call()` | Keep parameters bounded, public scalars. No secret-shaped names or values and no environment coordinates. Automation continues to pass parameter JSON through stdin, never argv. The loader does not inspect arbitrary module prose or asset values for every secret shape, so authored module descriptions, README, integration, and seed files still need explicit review. |
| Integrity and supply boundary: RAES associated-artifact models, `validate_associated_artifact_manifest()`, `associated_artifact_set_digest()` | Bind the exact release inventory, real byte checksums/sizes, canonical SDL parent digest, manifest id/version, and one immutable set digest. The kit's MIT license covers authored kit content; it does not relabel upstream product licensing. Keep the product source unresolved unless an immutable artifact is actually shipped or pinned. |
| Discovery and persistence: `load_kit_release()`, `build_kit_catalog()`, `inspect_kit()`, `KitRelease`/`KitSource` | Directory identity, manifest identity, module identity/version, and deterministic catalog projection must agree. The checked-in release directory is the source of truth; add no hand-maintained catalog index or database. A consumer's materialization ledger remains inert ownership/provenance, not a second module lock. |
| Materialization: `KitProposal`, `propose_*()`, `apply_proposal()`, `_transactions` | Existing proposal review, static successor validation, ownership conflict handling, concurrent-change checks, and atomic exchange apply unchanged. Kit assets never install validators, tests, hooks, workflows, or backend configuration. |
| Host authorization and write admission: `AuthoringSession`, `create_server()`, `_trusted_root()`, `_admit_tree()` | Discovery and inspection remain limited to host-admitted local source handles. MCP preparation and apply remain separate stored-proposal operations behind `allow_prepare` and `allow_writes`, a dedicated write root, review, and exact-input recapture. The local library adds no authentication or authorization policy; a hosting adapter retains actor authorization and redacted audit responsibility. |
| Errors and observability: `KitError`, `KitRecoveryError`, `Diagnostic`, CLI exits `0/1/2/3`, authoring safe envelopes | Keep failures bounded and value-free. Libraries remain silent; no kit-specific exception or logging layer. CLI/MCP output must not echo parameter values, credentials, parser internals, or upstream responses. |
| Repository gates: `tests/test_published_kits.py`, `tests/test_kits.py`, `.github/workflows/ci.yml`, `AGENTS.md` | The publication count becomes 46; every release must load deterministically, compose with default and materially different domain parameters, contain substantive authoring material, and preserve representative multi-kit composition. Use the repository's full verification commands; do not create a parallel kit validator. |

`raes-pack-validate --repo .` and `raes-pack-release check --all` remain pack
gates. Checked-in kit release admission is exercised by the unit suite through
`load_kit_release()` and the published-kit tests. Passing a YAML parse alone is
not release validation.

## Non-goals and anti-patterns

- Do not change the kit, catalog, materialization, pack, or RAES schemas for this
collection extension, and do not duplicate any of their validation logic.
- Do not add a ninth load-balancer kit, product aliases, an authored catalog
file, kit generator framework, runtime plugin, deployment recipe, container
image, package installation, health probe, or backend capability claim.
- Do not treat a source name/version as an immutable artifact, SBOM, signature,
vulnerability result, runtime readiness claim, or proof that a backend can
realize the node.
- Do not turn OpenBao secret values, step-ca key material, RabbitMQ credentials,
LDAP passwords, or k3s join tokens into parameters or benign seed examples.
- Do not represent nftables policy as a listening daemon, client ports as server
listeners, optional management plugins as mandatory services, or every
intra-cluster port as a public endpoint.
- Do not hand-edit `pyproject.toml` version or `CHANGELOG.md`. Each kit has its
own `1.0.0` identity; repository package release metadata remains owned by
release-please.

The extension seam is the existing RAES module parameter/export contract. One
reasonable future variation should be expressible by a domain parameter and
pack-root relationship without changing the kit carrier. If it instead needs a
new semantic concept, resolution belongs upstream in RAES; if it needs runtime
realization, it belongs in a backend.
13 changes: 13 additions & 0 deletions kits/infrastructure.cache-key-value-store/1.0.0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Cache / key-value store

Reusable cache / key-value store authoring content using the RAES module `infrastructure/cache-key-value-store` and declared `valkey` source.

The module exports `nodes.cache` and `content.seed_inventory`. Its `key_prefix` parameter varies the declared inventory without changing those identities.

Declared service surface:

- resp: 6379/tcp — RESP client endpoint.

The seed inventory names keyspace, seed_keys, eviction_policy, persistence_policy. Connect clients at the pack root and choose persistence and access controls in the consuming environment.

This release is static authoring content. The consuming pack and backend own relationships, credential delivery, launch, configuration, and any runtime evidence.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Cache / key-value store integration material

Author parameter: `key_prefix` (default `lab:`).

## Exported RAES declarations

- `nodes.cache`
- `content.seed_inventory`

## Composition notes

- Connect clients at the pack root and choose persistence and access controls in the consuming environment.
- Keep credentials, private keys, and runtime-selected endpoints outside kit parameters and seed assets.
- Validate the completed ordinary pack after adding pack-level relationships.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
schema_version: environment-kit-seed/v1
kit: infrastructure.cache-key-value-store
configuration:
key_prefix: 'lab:'
deployment_profile: standard
service_label: cache-key-value-store
declared_objects:
- id: keyspace
kind: infrastructure-seed
sensitivity: non-secret
- id: seed_keys
kind: infrastructure-seed
sensitivity: non-secret
- id: eviction_policy
kind: infrastructure-seed
sensitivity: non-secret
- id: persistence_policy
kind: infrastructure-seed
sensitivity: non-secret
integration_requirements:
- Connect clients at the pack root and choose persistence and access controls in the consuming
environment.
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"schema_version": "associated-artifact-manifest/v1",
"manifest_id": "infrastructure.cache-key-value-store-associated-artifacts",
"manifest_version": "1.0.0",
"canonicalization_profile": "associated-artifact-set/v1",
"scope": "scenario",
"parent_ref": {
"ref_kind": "scenario-snapshot",
"ref_id": "cache-key-value-store",
"ref_version": null,
"ref_digest": "sha256:049bc9ab36decfd4b7c5f0bd91be421e12a31afd2b5a99a204d56f0c8082b7a3",
"ref_path": null
},
"artifacts": {
"readme": {
"artifact_id": "readme",
"role": "documentation",
"media_type": "text/markdown",
"uri": "raes-environment-kit:/README.md",
"checksum": {
"algorithm": "sha256",
"value": "4362372dbed803d26bb18b12e7503d81397c926a5ea3442e618d17fba17cce34"
},
"size_bytes": 749,
"created_at": "2026-09-20T00:00:00Z",
"source": "infrastructure.cache-key-value-store@1.0.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": "2807ddee824a3e26cc95423230eb9301f6e4fce7b3e1d1bd0ed0e4a91b099cef"
},
"size_bytes": 486,
"created_at": "2026-09-20T00:00:00Z",
"source": "infrastructure.cache-key-value-store@1.0.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": "e0cfb884918e6ccf5832364373d02c5d4e4bd327a56f88fdd04aafe6a74c1393"
},
"size_bytes": 636,
"created_at": "2026-09-20T00:00:00Z",
"source": "infrastructure.cache-key-value-store@1.0.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": "e1560ef1390d68d820d5b08cf30015c2ce6ca718bea8f998c3370dbb41d1d125"
},
"size_bytes": 1583,
"created_at": "2026-09-20T00:00:00Z",
"source": "infrastructure.cache-key-value-store@1.0.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": "210954d98a8847343c98abe9f64f656099e2ffdf03c9edf7a2a7d1ae81f18c78"
},
"size_bytes": 2013,
"created_at": "2026-09-20T00:00:00Z",
"source": "infrastructure.cache-key-value-store@1.0.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": "8abbb7bb9963a9b5a9513111fe4b9028ce0ba8f227c682509ed0f7a614f0a6f1"
},
"size_bytes": 247,
"created_at": "2026-09-20T00:00:00Z",
"source": "infrastructure.cache-key-value-store@1.0.0",
"satisfies_refs": [],
"sensitivity": "public",
"description": null
}
},
"set_digest": "sha256:6e0532671296ce71cab3cd0f69ca0d3a1654ab3c6b8e241be0ce4a2c69fcecb2"
}
47 changes: 47 additions & 0 deletions kits/infrastructure.cache-key-value-store/1.0.0/kit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
schema_version: environment-pack-kit/v1
id: infrastructure.cache-key-value-store
version: 1.0.0
title: Cache / key-value store
summary: Reusable cache / key-value store with a declared software source, service or policy
surfaces, benign seed inventory, and pack-local integration material.
concern: data-workflow
released_at: '2026-09-20T00:00:00Z'
module:
path: module.sdl.yaml
assets:
- source: assets/integration.md
target: assets/kits/cache-key-value-store/integration.md
visibility: operator
artifact_id: integration-material
- source: assets/seed.yaml
target: assets/kits/cache-key-value-store/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 and seeded state only; no launch, readiness, traffic attachment,
or runtime evidence is claimed.
- No cluster bus, live cache contents, or persistence readback is asserted.
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/cache/source
description: RAES carries the declared valkey source; immutable artifact selection remains
unresolved until pack publication.
associated_artifact_manifest: associated-artifacts.json
Loading
Loading