Buyer / data-governance gap
Protected develop@622e5e6c3d534f230c390f10e3832efadfc01825 configures replica-consumer failure recovery with Spring Kafka DeadLetterPublishingRecoverer and sends exhausted/non-retryable records to <source-topic>.DLT. The repository operations guide advertises this as a real reliability feature, but the repository has no corresponding DLT retention, access-control, encryption, redrive/replay, deletion, or data-classification contract.
This matters because the DLT is not merely a failure counter. Protected KafkaConfig constructs the standard recoverer without a custom producer-record sanitizer/transformer. Spring Kafka's maintained API documents that the default producer-record construction copies the failed consumer record key/value and adds original-record and DLT/exception headers; the framework exposes customization specifically when the contents sent to dead-letter/retry topics must change. Therefore business CDC payload retained for operational recovery can also become a second durable data copy with additional diagnostic metadata.
Primary Spring evidence to reverify at implementation time:
- Spring for Apache Kafka
DeadLetterPublishingRecoverer API (createProducerRecord default copies key/value and adds headers);
- Spring Kafka reference,
Managing Dead Letter Record Headers (original/exception header behavior and growth semantics).
RCA
- Immediate cause: exhausted/non-retryable replica records are republished to
.DLT through the default recoverer behavior.
- Technical root cause: retry/recovery semantics exist, but durable dead-letter data ownership is not modeled as a governed product boundary.
- Control failure:
KafkaConfigTest proves that a dead-letter recoverer/backoff is configured, but does not prove payload/header classification, retention, ACLs, encryption, redrive authority, deletion, or bounded diagnostic headers; docs/cdc/ops-and-reliability.md names the DLT but contains no lifecycle/control contract.
- Risk: DLT records can contain the same business/PII-bearing Debezium value/key data required for replay, plus failure/origin metadata. Blanket payload masking is not automatically acceptable because it may destroy recovery utility; the product needs purpose-bound governance instead.
Distinct remediation options / feasibility
Preferred — purpose-bound raw-record DLT with explicit governance
Keep replay-capable record key/value only if operational recovery genuinely requires it, but make the boundary explicit and testable:
- versioned DLT naming/provisioning policy rather than undocumented accidental lifecycle;
- bounded topic retention/deletion policy appropriate to supported deployments;
- least-privilege producer/consumer ACL ownership and tenant/environment separation;
- encryption in transit and broker/storage controls owned by the deployment profile;
- explicit classification of key/value and retained original/exception headers;
- exclude or bound exception stack/message headers when they can contain payload/provider/credential-adjacent diagnostics while retaining stable finite failure classification;
- auditable redrive/replay authority and idempotency/fencing so replay cannot silently duplicate effects;
- deletion/incident/runbook semantics and metrics without payload/high-cardinality identifiers.
Alternative — sanitized/quarantine envelope
Publish a bounded quarantine envelope with source identity, digest, stable failure code and an authorized pointer to separately protected payload evidence only if a real governed evidence store exists. Do not invent a new database/object store merely to avoid Kafka retention; this option needs a separately accepted persistence/authority design.
Reject
- silently discarding payload by masking/truncating it when that prevents valid recovery;
- retaining raw payload indefinitely with no ownership/retention decision;
- logging DLT payloads as the diagnostic mechanism;
- automatic replay without owner authorization, exact source identity, idempotency/fencing and duplicate-effect analysis;
- assuming the broker's deployment-specific defaults constitute mightyETL's retention/security contract.
TDD / acceptance
Before production mutation, add a fail-first contract at the actual DeadLetterPublishingRecoverer/Kafka record boundary. The accepted design must prove, as applicable:
- the exact DLT producer record contents (key/value + allowed headers) are deliberate and bounded;
- credentials, JDBC URLs, SQL, raw exception stack/message material, and unrelated headers are not added merely for diagnostics;
- business payload remains available only when the selected recovery model explicitly requires it;
- DLT topic naming cannot collide across unsupported tenant/environment boundaries;
- supported deployment profiles provide an explicit finite retention/deletion policy rather than relying on unspecified broker defaults;
- producer/consumer/redrive authority is least-privilege and documented; ordinary app callers cannot invoke replay by knowing a topic name;
- redrive/replay uses a reviewed idempotent/fenced contract and does not claim exactly-once where the target cannot prove it;
- poison messages cannot loop indefinitely between source and DLT;
- topic/record/header size bounds and exception-header growth are handled fail-closed;
- observability contains finite outcome/failure classifications without payload, key, row ID, principal, SQL or exception text;
- canonical Data Governance/Security/Threat Model/Operability/Architecture/Traceability explains DLT ownership, retention, encryption, access, replay and deletion;
- exact-source CI, dependency, SBOM, SAST/security, non-vacuous coverage and review gates pass before protected integration.
Current implementation classification
planned / known_gap. Do not open a source PR until the exact payload-retention/redrive policy is selected from the evidence above and current CDC writer overlap is rechecked. This issue can advance in parallel through documentation/data-governance analysis without racing #139 acknowledgement, #170–#174 diagnostics, or connector-retirement work.
Relationship: #139 owns Kafka acknowledgement-before-offset progress; #141 owns graceful CDC stop; #170–#176 own diagnostic confidentiality; #159 owns canonical data-governance/operability traceability. This issue owns the durable dead-letter data lifecycle and replay authority, not ordinary logging.
Buyer / data-governance gap
Protected
develop@622e5e6c3d534f230c390f10e3832efadfc01825configures replica-consumer failure recovery with Spring KafkaDeadLetterPublishingRecovererand sends exhausted/non-retryable records to<source-topic>.DLT. The repository operations guide advertises this as a real reliability feature, but the repository has no corresponding DLT retention, access-control, encryption, redrive/replay, deletion, or data-classification contract.This matters because the DLT is not merely a failure counter. Protected
KafkaConfigconstructs the standard recoverer without a custom producer-record sanitizer/transformer. Spring Kafka's maintained API documents that the default producer-record construction copies the failed consumer record key/value and adds original-record and DLT/exception headers; the framework exposes customization specifically when the contents sent to dead-letter/retry topics must change. Therefore business CDC payload retained for operational recovery can also become a second durable data copy with additional diagnostic metadata.Primary Spring evidence to reverify at implementation time:
DeadLetterPublishingRecovererAPI (createProducerRecorddefault copies key/value and adds headers);Managing Dead Letter Record Headers(original/exception header behavior and growth semantics).RCA
.DLTthrough the default recoverer behavior.KafkaConfigTestproves that a dead-letter recoverer/backoff is configured, but does not prove payload/header classification, retention, ACLs, encryption, redrive authority, deletion, or bounded diagnostic headers;docs/cdc/ops-and-reliability.mdnames the DLT but contains no lifecycle/control contract.Distinct remediation options / feasibility
Preferred — purpose-bound raw-record DLT with explicit governance
Keep replay-capable record key/value only if operational recovery genuinely requires it, but make the boundary explicit and testable:
Alternative — sanitized/quarantine envelope
Publish a bounded quarantine envelope with source identity, digest, stable failure code and an authorized pointer to separately protected payload evidence only if a real governed evidence store exists. Do not invent a new database/object store merely to avoid Kafka retention; this option needs a separately accepted persistence/authority design.
Reject
TDD / acceptance
Before production mutation, add a fail-first contract at the actual
DeadLetterPublishingRecoverer/Kafka record boundary. The accepted design must prove, as applicable:Current implementation classification
planned / known_gap. Do not open a source PR until the exact payload-retention/redrive policy is selected from the evidence above and current CDC writer overlap is rechecked. This issue can advance in parallel through documentation/data-governance analysis without racing #139 acknowledgement, #170–#174 diagnostics, or connector-retirement work.Relationship: #139 owns Kafka acknowledgement-before-offset progress; #141 owns graceful CDC stop; #170–#176 own diagnostic confidentiality; #159 owns canonical data-governance/operability traceability. This issue owns the durable dead-letter data lifecycle and replay authority, not ordinary logging.