# StackToIT Assess — analysis details — default

> PROPOSAL — generated by StackToIT Assess. Architect review required before any decision.

Run `f6267c3f-2848-4aa5-89df-5fee8b15b3b9` · source digest `sha256:812c5ae3f6cc8530163abbf5b6fbe305ed3b363c4886ec6b87623db857ea0c70`

The working behind `engineering/architect-report.md`. Nothing here is a second decision: the class, confidence and what to do are in `engineering/architect-report.md` and `assessment.json`. For a decision that depends on relations the engine could not resolve statically, this file keeps the engine's own text with every combination it evaluated.

## Uncertainty by cause

8 unit(s) exist only if a plan says so: their count/for_each is not known from the source. They are not counted in the unit totals and the classes above, they are not wave members (the migration plan lists them as prerequisites), they are not automation-eligible (gate blocker `TOPOLOGY:unknown`), and the class shown for them is the one they would get if they exist. Below, they are grouped by the kind of cause; each group names what decides them and the remedy.

By precision state (`summary.presence.conditional_by_state`; no state says the unit exists): 3 off with the defaults of their variables (a variable can switch them on), 5 decided by data OpenTofu reads when it plans.

### A data source, read when a plan runs — 5 unit(s)

**Remedy.** The deciding data source is read when a plan runs, so only a plan resolves it. Produce a plan in your environment (`tofu plan -out p && tofu show -json p > plan.json`): a plan would resolve this value, but StackToIT does not read plans.

**Source constraint.** 5 of these unit(s) have a count that rests on a call the source may not be valid for, so it is an interval, never an exact number (POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact). A plan that succeeds settles it.

| Decided by | Units | Which |
|---|---:|---|
| `module.vpc.data.aws_availability_zones.available` | 5 | `module.vpc.module.vpc.aws_internet_gateway.this`, `module.vpc.module.vpc.aws_route_table.private`, `module.vpc.module.vpc.aws_route_table.public`, `module.vpc.module.vpc.aws_subnet.private`, `module.vpc.module.vpc.aws_subnet.public` |

- `module.vpc.module.vpc.aws_internet_gateway.this` — count: `local.create_public_subnets && var.create_igw ? 1 : 0` (a data source, read when a plan runs) — 0–1 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact — state RUNTIME_DATA_UNKNOWN — would map to RECONFIGURE / MEDIUM (implicit (STACKIT network default gateway))
- `module.vpc.module.vpc.aws_route_table.private` — count: `local.create_private_subnets && local.max_subnet_length > 0 ? local.nat_gateway_count : 0` (a data source, read when a plan runs) — 0–1 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact — state RUNTIME_DATA_UNKNOWN — would map to RECONFIGURE / LOW (implicit (STACKIT network default routing))
- `module.vpc.module.vpc.aws_route_table.public` — count: `local.create_public_subnets ? local.num_public_route_tables : 0` (a data source, read when a plan runs) — 0–1 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact — state RUNTIME_DATA_UNKNOWN — would map to RECONFIGURE / MEDIUM (implicit (STACKIT network default routing))
- `module.vpc.module.vpc.aws_subnet.private` — count: `local.create_private_subnets ? local.len_private_subnets : 0` (a data source, read when a plan runs) — 0–3 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact — state RUNTIME_DATA_UNKNOWN — would map to RECONFIGURE / MEDIUM (STACKIT network)
- `module.vpc.module.vpc.aws_subnet.public` — count: `local.create_public_subnets && (!var.one_nat_gateway_per_az || local.len_public_subnets >= length(var.azs)) ? local.len_public_subnets : 0` (a data source, read when a plan runs) — 0–3 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact — state RUNTIME_DATA_UNKNOWN — would map to RECONFIGURE / MEDIUM (STACKIT network)

### A root variable that a variable file or the command line can override — 3 unit(s)

**Remedy.** Only the default of a root variable decides whether this exists on the defaults (a default of 0, false or an empty set switches it off) and how often, and a default is not a fact of the source: a variable file, `-var` or `TF_VAR_<name>` can change it, so it is never read as existing now. Give the variable its value — `--var-file FILE`, or a `terraform.tfvars` / `*.auto.tfvars` next to the source — and assess again; StackToIT then reads that value as the source's.

| Decided by | Units | Which |
|---|---:|---|
| the defaults of the variables `var.container_insights_setting`, `var.lifecycle_events_enabled` | 3 | `module.retail_app_ecs.aws_cloudwatch_event_rule.ecs_events`, `module.retail_app_ecs.aws_cloudwatch_log_group.ecs_container_insights`, `module.retail_app_ecs.aws_cloudwatch_log_resource_policy.eventbridge_ecs` |

- `module.retail_app_ecs.aws_cloudwatch_event_rule.ecs_events` — count: `(var.container_insights_setting == "enhanced" && var.lifecycle_events_enabled) ? 1 : 0` (a root variable that a variable file or the command line can override) — state DISABLED_ON_DEFAULTS_BUT_OVERRIDABLE — would map to REDESIGN / MEDIUM (none managed — application events over RabbitMQ)
- `module.retail_app_ecs.aws_cloudwatch_log_group.ecs_container_insights` — count: `(var.container_insights_setting == "enhanced" && var.lifecycle_events_enabled) ? 1 : 0` (a root variable that a variable file or the command line can override) — state DISABLED_ON_DEFAULTS_BUT_OVERRIDABLE — would map to RECONFIGURE / MEDIUM (STACKIT Logs)
- `module.retail_app_ecs.aws_cloudwatch_log_resource_policy.eventbridge_ecs` — count: `(var.container_insights_setting == "enhanced" && var.lifecycle_events_enabled) ? 1 : 0` (a root variable that a variable file or the command line can override) — state DISABLED_ON_DEFAULTS_BUT_OVERRIDABLE — would map to RECONFIGURE / LOW (STACKIT Logs access tokens)

## Resources a default switches off

11 resource(s) are switched off by the default of a root variable (or by the workspace): their count/for_each reads zero there, a variable file or `-var` can change it, so whether they exist is decided when a plan runs. They are no migration unit, they are not drafted, and the unit that carries one lists it in its Configuration line. Give the variable its value — `--var-file FILE`, or a `terraform.tfvars` / `*.auto.tfvars` next to the source — and they are decided.

| Decided by | Resources | Which |
|---|---:|---|
| the default of variable `var.opentelemetry_enabled` | 10 | `module.retail_app_ecs.module.carts_service.aws_iam_policy.cloudwatch_agent`, `module.retail_app_ecs.module.carts_service.aws_iam_role_policy_attachment.cloudwatch_agent`, `module.retail_app_ecs.module.catalog_service.aws_iam_policy.cloudwatch_agent`, `module.retail_app_ecs.module.catalog_service.aws_iam_role_policy_attachment.cloudwatch_agent`, `module.retail_app_ecs.module.checkout_service.aws_iam_policy.cloudwatch_agent`, `module.retail_app_ecs.module.checkout_service.aws_iam_role_policy_attachment.cloudwatch_agent`, `module.retail_app_ecs.module.orders_service.aws_iam_policy.cloudwatch_agent`, `module.retail_app_ecs.module.orders_service.aws_iam_role_policy_attachment.cloudwatch_agent`, `module.retail_app_ecs.module.ui_service.aws_iam_policy.cloudwatch_agent`, `module.retail_app_ecs.module.ui_service.aws_iam_role_policy_attachment.cloudwatch_agent` |
| the defaults of the variables `var.container_insights_setting`, `var.lifecycle_events_enabled` | 1 | `module.retail_app_ecs.aws_cloudwatch_event_target.ecs_events_target` |

- `module.retail_app_ecs.module.carts_service.aws_iam_policy.cloudwatch_agent` (aws_iam_policy) — carried by no unit — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.carts_service.aws_iam_role_policy_attachment.cloudwatch_agent` (aws_iam_role_policy_attachment) — carried by `module.retail_app_ecs.module.carts_service.aws_iam_role.task_role` — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.catalog_service.aws_iam_policy.cloudwatch_agent` (aws_iam_policy) — carried by no unit — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.catalog_service.aws_iam_role_policy_attachment.cloudwatch_agent` (aws_iam_role_policy_attachment) — carried by `module.retail_app_ecs.module.catalog_service.aws_iam_role.task_role` — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.checkout_service.aws_iam_policy.cloudwatch_agent` (aws_iam_policy) — carried by no unit — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.checkout_service.aws_iam_role_policy_attachment.cloudwatch_agent` (aws_iam_role_policy_attachment) — carried by `module.retail_app_ecs.module.checkout_service.aws_iam_role.task_role` — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.orders_service.aws_iam_policy.cloudwatch_agent` (aws_iam_policy) — carried by no unit — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.orders_service.aws_iam_role_policy_attachment.cloudwatch_agent` (aws_iam_role_policy_attachment) — carried by `module.retail_app_ecs.module.orders_service.aws_iam_role.task_role` — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.ui_service.aws_iam_policy.cloudwatch_agent` (aws_iam_policy) — carried by no unit — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.module.ui_service.aws_iam_role_policy_attachment.cloudwatch_agent` (aws_iam_role_policy_attachment) — carried by `module.retail_app_ecs.module.ui_service.aws_iam_role.task_role` — count: `var.opentelemetry_enabled ? 1 : 0`
- `module.retail_app_ecs.aws_cloudwatch_event_target.ecs_events_target` (aws_cloudwatch_event_target) — carried by `module.retail_app_ecs.aws_cloudwatch_event_rule.ecs_events` — count: `(var.container_insights_setting == "enhanced" && var.lifecycle_events_enabled) ? 1 : 0`

## Modules

Every module call the scan reached, as the loader found it. A module whose state is not LOADED was not read: its resources are invisible to this assessment.

| Module call | Source kind | Source | Version constraint → resolved | State | Reason | Presence | Dir |
|---|---|---|---|---|---|---|---|
| `module.dependencies` | local | ../../lib/dependencies | — | LOADED | — | KNOWN_PRESENT | ../../lib/dependencies |
| `module.dependencies.module.catalog_opensearch` | registry | terraform-aws-modules/opensearch/aws | 1.5.0 → 1.5.0 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.catalog_opensearch |
| `module.dependencies.module.catalog_rds` | registry | terraform-aws-modules/rds-aurora/aws | 7.7.1 → 7.7.1 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.catalog_rds |
| `module.dependencies.module.checkout_elasticache_redis` | registry | cloudposse/elasticache-redis/aws | 0.53.0 → 0.53.0 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.checkout_elasticache_redis |
| `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group` | registry | cloudposse/security-group/aws | 1.0.1 → 1.0.1 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.checkout_elasticache_redis.aws_security_group |
| `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.module.this` | registry | cloudposse/label/null | 0.25.0 → 0.25.0 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.checkout_elasticache_redis.aws_security_group.this |
| `module.dependencies.module.checkout_elasticache_redis.module.dns` | registry | cloudposse/route53-cluster-hostname/aws | 0.12.2 → 0.12.2 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.checkout_elasticache_redis.dns |
| `module.dependencies.module.checkout_elasticache_redis.module.dns.module.this` | registry | cloudposse/label/null | 0.25.0 → 0.25.0 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.checkout_elasticache_redis.dns.this |
| `module.dependencies.module.checkout_elasticache_redis.module.this` | registry | cloudposse/label/null | 0.25.0 → 0.25.0 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.checkout_elasticache_redis.this |
| `module.dependencies.module.dynamodb_carts` | registry | terraform-aws-modules/dynamodb-table/aws | 3.3.0 → 3.3.0 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.dynamodb_carts |
| `module.dependencies.module.orders_rds` | registry | terraform-aws-modules/rds-aurora/aws | 7.7.1 → 7.7.1 | LOADED | — | KNOWN_PRESENT | .terraform/modules/dependencies.orders_rds |
| `module.retail_app_ecs` | local | ../../lib/ecs | — | LOADED | — | KNOWN_PRESENT | ../../lib/ecs |
| `module.retail_app_ecs.module.alb` | registry | terraform-aws-modules/alb/aws | ~> 8.0 → 8.7.0 | LOADED | — | KNOWN_PRESENT | .terraform/modules/retail_app_ecs.alb |
| `module.retail_app_ecs.module.alb_sg` | registry | terraform-aws-modules/security-group/aws | ~> 4.0 → 4.17.2 | LOADED | — | KNOWN_PRESENT | .terraform/modules/retail_app_ecs.alb_sg |
| `module.retail_app_ecs.module.carts_service` | local | ./service | — | LOADED | — | KNOWN_PRESENT | ../../lib/ecs/service |
| `module.retail_app_ecs.module.catalog_service` | local | ./service | — | LOADED | — | KNOWN_PRESENT | ../../lib/ecs/service |
| `module.retail_app_ecs.module.checkout_service` | local | ./service | — | LOADED | — | KNOWN_PRESENT | ../../lib/ecs/service |
| `module.retail_app_ecs.module.container_images` | local | ../images | — | LOADED | — | KNOWN_PRESENT | ../../lib/images |
| `module.retail_app_ecs.module.orders_service` | local | ./service | — | LOADED | — | KNOWN_PRESENT | ../../lib/ecs/service |
| `module.retail_app_ecs.module.ui_service` | local | ./service | — | LOADED | — | KNOWN_PRESENT | ../../lib/ecs/service |
| `module.tags` | local | ../../lib/tags | — | LOADED | — | KNOWN_PRESENT | ../../lib/tags |
| `module.vpc` | local | ../../lib/vpc | — | LOADED | — | KNOWN_PRESENT | ../../lib/vpc |
| `module.vpc.module.vpc` | registry | terraform-aws-modules/vpc/aws | 5.21.0 → 5.21.0 | LOADED | — | KNOWN_PRESENT | .terraform/modules/vpc.vpc |

### Compute

#### `module.retail_app_ecs.aws_ecs_cluster.cluster`

- **Source:** `aws_ecs_cluster` — ../../lib/ecs/cluster.tf:1
- **Classification:** REPLATFORM · **Confidence:** MEDIUM · rule `aws.ecs/ecs-to-ske`
- **Semantic surface** (contract `aws.ecs`): 0 of 122 semantics stated by the source, 0 accounted, 0 unaccounted
- **Property accounting:** 3 of 3 meaningful properties accounted (not carried 2 · contract 0 · consumed by the draft 1 · relation 0 · placement 0)

#### `module.retail_app_ecs.module.carts_service.aws_ecs_service.this`

- **Source:** `aws_ecs_service` — ../../lib/ecs/service/ecs.tf:136
- **Classification:** REPLATFORM · **Confidence:** LOW · rule `aws.ecs/ecs-to-ske`
- **Semantic surface** (contract `aws.ecs`): 15 of 122 semantics stated by the source, 15 accounted, 0 unaccounted — critical left for review/accepted loss: service-connect-values, service-desired-count, service-discovery, service-execute-command, service-network-placement, service-public-ip-setting, service-task-definition, task-definition, td-container-definitions, td-container-image-registry, td-container-plaintext-secret-env, td-container-secret-references, td-execution-role-arn, td-network-mode, td-task-role-arn (**not automation-eligible**: no property the unit sets is read by linked-dependency:aws_dynamodb_table, service-discovery)
  - `service-discovery` (critical): REVIEW · a check of the knowledge base (ecs service discovery) (knowledge-base check ecs-service-discovery)
    - why it is open: A check of the knowledge base (ecs service discovery) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting states how ECS services find each other: AWS Cloud Map registries and namespaces, or ECS Service Connect.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person replaces the lookups with Kubernetes Services and cluster DNS on SKE.
  - `task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The ECS task definition: the containers a service runs, with their CPU and memory, environment, secrets and health checks.
    - what closes it: A person translates the task definition into Kubernetes Deployments and Services on SKE (CPU and memory, environment, secrets and health checks become manifest fields); the rule names a Cloud Foundry push as the other way for a simple web app.
  - `service-task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition the service runs (family:revision or ARN) becomes the Deployment's pod template; ecs_service.task_definition names it as a string, the definition itself is a separate resource a person translates.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-desired-count` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. desired_count is the number of tasks ECS keeps running (ecs_service docs: 'Number of instances of the task definition to place and keep running'); on SKE it becomes Deployment replicas or a HorizontalPodAutoscaler floor. The draft writes it as the replicas of the Deployment in kubernetes/<service>/manifests.yaml when it is a literal number (a HorizontalPodAutoscaler owns the count where the service has a scaling target and policy the draft translates; a number that is not visible statically is a REQUIRED_ token) — a person confirms the number, REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-execute-command` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ECS Exec opens a shell in a running task; kubectl exec (and who may use it through RBAC) is the counterpart and is not part of the draft.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-network-placement` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The subnets and security groups the tasks' network interfaces use (awsvpc mode); on SKE pods take the cluster's network and NetworkPolicies decide reachability — a person re-expresses the security group rules.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-public-ip-setting` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. assign_public_ip in either state (the public ip setting reads only true through the public address check): tasks with a public address are exposed unless a person decides the exposure on SKE explicitly (LoadBalancer services, network policies); false is the private default and is still re-checked, the draft carries no service block.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-connect-values` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Service Connect's switch, namespace, service names, client aliases (DNS name and port), traffic-test header rules, mTLS settings (KMS key, role, private CA) and proxy logging: an AWS-managed service mesh with no draft counterpart; discovery on SKE is Kubernetes Services and DNS, mesh features a person's choice.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-definitions` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.container_definitions of the unit that runs the task. The containers of the task: images, commands, environment, secret references, ports, health checks, log configuration - the workload itself, and where its credentials are injected. Decide per container: the image and where it lives, command and entry point, environment, ports and health check, cpu/memory as requests and limits, and the log destination; the secret references and the plaintext secrets among the environment entries are read by the settings of the secret references and of the plaintext secrets, the registry by the setting of the image registry. The unit names module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this (aws_dynamodb_table) through this setting (the target does not carry it: it is REDESIGN), so what the reference becomes is part of this setting.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-secret-references` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition's container_definitions state secret references (the `secrets` list: name and valueFrom, "the full ARN of the AWS Secrets Manager secret or the full ARN of the parameter in the SSM Parameter Store", AWS ECS API reference, Secret). A person decides first which STACKIT Secrets Manager instance holds each referenced secret (stackit_secretsmanager_instance, pinned provider: name, acls, kms_key; the secret entries themselves have no Terraform resource in the pinned provider, they are created through the API or the portal, and their VALUES are never in the Terraform sources - a person copies them). Second, a person decides how the pods read them (the STACKIT Secrets Manager authenticates with Vault-compatible tokens and AppRole, docs.stackit.cloud/products/security/secrets-manager/; ECS injects valueFrom into environment variables when the container starts, and no STACKIT equivalent of that injection is stated on the documentation page checked 2026-10-06, so the Kubernetes Secret or the in-pod fetch is a design of its own).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-plaintext-secret-env` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. An `environment` entry whose NAME looks like a credential (password, secret, token, api key, private key, credential) carries a non-empty plaintext value in the task definition (a name heuristic, not a proof: the value is never shown). Decide: whether the value is a secret; if it is, it must not be copied into a Kubernetes manifest or a Terraform variable default but stored in a STACKIT Secrets Manager entry and the plaintext copy in the AWS state and task definition rotated.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-image-registry` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A container image comes from Amazon ECR (a `.dkr.ecr.` or public.ecr.aws registry host) or needs `repositoryCredentials`. The images are not moved by the draft and a pod on STACKIT cannot assume the ECR pull rights of the ECS execution role. Decide: where the images live on STACKIT (the STACKIT Container Registry has a GA API, the Container Registry API specification, but no Terraform resource in pinned provider; a registry of your choice works too), how they are copied, and the pull secret the cluster uses.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-execution-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.execution_role_arn of the template the group builds its instances from: The role ECS uses to pull images and read the secrets it injects into the containers. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-network-mode` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.network_mode of the template the group builds its instances from: How the containers are networked (awsvpc, bridge, host, none): whether each task has its own interface and security groups or shares the host's network. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-task-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.task_role_arn of the template the group builds its instances from: The role the application in the containers acts as towards AWS APIs. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `linked-dependency:aws_dynamodb_table` (critical): REVIEW · linked-dependency:aws_dynamodb_table
