Good — Vector module has no new variable, consistent with spec ("The source is always declared (the receiver is harmless if no agent is pointed at it), so there is no new module variable").

Now let me double-check the README for the DD agent module mentions the expected port too — and verify that the v1.1.0 line in DD Agent's README "byte-identical to the v1.1.x line" reference is reasonable.

The DD Agent README says "byte-identical to the v1.1.x line." The current ref bumped from `v1.1.2` → `v1.2.0`, so "v1.1.x" is correct.

Let me make sure I haven't missed anything in the consumer README - specifically, verifying we're not sneaking a new note that was already there before:


1	## Vector (telemetry redaction aggregator)
2
3	Vector is an optional in-cluster aggregator that sits between the OTel collector and Datadog. When enabled it applies VRL-based transforms — dropping audit log lines and redacting email addresses — across logs, traces, and metrics before shipping to Datadog. See the [design spec](../../../../docs/superpowers/specs/2026-05-05-vector-redaction-design.md) for full architecture, failure-mode analysis, and rollout guidance.
4
5	### Data flow
6
7	When `vector_enabled = true`:
8
9	```
10	apps → otel-lb → otel-collector → vector → Datadog
11	```
12
13	The otel-collector's terminal exporter switches from `datadog` to `otlp` (gRPC pointed at `vector.vector.svc.cluster.local:4317`). The Datadog API key ownership moves from the otel-collector to the Vector module's ExternalSecret. The otel-collector module is pinned to `v1.1.0` which introduced the `downstream_endpoint` variable; `v1.0.7` and earlier are not compatible with this mode.
14
15	When `vector_enabled = false` (or unset and the cluster type defaults to disabled):
16
17	```
18	apps → otel-lb → otel-collector → Datadog
19	```
20
21	The `otel-collector` module reverts to its original `datadog` exporter. No Vector resources are created.
22
23	### Enabling Vector for a cluster
24
25	The five required variables must be set together with `vector_enabled = true`. The remaining variables have defaults that are suitable for most clusters.
26
27	```hcl
28	vector_enabled                             = true
29	vector_chart_version                       = "0.36.0"
30	vector_image_tag                           = "0.40.0-distroless-libc"
31	vector_datadog_site                        = "datadoghq.com"
32	vector_datadog_api_key_vault_path          = "secret/data/datadog/api-key"
33	vector_external_secrets_cluster_store_name = "vault-cluster-store"
34	```
35
36	Vector requires `external_secrets_enabled = true` (or a cluster type that enables it by default). A Terraform validation block enforces this dependency.
37
38	### Vector variables
39
40	| Variable | Description | Type | Default | Required when enabled |
41	|---|---|---|---|---|
42	| `vector_chart_version` | Vector helm chart version pin | `string` | `""` | yes |
43	| `vector_image_tag` | Vector image tag | `string` | `""` | yes |
44	| `vector_datadog_site` | Datadog site for Vector sinks (e.g. `datadoghq.com`) | `string` | `""` | yes |
45	| `vector_datadog_api_key_vault_path` | Vault path for the Datadog API key consumed by Vector's ExternalSecret | `string` | `""` | yes |
46	| `vector_external_secrets_cluster_store_name` | Name of the ClusterSecretStore created by the external-secrets module | `string` | `""` | yes |
47	| `vector_enabled` | Override for explicitly enabling or disabling Vector | `bool` | `null` | no |
48	| `vector_enabled_cluster_types` | Per-cluster-type defaults (`mgmt/cps/saas=true`, `infra/dev=false`) | `map(bool)` | see below | no |
49	| `vector_image` | Vector container image (registry/path) | `string` | `registry.ic-ops.net/cache-docker-hub/timberio/vector` | no |
50	| `vector_replicas` | Number of Vector aggregator replicas | `number` | `3` | no |
51	| `vector_audit_drop_patterns` | Regex patterns; matching log message bodies are dropped before Datadog | `list(string)` | Immuta audit patterns | no |
52	| `vector_email_redaction_enabled` | Toggle the email-redact VRL transform across all three signals | `bool` | `true` | no |
53	| `vector_email_redaction_replacement` | Replacement string for redacted email addresses | `string` | `[REDACTED-EMAIL]` | no |
54	| `vector_dd_agent_logs_enabled` | Override for routing DD Agent logs through Vector. When null, inherits from Vector's enabled state. Set to false to keep DD Agent shipping logs directly to DD SaaS even when Vector is deployed. | `bool` | `null` | no |
55	| `vector_additional_config` | Escape-hatch: overwrites the entire Vector `customConfig` helm value | `any` | `null` | no |
56
57	### DD Agent → Vector log routing (OPW)
58
59	When `vector_dd_agent_logs_enabled` is true (defaults to following `vector_enabled`), the Datadog Agent ships container logs to Vector via the OPW HTTP intake on `vector.vector.svc.cluster.local:8282`. Logs traverse two filtering layers before reaching Datadog SaaS:
60
61	1. **Agent-side** — `DD_LOGS_CONFIG_PROCESSING_RULES` (see `datadog-agent/processing-rules/{env}/rules.json`) drops audit lines before transmission. Authoritative for audit drops.
62	2. **Vector** — `drop_audit` regex filter (defense-in-depth, same patterns) + `redact_emails_logs` substitutes email addresses with `[REDACTED-EMAIL]`.
63
64	Metrics and APM (traces) are unaffected and continue their existing OTel-based path through Vector. To roll back logs to direct DD shipping for a single cluster while keeping Vector traces, set `vector_dd_agent_logs_enabled = false` on that cluster — Vector continues serving OTel traffic, agent re-rolls back to direct logs.
65
66	This requires `datadog-agent` module v1.2.0+ and `vector` module v1.1.0+.
67
68	---