- **Property accounting:** 24 of 24 meaningful properties accounted (not carried 14 · contract 8 · consumed by the draft 2 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.desired_count` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.enable_execute_command` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.network_configuration.assign_public_ip` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.network_configuration.security_groups` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.network_configuration.subnets` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.service_connect_configuration.enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.service_connect_configuration.namespace` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.dns_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.service_connect_configuration.service.discovery_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.service_connect_configuration.service.port_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_service.this.task_definition` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_task_definition.this.container_definitions` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_task_definition.this.execution_role_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_task_definition.this.network_mode` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_ecs_task_definition.this.task_role_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this`

- **Source:** `aws_ecs_service` — ../../lib/ecs/service/ecs.tf:136
- **Classification:** REPLATFORM · **Confidence:** LOW · rule `aws.ecs/ecs-to-ske`
- **Semantic surface** (contract `aws.ecs`): 15 of 122 semantics stated by the source, 15 accounted, 0 unaccounted — critical left for review/accepted loss: service-connect-values, service-desired-count, service-discovery, service-execute-command, service-network-placement, service-public-ip-setting, service-task-definition, task-definition, td-container-definitions, td-container-image-registry, td-container-plaintext-secret-env, td-container-secret-references, td-execution-role-arn, td-network-mode, td-task-role-arn (**not automation-eligible**: no property the unit sets is read by linked-dependency:aws_secretsmanager_secret_version, service-discovery)
  - `service-discovery` (critical): REVIEW · a check of the knowledge base (ecs service discovery) (knowledge-base check ecs-service-discovery)
    - why it is open: A check of the knowledge base (ecs service discovery) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting states how ECS services find each other: AWS Cloud Map registries and namespaces, or ECS Service Connect.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person replaces the lookups with Kubernetes Services and cluster DNS on SKE.
  - `task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The ECS task definition: the containers a service runs, with their CPU and memory, environment, secrets and health checks.
    - what closes it: A person translates the task definition into Kubernetes Deployments and Services on SKE (CPU and memory, environment, secrets and health checks become manifest fields); the rule names a Cloud Foundry push as the other way for a simple web app.
  - `service-task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition the service runs (family:revision or ARN) becomes the Deployment's pod template; ecs_service.task_definition names it as a string, the definition itself is a separate resource a person translates.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-desired-count` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. desired_count is the number of tasks ECS keeps running (ecs_service docs: 'Number of instances of the task definition to place and keep running'); on SKE it becomes Deployment replicas or a HorizontalPodAutoscaler floor. The draft writes it as the replicas of the Deployment in kubernetes/<service>/manifests.yaml when it is a literal number (a HorizontalPodAutoscaler owns the count where the service has a scaling target and policy the draft translates; a number that is not visible statically is a REQUIRED_ token) — a person confirms the number, REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-execute-command` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ECS Exec opens a shell in a running task; kubectl exec (and who may use it through RBAC) is the counterpart and is not part of the draft.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-network-placement` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The subnets and security groups the tasks' network interfaces use (awsvpc mode); on SKE pods take the cluster's network and NetworkPolicies decide reachability — a person re-expresses the security group rules.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-public-ip-setting` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. assign_public_ip in either state (the public ip setting reads only true through the public address check): tasks with a public address are exposed unless a person decides the exposure on SKE explicitly (LoadBalancer services, network policies); false is the private default and is still re-checked, the draft carries no service block.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-connect-values` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Service Connect's switch, namespace, service names, client aliases (DNS name and port), traffic-test header rules, mTLS settings (KMS key, role, private CA) and proxy logging: an AWS-managed service mesh with no draft counterpart; discovery on SKE is Kubernetes Services and DNS, mesh features a person's choice.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-definitions` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.container_definitions of the unit that runs the task. The containers of the task: images, commands, environment, secret references, ports, health checks, log configuration - the workload itself, and where its credentials are injected. Decide per container: the image and where it lives, command and entry point, environment, ports and health check, cpu/memory as requests and limits, and the log destination; the secret references and the plaintext secrets among the environment entries are read by the settings of the secret references and of the plaintext secrets, the registry by the setting of the image registry. The unit names 2 resources through this setting whose references the draft does not resolve: module.retail_app_ecs.aws_secretsmanager_secret_version.catalog_db (aws_secretsmanager_secret_version), module.retail_app_ecs.aws_secretsmanager_secret_version.catalog_opensearch (aws_secretsmanager_secret_version). What each reference becomes is part of this setting.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-secret-references` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition's container_definitions state secret references (the `secrets` list: name and valueFrom, "the full ARN of the AWS Secrets Manager secret or the full ARN of the parameter in the SSM Parameter Store", AWS ECS API reference, Secret). A person decides first which STACKIT Secrets Manager instance holds each referenced secret (stackit_secretsmanager_instance, pinned provider: name, acls, kms_key; the secret entries themselves have no Terraform resource in the pinned provider, they are created through the API or the portal, and their VALUES are never in the Terraform sources - a person copies them). Second, a person decides how the pods read them (the STACKIT Secrets Manager authenticates with Vault-compatible tokens and AppRole, docs.stackit.cloud/products/security/secrets-manager/; ECS injects valueFrom into environment variables when the container starts, and no STACKIT equivalent of that injection is stated on the documentation page checked 2026-10-06, so the Kubernetes Secret or the in-pod fetch is a design of its own).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-plaintext-secret-env` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. An `environment` entry whose NAME looks like a credential (password, secret, token, api key, private key, credential) carries a non-empty plaintext value in the task definition (a name heuristic, not a proof: the value is never shown). Decide: whether the value is a secret; if it is, it must not be copied into a Kubernetes manifest or a Terraform variable default but stored in a STACKIT Secrets Manager entry and the plaintext copy in the AWS state and task definition rotated.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-image-registry` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A container image comes from Amazon ECR (a `.dkr.ecr.` or public.ecr.aws registry host) or needs `repositoryCredentials`. The images are not moved by the draft and a pod on STACKIT cannot assume the ECR pull rights of the ECS execution role. Decide: where the images live on STACKIT (the STACKIT Container Registry has a GA API, the Container Registry API specification, but no Terraform resource in pinned provider; a registry of your choice works too), how they are copied, and the pull secret the cluster uses.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-execution-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.execution_role_arn of the template the group builds its instances from: The role ECS uses to pull images and read the secrets it injects into the containers. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-network-mode` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.network_mode of the template the group builds its instances from: How the containers are networked (awsvpc, bridge, host, none): whether each task has its own interface and security groups or shares the host's network. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-task-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.task_role_arn of the template the group builds its instances from: The role the application in the containers acts as towards AWS APIs. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `linked-dependency:aws_secretsmanager_secret_version` (critical): REVIEW · linked-dependency:aws_secretsmanager_secret_version
- **Property accounting:** 24 of 24 meaningful properties accounted (not carried 14 · contract 8 · consumed by the draft 2 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.desired_count` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.enable_execute_command` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.network_configuration.assign_public_ip` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.network_configuration.security_groups` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.network_configuration.subnets` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.service_connect_configuration.enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.service_connect_configuration.namespace` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.dns_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.service_connect_configuration.service.discovery_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.service_connect_configuration.service.port_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_service.this.task_definition` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_task_definition.this.container_definitions` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_task_definition.this.execution_role_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_task_definition.this.network_mode` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_ecs_task_definition.this.task_role_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.orders_service.aws_ecs_service.this`

- **Source:** `aws_ecs_service` — ../../lib/ecs/service/ecs.tf:136
- **Classification:** REPLATFORM · **Confidence:** LOW · rule `aws.ecs/ecs-to-ske`
- **Semantic surface** (contract `aws.ecs`): 15 of 122 semantics stated by the source, 15 accounted, 0 unaccounted — critical left for review/accepted loss: service-connect-values, service-desired-count, service-discovery, service-execute-command, service-network-placement, service-public-ip-setting, service-task-definition, task-definition, td-container-definitions, td-container-image-registry, td-container-plaintext-secret-env, td-container-secret-references, td-execution-role-arn, td-network-mode, td-task-role-arn (**not automation-eligible**: no property the unit sets is read by linked-dependency:aws_secretsmanager_secret_version, service-discovery)
  - `service-discovery` (critical): REVIEW · a check of the knowledge base (ecs service discovery) (knowledge-base check ecs-service-discovery)
    - why it is open: A check of the knowledge base (ecs service discovery) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting states how ECS services find each other: AWS Cloud Map registries and namespaces, or ECS Service Connect.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person replaces the lookups with Kubernetes Services and cluster DNS on SKE.
  - `task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The ECS task definition: the containers a service runs, with their CPU and memory, environment, secrets and health checks.
    - what closes it: A person translates the task definition into Kubernetes Deployments and Services on SKE (CPU and memory, environment, secrets and health checks become manifest fields); the rule names a Cloud Foundry push as the other way for a simple web app.
  - `service-task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition the service runs (family:revision or ARN) becomes the Deployment's pod template; ecs_service.task_definition names it as a string, the definition itself is a separate resource a person translates.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-desired-count` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. desired_count is the number of tasks ECS keeps running (ecs_service docs: 'Number of instances of the task definition to place and keep running'); on SKE it becomes Deployment replicas or a HorizontalPodAutoscaler floor. The draft writes it as the replicas of the Deployment in kubernetes/<service>/manifests.yaml when it is a literal number (a HorizontalPodAutoscaler owns the count where the service has a scaling target and policy the draft translates; a number that is not visible statically is a REQUIRED_ token) — a person confirms the number, REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-execute-command` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ECS Exec opens a shell in a running task; kubectl exec (and who may use it through RBAC) is the counterpart and is not part of the draft.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-network-placement` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The subnets and security groups the tasks' network interfaces use (awsvpc mode); on SKE pods take the cluster's network and NetworkPolicies decide reachability — a person re-expresses the security group rules.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-public-ip-setting` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. assign_public_ip in either state (the public ip setting reads only true through the public address check): tasks with a public address are exposed unless a person decides the exposure on SKE explicitly (LoadBalancer services, network policies); false is the private default and is still re-checked, the draft carries no service block.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-connect-values` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Service Connect's switch, namespace, service names, client aliases (DNS name and port), traffic-test header rules, mTLS settings (KMS key, role, private CA) and proxy logging: an AWS-managed service mesh with no draft counterpart; discovery on SKE is Kubernetes Services and DNS, mesh features a person's choice.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-definitions` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.container_definitions of the unit that runs the task. The containers of the task: images, commands, environment, secret references, ports, health checks, log configuration - the workload itself, and where its credentials are injected. Decide per container: the image and where it lives, command and entry point, environment, ports and health check, cpu/memory as requests and limits, and the log destination; the secret references and the plaintext secrets among the environment entries are read by the settings of the secret references and of the plaintext secrets, the registry by the setting of the image registry. The unit names 2 resources through this setting whose references the draft does not resolve: module.retail_app_ecs.aws_secretsmanager_secret_version.mq (aws_secretsmanager_secret_version), module.retail_app_ecs.aws_secretsmanager_secret_version.orders_db (aws_secretsmanager_secret_version). What each reference becomes is part of this setting.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-secret-references` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition's container_definitions state secret references (the `secrets` list: name and valueFrom, "the full ARN of the AWS Secrets Manager secret or the full ARN of the parameter in the SSM Parameter Store", AWS ECS API reference, Secret). A person decides first which STACKIT Secrets Manager instance holds each referenced secret (stackit_secretsmanager_instance, pinned provider: name, acls, kms_key; the secret entries themselves have no Terraform resource in the pinned provider, they are created through the API or the portal, and their VALUES are never in the Terraform sources - a person copies them). Second, a person decides how the pods read them (the STACKIT Secrets Manager authenticates with Vault-compatible tokens and AppRole, docs.stackit.cloud/products/security/secrets-manager/; ECS injects valueFrom into environment variables when the container starts, and no STACKIT equivalent of that injection is stated on the documentation page checked 2026-10-06, so the Kubernetes Secret or the in-pod fetch is a design of its own).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-plaintext-secret-env` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. An `environment` entry whose NAME looks like a credential (password, secret, token, api key, private key, credential) carries a non-empty plaintext value in the task definition (a name heuristic, not a proof: the value is never shown). Decide: whether the value is a secret; if it is, it must not be copied into a Kubernetes manifest or a Terraform variable default but stored in a STACKIT Secrets Manager entry and the plaintext copy in the AWS state and task definition rotated.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-image-registry` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A container image comes from Amazon ECR (a `.dkr.ecr.` or public.ecr.aws registry host) or needs `repositoryCredentials`. The images are not moved by the draft and a pod on STACKIT cannot assume the ECR pull rights of the ECS execution role. Decide: where the images live on STACKIT (the STACKIT Container Registry has a GA API, the Container Registry API specification, but no Terraform resource in pinned provider; a registry of your choice works too), how they are copied, and the pull secret the cluster uses.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-execution-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.execution_role_arn of the template the group builds its instances from: The role ECS uses to pull images and read the secrets it injects into the containers. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-network-mode` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.network_mode of the template the group builds its instances from: How the containers are networked (awsvpc, bridge, host, none): whether each task has its own interface and security groups or shares the host's network. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-task-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.task_role_arn of the template the group builds its instances from: The role the application in the containers acts as towards AWS APIs. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `linked-dependency:aws_secretsmanager_secret_version` (critical): REVIEW · linked-dependency:aws_secretsmanager_secret_version
- **Property accounting:** 24 of 24 meaningful properties accounted (not carried 14 · contract 8 · consumed by the draft 2 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.desired_count` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.enable_execute_command` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.network_configuration.assign_public_ip` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.network_configuration.security_groups` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.network_configuration.subnets` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.service_connect_configuration.enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.service_connect_configuration.namespace` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.dns_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.service_connect_configuration.service.discovery_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.service_connect_configuration.service.port_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_service.this.task_definition` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_task_definition.this.container_definitions` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_task_definition.this.execution_role_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_task_definition.this.network_mode` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_ecs_task_definition.this.task_role_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this`

- **Source:** `aws_ecs_service` — ../../lib/ecs/service/ecs.tf:136
- **Classification:** REPLATFORM · **Confidence:** MEDIUM · rule `aws.ecs/ecs-to-ske`
- **Semantic surface** (contract `aws.ecs`): 15 of 122 semantics stated by the source, 15 accounted, 0 unaccounted — critical left for review/accepted loss: service-discovery, task-definition, service-task-definition, service-desired-count, service-execute-command, service-network-placement, service-public-ip-setting, service-connect-values, td-container-definitions, td-container-secret-references, td-container-plaintext-secret-env, td-container-image-registry, td-execution-role-arn, td-network-mode, td-task-role-arn (**not automation-eligible**: no property the unit sets is read by service-discovery)
  - `service-discovery` (critical): REVIEW · a check of the knowledge base (ecs service discovery) (knowledge-base check ecs-service-discovery)
    - why it is open: A check of the knowledge base (ecs service discovery) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting states how ECS services find each other: AWS Cloud Map registries and namespaces, or ECS Service Connect.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person replaces the lookups with Kubernetes Services and cluster DNS on SKE.
  - `task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The ECS task definition: the containers a service runs, with their CPU and memory, environment, secrets and health checks.
    - what closes it: A person translates the task definition into Kubernetes Deployments and Services on SKE (CPU and memory, environment, secrets and health checks become manifest fields); the rule names a Cloud Foundry push as the other way for a simple web app.
  - `service-task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition the service runs (family:revision or ARN) becomes the Deployment's pod template; ecs_service.task_definition names it as a string, the definition itself is a separate resource a person translates.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-desired-count` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. desired_count is the number of tasks ECS keeps running (ecs_service docs: 'Number of instances of the task definition to place and keep running'); on SKE it becomes Deployment replicas or a HorizontalPodAutoscaler floor. The draft writes it as the replicas of the Deployment in kubernetes/<service>/manifests.yaml when it is a literal number (a HorizontalPodAutoscaler owns the count where the service has a scaling target and policy the draft translates; a number that is not visible statically is a REQUIRED_ token) — a person confirms the number, REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-execute-command` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ECS Exec opens a shell in a running task; kubectl exec (and who may use it through RBAC) is the counterpart and is not part of the draft.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-network-placement` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The subnets and security groups the tasks' network interfaces use (awsvpc mode); on SKE pods take the cluster's network and NetworkPolicies decide reachability — a person re-expresses the security group rules.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-public-ip-setting` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. assign_public_ip in either state (the public ip setting reads only true through the public address check): tasks with a public address are exposed unless a person decides the exposure on SKE explicitly (LoadBalancer services, network policies); false is the private default and is still re-checked, the draft carries no service block.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-connect-values` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Service Connect's switch, namespace, service names, client aliases (DNS name and port), traffic-test header rules, mTLS settings (KMS key, role, private CA) and proxy logging: an AWS-managed service mesh with no draft counterpart; discovery on SKE is Kubernetes Services and DNS, mesh features a person's choice.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-definitions` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.container_definitions of the unit that runs the task. The containers of the task: images, commands, environment, secret references, ports, health checks, log configuration - the workload itself, and where its credentials are injected. Decide per container: the image and where it lives, command and entry point, environment, ports and health check, cpu/memory as requests and limits, and the log destination; the secret references and the plaintext secrets among the environment entries are read by the settings of the secret references and of the plaintext secrets, the registry by the setting of the image registry.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-secret-references` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition's container_definitions state secret references (the `secrets` list: name and valueFrom, "the full ARN of the AWS Secrets Manager secret or the full ARN of the parameter in the SSM Parameter Store", AWS ECS API reference, Secret). A person decides first which STACKIT Secrets Manager instance holds each referenced secret (stackit_secretsmanager_instance, pinned provider: name, acls, kms_key; the secret entries themselves have no Terraform resource in the pinned provider, they are created through the API or the portal, and their VALUES are never in the Terraform sources - a person copies them). Second, a person decides how the pods read them (the STACKIT Secrets Manager authenticates with Vault-compatible tokens and AppRole, docs.stackit.cloud/products/security/secrets-manager/; ECS injects valueFrom into environment variables when the container starts, and no STACKIT equivalent of that injection is stated on the documentation page checked 2026-10-06, so the Kubernetes Secret or the in-pod fetch is a design of its own).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-plaintext-secret-env` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. An `environment` entry whose NAME looks like a credential (password, secret, token, api key, private key, credential) carries a non-empty plaintext value in the task definition (a name heuristic, not a proof: the value is never shown). Decide: whether the value is a secret; if it is, it must not be copied into a Kubernetes manifest or a Terraform variable default but stored in a STACKIT Secrets Manager entry and the plaintext copy in the AWS state and task definition rotated.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-image-registry` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A container image comes from Amazon ECR (a `.dkr.ecr.` or public.ecr.aws registry host) or needs `repositoryCredentials`. The images are not moved by the draft and a pod on STACKIT cannot assume the ECR pull rights of the ECS execution role. Decide: where the images live on STACKIT (the STACKIT Container Registry has a GA API, the Container Registry API specification, but no Terraform resource in pinned provider; a registry of your choice works too), how they are copied, and the pull secret the cluster uses.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-execution-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.execution_role_arn of the template the group builds its instances from: The role ECS uses to pull images and read the secrets it injects into the containers. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-network-mode` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.network_mode of the template the group builds its instances from: How the containers are networked (awsvpc, bridge, host, none): whether each task has its own interface and security groups or shares the host's network. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-task-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.task_role_arn of the template the group builds its instances from: The role the application in the containers acts as towards AWS APIs. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
- **Property accounting:** 24 of 24 meaningful properties accounted (not carried 14 · contract 8 · consumed by the draft 2 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.desired_count` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.enable_execute_command` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.network_configuration.assign_public_ip` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.network_configuration.security_groups` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.network_configuration.subnets` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.service_connect_configuration.enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.service_connect_configuration.namespace` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.dns_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.service_connect_configuration.service.discovery_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.service_connect_configuration.service.port_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_service.this.task_definition` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_task_definition.this.container_definitions` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_task_definition.this.execution_role_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_task_definition.this.network_mode` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_ecs_task_definition.this.task_role_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.ui_service.aws_ecs_service.this`

- **Source:** `aws_ecs_service` — ../../lib/ecs/service/ecs.tf:136
- **Classification:** REPLATFORM · **Confidence:** MEDIUM · rule `aws.ecs/ecs-to-ske`
- **Semantic surface** (contract `aws.ecs`): 16 of 122 semantics stated by the source, 16 accounted, 0 unaccounted — critical left for review/accepted loss: service-discovery, task-definition, service-task-definition, service-desired-count, service-execute-command, service-load-balancer-target, service-network-placement, service-public-ip-setting, service-connect-values, td-container-definitions, td-container-secret-references, td-container-plaintext-secret-env, td-container-image-registry, td-execution-role-arn, td-network-mode, td-task-role-arn (**not automation-eligible**: no property the unit sets is read by service-discovery)
  - `service-discovery` (critical): REVIEW · a check of the knowledge base (ecs service discovery) (knowledge-base check ecs-service-discovery)
    - why it is open: A check of the knowledge base (ecs service discovery) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting states how ECS services find each other: AWS Cloud Map registries and namespaces, or ECS Service Connect.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person replaces the lookups with Kubernetes Services and cluster DNS on SKE.
  - `task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The ECS task definition: the containers a service runs, with their CPU and memory, environment, secrets and health checks.
    - what closes it: A person translates the task definition into Kubernetes Deployments and Services on SKE (CPU and memory, environment, secrets and health checks become manifest fields); the rule names a Cloud Foundry push as the other way for a simple web app.
  - `service-task-definition` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition the service runs (family:revision or ARN) becomes the Deployment's pod template; ecs_service.task_definition names it as a string, the definition itself is a separate resource a person translates.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-desired-count` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. desired_count is the number of tasks ECS keeps running (ecs_service docs: 'Number of instances of the task definition to place and keep running'); on SKE it becomes Deployment replicas or a HorizontalPodAutoscaler floor. The draft writes it as the replicas of the Deployment in kubernetes/<service>/manifests.yaml when it is a literal number (a HorizontalPodAutoscaler owns the count where the service has a scaling target and policy the draft translates; a number that is not visible statically is a REQUIRED_ token) — a person confirms the number, REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-execute-command` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ECS Exec opens a shell in a running task; kubectl exec (and who may use it through RBAC) is the counterpart and is not part of the draft.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-load-balancer-target` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states which container and port receive the load balancer's traffic, the target group or classic load balancer name, and the blue/green listener rules and role: the wiring becomes a Kubernetes Service / Ingress selector and a STACKIT load balancer target pool, written by a person (the draft has no service block to carry it).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-network-placement` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The subnets and security groups the tasks' network interfaces use (awsvpc mode); on SKE pods take the cluster's network and NetworkPolicies decide reachability — a person re-expresses the security group rules.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-public-ip-setting` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. assign_public_ip in either state (the public ip setting reads only true through the public address check): tasks with a public address are exposed unless a person decides the exposure on SKE explicitly (LoadBalancer services, network policies); false is the private default and is still re-checked, the draft carries no service block.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `service-connect-values` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Service Connect's switch, namespace, service names, client aliases (DNS name and port), traffic-test header rules, mTLS settings (KMS key, role, private CA) and proxy logging: an AWS-managed service mesh with no draft counterpart; discovery on SKE is Kubernetes Services and DNS, mesh features a person's choice.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-definitions` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.container_definitions of the unit that runs the task. The containers of the task: images, commands, environment, secret references, ports, health checks, log configuration - the workload itself, and where its credentials are injected. Decide per container: the image and where it lives, command and entry point, environment, ports and health check, cpu/memory as requests and limits, and the log destination; the secret references and the plaintext secrets among the environment entries are read by the settings of the secret references and of the plaintext secrets, the registry by the setting of the image registry.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-secret-references` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The task definition's container_definitions state secret references (the `secrets` list: name and valueFrom, "the full ARN of the AWS Secrets Manager secret or the full ARN of the parameter in the SSM Parameter Store", AWS ECS API reference, Secret). A person decides first which STACKIT Secrets Manager instance holds each referenced secret (stackit_secretsmanager_instance, pinned provider: name, acls, kms_key; the secret entries themselves have no Terraform resource in the pinned provider, they are created through the API or the portal, and their VALUES are never in the Terraform sources - a person copies them). Second, a person decides how the pods read them (the STACKIT Secrets Manager authenticates with Vault-compatible tokens and AppRole, docs.stackit.cloud/products/security/secrets-manager/; ECS injects valueFrom into environment variables when the container starts, and no STACKIT equivalent of that injection is stated on the documentation page checked 2026-10-06, so the Kubernetes Secret or the in-pod fetch is a design of its own).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-plaintext-secret-env` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. An `environment` entry whose NAME looks like a credential (password, secret, token, api key, private key, credential) carries a non-empty plaintext value in the task definition (a name heuristic, not a proof: the value is never shown). Decide: whether the value is a secret; if it is, it must not be copied into a Kubernetes manifest or a Terraform variable default but stored in a STACKIT Secrets Manager entry and the plaintext copy in the AWS state and task definition rotated.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-container-image-registry` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A container image comes from Amazon ECR (a `.dkr.ecr.` or public.ecr.aws registry host) or needs `repositoryCredentials`. The images are not moved by the draft and a pod on STACKIT cannot assume the ECR pull rights of the ECS execution role. Decide: where the images live on STACKIT (the STACKIT Container Registry has a GA API, the Container Registry API specification, but no Terraform resource in pinned provider; a registry of your choice works too), how they are copied, and the pull secret the cluster uses.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-execution-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.execution_role_arn of the template the group builds its instances from: The role ECS uses to pull images and read the secrets it injects into the containers. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-network-mode` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.network_mode of the template the group builds its instances from: How the containers are networked (awsvpc, bridge, host, none): whether each task has its own interface and security groups or shares the host's network. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `td-task-role-arn` (critical): REVIEW · the mapping rule for aws_ecs_service (knowledge-base case ecs-to-ske)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. ecs_task_definition.task_role_arn of the template the group builds its instances from: The role the application in the containers acts as towards AWS APIs. Not verified as carried by any semantic of this family — reviewed.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
- **Property accounting:** 27 of 27 meaningful properties accounted (not carried 14 · contract 11 · consumed by the draft 2 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.desired_count` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.enable_execute_command` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.load_balancer.container_name` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.load_balancer.container_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.load_balancer.target_group_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.network_configuration.assign_public_ip` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.network_configuration.security_groups` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.network_configuration.subnets` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.service_connect_configuration.enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.service_connect_configuration.namespace` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.dns_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.service_connect_configuration.service.client_alias.port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.service_connect_configuration.service.discovery_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.service_connect_configuration.service.port_name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_service.this.task_definition` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_task_definition.this.container_definitions` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_task_definition.this.execution_role_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_task_definition.this.network_mode` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_ecs_task_definition.this.task_role_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

### Data

#### `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this`

- **Source:** `aws_dynamodb_table` — .terraform/modules/dependencies.dynamodb_carts/main.tf:1
- **Classification:** REDESIGN · **Confidence:** MEDIUM · rule `aws.dynamodb_table/dynamodb`
- **Semantic surface** (contract `aws.dynamodb_table`): 8 of 44 semantics stated by the source, 8 accounted, 0 unaccounted — critical left for review/accepted loss: key-schema, index-projection-and-name, encryption-at-rest, point-in-time-recovery, ttl, tc-dynamodb-table-name
  - `key-schema` (critical): REVIEW · the mapping rule for aws_dynamodb_table (knowledge-base case dynamodb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The draft names the partition/sort key as the collection's unique index; the data model is rewritten by people.
    - what closes it: A person designs the keys and indexes of the replacement collection (partition and sort key, attribute names and types, secondary index keys), because the draft names only the key as the collection's unique index.
  - `index-projection-and-name` (critical): REVIEW · the mapping rule for aws_dynamodb_table (knowledge-base case dynamodb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The projection of a secondary index (keys only, INCLUDE with its non_key_attributes, ALL) decides which attributes an index query can return, and the index name is what every Query / Scan on the index selects it by (API Query IndexName). STACKIT has no provider resource for an index (pinned provider), a person re-creates the indexes and the queries that name them in the chosen engine — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `encryption-at-rest` (critical): REVIEW · the mapping rule for aws_dynamodb_table (knowledge-base case dynamodb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. It is not stated in stackit_mongodbflex_instance (no encryption attribute) whether STACKIT MongoDB Flex encrypts data at rest: REVIEW (the customer managed key setting reads the key).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `point-in-time-recovery` (critical): REVIEW · the mapping rule for aws_dynamodb_table (knowledge-base case dynamodb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. MongoDB Flex has a point-in-time window in hours (options.point_in_time_window_hours); its maximum is not documented in the provider schema. The draft carries no value for it.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `ttl` (critical): REVIEW · the mapping rule for aws_dynamodb_table (knowledge-base case dynamodb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. DynamoDB TTL reads epoch seconds; a MongoDB TTL index expires only BSON dates, so the attribute changes type. The time-to-live check still fires only for enabled = true; the case handler REVIEW covers the other states.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `secondary-indexes`: REVIEW · a check of the knowledge base (dynamodb secondary indexes) (knowledge-base check dynamodb-secondary-indexes)
  - `capacity-mode`: UNSUPPORTED · the mapping rule for aws_dynamodb_table (knowledge-base case dynamodb)
  - `tc-dynamodb-table-name` (critical): REVIEW · the mapping rule for aws_dynamodb_table (knowledge-base case dynamodb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_dynamodb_table.name: Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract). No semantic of this family has verified it as carried.
    - what closes it: A person confirms the name the replacement collection carries on the target against what refers to the source name, or accepts the new name.
- **Property accounting:** 13 of 13 meaningful properties accounted (not carried 2 · contract 11 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.attribute.name` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.attribute.type` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.global_secondary_index.hash_key` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.global_secondary_index.name` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.global_secondary_index.projection_type` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.hash_key` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.name` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.point_in_time_recovery.enabled` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.server_side_encryption.enabled` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.ttl.attribute_name` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this.ttl.enabled` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this`

- **Source:** `aws_opensearch_domain` — .terraform/modules/dependencies.catalog_opensearch/main.tf:29
- **Classification:** REPLATFORM · **Confidence:** LOW · rule `aws.opensearch/opensearch`
- **Semantic surface** (contract `aws.opensearch`): 14 of 35 semantics stated by the source, 14 accounted, 0 unaccounted — critical left for review/accepted loss: engine-version, fine-grained-access, private-endpoint, encryption-at-rest, domain-settings, domain-credentials-and-keys, access-and-encryption-settings, cluster-layout-settings, credentials-and-keys-settings, network-settings, storage-settings, tc-opensearch-domain-domain-name, nbr-aws-opensearch-domain-policy, opensearch-domain-policy-resource (**not automation-eligible**: no property the unit sets is read by private-endpoint)
  - `engine-version` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states which engine and version the OpenSearch domain runs: OpenSearch or legacy Elasticsearch, with its version number.
    - what closes it: A person chooses the version of the STACKIT OpenSearch instance, which has a version setting (pinned provider), and checks that the domain's clients work with it.
  - `fine-grained-access` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states whether fine-grained access control, with users, roles and permissions inside the domain, is switched on.
    - what closes it: A person re-creates the access rules another way, because fine-grained IAM access has no equivalent on STACKIT OpenSearch, which offers an access list and credentials per instance.
  - `private-endpoint` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states whether the domain lives inside a VPC, with subnets and security groups, instead of behind a public endpoint.
    - what closes it: A person translates the networks that may reach the domain into the access list (a list of CIDR ranges) of the STACKIT OpenSearch instance, which has no network or subnet input (pinned provider).
  - `encryption-at-rest` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states whether the data the domain stores is encrypted at rest.
    - what closes it: A person confirms the encryption of the STACKIT OpenSearch instance on the target; the instance has no encryption setting (pinned provider), and no STACKIT fact about it is documented here.
  - `domain-settings` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. stackit_opensearch_instance takes a plan (plan_name: nodes and storage), a version and parameters (sgw_acl, syslog, tls_protocols, tls_ciphers, etc.; pinned provider): the domain's node layout, zone awareness, storage, access policy, endpoint TLS and HTTPS settings, internal user database and log publishing are not generated — a person maps them to the plan and parameters — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `domain-credentials-and-keys` (critical): UNSUPPORTED · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit found a setting the target has no counterpart for. STACKIT generates the OpenSearch credential (stackit_opensearch_credential username and password are computed), offers no customer KMS key for the instance and no custom endpoint certificate (pinned provider) — UNSUPPORTED.
    - what closes it: A person accepts the difference or the design changes: nothing in the source can make the target carry it.
  - `access-and-encryption-settings` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The access policy, free-form engine options, fine-grained access switches, encryption at rest and between nodes, the HTTPS and TLS policy of the endpoint and the engine version of the domain, read wherever they are set.
    - what closes it: A person maps each setting to the STACKIT OpenSearch instance, which has an access list, TLS protocols and ciphers and a version, but no policy document, no free-form option map and no encryption switch (pinned provider).
  - `cluster-layout-settings` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Every node-layout setting of the domain, read where it is set whatever its value (on, off, empty, a variable, a reference, a block written as an attribute object): instance count, dedicated masters, warm and cold storage, zone awareness and its zone count, multi-AZ with standby and the deployment strategy. A stackit_opensearch_instance takes a plan (plan_name) that fixes nodes, topology and storage, no zone-awareness or tier setting (pinned provider, the provider documentation of opensearch_instance) - REVIEW: a person picks the plan that matches the layout.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `credentials-and-keys-settings` (critical): UNSUPPORTED · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit found a setting the target has no counterpart for. The IAM master user, the master user name and password, the customer KMS key and the custom endpoint certificate, read where they are set whatever their value. STACKIT generates the OpenSearch credential (stackit_opensearch_credential username and password are computed), offers no customer KMS key for the instance and no custom endpoint certificate (pinned provider) - UNSUPPORTED; a password is never carried.
    - what closes it: A person accepts the difference or the design changes: nothing in the source can make the target carry it.
  - `network-settings` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The VPC placement of the domain (subnet and security group ids, IP address type), read where it is set whatever its value. stackit_opensearch_instance has no network or subnet input; its access control is parameters.sgw_acl, a CIDR list (pinned provider) - REVIEW: a person translates the reachable networks into sgw_acl.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `storage-settings` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states whether the data nodes use EBS volumes, read where it is set whatever its value. Storage of a stackit_opensearch_instance is defined by its plan (pinned provider, the provider documentation of opensearch_instance): no EBS switch - REVIEW: a person picks a plan whose disk fits the index size.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `tc-opensearch-domain-domain-name` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_opensearch_domain.domain_name: Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract). No semantic of this family has verified it as carried.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `nbr-aws-opensearch-domain-policy` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_opensearch_domain_policy (search access policy) attaches an access policy to this domain, so who may reach and use it is decided by that policy and not by the domain's own settings.
    - what closes it: A person reads the policy the neighbour attaches and confirms that the replacing OpenSearch domain lets the same principals act on it, and no more, or that the access is dropped on purpose.
  - `opensearch-domain-policy-resource` (critical): REVIEW · the mapping rule for aws_opensearch_domain (knowledge-base case opensearch)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The domain's resource-based access policy, written as aws_opensearch_domain_policy (a part of the domain), has no counterpart on STACKIT OpenSearch.
    - what closes it: A person lists the principals and conditions the policy names, decides how their separation is kept (one instance per trust level, or in the application) and puts the source ranges into sgw_acl.
- **Property accounting:** 24 of 24 meaningful properties accounted (not carried 23 · contract 1 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.advanced_options` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.advanced_security_options.anonymous_auth_enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.advanced_security_options.enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.advanced_security_options.internal_user_database_enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.advanced_security_options.master_user_options.master_user_name` (CRITICAL/CLOSED:NC+UNSUPPORTED), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.advanced_security_options.master_user_options.master_user_password` (CRITICAL/CLOSED:NC+UNSUPPORTED), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.cluster_config.dedicated_master_count` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.cluster_config.dedicated_master_enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.cluster_config.instance_count` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.cluster_config.zone_awareness_enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.domain_endpoint_options.enforce_https` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.domain_endpoint_options.tls_security_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.domain_name` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.ebs_options.ebs_enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.encrypt_at_rest.enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.engine_version` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.node_to_node_encryption.enabled` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.vpc_options.security_group_ids` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain.this.vpc_options.subnet_ids` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_opensearch.aws_opensearch_domain_policy.this.access_policies` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.dependencies.module.catalog_rds.aws_rds_cluster.this`

- **Source:** `aws_rds_cluster` — .terraform/modules/dependencies.catalog_rds/main.tf:61
- **Classification:** REPLATFORM · **Confidence:** LOW · rule `aws.rds_cluster/aurora-mysql`
- **Engine reason (every relation combination evaluated):** Aurora MySQL has no MySQL target on STACKIT; MariaDB is the closest engine and needs compatibility testing. (Whether dependency `module.dependencies.module.catalog_rds.aws_db_subnet_group.this` (the value of db_subnet_group_name of module.dependencies.module.catalog_rds.aws_rds_cluster.this may be null (a condition not known statically); the same cause covers 1 more relationship(s)) exist was evaluated for each possibility; the mapping decides the same either way.)
- **Semantic surface** (contract `aws.rds_cluster`): 24 of 113 semantics stated by the source, 24 accounted, 0 unaccounted — critical left for review/accepted loss: admin-password, admin-username-not-carried, backup-retention, db-network-placement, engine, engine-version, final-snapshot, member-engine, member-settings, parameter-and-option-groups, security-groups, storage-encryption, tc-database-name, tcf-rds-cluster-instance--identifier
  - `engine` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The database engine of the cluster (Aurora PostgreSQL, Aurora MySQL, or a Multi-AZ cluster on PostgreSQL or MySQL), which decides the STACKIT database service it lands on.
    - what closes it: For a MySQL-compatible cluster a person tests the schemas and queries on STACKIT MariaDB, the closest managed engine, because STACKIT has no MySQL product; for a PostgreSQL cluster, which lands on PostgreSQL Flex, a person confirms that no Aurora-only feature (storage auto-scaling, fast clones, global databases, serverless v2 scaling) is relied on.
  - `engine-version` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The version of the database engine that the cluster runs.
    - what closes it: For a PostgreSQL cluster a person picks a major version that PostgreSQL Flex offers (14 to 18; 18 is beta in eu01, so production needs 17 or a generally available 18) and plans an upgrade for any other version. For a MySQL-compatible cluster a person tests the MySQL 8 features in use on STACKIT MariaDB.
  - `backup-retention` (critical): LEDGER · ledger:backup retention
    - why it is open: Whether the draft carries this setting is decided by its semantic ledger entry "backup retention", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). A retention not visible statically (a variable) is read by no fact and the draft carries nothing for it: a person compares it with the target's backup retention (REVIEW).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `storage-encryption` (critical): REVIEW · a check of the knowledge base (aurora storage encrypted mariadb) (knowledge-base check aurora-storage-encrypted-mariadb)
    - why it is open: A check of the knowledge base (aurora storage encrypted mariadb) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting states whether the storage of the database cluster is encrypted at rest, with the AWS-managed key because no customer key is named.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person confirms the at-rest encryption of the target database on STACKIT: the PostgreSQL Flex encryption block covers customer keys only and the default without it is not stated, and a MariaDB sandbox instance had database-level encryption off, so whether its volumes are encrypted is not stated (pinned provider).
  - `log-exports-none` (critical): PRESERVED · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `multiaz-high-availability` (critical): NOT_APPLICABLE · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `multiaz-network-exposure` (critical): NOT_APPLICABLE · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `readable-standbys` (critical): NOT_APPLICABLE · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `db-network-placement` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The STACKIT database resource has no subnet, availability-zone or IP-family attribute (pinned provider): clients reach it at the endpoint STACKIT assigns, restricted by its ACL — a person decides how clients reach it — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `admin-username-not-carried` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The master username is not a literal of a single cluster that PostgreSQL Flex accepts: a name a variable supplies or that is not visible statically (the draft writes the user with a variable that has no default), a name STACKIT reserves (admin and postgres: the draft writes a variable that rejects them), or a repeated cluster (a user per cluster only when every instance is evaluated). A person chooses the administrator's name on the target — REVIEW.
    - what closes it: A person creates the administrator on the target with a name the target accepts and confirms the application connects with it.
  - `admin-password` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The source password (or its Secrets Manager management) is never copied, and no STACKIT database user takes a password: stackit_postgresflex_user and stackit_mariadb_credential compute it (password is computed and sensitive, pinned provider) and the create-user API of PostgreSQL Flex has no password field.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `security-groups` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT database instances have no security groups: access is a CIDR ACL (network.acl, pinned provider); the draft's ACL variable defaults to the CIDRs of the groups' ingress rules where visible, and group-to-group rules cannot be expressed — a person checks the ACL — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `parameter-and-option-groups` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The STACKIT database resource has no parameter-group or option-group attribute (pinned provider): the group's settings (even a default.* group of the source engine) must be mapped to the STACKIT instance's options by a person — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `final-snapshot` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The STACKIT database resource has no final snapshot or delete-time backup setting (pinned provider): it is deleted when Terraform destroys it — a person decides how data survives a destroy (export first) — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `member-engine` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Cluster members must run the cluster's engine and version (AWS), which the draft follows (TODO when a member states another): the members' engine and version are what the cluster's engine and the engine version setting decide — TRANSFORMED/PRESERVED for a supported PostgreSQL version, REVIEW otherwise.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `member-settings` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Cluster members are not separate STACKIT resources (the flavor defines the nodes, pinned provider): a member's failover priority, parameter group, subnet group, zone, CA certificate and Performance Insights key have no attribute — a person decides what the nodes need — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `tcp-backup-retention-period` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `tcp-db-cluster-parameter-group-name` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `tcp-db-subnet-group-name` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `tcfp-rds-cluster-instance--engine` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `tcfp-rds-cluster-instance--engine-version` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `tcp-vpc-security-group-ids` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
  - `tc-database-name` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_rds_cluster.database_name: Name of the initial database created in the cluster; application setup. No semantic of this family has verified it as carried. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `tcf-rds-cluster-instance--identifier` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-mysql)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_rds_cluster_instance.identifier (a facet of the unit): Name of the instance; it identifies the resource and changes no access, encryption, backup or availability behaviour. No semantic of this family has verified it as carried. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
- **Property accounting:** 26 of 26 meaningful properties accounted (not carried 16 · contract 7 · consumed by the draft 3 · relation 0 · placement 0)
- **Critical-property gate:** `module.dependencies.module.catalog_rds.aws_rds_cluster.this.backup_retention_period` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.database_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.db_cluster_parameter_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.db_subnet_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.engine` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.engine_version` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.master_password` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.master_username` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.skip_final_snapshot` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.storage_encrypted` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster.this.vpc_security_group_ids` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster_instance.this.db_parameter_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster_instance.this.db_subnet_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster_instance.this.engine` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster_instance.this.engine_version` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_rds_cluster_instance.this.identifier` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default`

- **Source:** `aws_elasticache_replication_group` — .terraform/modules/dependencies.checkout_elasticache_redis/main.tf:115
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.elasticache/redis-valkey`
- **Semantic surface** (contract `aws.elasticache`): 12 of 68 semantics stated by the source, 12 accounted, 0 unaccounted — critical left for review/accepted loss: parameter-group, parameter-group-default, failover-off, snapshots-off, at-rest-encryption-off, network-placement, seed-snapshot, tcp-elasticache-replication-group-transit-encryption-enabled, tc-elasticache-replication-group-replication-group-id
  - `engine-version` (critical): TRANSFORMED · a check of the knowledge base (redis engine version) (knowledge-base check redis-engine-version)
  - `parameter-group` (critical): REVIEW · a check of the knowledge base that the source cannot settle (redis parameter group) (knowledge-base check redis-parameter-group)
    - why it is open: A check of the knowledge base (redis parameter group) needs a value the scan cannot read statically, so it could not decide. The setting states which custom set of engine parameters (a parameter group) the cache runs with.
    - what closes it: A literal value or a resolved reference in the source lets the check decide, or a person verifies the value.
  - `parameter-group-default` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A parameter group named default.<family> carries the AWS default settings of that engine family and version, and its name can carry the topology: a group with cluster.on in its name enables cluster mode.
    - what closes it: A person confirms that the defaults of the source parameter group family are what the application needs on the target and, for a cluster-mode group, treats it as the cluster-mode question.
  - `failover-off` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A single node without failover: the draft asks for the plan (plan_name is a variable), so whether the target is a Single plan is a person's choice — REVIEW, not PRESERVED.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `snapshots-off` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. No snapshots in the source; whether a STACKIT Valkey instance takes snapshots by default (parameters.snapshot, not generated) is not documented — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `at-rest-encryption-off` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. No at-rest encryption in the source; stackit_valkey_instance states nothing about at-rest encryption (pinned provider) — REVIEW, not PRESERVED.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `network-placement` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. stackit_valkey_instance has no subnet, security-group, zone or IP-family attribute; client access can be limited by CIDR with parameters.sgw_acl, which the draft does not generate — a person decides it.
    - what closes it: A person decides how clients reach the Valkey instance, which has no subnet or security-group setting, for example by limiting client CIDR ranges with its access parameter.
  - `seed-snapshot` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The instance is created empty: the data is migrated by a person (RDB export and import, or replication); stackit_valkey_instance and stackit_redis_instance have no snapshot or restore attribute (pinned provider). snapshot_arns is observed for every set value, an empty list included: the draft names snapshot_arns NOT CARRIED even when it is empty; a conditional with a null branch stays undecided, hence REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `tcp-elasticache-replication-group-at-rest-encryption-enabled` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
  - `tcp-elasticache-replication-group-num-cache-clusters` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
  - `tcp-elasticache-replication-group-transit-encryption-enabled` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_elasticache_replication_group.transit_encryption_enabled: Encryption in transit (TLS) between clients and the cache; losing it sends data and AUTH in clear. Held CRITICAL: it decides whether and with which key data or metadata is encrypted; dropping it silently could leave data unencrypted on the target.
    - what closes it: A person confirms that clients reach the cache over TLS on the target, so that data and the authentication token are not sent in clear.
  - `tc-elasticache-replication-group-replication-group-id` (critical): REVIEW · the mapping rule for aws_elasticache_replication_group (knowledge-base case redis-valkey)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The identifier of the cache replication group. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the instance name the target uses against what refers to the replication group id, or accepts the new name.
- **Property accounting:** 18 of 18 meaningful properties accounted (not carried 10 · contract 7 · consumed by the draft 1 · relation 0 · placement 0)
- **Critical-property gate:** `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.at_rest_encryption_enabled` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.automatic_failover_enabled` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.multi_az_enabled` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.num_cache_clusters` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.parameter_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.replication_group_id` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.security_group_ids` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.snapshot_arns` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.snapshot_retention_limit` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.subnet_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.checkout_elasticache_redis.aws_elasticache_replication_group.default.transit_encryption_enabled` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.dependencies.module.orders_rds.aws_rds_cluster.this`

- **Source:** `aws_rds_cluster` — .terraform/modules/dependencies.orders_rds/main.tf:61
- **Classification:** REPLATFORM · **Confidence:** MEDIUM · rule `aws.rds_cluster/aurora-postgres`
- **Engine reason (every relation combination evaluated):** Aurora PostgreSQL is wire-compatible PostgreSQL; it lands on PostgreSQL Flex. Aurora-only features (storage auto-scaling up to 256 TiB, fast clones, global databases, serverless v2 scaling) have no equivalent. (Whether dependency `module.dependencies.module.orders_rds.aws_db_subnet_group.this` (the value of db_subnet_group_name of module.dependencies.module.orders_rds.aws_rds_cluster.this may be null (a condition not known statically); the same cause covers 1 more relationship(s)) exist was evaluated for each possibility; the mapping decides the same either way.)
- **Semantic surface** (contract `aws.rds_cluster`): 25 of 113 semantics stated by the source, 25 accounted, 0 unaccounted — critical left for review/accepted loss: storage-encryption, db-network-placement, admin-username-not-carried, admin-password, security-groups, parameter-and-option-groups, final-snapshot, member-settings, tc-database-name, tcf-rds-cluster-instance--identifier
  - `engine` (critical): TRANSFORMED · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `engine-version` (critical): PRESERVED · a check of the knowledge base (aurora pg version supported) (knowledge-base check aurora-pg-version-supported)
  - `backup-retention` (critical): LEDGER · ledger:backup retention
  - `storage-encryption` (critical): REVIEW · a check of the knowledge base (aurora storage encrypted) (knowledge-base check aurora-storage-encrypted)
    - why it is open: A check of the knowledge base (aurora storage encrypted) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting states whether the storage of the database cluster is encrypted at rest, with the AWS-managed key because no customer key is named.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person confirms the at-rest encryption of the target database on STACKIT: the PostgreSQL Flex encryption block covers customer keys only and the default without it is not stated, and a MariaDB sandbox instance had database-level encryption off, so whether its volumes are encrypted is not stated (pinned provider).
  - `log-exports-none` (critical): PRESERVED · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `multiaz-high-availability` (critical): NOT_APPLICABLE · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `multiaz-network-exposure` (critical): NOT_APPLICABLE · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `readable-standbys` (critical): NOT_APPLICABLE · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `db-network-placement` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The STACKIT database resource has no subnet, availability-zone or IP-family attribute (pinned provider): clients reach it at the endpoint STACKIT assigns, restricted by its ACL — a person decides how clients reach it — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `admin-username-not-carried` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The master username is not a literal of a single cluster that PostgreSQL Flex accepts: a name a variable supplies or that is not visible statically (the draft writes the user with a variable that has no default), a name STACKIT reserves (admin and postgres: the draft writes a variable that rejects them), or a repeated cluster (a user per cluster only when every instance is evaluated). A person chooses the administrator's name on the target — REVIEW.
    - what closes it: A person creates the administrator on the target with a name the target accepts and confirms the application connects with it.
  - `admin-password` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The source password (or its Secrets Manager management) is never copied, and no STACKIT database user takes a password: stackit_postgresflex_user and stackit_mariadb_credential compute it (password is computed and sensitive, pinned provider) and the create-user API of PostgreSQL Flex has no password field.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `security-groups` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT database instances have no security groups: access is a CIDR ACL (network.acl, pinned provider); the draft's ACL variable defaults to the CIDRs of the groups' ingress rules where visible, and group-to-group rules cannot be expressed — a person checks the ACL — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `parameter-and-option-groups` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The STACKIT database resource has no parameter-group or option-group attribute (pinned provider): the group's settings (even a default.* group of the source engine) must be mapped to the STACKIT instance's options by a person — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `final-snapshot` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The STACKIT database resource has no final snapshot or delete-time backup setting (pinned provider): it is deleted when Terraform destroys it — a person decides how data survives a destroy (export first) — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `aurora-extras` (critical): PRESERVED · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `member-engine` (critical): PRESERVED · a check of the knowledge base (aurora pg version supported) (knowledge-base check aurora-pg-version-supported)
  - `member-settings` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Cluster members are not separate STACKIT resources (the flavor defines the nodes, pinned provider): a member's failover priority, parameter group, subnet group, zone, CA certificate and Performance Insights key have no attribute — a person decides what the nodes need — REVIEW.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `tcp-backup-retention-period` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `tcp-db-cluster-parameter-group-name` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `tcp-db-subnet-group-name` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `tcfp-rds-cluster-instance--engine` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `tcfp-rds-cluster-instance--engine-version` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `tcp-vpc-security-group-ids` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
  - `tc-database-name` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_rds_cluster.database_name: Name of the initial database created in the cluster; application setup. No semantic of this family has verified it as carried. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `tcf-rds-cluster-instance--identifier` (critical): REVIEW · the mapping rule for aws_rds_cluster (knowledge-base case aurora-postgres)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_rds_cluster_instance.identifier (a facet of the unit): Name of the instance; it identifies the resource and changes no access, encryption, backup or availability behaviour. No semantic of this family has verified it as carried. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
- **Property accounting:** 27 of 27 meaningful properties accounted (not carried 12 · contract 11 · consumed by the draft 4 · relation 0 · placement 0)
- **Critical-property gate:** `module.dependencies.module.orders_rds.aws_rds_cluster.this.database_name` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster.this.db_cluster_parameter_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster.this.db_subnet_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster.this.master_password` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster.this.master_username` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster.this.skip_final_snapshot` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster.this.storage_encrypted` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster.this.vpc_security_group_ids` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster_instance.this.db_parameter_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster_instance.this.db_subnet_group_name` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.module.orders_rds.aws_rds_cluster_instance.this.identifier` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

### Identity

#### `module.retail_app_ecs.aws_kms_key.cmk`

- **Source:** `aws_kms_key` — ../../lib/ecs/common.tf:1
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.kms_key/kms`
- **Semantic surface** (contract `aws.kms_key`): 1 of 48 semantics stated by the source, 1 accounted, 0 unaccounted — critical left for review/accepted loss: deletion-window
  - `deletion-window` (critical): REVIEW · a check of the knowledge base (kms deletion window) (knowledge-base check kms-deletion-window)
    - why it is open: A check of the knowledge base (kms deletion window) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). STACKIT KMS deletes a key scheduled for deletion after 30 days (docs create-and-manage-keys, 'Delete a key'), with no setting: 30 is PRESERVED, another window REVIEW.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
- **Property accounting:** 1 of 1 meaningful properties accounted (not carried 1 · contract 0 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.aws_kms_key.cmk.deletion_window_in_days` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.carts_service.aws_iam_role.task_execution_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:14
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: trust, permissions, iam-trust-service-workload, iam-managed-ecs
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-ecs` (critical): REVIEW · a check of the knowledge base (iam managed ecs) (knowledge-base check iam-managed-ecs)
    - why it is open: A check of the knowledge base (iam managed ecs) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Managed policy of an ECS role (AWS: task execution pulls images from ECR and writes CloudWatch Logs; the container-instance role registers hosts with ECS). What to decide: the registry pull credential and the log destination of the replacing workload.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
- **Property accounting:** 3 of 3 meaningful properties accounted (not carried 2 · contract 1 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.carts_service.aws_iam_role.task_execution_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_iam_role_policy_attachment.task_execution_role_policy.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.checkout_service.aws_iam_role.task_execution_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:14
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: trust, permissions, iam-trust-service-workload, iam-managed-ecs
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-ecs` (critical): REVIEW · a check of the knowledge base (iam managed ecs) (knowledge-base check iam-managed-ecs)
    - why it is open: A check of the knowledge base (iam managed ecs) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Managed policy of an ECS role (AWS: task execution pulls images from ECR and writes CloudWatch Logs; the container-instance role registers hosts with ECS). What to decide: the registry pull credential and the log destination of the replacing workload.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
- **Property accounting:** 3 of 3 meaningful properties accounted (not carried 2 · contract 1 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.checkout_service.aws_iam_role.task_execution_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_iam_role_policy_attachment.task_execution_role_policy.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.ui_service.aws_iam_role.task_execution_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:14
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: trust, permissions, iam-trust-service-workload, iam-managed-ecs
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-ecs` (critical): REVIEW · a check of the knowledge base (iam managed ecs) (knowledge-base check iam-managed-ecs)
    - why it is open: A check of the knowledge base (iam managed ecs) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Managed policy of an ECS role (AWS: task execution pulls images from ECR and writes CloudWatch Logs; the container-instance role registers hosts with ECS). What to decide: the registry pull credential and the log destination of the replacing workload.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
- **Property accounting:** 3 of 3 meaningful properties accounted (not carried 2 · contract 1 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.ui_service.aws_iam_role.task_execution_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_iam_role_policy_attachment.task_execution_role_policy.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.aws_secretsmanager_secret.catalog_opensearch`

- **Source:** `aws_secretsmanager_secret` — ../../lib/ecs/catalog.tf:82
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.secretsmanager_secret/secret`
- **Semantic surface** (contract `aws.secretsmanager_secret`): 3 of 34 semantics stated by the source, 3 accounted, 0 unaccounted — critical left for review/accepted loss: secret-value, customer-managed-key, tc-secretsmanager-secret-name
  - `secret-value` (critical): REVIEW · the mapping rule for aws_secretsmanager_secret (knowledge-base case secret)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The value moves to STACKIT Secrets Manager (Vault-compatible KV). The draft generates the shared instance, and the plan a WriteSecret step for an aws_secretsmanager_secret or a SecureString aws_ssm_parameter that is not repeated. The step writes the document the person supplies and does not carry this setting (the value is the person's document); for a secret repeated by count or for_each whose instances are not all known, and for a parameter whose type is not the literal SecureString, only the instance is generated. What a person decides, per secret: where the value comes from (the same value fetched from a secure source, or a new one — moving is the moment to rotate) and the Vault path the application will read, then writes it with the Vault provider or CLI — REVIEW. History: added with aws_ssm_parameter on 2026-09-24; REVIEW since 2026-09-27 (was TRANSFORMED); 2026-10-29 the wording names the WriteSecret step of the plan; 2026-10-30 the step is also made for a SecureString parameter.
    - what closes it: A person decides per secret where the value comes from (the same value from a secure source, or a new one) and the Vault path the application reads, then writes it with a Vault KV v2 client.
  - `customer-managed-key` (critical): REVIEW · a check of the knowledge base (secret cmk) (knowledge-base check secret-cmk)
    - why it is open: A check of the knowledge base (secret cmk) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Critical and reading the key since 2026-09-27: the draft names it NOT CARRIED, except where it sets the instance's kms_key (below). The AWS key does not move, AWS's key per secret has no per-secret counterpart, and the draft sets the kms_key block (referencing the drafted STACKIT key) only when every source of the shared instance is an AWS secret that references that one key — otherwise it names the key NOT CARRIED with the reason; either way a person decides (REVIEW, see the customer-managed key check).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `tc-secretsmanager-secret-name` (critical): REVIEW · the mapping rule for aws_secretsmanager_secret (knowledge-base case secret)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_secretsmanager_secret.name: Friendly name used to address the secret; losing it breaks lookups by name but does not change who may reach or read the value, its encryption or deletion behaviour (IAM statements that scope by name are assessed on the IAM policy). No semantic of this family has verified it as carried. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the secret name or path the application looks up on the target, or accepts the new one.
- **Property accounting:** 3 of 3 meaningful properties accounted (not carried 3 · contract 0 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.aws_secretsmanager_secret.catalog_opensearch.kms_key_id` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.aws_secretsmanager_secret.catalog_opensearch.name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.aws_secretsmanager_secret_version.catalog_opensearch.secret_string` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.carts_service.aws_iam_role.task_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:31
- **Configuration:** conditional — the unit exists and counts in the totals, but part of what configures it is decided only when a plan runs; it is not automation-eligible (gate blocker `CONFIGURATION:conditional-facet`).
  - `module.retail_app_ecs.module.carts_service.aws_iam_role_policy_attachment.cloudwatch_agent` is switched off by default (the default of variable `var.opentelemetry_enabled`; a root variable that a variable file or the command line can override): nothing of it is drafted, and a variable file or `-var` that gives that input another value creates it
- **Classification:** RECONFIGURE · **Confidence:** LOW · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: iam-managed-customer-policy, iam-trust-service-workload, permissions, trust (**not automation-eligible**: no property the unit sets is read by linked-dependency:aws_dynamodb_table)
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person. The unit names module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this (aws_dynamodb_table) through this setting (the target does not carry it: it is REDESIGN), so what the reference becomes is part of this setting.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-customer-policy` (critical): REVIEW · a check of the knowledge base (iam managed customer policy) (knowledge-base check iam-managed-customer-policy)
    - why it is open: A check of the knowledge base (iam managed customer policy) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). This attachment names a customer-managed policy of this estate (an aws_iam_policy), not an AWS-managed one. What to decide: the roles of this role's service account from the findings of every policy attached here, and whether one policy shared by several roles becomes one set of role assignments or several.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `linked-dependency:aws_dynamodb_table` (critical): REVIEW · linked-dependency:aws_dynamodb_table
- **Property accounting:** 5 of 5 meaningful properties accounted (not carried 2 · contract 3 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.carts_service.aws_iam_role.task_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.carts_service.aws_iam_role_policy_attachment.cloudwatch_logs.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_iam_role_policy_attachment.ecs_exec.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_iam_role_policy_attachment.task_role_additional.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.catalog_service.aws_iam_role.task_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:31
- **Configuration:** conditional — the unit exists and counts in the totals, but part of what configures it is decided only when a plan runs; it is not automation-eligible (gate blocker `CONFIGURATION:conditional-facet`).
  - `module.retail_app_ecs.module.catalog_service.aws_iam_role_policy_attachment.cloudwatch_agent` is switched off by default (the default of variable `var.opentelemetry_enabled`; a root variable that a variable file or the command line can override): nothing of it is drafted, and a variable file or `-var` that gives that input another value creates it
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: trust, permissions, iam-trust-service-workload, iam-managed-customer-policy
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-customer-policy` (critical): REVIEW · a check of the knowledge base (iam managed customer policy) (knowledge-base check iam-managed-customer-policy)
    - why it is open: A check of the knowledge base (iam managed customer policy) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). This attachment names a customer-managed policy of this estate (an aws_iam_policy), not an AWS-managed one. What to decide: the roles of this role's service account from the findings of every policy attached here, and whether one policy shared by several roles becomes one set of role assignments or several.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
- **Property accounting:** 4 of 4 meaningful properties accounted (not carried 2 · contract 2 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.catalog_service.aws_iam_role.task_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_iam_role_policy_attachment.cloudwatch_logs.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_iam_role_policy_attachment.ecs_exec.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.checkout_service.aws_iam_role.task_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:31
- **Configuration:** conditional — the unit exists and counts in the totals, but part of what configures it is decided only when a plan runs; it is not automation-eligible (gate blocker `CONFIGURATION:conditional-facet`).
  - `module.retail_app_ecs.module.checkout_service.aws_iam_role_policy_attachment.cloudwatch_agent` is switched off by default (the default of variable `var.opentelemetry_enabled`; a root variable that a variable file or the command line can override): nothing of it is drafted, and a variable file or `-var` that gives that input another value creates it
- **Classification:** RECONFIGURE · **Confidence:** LOW · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: iam-managed-customer-policy, iam-trust-service-workload, permissions, trust (**not automation-eligible**: no property the unit sets is read by linked-dependency:aws_dynamodb_table)
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person. The unit names module.dependencies.module.dynamodb_carts.aws_dynamodb_table.this (aws_dynamodb_table) through this setting (the target does not carry it: it is REDESIGN), so what the reference becomes is part of this setting.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-customer-policy` (critical): REVIEW · a check of the knowledge base (iam managed customer policy) (knowledge-base check iam-managed-customer-policy)
    - why it is open: A check of the knowledge base (iam managed customer policy) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). This attachment names a customer-managed policy of this estate (an aws_iam_policy), not an AWS-managed one. What to decide: the roles of this role's service account from the findings of every policy attached here, and whether one policy shared by several roles becomes one set of role assignments or several.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `linked-dependency:aws_dynamodb_table` (critical): REVIEW · linked-dependency:aws_dynamodb_table
- **Property accounting:** 5 of 5 meaningful properties accounted (not carried 2 · contract 3 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.checkout_service.aws_iam_role.task_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.checkout_service.aws_iam_role_policy_attachment.cloudwatch_logs.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_iam_role_policy_attachment.ecs_exec.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_iam_role_policy_attachment.task_role_additional.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.orders_service.aws_iam_role.task_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:31
- **Configuration:** conditional — the unit exists and counts in the totals, but part of what configures it is decided only when a plan runs; it is not automation-eligible (gate blocker `CONFIGURATION:conditional-facet`).
  - `module.retail_app_ecs.module.orders_service.aws_iam_role_policy_attachment.cloudwatch_agent` is switched off by default (the default of variable `var.opentelemetry_enabled`; a root variable that a variable file or the command line can override): nothing of it is drafted, and a variable file or `-var` that gives that input another value creates it
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: trust, permissions, iam-trust-service-workload, iam-managed-customer-policy
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-customer-policy` (critical): REVIEW · a check of the knowledge base (iam managed customer policy) (knowledge-base check iam-managed-customer-policy)
    - why it is open: A check of the knowledge base (iam managed customer policy) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). This attachment names a customer-managed policy of this estate (an aws_iam_policy), not an AWS-managed one. What to decide: the roles of this role's service account from the findings of every policy attached here, and whether one policy shared by several roles becomes one set of role assignments or several.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
- **Property accounting:** 4 of 4 meaningful properties accounted (not carried 2 · contract 2 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.orders_service.aws_iam_role.task_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_iam_role_policy_attachment.cloudwatch_logs.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_iam_role_policy_attachment.ecs_exec.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.ui_service.aws_iam_role.task_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:31
- **Configuration:** conditional — the unit exists and counts in the totals, but part of what configures it is decided only when a plan runs; it is not automation-eligible (gate blocker `CONFIGURATION:conditional-facet`).
  - `module.retail_app_ecs.module.ui_service.aws_iam_role_policy_attachment.cloudwatch_agent` is switched off by default (the default of variable `var.opentelemetry_enabled`; a root variable that a variable file or the command line can override): nothing of it is drafted, and a variable file or `-var` that gives that input another value creates it
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: trust, permissions, iam-trust-service-workload, iam-managed-customer-policy
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-customer-policy` (critical): REVIEW · a check of the knowledge base (iam managed customer policy) (knowledge-base check iam-managed-customer-policy)
    - why it is open: A check of the knowledge base (iam managed customer policy) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). This attachment names a customer-managed policy of this estate (an aws_iam_policy), not an AWS-managed one. What to decide: the roles of this role's service account from the findings of every policy attached here, and whether one policy shared by several roles becomes one set of role assignments or several.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
- **Property accounting:** 4 of 4 meaningful properties accounted (not carried 2 · contract 2 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.ui_service.aws_iam_role.task_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.ui_service.aws_iam_role_policy_attachment.cloudwatch_logs.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_iam_role_policy_attachment.ecs_exec.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.aws_secretsmanager_secret.catalog_db`

- **Source:** `aws_secretsmanager_secret` — ../../lib/ecs/catalog.tf:65
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.secretsmanager_secret/secret`
- **Semantic surface** (contract `aws.secretsmanager_secret`): 3 of 34 semantics stated by the source, 3 accounted, 0 unaccounted — critical left for review/accepted loss: secret-value, customer-managed-key, tc-secretsmanager-secret-name
  - `secret-value` (critical): REVIEW · the mapping rule for aws_secretsmanager_secret (knowledge-base case secret)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The value moves to STACKIT Secrets Manager (Vault-compatible KV). The draft generates the shared instance, and the plan a WriteSecret step for an aws_secretsmanager_secret or a SecureString aws_ssm_parameter that is not repeated. The step writes the document the person supplies and does not carry this setting (the value is the person's document); for a secret repeated by count or for_each whose instances are not all known, and for a parameter whose type is not the literal SecureString, only the instance is generated. What a person decides, per secret: where the value comes from (the same value fetched from a secure source, or a new one — moving is the moment to rotate) and the Vault path the application will read, then writes it with the Vault provider or CLI — REVIEW. History: added with aws_ssm_parameter on 2026-09-24; REVIEW since 2026-09-27 (was TRANSFORMED); 2026-10-29 the wording names the WriteSecret step of the plan; 2026-10-30 the step is also made for a SecureString parameter.
    - what closes it: A person decides per secret where the value comes from (the same value from a secure source, or a new one) and the Vault path the application reads, then writes it with a Vault KV v2 client.
  - `customer-managed-key` (critical): REVIEW · a check of the knowledge base (secret cmk) (knowledge-base check secret-cmk)
    - why it is open: A check of the knowledge base (secret cmk) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Critical and reading the key since 2026-09-27: the draft names it NOT CARRIED, except where it sets the instance's kms_key (below). The AWS key does not move, AWS's key per secret has no per-secret counterpart, and the draft sets the kms_key block (referencing the drafted STACKIT key) only when every source of the shared instance is an AWS secret that references that one key — otherwise it names the key NOT CARRIED with the reason; either way a person decides (REVIEW, see the customer-managed key check).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `tc-secretsmanager-secret-name` (critical): REVIEW · the mapping rule for aws_secretsmanager_secret (knowledge-base case secret)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_secretsmanager_secret.name: Friendly name used to address the secret; losing it breaks lookups by name but does not change who may reach or read the value, its encryption or deletion behaviour (IAM statements that scope by name are assessed on the IAM policy). No semantic of this family has verified it as carried. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the secret name or path the application looks up on the target, or accepts the new one.
- **Property accounting:** 3 of 3 meaningful properties accounted (not carried 3 · contract 0 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.aws_secretsmanager_secret.catalog_db.kms_key_id` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.aws_secretsmanager_secret.catalog_db.name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.aws_secretsmanager_secret_version.catalog_db.secret_string` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.aws_secretsmanager_secret.mq`

- **Source:** `aws_secretsmanager_secret` — ../../lib/ecs/common.tf:11
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.secretsmanager_secret/secret`
- **Semantic surface** (contract `aws.secretsmanager_secret`): 2 of 34 semantics stated by the source, 2 accounted, 0 unaccounted — critical left for review/accepted loss: secret-value, tc-secretsmanager-secret-name
  - `secret-value` (critical): REVIEW · the mapping rule for aws_secretsmanager_secret (knowledge-base case secret)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The value moves to STACKIT Secrets Manager (Vault-compatible KV). The draft generates the shared instance, and the plan a WriteSecret step for an aws_secretsmanager_secret or a SecureString aws_ssm_parameter that is not repeated. The step writes the document the person supplies and does not carry this setting (the value is the person's document); for a secret repeated by count or for_each whose instances are not all known, and for a parameter whose type is not the literal SecureString, only the instance is generated. What a person decides, per secret: where the value comes from (the same value fetched from a secure source, or a new one — moving is the moment to rotate) and the Vault path the application will read, then writes it with the Vault provider or CLI — REVIEW. History: added with aws_ssm_parameter on 2026-09-24; REVIEW since 2026-09-27 (was TRANSFORMED); 2026-10-29 the wording names the WriteSecret step of the plan; 2026-10-30 the step is also made for a SecureString parameter.
    - what closes it: A person decides per secret where the value comes from (the same value from a secure source, or a new one) and the Vault path the application reads, then writes it with a Vault KV v2 client.
  - `tc-secretsmanager-secret-name` (critical): REVIEW · the mapping rule for aws_secretsmanager_secret (knowledge-base case secret)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_secretsmanager_secret.name: Friendly name used to address the secret; losing it breaks lookups by name but does not change who may reach or read the value, its encryption or deletion behaviour (IAM statements that scope by name are assessed on the IAM policy). No semantic of this family has verified it as carried. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the secret name or path the application looks up on the target, or accepts the new one.
- **Property accounting:** 2 of 2 meaningful properties accounted (not carried 2 · contract 0 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.aws_secretsmanager_secret.mq.name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.aws_secretsmanager_secret_version.mq.secret_string` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.aws_secretsmanager_secret.orders_db`

- **Source:** `aws_secretsmanager_secret` — ../../lib/ecs/orders.tf:68
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.secretsmanager_secret/secret`
- **Semantic surface** (contract `aws.secretsmanager_secret`): 2 of 34 semantics stated by the source, 2 accounted, 0 unaccounted — critical left for review/accepted loss: secret-value, tc-secretsmanager-secret-name
  - `secret-value` (critical): REVIEW · the mapping rule for aws_secretsmanager_secret (knowledge-base case secret)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The value moves to STACKIT Secrets Manager (Vault-compatible KV). The draft generates the shared instance, and the plan a WriteSecret step for an aws_secretsmanager_secret or a SecureString aws_ssm_parameter that is not repeated. The step writes the document the person supplies and does not carry this setting (the value is the person's document); for a secret repeated by count or for_each whose instances are not all known, and for a parameter whose type is not the literal SecureString, only the instance is generated. What a person decides, per secret: where the value comes from (the same value fetched from a secure source, or a new one — moving is the moment to rotate) and the Vault path the application will read, then writes it with the Vault provider or CLI — REVIEW. History: added with aws_ssm_parameter on 2026-09-24; REVIEW since 2026-09-27 (was TRANSFORMED); 2026-10-29 the wording names the WriteSecret step of the plan; 2026-10-30 the step is also made for a SecureString parameter.
    - what closes it: A person decides per secret where the value comes from (the same value from a secure source, or a new one) and the Vault path the application reads, then writes it with a Vault KV v2 client.
  - `tc-secretsmanager-secret-name` (critical): REVIEW · the mapping rule for aws_secretsmanager_secret (knowledge-base case secret)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_secretsmanager_secret.name: Friendly name used to address the secret; losing it breaks lookups by name but does not change who may reach or read the value, its encryption or deletion behaviour (IAM statements that scope by name are assessed on the IAM policy). No semantic of this family has verified it as carried. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the secret name or path the application looks up on the target, or accepts the new one.
- **Property accounting:** 2 of 2 meaningful properties accounted (not carried 2 · contract 0 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.aws_secretsmanager_secret.orders_db.name` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.aws_secretsmanager_secret_version.orders_db.secret_string` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.catalog_service.aws_iam_role.task_execution_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:14
- **Classification:** RECONFIGURE · **Confidence:** LOW · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: iam-managed-ecs, iam-trust-service-workload, permissions, trust (**not automation-eligible**: no property the unit sets is read by linked-dependency:aws_secretsmanager_secret)
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person. The unit names 2 resources through this setting whose references the draft does not resolve: module.retail_app_ecs.aws_secretsmanager_secret.catalog_db (aws_secretsmanager_secret), module.retail_app_ecs.aws_secretsmanager_secret.catalog_opensearch (aws_secretsmanager_secret). What each reference becomes is part of this setting.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-ecs` (critical): REVIEW · a check of the knowledge base (iam managed ecs) (knowledge-base check iam-managed-ecs)
    - why it is open: A check of the knowledge base (iam managed ecs) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Managed policy of an ECS role (AWS: task execution pulls images from ECR and writes CloudWatch Logs; the container-instance role registers hosts with ECS). What to decide: the registry pull credential and the log destination of the replacing workload.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `linked-dependency:aws_secretsmanager_secret` (critical): REVIEW · linked-dependency:aws_secretsmanager_secret
- **Property accounting:** 4 of 4 meaningful properties accounted (not carried 2 · contract 2 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.catalog_service.aws_iam_role.task_execution_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.catalog_service.aws_iam_role_policy_attachment.task_execution_role_additional.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_iam_role_policy_attachment.task_execution_role_policy.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.orders_service.aws_iam_role.task_execution_role`

- **Source:** `aws_iam_role` — ../../lib/ecs/service/iam.tf:14
- **Classification:** RECONFIGURE · **Confidence:** LOW · rule `aws.iam_role/role-workload-execution`
- **Semantic surface** (contract `aws.iam_role`): 6 of 103 semantics stated by the source, 6 accounted, 0 unaccounted — critical left for review/accepted loss: iam-managed-ecs, iam-trust-service-workload, permissions, trust (**not automation-eligible**: no property the unit sets is read by linked-dependency:aws_secretsmanager_secret)
  - `trust` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The trust policy document of the role (its principals and conditions) has no STACKIT counterpart: stackit_service_account has name and project_id only (pinned provider schema), and the draft names assume_role_policy as not carried.
    - what closes it: A person decides per principal who may assume the role: a federated identity provider (IRSA), a server attachment or a service account key; a role used only by an AWS service is dropped after a person confirms it.
  - `permissions` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. STACKIT IAM grants roles; the policy documents, conditions and resource patterns of the role are translated by a person. The unit names 2 resources through this setting whose references the draft does not resolve: module.retail_app_ecs.aws_secretsmanager_secret.mq (aws_secretsmanager_secret), module.retail_app_ecs.aws_secretsmanager_secret.orders_db (aws_secretsmanager_secret). What each reference becomes is part of this setting.
    - what closes it: A person translates each permission of the attached policies into STACKIT roles on the target resources.
  - `facet-link-role` (critical): NOT_APPLICABLE · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `tcfp-iam-role-policy-attachment--policy-arn` (critical): REVIEW · the mapping rule for aws_iam_role (knowledge-base case role-workload-execution)
  - `iam-trust-service-workload` (critical): REVIEW · a check of the knowledge base (iam trust service workload) (knowledge-base check iam-trust-service-workload)
    - why it is open: A check of the knowledge base (iam trust service workload) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Trust policy: lambda.amazonaws.com or ecs-tasks.amazonaws.com assumes this role, so an application workload (a Lambda function or an ECS task) runs as it. What to decide: key or federation, and the roles of the attached policies (see the permission findings of this unit).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `iam-managed-ecs` (critical): REVIEW · a check of the knowledge base (iam managed ecs) (knowledge-base check iam-managed-ecs)
    - why it is open: A check of the knowledge base (iam managed ecs) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Managed policy of an ECS role (AWS: task execution pulls images from ECR and writes CloudWatch Logs; the container-instance role registers hosts with ECS). What to decide: the registry pull credential and the log destination of the replacing workload.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `linked-dependency:aws_secretsmanager_secret` (critical): REVIEW · linked-dependency:aws_secretsmanager_secret
- **Property accounting:** 4 of 4 meaningful properties accounted (not carried 2 · contract 2 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.orders_service.aws_iam_role.task_execution_role.assume_role_policy` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.orders_service.aws_iam_role_policy_attachment.task_execution_role_additional.policy_arn` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_iam_role_policy_attachment.task_execution_role_policy.policy_arn` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

### Messaging

#### `module.dependencies.aws_mq_broker.mq`

- **Source:** `aws_mq_broker` — ../../lib/dependencies/mq.tf:12
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.mq_broker/rabbitmq`
- **Semantic surface** (contract `aws.mq_broker`): 14 of 44 semantics stated by the source, 14 accounted, 0 unaccounted — critical left for review/accepted loss: engine-version, broker-network, network-exposure, broker-users, tc-user--password, tc-user--username, tcp-deployment-mode, tc-mq-broker-broker-name (**not automation-eligible**: no property the unit sets is read by broker-users)
  - `engine-type` (critical): PRESERVED · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
  - `engine-version` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. stackit_rabbitmq_instance takes a STACKIT RabbitMQ version (the draft asks for it: rabbitmq_version) — which versions STACKIT offers is not in the rule's evidence.
    - what closes it: A person picks the RabbitMQ version for the target instance, since the versions STACKIT offers are not stated for this move.
  - `broker-network` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. stackit_rabbitmq_instance has no subnet or security-group attribute (pinned provider): clients reach the instance at the address STACKIT assigns, restricted by parameters.sgw_acl — a person decides the ranges.
    - what closes it: A person decides which client address ranges may reach the target RabbitMQ instance through its access list, in place of the source subnets and security groups.
  - `engine` (critical): TRANSFORMED · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
  - `network-exposure` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The broker is either reachable from the public internet or only from private networks.
    - what closes it: A person sets which networks may reach the STACKIT RabbitMQ instance with its access list (a list of CIDR networks); the draft sets none.
  - `broker-users` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Users become stackit_rabbitmq_credential entries with generated passwords; their permissions are set by a person.
    - what closes it: A person sets the permissions of each broker user on the generated RabbitMQ credentials and hands the new passwords to the clients.
  - `tc-user--password` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_mq_broker.user.password: The broker user's login credential; a literal secret. Held CRITICAL: it carries or names a credential; the value is never copied and a person re-creates it on the target. No semantic of this family has verified it as carried.
    - what closes it: A person hands the clients the password of the generated target credential instead of the literal in the source.
  - `tc-user--username` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_mq_broker.user.username: The broker user's login identity. Held CRITICAL: it decides who or what may use, read or change the resource or the data behind it. No semantic of this family has verified it as carried.
    - what closes it: A person confirms the user names the clients log in with; STACKIT generates each RabbitMQ credential's username, so the clients move to the new usernames.
  - `tcp-deployment-mode` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_mq_broker.deployment_mode: The family's own setting for high availability already reads this as critical: it selects single instance vs. active standby multi az vs. cluster multi az, i.e. whether the broker survives an AZ failure at all. Held CRITICAL: it decides capacity, delivery guarantees, retry or failure handling that consumers depend on.
    - what closes it: A person decides whether the target must survive a zone failure as the source deployment mode did, and finds out which RabbitMQ plan, if any, gives that, since the zone spread of the plans is not stated.
  - `tcp-engine-type` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
  - `tcp-engine-version` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
  - `tcp-security-groups` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
  - `tcp-subnet-ids` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
  - `tc-mq-broker-broker-name` (critical): REVIEW · the mapping rule for aws_mq_broker (knowledge-base case rabbitmq)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The name of the message broker. Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person confirms the broker name the target uses against what refers to the source broker name, or accepts the new name.
- **Property accounting:** 12 of 12 meaningful properties accounted (not carried 4 · contract 7 · consumed by the draft 1 · relation 0 · placement 0)
- **Critical-property gate:** `module.dependencies.aws_mq_broker.mq.broker_name` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_mq_broker.mq.deployment_mode` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_mq_broker.mq.engine_version` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_mq_broker.mq.publicly_accessible` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_mq_broker.mq.security_groups` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_mq_broker.mq.subnet_ids` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_mq_broker.mq.user.password` (CRITICAL/CLOSED:NC+REVIEW), `module.dependencies.aws_mq_broker.mq.user.username` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

### Network

#### `module.vpc.module.vpc.aws_eip.nat`

- **Source:** `aws_eip` — .terraform/modules/vpc.vpc/main.tf:1092
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.eip/eip-for-nat`
- **Semantic surface** (contract `aws.eip`): 1 of 15 semantics stated by the source, 1 accounted, 0 unaccounted — critical left for review/accepted loss: public-address (**not automation-eligible**: no property the unit sets is read by public-address)
  - `public-address` (critical): REVIEW · the mapping rule for aws_eip (knowledge-base case eip-for-nat)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The address changes. An Elastic IP of a NAT gateway is its fixed egress address, an open question on STACKIT (fixed egress ip of the NAT gateway rule).
    - what closes it: A person decides how peers that allow-list the Elastic IP are served: STACKIT egress uses the project's shared address, which differs from the Elastic IP, cannot be set and can change; a STACKIT public IP per server keeps its address.

#### `module.vpc.module.vpc.aws_vpc.this`

- **Source:** `aws_vpc` — .terraform/modules/vpc.vpc/main.tf:28
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.vpc/vpc`
- **Semantic surface** (contract `aws.vpc`): 22 of 102 semantics stated by the source, 22 accounted, 0 unaccounted — critical left for review/accepted loss: network-topology-boundary, dns-settings, default-nacl-rules, default-route-table, default-security-group-omitted-direction, main-table-set (**not automation-eligible**: no property the unit sets is read by default-security-group-omitted-direction, main-table-set, network-topology-boundary)
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). STACKIT has no VPC container in its stable model: the project is the boundary of its networks and its virtual router routes between all networks of one project (docs.stackit.cloud core-networking architecture, updated Aug 20, 2026: "Routing between multiple Virtual Networks in the same project"; SNA "extends the networking architecture to enable cross-project connectivity"). Several VPCs, or a count the scan cannot see: the draft puts every network in the one var.project_id and cannot keep them apart — REVIEW, the choice is the architect's. A unit that names a VPC, or is placed in a subnet (subnet_id, subnets, vpc_config.subnet_ids, ...), without one whole reference to the VPC or to a subnet of the estate may stand in a VPC the estate does not create: the architect decides it the same way (REVIEW).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `address-space` (critical): TRANSFORMED · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `default-tenancy` (critical): PRESERVED · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `dns-settings` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. enable_dns_support and enable_dns_hostnames of the VPC decide how names resolve for what runs in it; STACKIT has no VPC object (each subnet becomes a stackit_network).
    - what closes it: A person confirms how names resolve for the servers of the migrated networks.
  - `default-nacl-rules` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The account's default network ACL is adopted by the VPC (aws_default_network_acl); a deny rule, a rule that is not all-protocol, a CIDR other than 0.0.0.0/0 or ::/0, or an explicitly empty rule list narrows or leaves undecided what the AWS default allow-all states.
    - what closes it: A person re-expresses the default network ACL's rules as security group rules, because STACKIT has no stateless subnet ACL; no STACKIT documentation states that a server or network without an attached security group allows all traffic.
  - `default-route-table` (critical): REVIEW · a check of the knowledge base (vpc main table undecided) (knowledge-base check vpc-main-table-undecided)
    - why it is open: A check of the knowledge base (vpc main table undecided) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The account's default route table is adopted (a facet of the VPC, aws_default_route_table, AWS provider 6.66.0). Routes other than a plain 0.0.0.0/0 to an internet or NAT gateway are REVIEW.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `default-security-group-omitted-direction` (critical): REVIEW · a check of the knowledge base (vpc default sg no ingress rules) (knowledge-base check vpc-default-sg-no-ingress-rules)
    - why it is open: A check of the knowledge base (vpc default sg no ingress rules) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The adopted default security group of the VPC (a facet, aws_default_security_group) does not state an ingress or an egress direction. Nothing is drafted for this facet, so the empty direction is not reproduced: a person decides whether servers that used the default group must stay without outbound traffic (delete the allow-all egress rules of the STACKIT group after apply) or are meant to have it, and puts them in a STACKIT group that states no ingress rule, not in the project's default group.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `main-table-set` (critical): REVIEW · a check of the knowledge base (vpc main table undecided) (knowledge-base check vpc-main-table-undecided)
    - why it is open: A check of the knowledge base (vpc main table undecided) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting names the route table that is the main route table of the VPC, when the configuration sets it or the scan cannot tell. STACKIT has no main route table.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `tcfp-default-network-acl--egress--action` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--egress--cidr-block` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--egress--from-port` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--egress--ipv6-cidr-block` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--egress--protocol` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--egress--rule-no` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--egress--to-port` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--ingress--action` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--ingress--cidr-block` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--ingress--from-port` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--ingress--ipv6-cidr-block` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--ingress--protocol` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--ingress--rule-no` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
  - `tcfp-default-network-acl--ingress--to-port` (critical): REVIEW · the mapping rule for aws_vpc (knowledge-base case vpc)
- **Critical-property gate (implicit unit):** `module.vpc.module.vpc.aws_vpc.this.enable_dns_hostnames` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_vpc.this.enable_dns_support` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.egress.action` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.egress.cidr_block` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.egress.from_port` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.egress.ipv6_cidr_block` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.egress.protocol` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.egress.rule_no` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.egress.to_port` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.ingress.action` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.ingress.cidr_block` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.ingress.from_port` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.ingress.ipv6_cidr_block` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.ingress.protocol` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.ingress.rule_no` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_network_acl.this.ingress.to_port` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_default_route_table.default.propagating_vgws` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.alb.aws_security_group.this`

- **Source:** `aws_security_group` — .terraform/modules/retail_app_ecs.alb/main.tf:807
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 4 of 116 semantics stated by the source, 4 accounted, 0 unaccounted — critical left for review/accepted loss: egress-restriction, network-topology-boundary, security-group-vpc-membership, stateful (**not automation-eligible**: no property the unit sets is read by egress-restriction, network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `egress-restriction` (critical): REVIEW · a check of the knowledge base (sg egress restricted) (knowledge-base check sg-egress-restricted)
    - why it is open: A check of the knowledge base (sg egress restricted) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The security group restricts its outbound traffic: it has no rule that allows every protocol to 0.0.0.0/0 or ::/0.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
- **Property accounting:** 1 of 1 meaningful properties accounted (not carried 1 · contract 0 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.alb.aws_security_group.this.vpc_id` (CRITICAL/CLOSED:NC+UNSUPPORTED) — **not automation-eligible**

#### `module.retail_app_ecs.module.alb_sg.aws_security_group.this_name_prefix`

- **Source:** `aws_security_group` — .terraform/modules/retail_app_ecs.alb_sg/main.tf:37
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 10 of 116 semantics stated by the source, 10 accounted, 0 unaccounted — critical left for review/accepted loss: network-topology-boundary, rule-ports, security-group-vpc-membership, standalone-rule-empty-sources, standalone-rule-other-sources, standalone-rule-values, stateful (**not automation-eligible**: no property the unit sets is read by network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `rule-ports` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `revoke-rules-on-delete`: NOT_APPLICABLE · the mapping rule for aws_security_group (knowledge-base case sg)
  - `standalone-rule-values` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). An aws_security_group_rule becomes a stackit_security_group_rule: type → direction, protocol → protocol, cidr_blocks → ip_range (one rule per range), source_security_group_id → remote_security_group_id. A rule that is not generated is named NOT CARRIED and the group is REVIEW.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `standalone-rule-other-sources` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). A standalone rule's own group (self) and IPv6 ranges are written where the draft places the rule (self as remote_security_group_id of the group, an IPv6 range as ip_range with ether_type IPv6), and the draft names the rule NOT CARRIED when the plan withholds it; prefix lists are not generated (as rule other sources for inline rules; prefix lists: the prefix list check), and a person adds the rule if the traffic must pass — REVIEW in every order position.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `standalone-rule-empty-sources` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). self = false and empty IPv6/prefix-list lists (module defaults) add no source, as the drafted rule adds none — PRESERVED, per rule that states no source, next to rules that do (those are standalone rule other sources, REVIEW); REVIEW when a rule of the group is not generated (its settings are named NOT CARRIED, the rule not generated check) or a value is not visible statically: the draft names such a value NOT CARRIED and nothing here claims it carried.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `tcfp-security-group-rule--from-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
  - `tcfp-security-group-rule--to-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
- **Property accounting:** 16 of 16 meaningful properties accounted (not carried 15 · contract 1 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.alb_sg.aws_security_group.this_name_prefix.vpc_id` (CRITICAL/CLOSED:NC+UNSUPPORTED), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.egress_rules.cidr_blocks` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.egress_rules.from_port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.egress_rules.ipv6_cidr_blocks` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.egress_rules.prefix_list_ids` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.egress_rules.protocol` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.egress_rules.to_port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.egress_rules.type` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.ingress_rules.cidr_blocks` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.ingress_rules.from_port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.ingress_rules.ipv6_cidr_blocks` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.ingress_rules.prefix_list_ids` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.ingress_rules.protocol` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.ingress_rules.to_port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb_sg.aws_security_group_rule.ingress_rules.type` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.carts_service.aws_security_group.this`

- **Source:** `aws_security_group` — ../../lib/ecs/service/sg.tf:1
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 7 of 116 semantics stated by the source, 7 accounted, 0 unaccounted — critical left for review/accepted loss: egress-rule-protocol, egress-sources, ingress-sources, network-topology-boundary, rule-ports, security-group-vpc-membership, stateful (**not automation-eligible**: no property the unit sets is read by network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `rule-ports` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-rule-protocol` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. protocol → stackit_security_group_rule.protocol (pinned provider). the egress restriction setting reads the same attribute and is REVIEW exactly when the egress restriction check fires; this semantic is then REVIEW as well, so the two critical readers of egress.protocol never disagree (TRANSFORMED only when neither check fires).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `ingress-sources` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). cidr_blocks → stackit_security_group_rule.ip_range (one rule per range), security_groups → remote_security_group_id (pinned provider); REVIEW for the group when a rule is not generated, as rule ports (2026-09-27).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-sources` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. As ingress sources; the egress restriction setting reads egress.cidr_blocks too and is REVIEW exactly when the egress restriction check fires — the same order here, so the two never disagree.
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
- **Property accounting:** 10 of 10 meaningful properties accounted (not carried 2 · contract 8 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.carts_service.aws_security_group.this.egress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_security_group.this.egress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_security_group.this.egress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_security_group.this.egress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_security_group.this.ingress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_security_group.this.ingress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_security_group.this.ingress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_security_group.this.ingress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.carts_service.aws_security_group.this.vpc_id` (CRITICAL/CLOSED:NC+UNSUPPORTED) — **not automation-eligible**

#### `module.retail_app_ecs.module.catalog_service.aws_security_group.this`

- **Source:** `aws_security_group` — ../../lib/ecs/service/sg.tf:1
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 7 of 116 semantics stated by the source, 7 accounted, 0 unaccounted — critical left for review/accepted loss: egress-rule-protocol, egress-sources, ingress-sources, network-topology-boundary, rule-ports, security-group-vpc-membership, stateful (**not automation-eligible**: no property the unit sets is read by network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `rule-ports` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-rule-protocol` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. protocol → stackit_security_group_rule.protocol (pinned provider). the egress restriction setting reads the same attribute and is REVIEW exactly when the egress restriction check fires; this semantic is then REVIEW as well, so the two critical readers of egress.protocol never disagree (TRANSFORMED only when neither check fires).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `ingress-sources` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). cidr_blocks → stackit_security_group_rule.ip_range (one rule per range), security_groups → remote_security_group_id (pinned provider); REVIEW for the group when a rule is not generated, as rule ports (2026-09-27).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-sources` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. As ingress sources; the egress restriction setting reads egress.cidr_blocks too and is REVIEW exactly when the egress restriction check fires — the same order here, so the two never disagree.
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
- **Property accounting:** 10 of 10 meaningful properties accounted (not carried 2 · contract 8 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.catalog_service.aws_security_group.this.egress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_security_group.this.egress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_security_group.this.egress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_security_group.this.egress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_security_group.this.ingress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_security_group.this.ingress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_security_group.this.ingress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_security_group.this.ingress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.catalog_service.aws_security_group.this.vpc_id` (CRITICAL/CLOSED:NC+UNSUPPORTED) — **not automation-eligible**

#### `module.retail_app_ecs.module.checkout_service.aws_security_group.this`

- **Source:** `aws_security_group` — ../../lib/ecs/service/sg.tf:1
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 7 of 116 semantics stated by the source, 7 accounted, 0 unaccounted — critical left for review/accepted loss: egress-rule-protocol, egress-sources, ingress-sources, network-topology-boundary, rule-ports, security-group-vpc-membership, stateful (**not automation-eligible**: no property the unit sets is read by network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `rule-ports` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-rule-protocol` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. protocol → stackit_security_group_rule.protocol (pinned provider). the egress restriction setting reads the same attribute and is REVIEW exactly when the egress restriction check fires; this semantic is then REVIEW as well, so the two critical readers of egress.protocol never disagree (TRANSFORMED only when neither check fires).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `ingress-sources` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). cidr_blocks → stackit_security_group_rule.ip_range (one rule per range), security_groups → remote_security_group_id (pinned provider); REVIEW for the group when a rule is not generated, as rule ports (2026-09-27).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-sources` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. As ingress sources; the egress restriction setting reads egress.cidr_blocks too and is REVIEW exactly when the egress restriction check fires — the same order here, so the two never disagree.
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
- **Property accounting:** 10 of 10 meaningful properties accounted (not carried 2 · contract 8 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.checkout_service.aws_security_group.this.egress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_security_group.this.egress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_security_group.this.egress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_security_group.this.egress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_security_group.this.ingress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_security_group.this.ingress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_security_group.this.ingress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_security_group.this.ingress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.checkout_service.aws_security_group.this.vpc_id` (CRITICAL/CLOSED:NC+UNSUPPORTED) — **not automation-eligible**

#### `module.retail_app_ecs.module.orders_service.aws_security_group.this`

- **Source:** `aws_security_group` — ../../lib/ecs/service/sg.tf:1
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 7 of 116 semantics stated by the source, 7 accounted, 0 unaccounted — critical left for review/accepted loss: egress-rule-protocol, egress-sources, ingress-sources, network-topology-boundary, rule-ports, security-group-vpc-membership, stateful (**not automation-eligible**: no property the unit sets is read by network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `rule-ports` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-rule-protocol` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. protocol → stackit_security_group_rule.protocol (pinned provider). the egress restriction setting reads the same attribute and is REVIEW exactly when the egress restriction check fires; this semantic is then REVIEW as well, so the two critical readers of egress.protocol never disagree (TRANSFORMED only when neither check fires).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `ingress-sources` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). cidr_blocks → stackit_security_group_rule.ip_range (one rule per range), security_groups → remote_security_group_id (pinned provider); REVIEW for the group when a rule is not generated, as rule ports (2026-09-27).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-sources` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. As ingress sources; the egress restriction setting reads egress.cidr_blocks too and is REVIEW exactly when the egress restriction check fires — the same order here, so the two never disagree.
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
- **Property accounting:** 10 of 10 meaningful properties accounted (not carried 2 · contract 8 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.orders_service.aws_security_group.this.egress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_security_group.this.egress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_security_group.this.egress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_security_group.this.egress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_security_group.this.ingress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_security_group.this.ingress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_security_group.this.ingress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_security_group.this.ingress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.orders_service.aws_security_group.this.vpc_id` (CRITICAL/CLOSED:NC+UNSUPPORTED) — **not automation-eligible**

#### `module.retail_app_ecs.module.ui_service.aws_security_group.this`

- **Source:** `aws_security_group` — ../../lib/ecs/service/sg.tf:1
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 7 of 116 semantics stated by the source, 7 accounted, 0 unaccounted — critical left for review/accepted loss: egress-rule-protocol, egress-sources, ingress-sources, network-topology-boundary, rule-ports, security-group-vpc-membership, stateful (**not automation-eligible**: no property the unit sets is read by network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `rule-ports` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-rule-protocol` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. protocol → stackit_security_group_rule.protocol (pinned provider). the egress restriction setting reads the same attribute and is REVIEW exactly when the egress restriction check fires; this semantic is then REVIEW as well, so the two critical readers of egress.protocol never disagree (TRANSFORMED only when neither check fires).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `ingress-sources` (critical): LEDGER · ledger:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. Whether the draft carries this setting is decided by its semantic ledger entry "security group rules", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). cidr_blocks → stackit_security_group_rule.ip_range (one rule per range), security_groups → remote_security_group_id (pinned provider); REVIEW for the group when a rule is not generated, as rule ports (2026-09-27).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `egress-sources` (critical): REVIEW · unenforced:security group rules
    - why it is open: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. As ingress sources; the egress restriction setting reads egress.cidr_blocks too and is REVIEW exactly when the egress restriction check fires — the same order here, so the two never disagree.
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
- **Property accounting:** 10 of 10 meaningful properties accounted (not carried 2 · contract 8 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.ui_service.aws_security_group.this.egress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_security_group.this.egress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_security_group.this.egress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_security_group.this.egress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_security_group.this.ingress.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_security_group.this.ingress.from_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_security_group.this.ingress.protocol` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_security_group.this.ingress.to_port` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.ui_service.aws_security_group.this.vpc_id` (CRITICAL/CLOSED:NC+UNSUPPORTED) — **not automation-eligible**

#### `module.vpc.module.vpc.aws_nat_gateway.this`

- **Source:** `aws_nat_gateway` — .terraform/modules/vpc.vpc/main.tf:1111
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.nat_gateway/nat`
- **Semantic surface** (contract `aws.nat_gateway`): 4 of 8 semantics stated by the source, 4 accounted, 0 unaccounted — critical left for review/accepted loss: network-topology-boundary, fixed-egress-ip, nat-placement (**not automation-eligible**: no property the unit sets is read by network-topology-boundary)
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this NAT gateway included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `outbound-nat` (critical): TRANSFORMED · the mapping rule for aws_nat_gateway (knowledge-base case nat)
  - `fixed-egress-ip` (critical): REVIEW · the mapping rule for aws_nat_gateway (knowledge-base case nat)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A stable egress IP on STACKIT is an open question (no source in this repository answers it; the per-network SNAT address is computed and cannot be chosen or kept).
    - what closes it: A person decides how peers that allow-list the Elastic IP are served: a routed STACKIT network leaves by the project's shared egress address, which cannot be set and can change, so the allow-list follows it or each server gets a STACKIT public IP.
  - `nat-placement` (critical): REVIEW · the mapping rule for aws_nat_gateway (knowledge-base case nat)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. A zonal NAT gateway (subnet_id) is placed in one AZ; a regional one lists its per-AZ egress in availability_zone_address(es).availability_zone. STACKIT has no NAT gateway resource, and its documentation does not state whether the implicit outbound path is zone-scoped: REVIEW.
    - what closes it: A person decides whether the egress path must stay in one zone or per zone, because the STACKIT documentation does not state whether the implicit outbound path is scoped to a zone.
- **Critical-property gate (implicit unit):** `module.vpc.module.vpc.aws_nat_gateway.this.allocation_id` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_nat_gateway.this.subnet_id` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.dependencies.aws_security_group.catalog_opensearch_sg`

- **Source:** `aws_security_group` — ../../lib/dependencies/catalog_opensearch.tf:14
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 8 of 116 semantics stated by the source, 8 accounted, 0 unaccounted — critical left for review/accepted loss: egress-restriction, network-topology-boundary, security-group-vpc-membership, standalone-rule-not-generated, standalone-rule-remote-not-resolved, stateful (**not automation-eligible**: no property the unit sets is read by egress-restriction, network-topology-boundary, standalone-rule-remote-not-resolved, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `egress-restriction` (critical): REVIEW · a check of the knowledge base (sg egress restricted) (knowledge-base check sg-egress-restricted)
    - why it is open: A check of the knowledge base (sg egress restricted) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The security group restricts its outbound traffic: it has no rule that allows every protocol to 0.0.0.0/0 or ::/0.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `standalone-rule-not-generated` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. An aws_security_group_rule the draft does not generate (the draft names its settings NOT CARRIED, or the KB cannot decide that it generates it): a prefix list, an ICMP type with every code, ICMPv6 limited by type or code, a protocol with no STACKIT counterpart, a source or protocol or port not visible statically, a source group that is not one whole reference to a security group of the draft, or a repeated or conditionally created group. A person re-creates the rule with the STACKIT range or group it needs (a rule is never widened: a stackit_security_group_rule without source allows every address, pinned provider) - REVIEW, per rule.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `standalone-rule-remote-not-resolved` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The source of a standalone security group rule: the other security group (source_security_group_id) whose members the rule lets in.
    - what closes it: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A person re-creates the rule with the STACKIT security group or address range it needs; the draft does not widen it (a stackit_security_group_rule without a source allows everything, pinned provider).
  - `tcfp-security-group-rule--from-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
  - `tcfp-security-group-rule--to-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
- **Critical-property gate (implicit unit):** `module.dependencies.aws_security_group.catalog_opensearch_sg.vpc_id` (CRITICAL/CLOSED:UNSUPPORTED), `module.dependencies.aws_security_group_rule.allow_https_from_client.from_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_security_group_rule.allow_https_from_client.protocol` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_security_group_rule.allow_https_from_client.source_security_group_id` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_security_group_rule.allow_https_from_client.to_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_security_group_rule.allow_https_from_client.type` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.dependencies.aws_security_group.mq`

- **Source:** `aws_security_group` — ../../lib/dependencies/mq.tf:33
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 7 of 116 semantics stated by the source, 7 accounted, 0 unaccounted — critical left for review/accepted loss: egress-restriction, network-topology-boundary, security-group-vpc-membership, standalone-rule-not-generated, stateful (**not automation-eligible**: no property the unit sets is read by egress-restriction, network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `egress-restriction` (critical): REVIEW · a check of the knowledge base (sg egress restricted) (knowledge-base check sg-egress-restricted)
    - why it is open: A check of the knowledge base (sg egress restricted) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The security group restricts its outbound traffic: it has no rule that allows every protocol to 0.0.0.0/0 or ::/0.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `standalone-rule-not-generated` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. An aws_security_group_rule the draft does not generate (the draft names its settings NOT CARRIED, or the KB cannot decide that it generates it): a prefix list, an ICMP type with every code, ICMPv6 limited by type or code, a protocol with no STACKIT counterpart, a source or protocol or port not visible statically, a source group that is not one whole reference to a security group of the draft, or a repeated or conditionally created group. A person re-creates the rule with the STACKIT range or group it needs (a rule is never widened: a stackit_security_group_rule without source allows every address, pinned provider) - REVIEW, per rule.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `tcfp-security-group-rule--from-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
  - `tcfp-security-group-rule--to-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
- **Critical-property gate (implicit unit):** `module.dependencies.aws_security_group.mq.vpc_id` (CRITICAL/CLOSED:UNSUPPORTED), `module.dependencies.aws_security_group_rule.mq.from_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_security_group_rule.mq.protocol` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_security_group_rule.mq.source_security_group_id` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_security_group_rule.mq.to_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.aws_security_group_rule.mq.type` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.dependencies.module.catalog_rds.aws_security_group.this`

- **Source:** `aws_security_group` — .terraform/modules/dependencies.catalog_rds/main.tf:321
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 8 of 116 semantics stated by the source, 8 accounted, 0 unaccounted — critical left for review/accepted loss: egress-restriction, network-topology-boundary, rule-ports, security-group-vpc-membership, standalone-rule-values, stateful (**not automation-eligible**: no property the unit sets is read by egress-restriction, network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `egress-restriction` (critical): REVIEW · a check of the knowledge base (sg egress restricted) (knowledge-base check sg-egress-restricted)
    - why it is open: A check of the knowledge base (sg egress restricted) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The security group restricts its outbound traffic: it has no rule that allows every protocol to 0.0.0.0/0 or ::/0.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `rule-ports` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `standalone-rule-values` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). An aws_security_group_rule becomes a stackit_security_group_rule: type → direction, protocol → protocol, cidr_blocks → ip_range (one rule per range), source_security_group_id → remote_security_group_id. A rule that is not generated is named NOT CARRIED and the group is REVIEW.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `tcfp-security-group-rule--from-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
  - `tcfp-security-group-rule--to-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
- **Critical-property gate (implicit unit):** `module.dependencies.module.catalog_rds.aws_security_group.this.vpc_id` (CRITICAL/CLOSED:UNSUPPORTED), `module.dependencies.module.catalog_rds.aws_security_group_rule.default_ingress.from_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_security_group_rule.default_ingress.protocol` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_security_group_rule.default_ingress.source_security_group_id` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_security_group_rule.default_ingress.to_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.catalog_rds.aws_security_group_rule.default_ingress.type` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group.cbd`

- **Source:** `aws_security_group` — .terraform/modules/dependencies.checkout_elasticache_redis.aws_security_group/main.tf:81
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 10 of 116 semantics stated by the source, 10 accounted, 0 unaccounted — critical left for review/accepted loss: network-topology-boundary, rule-ports, security-group-vpc-membership, standalone-rule-empty-sources, standalone-rule-other-sources, standalone-rule-values, stateful (**not automation-eligible**: no property the unit sets is read by network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `rule-ports` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `revoke-rules-on-delete`: NOT_APPLICABLE · the mapping rule for aws_security_group (knowledge-base case sg)
  - `standalone-rule-values` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). An aws_security_group_rule becomes a stackit_security_group_rule: type → direction, protocol → protocol, cidr_blocks → ip_range (one rule per range), source_security_group_id → remote_security_group_id. A rule that is not generated is named NOT CARRIED and the group is REVIEW.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `standalone-rule-other-sources` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). A standalone rule's own group (self) and IPv6 ranges are written where the draft places the rule (self as remote_security_group_id of the group, an IPv6 range as ip_range with ether_type IPv6), and the draft names the rule NOT CARRIED when the plan withholds it; prefix lists are not generated (as rule other sources for inline rules; prefix lists: the prefix list check), and a person adds the rule if the traffic must pass — REVIEW in every order position.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `standalone-rule-empty-sources` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). self = false and empty IPv6/prefix-list lists (module defaults) add no source, as the drafted rule adds none — PRESERVED, per rule that states no source, next to rules that do (those are standalone rule other sources, REVIEW); REVIEW when a rule of the group is not generated (its settings are named NOT CARRIED, the rule not generated check) or a value is not visible statically: the draft names such a value NOT CARRIED and nothing here claims it carried.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `tcfp-security-group-rule--from-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
  - `tcfp-security-group-rule--to-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
- **Critical-property gate (implicit unit):** `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group.cbd.vpc_id` (CRITICAL/CLOSED:UNSUPPORTED), `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group_rule.keyed.cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group_rule.keyed.from_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group_rule.keyed.ipv6_cidr_blocks` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group_rule.keyed.prefix_list_ids` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group_rule.keyed.protocol` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group_rule.keyed.source_security_group_id` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group_rule.keyed.to_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.checkout_elasticache_redis.module.aws_security_group.aws_security_group_rule.keyed.type` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.dependencies.module.orders_rds.aws_security_group.this`

- **Source:** `aws_security_group` — .terraform/modules/dependencies.orders_rds/main.tf:321
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.security_group/sg`
- **Semantic surface** (contract `aws.security_group`): 8 of 116 semantics stated by the source, 8 accounted, 0 unaccounted — critical left for review/accepted loss: egress-restriction, network-topology-boundary, rule-ports, security-group-vpc-membership, standalone-rule-values, stateful (**not automation-eligible**: no property the unit sets is read by egress-restriction, network-topology-boundary, stateful)
  - `security-group-vpc-membership` (critical): UNSUPPORTED · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (topology vpc unproven) found a setting the target has no counterpart for (a finding of this unit describes it). UNSUPPORTED, by name: a STACKIT security group has no network (VPC) scope. stackit_security_group takes project_id, name, description, labels, stateful and region only (pinned provider), and the IaaS API object SecurityGroup has no network field either (stackit-api-specifications services/iaas/v2); the group is project-wide and can be attached to the network interfaces of every network of the project.
    - what closes it: A person confirms which VPC each network resource of the estate is in and whether the networks of another VPC belong in this project or in a project of their own joined through a Network Area; the group is then attached only to the interfaces of the networks that replace its VPC.
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this security group included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `stateful` (critical): REVIEW · unenforced:security group rules
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: UNENFORCED: the security group is attached to no block of the target (it is written in the draft and listed by no resource, or, where the access lists of its members carry it, not written), so its rules ("security group rules") restrict nothing on the target until an attachment is designed; this setting is not carried as an enforced control. STACKIT security groups are stateful by default (tested on a STACKIT project on 2026-09-24: stateful=true).
    - what closes it: A person designs how the target enforces what the group allowed (attaches the group, or its replacement, to the target resources that take its place), or accepts the difference.
  - `egress-restriction` (critical): REVIEW · a check of the knowledge base (sg egress restricted) (knowledge-base check sg-egress-restricted)
    - why it is open: A check of the knowledge base (sg egress restricted) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The security group restricts its outbound traffic: it has no rule that allows every protocol to 0.0.0.0/0 or ::/0.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `rule-ports` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Each rule becomes a stackit_security_group_rule: protocol → protocol.name/protocol.number, from_port/to_port → port_range.min/max, or icmp_parameters type/code for icmp (pinned provider schema).
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `standalone-rule-values` (critical): REVIEW · a check of the knowledge base (sg rule not rendered) (knowledge-base check sg-rule-not-rendered)
    - why it is open: This draft writes no stackit_security_group, stackit_security_group_rule for this unit: every unit that names the group is a managed data service of STACKIT, which has no security group and takes its clients from an access list of its own, so the group is listed by no resource and what it admitted reaches those access lists as addresses only. What follows states the knowledge base's candidate target, not a block of this draft: A check of the knowledge base (sg rule not rendered) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). An aws_security_group_rule becomes a stackit_security_group_rule: type → direction, protocol → protocol, cidr_blocks → ip_range (one rule per range), source_security_group_id → remote_security_group_id. A rule that is not generated is named NOT CARRIED and the group is REVIEW.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
  - `tcfp-security-group-rule--from-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
  - `tcfp-security-group-rule--to-port` (critical): REVIEW · the mapping rule for aws_security_group (knowledge-base case sg)
- **Critical-property gate (implicit unit):** `module.dependencies.module.orders_rds.aws_security_group.this.vpc_id` (CRITICAL/CLOSED:UNSUPPORTED), `module.dependencies.module.orders_rds.aws_security_group_rule.default_ingress.from_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.orders_rds.aws_security_group_rule.default_ingress.protocol` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.orders_rds.aws_security_group_rule.default_ingress.source_security_group_id` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.orders_rds.aws_security_group_rule.default_ingress.to_port` (CRITICAL/CLOSED:REVIEW), `module.dependencies.module.orders_rds.aws_security_group_rule.default_ingress.type` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.retail_app_ecs.module.alb.aws_lb.this`

- **Source:** `aws_lb` — .terraform/modules/retail_app_ecs.alb/main.tf:5
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.lb/alb`
- **Semantic surface** (contract `aws.lb`): 19 of 134 semantics stated by the source, 19 accounted, 0 unaccounted — critical left for review/accepted loss: client-restriction, lb-connection-timeouts, lb-routing-and-addressing, lb-subnets, network-exposure, request-handling, request-header-options, tc-lb-name (**not automation-eligible**: no property the unit sets is read by client-restriction)
  - `lb-connection-timeouts` (critical): REVIEW · the mapping rule for aws_lb (knowledge-base case alb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_lb.idle_timeout and client_keep_alive (aws 6.66.0): how long the load balancer lets a client connection idle and how long it keeps it open. The STACKIT application load balancer has no such attribute and the draft does not carry them - REVIEW: a person decides whether the applications behind the load balancer (long polling, streaming, WebSockets, slow requests) cope with the STACKIT default. aws_alb, the alias type, is not read here.
    - what closes it: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  - `network-exposure` (critical): LEDGER · ledger:network exposure
    - why it is open: Whether the draft carries this setting is decided by its semantic ledger entry "network exposure", and that entry does not state it as carried (it reads review or unsupported, is missing, or rests on a variable's default). internal not visible statically (a variable): the source states no exposure and the draft carries nothing for it; a person decides whether the STACKIT load balancer is private_network_only (REVIEW).
    - what closes it: The ledger entry reads preserved or transformed with a value that is a fact of the source, or a person accepts the difference.
  - `frontend-http2`: UNSUPPORTED · a check of the knowledge base (alb http2 frontend) (knowledge-base check alb-http2-frontend)
  - `client-restriction` (critical): REVIEW · a check of the knowledge base (lb security groups) (knowledge-base check lb-security-groups)
    - why it is open: A check of the knowledge base (lb security groups) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Who may reach the load balancer, read from the ingress rules of the security groups that filter its clients. A group reference, a prefix list, an IPv6 range or a variable is not carried: the plan lists the clients the target would block and adds the client-access manual step for the Security Architect.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person confirms the carried ranges against the source rules, or decides the open client-access step, and the regenerated draft carries the result.
  - `request-handling` (critical): REVIEW · the mapping rule for aws_lb (knowledge-base case alb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states how the load balancer treats HTTP requests that may carry a request-smuggling (desync) risk, and how it rewrites the X-Forwarded-For header before the target sees it.
    - what closes it: A person confirms that the application does not depend on either behaviour: the STACKIT application load balancer has neither setting and its documentation does not state the behaviour (pinned provider), also for the AWS default values.
  - `request-header-options` (critical): REVIEW · the mapping rule for aws_lb (knowledge-base case alb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states which extra headers the load balancer adds to the request the target receives (TLS version and cipher suite, the client port in X-Forwarded-For) and whether it keeps the original Host header.
    - what closes it: A person decides, for each setting, what the STACKIT load balancer or the application does instead, because the STACKIT application load balancer has no setting that adds, rewrites or renames a request header towards its targets (pinned provider).
  - `lb-routing-and-addressing` (critical): REVIEW · the mapping rule for aws_lb (knowledge-base case alb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states how the load balancer answers DNS for clients (Availability Zone affinity), whether it still forwards to targets when AWS WAF cannot be reached (fail open), zonal shift, customer-owned address pools and IPv6 source NAT prefixes.
    - what closes it: A person decides whether the STACKIT load balancer needs an equivalent for each of them, because the STACKIT application and network load balancers have no setting for any of them (pinned provider).
  - `lb-type` (critical): TRANSFORMED · the mapping rule for aws_lb (knowledge-base case alb)
  - `lb-subnets` (critical): REVIEW · the value could not be read; the mapping rule for aws_lb (knowledge-base case alb)
    - why it is open: The value is not visible statically (a case of the mapping rule for this kind of unit), so nothing is credited for it. The load balancer takes the network of its one converted subnet (networks.network_id; several subnets are lb subnets several, REVIEW): STACKIT networks are regional, one network holds what the source spread over zonal subnets.
    - what closes it: A literal value or a resolved reference in the source closes it, or a person confirms the value.
  - `deletion-protection` (critical): PRESERVED · the mapping rule for aws_lb (knowledge-base case alb)
  - `cross-zone` (critical): PRESERVED · the mapping rule for aws_lb (knowledge-base case alb)
  - `drop-invalid-headers` (critical): PRESERVED · the mapping rule for aws_lb (knowledge-base case alb)
  - `ip-address-type` (critical): PRESERVED · the mapping rule for aws_lb (knowledge-base case alb)
  - `listener-protocol` (critical): TRANSFORMED · the mapping rule for aws_lb (knowledge-base case alb)
  - `listeners` (critical): TRANSFORMED · the mapping rule for aws_lb (knowledge-base case alb)
  - `tcfp-lb-listener--default-action--type` (critical): REVIEW · the mapping rule for aws_lb (knowledge-base case alb)
  - `tcfp-lb-listener--protocol` (critical): REVIEW · the mapping rule for aws_lb (knowledge-base case alb)
  - `tcfp-lb-listener--default-action--target-group-arn` (critical): REVIEW · the mapping rule for aws_lb (knowledge-base case alb)
  - `tc-lb-name` (critical): REVIEW · the mapping rule for aws_lb (knowledge-base case alb)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_lb.name: Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract). No semantic of this family has verified it as carried.
    - what closes it: A person confirms the name the load balancer carries on the target against what refers to the source name, or accepts the new name.
- **Property accounting:** 21 of 21 meaningful properties accounted (not carried 6 · contract 15 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.module.alb.aws_lb.this.desync_mitigation_mode` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.enable_tls_version_and_cipher_suite_headers` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.enable_waf_fail_open` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.enable_xff_client_port` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.idle_timeout` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.internal` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.name` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.preserve_host_header` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.security_groups` (CRITICAL/CLOSED:NC+REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.subnets` (CRITICAL/CLOSED:REVIEW), `module.retail_app_ecs.module.alb.aws_lb.this.xff_header_processing_mode` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.vpc.module.vpc.aws_internet_gateway.this`

- **Source:** `aws_internet_gateway` — .terraform/modules/vpc.vpc/main.tf:1051 · instances: 0–1 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact
- **Standing:** conditional — whether it exists is decided only when a plan runs; the class below is the one it would get, it is not counted in the totals and not automation-eligible (gate blocker `TOPOLOGY:unknown`).
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.internet_gateway/igw`
- **Semantic surface** (contract `aws.internet_gateway`): 3 of 8 semantics stated by the source, 3 accounted, 0 unaccounted — critical left for review/accepted loss: network-topology-boundary (**not automation-eligible**: no property the unit sets is read by network-topology-boundary)
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this gateway included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `internet-access` (critical): TRANSFORMED · the mapping rule for aws_internet_gateway (knowledge-base case igw)
  - `attached-vpc` (critical): TRANSFORMED · the mapping rule for aws_internet_gateway (knowledge-base case igw)

#### `module.vpc.module.vpc.aws_route_table.private`

- **Source:** `aws_route_table` — .terraform/modules/vpc.vpc/main.tf:296 · instances: 0–1 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact
- **Standing:** conditional — whether it exists is decided only when a plan runs; the class below is the one it would get, it is not counted in the totals and not automation-eligible (gate blocker `TOPOLOGY:unknown`).
- **Configuration:** conditional — whether the unit exists is decided when a plan runs, and so is part of what configures it; the facets below are open too.
  - the configuration of `module.vpc.module.vpc.aws_route_table_association.private` is decided by `module.vpc.data.aws_availability_zones.available` (a data source, read when a plan runs)
- **Classification:** RECONFIGURE · **Confidence:** LOW · rule `aws.route_table/rt-default-only-nat`
- **Engine reason (every relation combination evaluated):** A route of the table sends traffic to a NAT gateway (the others, if any, to an internet gateway), and the draft's project is outside a Network Area. Observed on the target (tested on a STACKIT project in eu01 on 2026-10-10, a project outside a Network Area): a routed STACKIT network gives servers with and without a public IP the same outbound reachability with no route and no routing table, nothing initiated from the internet reaches a server behind the network address, and egress is restricted by the egress rules of security groups. The table is therefore not drafted: STACKIT's default routing replaces it. What a NAT gateway has beyond an internet route is NOT CARRIED and stays an open review: the gateway's fixed egress address is LOST (observed: the address a routed network leaves by is its project's publicIp, one address for every routed network of the project, not fixed - it changed after every network of the project was deleted, twice - and not settable, a PATCH answers 202 and is ignored), so a third party's allow-list on the NAT gateway's address does not survive and needs a STACKIT public IP per server (the only address the probe saw stay fixed); the restriction of egress to the gateway is carried only by security-group egress rules, which the draft does not tie to this table; the absence of an inbound path is observed. LOW: the loss is for a person to decide, as the plan decision NAT_FIXED_EGRESS_ADDRESS_LOST. The egress itself is not widened where the gateway is a public one: the subnets of this table reached the internet through it in the source, so the plan decision EXPOSURE_WIDENED_EGRESS (a subnet whose source had no route to the internet; a subnet behind a private NAT gateway is one, a private gateway gives no internet access) is not what this table raises; what changes is the address. STACKIT documents the way out as source NAT of the network (Virtual Network concepts, last updated Mar 11, 2026). Which NAT gateway the route names does not change this: a table that picks its NAT gateway by an index (one gateway per availability zone) or by a conditional between NAT gateways is decided as a table with one plain reference, because every gateway it can name is lost the same way and STACKIT has no NAT gateway to pick. A Gateway endpoint of S3 or DynamoDB that names the table adds a route that is NOT CARRIED (Object Storage is reached over the network's default path); it does not change the case, a check on the gateway endpoint names it. The destinations are read by the check of the route destinations. (Whether dependency `module.vpc.module.vpc.aws_subnet.private` (module.vpc.module.vpc.aws_route_table_association.private's count/for_each is not known statically (it may not exist)) exist was evaluated for each possibility; the mapping decides the same either way.)
- **Semantic surface** (contract `aws.route_table`): 11 of 37 semantics stated by the source, 11 accounted, 0 unaccounted — critical left for review/accepted loss: routes, route-destinations, route-targets, nat-fixed-egress-address, egress-restriction, subnet-association-target, tcr-route-table-vpc-id, network-topology-boundary (**not automation-eligible**: no property the unit sets is read by egress-restriction, nat-fixed-egress-address, network-topology-boundary)
  - `routes` (critical): REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only-nat)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Custom routes map to stackit_routing_table_route, an experimental resource (experiment routing-tables); next hops that name AWS gateways are chosen anew.
    - what closes it: A person creates the routes on the STACKIT routing table (stackit_routing_table_route, experimental) and chooses the next hops anew, because they name AWS gateways.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `route-destinations` (critical): REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only-nat)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Destinations are read by value: every route of a default-only table sends 0.0.0.0/0 to an internet or NAT gateway — STACKIT's default network routing, observed equivalent for a draft outside a Network Area (the test of 2026-10-10) and REVIEW all the same.
    - what closes it: A person confirms every route destination that is not the default route to an internet or NAT gateway (a CIDR, a prefix list, any IPv6 route): the draft carries none, and a specific destination needs a stackit_routing_table_route, which takes IPv4 CIDR destinations only.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `route-targets` (critical): REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only-nat)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The next hop of each route of the table: a route whose target is anything but an internet or NAT gateway, or that names none, makes the table a custom routing table.
    - what closes it: A person decides the next hop of each route on STACKIT: an internet gateway becomes the next hop internet, an appliance (a network interface or an instance) a next hop of type ipv4. A NAT gateway, a transit gateway or a VPC peering has no STACKIT counterpart, so the connectivity design is the person's.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `nat-fixed-egress-address` (critical): REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only-nat)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. NOT CARRIED, an observed loss (the test of 2026-10-10): the NAT gateway's fixed egress address.
    - what closes it: A person accepts the project's shared egress address, which can change and cannot be set, or gives each server a STACKIT public IP when a third party allow-lists the old address.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `egress-restriction` (critical): REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only-nat)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The restriction of egress to the NAT gateway (the only way out of a private subnet) is carried on STACKIT by the egress rules of the security groups, not by a route (the test of 2026-10-10: with egress rules for one /32 only that destination was reachable, with none nothing left). Whether the source restricts egress that way, and whether the draft carries those rules for the servers of this table's subnets, is not something this contract can read, so it is REVIEW and never PRESERVED: a person confirms that the servers of the private subnets keep a restricting egress rule set.
    - what closes it: A person confirms that the servers of the private subnets keep a restricting egress rule set in their security groups, because on STACKIT the restriction of egress is carried by egress rules, not by a route.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `inbound-none` (critical): PRESERVED · the mapping rule for aws_route_table (knowledge-base case rt-default-only-nat)
  - `route-set-completeness` (critical): PRESERVED · the mapping rule for aws_route_table (knowledge-base case rt-default-only-nat)
  - `associations`: REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only-nat)
  - `subnet-association-target` (critical): REVIEW · a check of the knowledge base (rt private subnet association) (knowledge-base check rt-private-subnet-association)
    - why it is open: A check of the knowledge base (rt private subnet association) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The setting states which subnet uses this route table, for the associations the draft does not attach.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person decides which networks of the Network Area take the routing table and sets routing_table_id on them: STACKIT attaches a routing table to a whole network (stackit_network.routing_table_id), there is no per-subnet association, and routing tables apply only to routed Layer 3 networks in a Network Area.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `tcr-route-table-vpc-id` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). aws_route_table.vpc_id: The VPC whose subnets this route table's rules apply to; a route table's entries only make sense, and only affect reachability, within this one VPC, so losing or mismapping it silently changes which network the routing rules govern. A custom table is REVIEW whatever the estate: the draft's stackit_routing_table is organisation and Network Area scoped (organization_id, network_area_id, pinned provider), not a resource of the project that is the VPC's boundary (the experimental stackit_vpc_routing_table, pinned provider: project_id, vpc_id, is a VPC-scoped table that the draft does not write and that nothing establishes as the counterpart of an AWS route table), so which networks the table governs is decided by the Network Area the person puts the project in and the routing_table_id each network is given. A table the draft does not make (count or for_each) and one left to the architect are REVIEW. Several VPCs, a VPC count that is not visible, or a vpc_id (this table's or another unit's) that is a literal, a variable, a data source or an expression the scan cannot reduce to the estate's VPC: which routing domain the table belongs to is the architect's decision — REVIEW. Held CRITICAL: it decides which networks, clients or endpoints reach the resource or what it reaches.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person decides which STACKIT networks the routing table governs: the draft's custom table is organisation and Network Area scoped, so the Network Area the project joins and the routing table each network is given decide it.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this route table included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
- **Critical-property gate (implicit unit):** `module.vpc.module.vpc.aws_route_table.private.vpc_id` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_route.private_nat_gateway.destination_cidr_block` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_route.private_nat_gateway.nat_gateway_id` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_route_table_association.private.subnet_id` (CRITICAL/CLOSED:REVIEW) — **not automation-eligible**

#### `module.vpc.module.vpc.aws_route_table.public`

- **Source:** `aws_route_table` — .terraform/modules/vpc.vpc/main.tf:164 · instances: 0–1 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact
- **Standing:** conditional — whether it exists is decided only when a plan runs; the class below is the one it would get, it is not counted in the totals and not automation-eligible (gate blocker `TOPOLOGY:unknown`).
- **Configuration:** conditional — whether the unit exists is decided when a plan runs, and so is part of what configures it; the facets below are open too.
  - the configuration of `module.vpc.module.vpc.aws_route.public_internet_gateway` is decided by `module.vpc.data.aws_availability_zones.available` (a data source, read when a plan runs)
  - the configuration of `module.vpc.module.vpc.aws_route_table_association.public` is decided by `module.vpc.data.aws_availability_zones.available` (a data source, read when a plan runs)
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.route_table/rt-default-only`
- **Engine reason (every relation combination evaluated):** Every route of the table sends traffic to an internet gateway (a reference to an aws_internet_gateway, or an ID that is not a virtual private gateway's) and the draft's project is outside a Network Area. Observed on the target (tested on a STACKIT project in eu01 on 2026-10-10, a project outside a Network Area): a routed STACKIT network gives servers with and without a public IP the same outbound reachability with no route and no routing table configured (HTTPS, ICMP, DNS and TCP 443 in 62 of 62 rounds over 30 minutes per server; a non-routed network reaches nothing), nothing initiated from the internet reaches a server behind the network address (tcp 22, 80, 8080 timed out in 137 of 137 samples with an admitting security group), egress is restricted by the egress rules of security groups, and routed networks reach each other with no table. The table is therefore not drafted: STACKIT's default routing replaces it. Equivalent for a server that has a public IP. NOT equivalent for a server WITHOUT one: in the source an internet gateway serves only an instance with a public IPv4 or Elastic IP address ("the instances in the public subnet must have public IP addresses or Elastic IP addresses to enable communication with the internet over the internet gateway", AWS internet gateway documentation), so such an instance has no internet path; on STACKIT the same server leaves through the SNAT address of its network (observed in the STACKIT sandbox on two rounds; "VM without one: the SNAT address of its network, shared by every VM in that network without its own public IP", stackitcloud/professional-service examples/vpn-full-tunnel-central-egress README). The draft therefore GIVES egress to servers the source did not give it; the table does not carry that, and it is decided on the subnet (the finding that the egress of the subnet is not proven, and the plan decision EXPOSURE_WIDENED_EGRESS of the subnet, private egress ipv4), not here. What the STACKIT documentation says of the same behaviour (Virtual Network concepts, last updated Mar 11, 2026, read 2026-10-27): "Every subnet is routed to the public internet. Technically this is done by source NAT (SNAT) in combination with masquerading", it "supports outbound internet access but does not allow traffic initiated from the public internet to reach your resources", and the routing "can be controlled using Routing tables" only for projects that are part of a Network Area. So outside an area the equivalence rests on the documentation and on the test of 2026-10-10, which agree. Not HIGH: the test was one project, one region, one day, no probe in a Network Area (a draft that writes a Network Area is the case of a table in a Network Area), and the servers without a public IP are not equivalent (above). The destinations are read by the check of the route destinations: only 0.0.0.0/0 is default routing, any other destination (IPv6 included) is REVIEW. A Gateway endpoint of S3 or DynamoDB that names the table adds a route that is NOT CARRIED and does not change the case. (Whether dependency `module.vpc.module.vpc.aws_internet_gateway.this` (module.vpc.module.vpc.aws_route.public_internet_gateway's count/for_each is not known statically (it may not exist)); dependency `module.vpc.module.vpc.aws_subnet.public` (module.vpc.module.vpc.aws_route_table_association.public's count/for_each is not known statically (it may not exist)) exist was evaluated for each possibility; the mapping decides the same either way.)
- **Semantic surface** (contract `aws.route_table`): 8 of 37 semantics stated by the source, 8 accounted, 0 unaccounted — critical left for review/accepted loss: routes, route-destinations, route-targets, tcr-route-table-vpc-id, network-topology-boundary (**not automation-eligible**: no property the unit sets is read by network-topology-boundary)
  - `routes` (critical): REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Custom routes map to stackit_routing_table_route, an experimental resource (experiment routing-tables); next hops that name AWS gateways are chosen anew.
    - what closes it: A person creates the routes on the STACKIT routing table (stackit_routing_table_route, experimental) and chooses the next hops anew, because they name AWS gateways.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `route-destinations` (critical): REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. Destinations are read by value: every route of a default-only table sends 0.0.0.0/0 to an internet or NAT gateway — STACKIT's default network routing, observed equivalent for a draft outside a Network Area (the test of 2026-10-10) and REVIEW all the same.
    - what closes it: A person confirms every route destination that is not the default route to an internet or NAT gateway (a CIDR, a prefix list, any IPv6 route): the draft carries none, and a specific destination needs a stackit_routing_table_route, which takes IPv4 CIDR destinations only.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `route-targets` (critical): REVIEW · the mapping rule for aws_route_table (knowledge-base case rt-default-only)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The next hop of each route of the table: a route whose target is anything but an internet or NAT gateway, or that names none, makes the table a custom routing table.
    - what closes it: A person decides the next hop of each route on STACKIT: an internet gateway becomes the next hop internet, an appliance (a network interface or an instance) a next hop of type ipv4. A NAT gateway, a transit gateway or a VPC peering has no STACKIT counterpart, so the connectivity design is the person's.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `route-set-completeness` (critical): PRESERVED · the mapping rule for aws_route_table (knowledge-base case rt-default-only)
  - `associations`: NOT_APPLICABLE · the mapping rule for aws_route_table (knowledge-base case rt-default-only)
  - `subnet-association-target` (critical): NOT_APPLICABLE · the mapping rule for aws_route_table (knowledge-base case rt-default-only)
  - `tcr-route-table-vpc-id` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). aws_route_table.vpc_id: The VPC whose subnets this route table's rules apply to; a route table's entries only make sense, and only affect reachability, within this one VPC, so losing or mismapping it silently changes which network the routing rules govern. A custom table is REVIEW whatever the estate: the draft's stackit_routing_table is organisation and Network Area scoped (organization_id, network_area_id, pinned provider), not a resource of the project that is the VPC's boundary (the experimental stackit_vpc_routing_table, pinned provider: project_id, vpc_id, is a VPC-scoped table that the draft does not write and that nothing establishes as the counterpart of an AWS route table), so which networks the table governs is decided by the Network Area the person puts the project in and the routing_table_id each network is given. A table the draft does not make (count or for_each) and one left to the architect are REVIEW. Several VPCs, a VPC count that is not visible, or a vpc_id (this table's or another unit's) that is a literal, a variable, a data source or an expression the scan cannot reduce to the estate's VPC: which routing domain the table belongs to is the architect's decision — REVIEW. Held CRITICAL: it decides which networks, clients or endpoints reach the resource or what it reaches.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person decides which STACKIT networks the routing table governs: the draft's custom table is organisation and Network Area scoped, so the Network Area the project joins and the routing table each network is given decide it.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this route table included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
- **Critical-property gate (implicit unit):** `module.vpc.module.vpc.aws_route_table.public.vpc_id` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_route.public_internet_gateway.destination_cidr_block` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_route.public_internet_gateway.gateway_id` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_route_table_association.public.subnet_id` (CRITICAL/OPEN:not-applicable) — **not automation-eligible**
  - `module.vpc.module.vpc.aws_route_table_association.public.subnet_id`: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The setting states which subnet uses this route table, for the associations the draft does not attach. Closes when: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.

#### `module.vpc.module.vpc.aws_subnet.private`

- **Source:** `aws_subnet` — .terraform/modules/vpc.vpc/main.tf:267 · instances: 0–3 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact
- **Standing:** conditional — whether it exists is decided only when a plan runs; the class below is the one it would get, it is not counted in the totals and not automation-eligible (gate blocker `TOPOLOGY:unknown`).
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.subnet/subnet`
- **Semantic surface** (contract `aws.subnet`): 9 of 96 semantics stated by the source, 9 accounted, 0 unaccounted — critical left for review/accepted loss: subnet-vpc-membership, network-topology-boundary, private-egress-ipv4, prefix, availability-zone (**not automation-eligible**: no property the unit sets is read by network-topology-boundary, private-egress-ipv4)
  - `subnet-vpc-membership` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The VPC the subnet belongs to: the draft creates every network in one project, so the source VPC's boundary is kept only when the estate has one VPC and every resource that names a VPC provably names it; the draft states the estate's topology and what the architect decides about it once, at the top of its network file.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this subnet included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `private-egress-ipv4` (critical): REVIEW · a check of the knowledge base (subnet egress ipv4 unproven) (knowledge-base check subnet-egress-ipv4-unproven)
    - why it is open: A check of the knowledge base (subnet egress ipv4 unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The source and the target are not equivalent for outbound access, and the draft closes nothing: REVIEW.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `prefix` (critical): REVIEW · the value could not be read; the mapping rule for aws_subnet (knowledge-base case subnet)
    - why it is open: The value is not visible statically (a case of the mapping rule for this kind of unit), so nothing is credited for it. stackit_network.ipv4_prefix. TRANSFORMED for a CIDR the scan has seen. The draft carries the prefix as stackit_network.ipv4_prefix taken from a variable without a default (pinned provider: "The IPv4 prefix of the network (CIDR)") and says in the variable's description that the source CIDR is not visible; decide the CIDR each STACKIT network gets (the source CIDRs are reused unless the address plan changes) and enter it before plan.
    - what closes it: A literal value or a resolved reference in the source closes it, or a person confirms the value.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `ipv6` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
  - `availability-zone` (critical): REVIEW · the mapping rule for aws_subnet (knowledge-base case subnet)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The availability zone of the subnet. STACKIT networks are regional (stackit_network has no zone field, pinned provider); the zone is chosen per server and volume, and AWS zone names do not map to STACKIT zones.
    - what closes it: A person decides, per source zone, which STACKIT zone (eu01-1, eu01-2 or eu01-3) takes the servers and volumes that sat in it, so that the source's spread and its failure domains are kept.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `dns64` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
  - `tc-subnet-enable-resource-name-dns-a-record-on-launch` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
  - `tc-subnet-enable-resource-name-dns-aaaa-record-on-launch` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
- **Property accounting:** 9 of 9 meaningful properties accounted (not carried 3 · contract 6 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.vpc.module.vpc.aws_subnet.private.availability_zone` (CRITICAL/CLOSED:NC+REVIEW), `module.vpc.module.vpc.aws_subnet.private.availability_zone_id` (CRITICAL/CLOSED:NC+REVIEW), `module.vpc.module.vpc.aws_subnet.private.cidr_block` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_subnet.private.vpc_id` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

#### `module.vpc.module.vpc.aws_subnet.public`

- **Source:** `aws_subnet` — .terraform/modules/vpc.vpc/main.tf:131 · instances: 0–3 instances (decided by `module.vpc.data.aws_availability_zones.available`); POSSIBLE_SOURCE_ERROR: `slice(…, 3)` fails in Terraform and OpenTofu when the list has fewer than 3 elements (the source proves none), so the count is not exact
- **Standing:** conditional — whether it exists is decided only when a plan runs; the class below is the one it would get, it is not counted in the totals and not automation-eligible (gate blocker `TOPOLOGY:unknown`).
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.subnet/subnet`
- **Semantic surface** (contract `aws.subnet`): 11 of 96 semantics stated by the source, 11 accounted, 0 unaccounted — critical left for review/accepted loss: subnet-vpc-membership, network-topology-boundary, effective-route-table, private-egress-ipv4, prefix, availability-zone (**not automation-eligible**: no property the unit sets is read by effective-route-table, network-topology-boundary, private-egress-ipv4)
  - `subnet-vpc-membership` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The VPC the subnet belongs to: the draft creates every network in one project, so the source VPC's boundary is kept only when the estate has one VPC and every resource that names a VPC provably names it; the draft states the estate's topology and what the architect decides about it once, at the top of its network file.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `network-topology-boundary` (critical): REVIEW · a check of the knowledge base (topology vpc unproven) (knowledge-base check topology-vpc-unproven)
    - why it is open: A check of the knowledge base (topology vpc unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). Several VPCs, a VPC count that is not visible, or a unit of the estate that names a VPC, or is placed in a subnet, the scan cannot prove is the estate's, leave the architecture to the architect for every unit of the topology, this subnet included: STACKIT has no VPC container in its stable model, the project is the boundary of its networks, so the draft cannot keep several VPCs apart in one project.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `effective-route-table` (critical): REVIEW · a check of the knowledge base (subnet route table undecided) (knowledge-base check subnet-route-table-undecided)
    - why it is open: A check of the knowledge base (subnet route table undecided) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The subnet follows the VPC's main route table when no association names a route table.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded. A person decides which routes the subnet's network gets: the draft attaches no routing table to the network, and a STACKIT network gets a default gateway unless it is told not to, so what the subnet reaches can differ from AWS.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `private-egress-ipv4` (critical): REVIEW · a check of the knowledge base (subnet egress ipv4 unproven) (knowledge-base check subnet-egress-ipv4-unproven)
    - why it is open: A check of the knowledge base (subnet egress ipv4 unproven) fired on this unit and leaves the setting to a person: the target does not settle it by itself (a finding of this unit describes it). The source and the target are not equivalent for outbound access, and the draft closes nothing: REVIEW.
    - what closes it: A person decides it as that finding asks, and the finding's closing evidence or decision is recorded.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `prefix` (critical): REVIEW · the value could not be read; the mapping rule for aws_subnet (knowledge-base case subnet)
    - why it is open: The value is not visible statically (a case of the mapping rule for this kind of unit), so nothing is credited for it. stackit_network.ipv4_prefix. TRANSFORMED for a CIDR the scan has seen. The draft carries the prefix as stackit_network.ipv4_prefix taken from a variable without a default (pinned provider: "The IPv4 prefix of the network (CIDR)") and says in the variable's description that the source CIDR is not visible; decide the CIDR each STACKIT network gets (the source CIDRs are reused unless the address plan changes) and enter it before plan.
    - what closes it: A literal value or a resolved reference in the source closes it, or a person confirms the value.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `public-ip-on-launch` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
  - `ipv6` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
  - `availability-zone` (critical): REVIEW · the mapping rule for aws_subnet (knowledge-base case subnet)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. The availability zone of the subnet. STACKIT networks are regional (stackit_network has no zone field, pinned provider); the zone is chosen per server and volume, and AWS zone names do not map to STACKIT zones.
    - what closes it: A person decides, per source zone, which STACKIT zone (eu01-1, eu01-2 or eu01-3) takes the servers and volumes that sat in it, so that the source's spread and its failure domains are kept.
    - not read instance by instance (unknown_count: the number of instances is not known statically)
  - `dns64` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
  - `tc-subnet-enable-resource-name-dns-a-record-on-launch` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
  - `tc-subnet-enable-resource-name-dns-aaaa-record-on-launch` (critical): PRESERVED · the mapping rule for aws_subnet (knowledge-base case subnet)
- **Property accounting:** 10 of 10 meaningful properties accounted (not carried 3 · contract 7 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.vpc.module.vpc.aws_subnet.public.availability_zone` (CRITICAL/CLOSED:NC+REVIEW), `module.vpc.module.vpc.aws_subnet.public.availability_zone_id` (CRITICAL/CLOSED:NC+REVIEW), `module.vpc.module.vpc.aws_subnet.public.cidr_block` (CRITICAL/CLOSED:REVIEW), `module.vpc.module.vpc.aws_subnet.public.vpc_id` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**

### Observability

#### `module.retail_app_ecs.aws_cloudwatch_log_group.ecs_tasks`

- **Source:** `aws_cloudwatch_log_group` — ../../lib/ecs/cluster.tf:10
- **Classification:** RECONFIGURE · **Confidence:** MEDIUM · rule `aws.cloudwatch_log_group/log-group`
- **Semantic surface** (contract `aws.cloudwatch_log_group`): 1 of 33 semantics stated by the source, 1 accounted, 0 unaccounted — critical left for review/accepted loss: tc-name
  - `tc-name` (critical): REVIEW · the mapping rule for aws_cloudwatch_log_group (knowledge-base case log-group)
    - why it is open: The mapping rule for this kind of unit recognises the unit but only passes this setting to a person; it does not decide its value. aws_cloudwatch_log_group.name is the address a log producer writes to (awslogs-group, PutLogEvents logGroupName). The name is therefore not carried by anything the draft generates, and no producer is rewired: a person decides the label convention and reconfigures each producer - REVIEW (the plan holds it as a label convention manual action). Held CRITICAL: the workload, its clients or its neighbours rely on it (an address, a name, a protocol or an execution contract).
    - what closes it: A person decides the label convention under which the log group name survives in STACKIT Logs and reconfigures each producer to send it; the draft configures no shipper.
- **Property accounting:** 1 of 1 meaningful properties accounted (not carried 1 · contract 0 · consumed by the draft 0 · relation 0 · placement 0)
- **Critical-property gate:** `module.retail_app_ecs.aws_cloudwatch_log_group.ecs_tasks.name` (CRITICAL/CLOSED:NC+REVIEW) — **not automation-eligible**