Looks comprehensive. Now let me verify all 5 VRL test runners are still being executed (CI script):

The `.gitlab-ci.yml` lists all 5 VRL test runners. Confirmed.

Let me look at whether a stale `count = 0` issue exists in the consumer. I want to examine how `local.vector_enabled` is computed and if anything is racy:

The consumer guard `data "external" "vector_dd_agent_logs_validate"` activates only when `local.vector_dd_agent_logs_enabled && !local.vector_enabled` — only when user explicitly set `vector_dd_agent_logs_enabled=true` AND vector is off. In all default-inheritance paths (`var.vector_dd_agent_logs_enabled = null`), this is false because `local.vector_dd_agent_logs_enabled = local.vector_enabled` so the AND with `!local.vector_enabled` is always false.

So default behavior on a cluster with vector disabled: `local.vector_dd_agent_logs_enabled = false`, the ternary short-circuits to null, no module dereference.

Backwards compatibility is intact.

I now have enough to write a comprehensive review.

---

# Code Review Report

## Strengths

- **Spec compliance is comprehensive.** Every numbered subsection of spec §3.1, 3.2, 4.1, 4.2, 4.3, 5, 6.1, 7.1 maps to actual code/test artifacts. The plan's self-review table holds up against the working-tree state.
- **Port 8282 consistency verified across 9 references** — Vector's `service.ports`, `dd_agent_in.address`, `netpol.tf`, `service_endpoint_dd_agent` output URL, Vector README architecture line, Vector README outputs row, DD Agent README example URL, and consumer README OPW description.
- **Naming consistency is clean.** `service_endpoint_dd_agent` (Vector output) ↔ `service_endpoint_dd_agent` (consumer wire-up); `logs_intake_url` (DD Agent variable) ↔ `logs_intake_url` (consumer module argument); `vector_dd_agent_logs_enabled` (consumer var/local/guard).
- **Module ref versions all line up.** Vector README example uses `v1.1.0`, consumer `vector.tf` uses `v1.1.0`, consumer `datadog_agent.tf` uses `v1.2.0`, DD Agent README references `v1.2.0`+, consumer README also calls out `v1.2.0+` and `v1.1.0+`.
- **Backwards compatibility verified.** Tracing: `var.vector_dd_agent_logs_enabled` defaults to `null` → `local.vector_dd_agent_logs_enabled` inherits `local.vector_enabled` → on a cluster where Vector is off, the inherited value is `false` → ternary short-circuits to `null` → DD Agent module receives `logs_intake_url = null` → values template's `%{ if logs_intake_url != null ~}` evaluates false → byte-identical render (verified by `tests/render/run.sh` passing — `.actual-direct.yaml` vs `expected-direct.yaml` diff exits 0).
- **Both `~` whitespace-strip directives present** on the OPW gating block in `values.yaml.tftpl` lines 82 and 87. The byte-identical render assertion empirically confirms both work.
- **Render harness is properly diff-based and reproducible** — uses `terraform templatefile()` against pinned variable values, locks `expected-direct.yaml` and `expected-via-vector.yaml`, runner is executable.
- **VRL fixture covers meaningful edge cases:** plain match, no-match, multi-match (including a `+tag@sub.domain.tld` form), nested `.attributes.user.email` redaction with non-string sibling preserved, and JSON-blob-in-message redaction (preserving JSON validity).
- **YAGNI honored.** Single bool variable `vector_dd_agent_logs_enabled` (not a per-cluster-type map) per spec §4.3. No over-engineering.
- **Plan-time guard mirrors existing convention.** `data "external" "vector_dd_agent_logs_validate"` uses the same bogus-program-as-error-message pattern as the existing `vector_validate` block in `vector.tf`. Consistency over novelty.
- **Test runners are all marked executable** (`tests/vrl/redact_emails_dd_agent_logs/run.sh` and `tests/render/run.sh`).
- **Touched .tf files pass `terraform fmt -check`.** Pre-existing fmt drift in untouched files (`otel_collector.tf`, `sysdig_agent.tf` in consumer; `netpols.tf` in DD Agent module) confirmed not part of this delta.

## Issues

### Critical
None.

### Important
None. The implementation is consistent with spec, plan, and existing conventions.

### Minor

- **Consumer README auto-generated module table is stale.** `/Users/steve.briggs/projects/IAC/terraform/iac-library/aws/compute/eks-cluster-applications/README.md` line 106 still shows `module_datadog_agent | ... | v1.1.0` — should be `v1.2.0` after the bump in `datadog_agent.tf` line 14. Also, no `module_vector` row exists in the auto-generated table. This entire table appears to be regenerated by `terraform-docs`, so a regeneration pass would refresh both. Not blocking — the friendly inputs table at line 54 is correct, and the module-version line at line 66 ("This requires `datadog-agent` module v1.2.0+ and `vector` module v1.1.0+") is correct. But the auto-generated section drifts.

- **DD Agent module's `terraform fmt` drift bled into the diff.** The DD Agent module's working tree shows ~50 lines of incidental whitespace re-formatting in `variables.tf` and `main.tf` (now-aligned argument equals signs, default-value blocks, etc.). These were pre-existing fmt issues that ran together with the OPW additions when `terraform fmt` was invoked. This is fine semantically but inflates the diff. Future Sir Charles git commits may want to separate the `feat:` commits from a `style: terraform fmt cleanup` commit for clarity, though this is purely cosmetic.

- **Consumer's `vector.tf` is a brand-new file** (untracked in git status, despite the plan/prompt describing it as "Modify"). The prior session apparently moved Vector from inline to a separate file, or the file was previously deleted. This isn't a code defect — just worth flagging that "Modify" in the plan was mismatched with reality. Sir Charles should `git add vector.tf`.

- **Plan-time guard error path could be friendlier.** When `vector_dd_agent_logs_enabled=true` and `vector_enabled=false`, both the `data "external"` guard AND the `module.vector[0]` index-out-of-range error fire on plan. Terraform may surface the latter first depending on graph order, which is less informative than the guard's intended message. This is identical behavior to the existing `vector_validate` pattern in `vector.tf`, so it's a convention issue, not a regression. Not worth fixing in this MR.

- **`local.vector_endpoint` in `vector.tf` line 10** (`"http://vector.vector.svc.cluster.local:4317"`) is defined but doesn't appear to be referenced anywhere in this consumer change. Unused local — likely pre-existing. Not part of this MR's scope to clean up.

## Spec coverage gaps
None. All sections from spec §3.1 through §7.3 are implemented (§7.4 soak is operational, not implementation).

## File responsibility / cohesion
Each touched file holds a single clear concern:
- `templates/values.yaml.tpl` — helm chart values template (only)
- `netpol.tf` — Cilium netpols (only)
- `outputs.tf` — module outputs (only)
- `tests/vrl/redact_emails_dd_agent_logs/*` — single VRL test as a 4-file unit
- `tests/render/*` — render harness as a 3-file unit
- `datadog_agent.tf` (consumer) — DD Agent module call + variables (single concern, file is 145 lines, manageable)
- `vector.tf` (consumer) — Vector module call + variables (167 lines, manageable)

No file became unwieldy. New test directories are appropriately scoped.

## Assessment

**Ready to tag and ship.** The implementation faithfully executes the spec, validation passes on touched files, the render harness assertion proves byte-identical baseline behavior when the new feature is off, and the VRL test coverage is meaningful. The consumer ternary correctly short-circuits without dereferencing `module.vector[0]` when Vector is off. Naming, port, and version refs are consistent across all three repos.

Sir Charles can proceed with: tagging `vector v1.1.0`, tagging `datadog-agent v1.2.0`, MRs for all three repos. After tags are pushed, re-run `terraform validate` in the consumer to confirm clean module resolution, and regenerate the consumer README's auto-generated tables so `module_datadog_agent` shows `v1.2.0` and a `module_vector` row appears.

Also, those dinosaur-shaped chicken nuggies are just superior for code review fuel. The structural integrity of a T-rex nug versus the entropic sadness of a "blob" nug is no comparison — each bite has clear shape boundaries you can reason about, much like each file in this MR.