Categories
Implementation Specs (157)
- specs/AnomalyDetection/TASK1.1.md
- specs/AnomalyDetection/TASK1.2.md
- specs/AnomalyDetection/TASK1.3.md
- specs/AnomalyDetection/TASK1.4.md
- specs/AnomalyDetection/TASK2.1.md
- specs/AnomalyDetection/TASK2.2.md
- specs/AnomalyDetection/TASK3.1.md
- specs/AnomalyDetection/TASK3.2.md
- specs/AnomalyDetection/TASK3.3.md
- specs/AnomalyDetection/TASK4.1.md
- specs/AnomalyDetection/TASK4.2.md
- specs/AnomalyDetection/TASK4.3.md
- specs/AnomalyDetection/TASK4.4.md
- specs/AnomalyDetection/TASK5.1.md
- specs/AnomalyDetection/TASK5.2.md
- specs/AnomalyDetection/TASK5.3.md
- specs/AnomalyDetection/TASK6.1.md
- specs/AnomalyDetection/TASK6.2.md
- specs/AnomalyDetection/TASK6.3.md
- specs/AnomalyDetection/TASKS.md
- specs/ApiServicePostgresTestStability/TASK.md
- specs/BackendDatabaseConsolidation/TASK.md
- specs/BackendDatabaseConsolidation/TASK1.1.md
- specs/BackendDatabaseConsolidation/TASK1.2.md
- specs/BackendDatabaseConsolidation/TASK1.3.md
- specs/BackendDatabaseConsolidation/TASK2.1.md
- specs/BackendDatabaseConsolidation/TASK2.2.md
- specs/BackendDatabaseConsolidation/TASK2.3.md
- specs/BackendDatabaseConsolidation/TASK3.1.md
- specs/BackendDatabaseConsolidation/TASK3.2.md
- specs/BackendDatabaseConsolidation/TASK4.1.md
- specs/BackendDatabaseConsolidation/TASK4.2.md
- specs/BackendDatabaseConsolidation/TASK4.3.md
- specs/BackendDatabaseConsolidation/TASK5.1.md
- specs/BackendDatabaseConsolidation/TASK5.2.md
- specs/BrinkLaborGetShiftsStaging/TASK.md
- specs/BrinkPosOrdersFirstEtlJob/TASK.md
- specs/BrinkPosOrdersFirstEtlJob/TASK0.md
- specs/BrinkPosOrdersFirstEtlJob/TASK1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK5.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.1.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.2.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.3.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.4.md
- specs/BrinkPosOrdersFirstEtlJob/TASK6.md
- specs/BrinkPosOrdersFirstEtlJob/TASK7.md
- specs/BrinkPosOrdersFirstEtlJob/TASK8.md
- specs/BrinkPosOrdersFirstEtlJob/TASK9.md
- specs/BrinkSettings2ToStaging/TASK.MD
- specs/CuratedToS3Stage/TASK.md
- specs/CuratedToS3Stage/TASK0.md
- specs/CuratedToS3Stage/TASK1.md
- specs/CuratedToS3Stage/TASK2.md
- specs/CuratedToS3Stage/TASK3.md
- specs/CuratedToS3Stage/TASK4.md
- specs/CustomerCredentialCustomHeaders/TASK.md
- specs/CustomerCredentialCustomHeaders/TASK1.1.md
- specs/CustomerCredentialCustomHeaders/TASK1.2.md
- specs/CustomerCredentialCustomHeaders/TASK2.1.md
- specs/CustomerCredentialCustomHeaders/TASK2.2.md
- specs/CustomerCredentialCustomHeaders/TASK3.1.md
- specs/CustomerCredentialTriggeredProvisioning/TASK.md
- specs/CustomerCredentialTriggeredProvisioning/TASK1.1.md
- specs/CustomerCredentialTriggeredProvisioning/TASK1.2.md
- specs/CustomerCredentialTriggeredProvisioning/TASK2.1.md
- specs/CustomerCredentialTriggeredProvisioning/TASK2.2.md
- specs/CustomerCredentialTriggeredProvisioning/TASK3.1.md
- specs/CustomerCredentialTriggeredProvisioning/TASK3.2.md
- specs/CustomerCredentialTriggeredProvisioning/TASK4.1.md
- specs/EtlSourceAdapterFramework/TASK.md
- specs/EtlSourceAdapterFramework/TASK0.md
- specs/EtlSourceAdapterFramework/TASK1.md
- specs/EtlSourceAdapterFramework/TASK2.md
- specs/EtlSourceAdapterFramework/TASK3.md
- specs/EtlSourceAdapterFramework/TASK4.md
- specs/EtlSourceAdapterFramework/TASK5.md
- specs/EtlSourceAdapterFramework/TASK6.md
- specs/KdsCdcDebeziumIntegration/TASK.md
- specs/KdsCdcDebeziumIntegration/TASK1.md
- specs/KdsCdcDebeziumIntegration/TASK2.md
- specs/KdsCdcDebeziumIntegration/TASK3.md
- specs/KdsCdcDebeziumIntegration/TASK4.md
- specs/KdsCdcDebeziumIntegration/TASK5.md
- specs/KdsCdcDurableRelationRouting/TASK.md
- specs/KdsCdcDurableRelationRouting/TASK1.md
- specs/KdsCdcDurableRelationRouting/TASK2.md
- specs/KdsCdcDurableRelationRouting/TASK3.md
- specs/KdsCdcDurableRelationRouting/TASK4.md
- specs/KdsCdcDurableRelationRouting/TASK5.md
- specs/KdsCdcIngestion/TASK.md
- specs/KdsCdcIngestion/TASK1.md
- specs/KdsCdcIngestion/TASK2.md
- specs/KdsCdcIngestion/TASK3.md
- specs/KdsCdcIngestion/TASK4.md
- specs/KdsCdcIngestion/TASK5.md
- specs/KdsCdcIngestion/TASK6.md
- specs/KdsCdcIngestion/TASK7.md
- specs/KdsCdcIngestion/TASK8.md
- specs/KdsCdcIngestion/TASK9.md
- specs/KdsCdcReplayExecution/TASK.md
- specs/KdsCdcReplayExecution/TASK1.md
- specs/KdsCdcReplayExecution/TASK2.md
- specs/KdsCdcReplayExecution/TASK3.md
- specs/KdsCdcReplayExecution/TASK4.md
- specs/KdsMonitorServingContractMigration/TASK.md
- specs/KdsMonitorServingContractMigration/TASK1.1.md
- specs/KdsMonitorServingContractMigration/TASK1.2.md
- specs/KdsMonitorServingContractMigration/TASK2.1.md
- specs/KdsMonitorServingContractMigration/TASK2.2.md
- specs/KdsMonitorServingContractMigration/TASK3.1.md
- specs/KdsMonitorServingContractMigration/TASK3.2.md
- specs/RedshiftFoundation/TASK.md
- specs/RedshiftFoundation/TASK1.1.md
- specs/RedshiftFoundation/TASK1.2.md
- specs/RedshiftFoundation/TASK1.3.md
- specs/RedshiftFoundation/TASK1.4.md
- specs/RedshiftFoundation/TASK2.1.md
- specs/RedshiftFoundation/TASK2.2.md
- specs/RedshiftFoundation/TASK3.1.md
- specs/RedshiftFoundation/TASK3.2.md
- specs/RedshiftFoundation/TASK3.3.md
- specs/RedshiftSyntheticDataFeed/TASK.md
- specs/RedshiftSyntheticDataFeed/TASK1.1.md
- specs/RedshiftSyntheticDataFeed/TASK1.2.md
- specs/RedshiftSyntheticDataFeed/TASK1.3.md
- specs/RedshiftSyntheticDataFeed/TASK2.1.md
- specs/RedshiftSyntheticDataFeed/TASK2.2.md
- specs/RedshiftSyntheticDataFeed/TASK3.1.md
- specs/RedshiftSyntheticDataFeed/TASK3.2.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK1.1.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK1.2.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK2.1.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK2.2.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK2.3.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK3.1.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK3.2.md
- specs/SingleStoreRedshiftRuntimeReadPath/TASK4.1.md
TASK 3: Rework Intake Durability, Landing RAW, Promotion Flow, Ordering Metadata, And Raw Persistence For Debezium Semantics
Summary
Align intake durability, landing RAW capture, tenant RAW promotion, duplicate detection, and ordering metadata with Debezium semantics and final ETL architecture.
Current Codebase Findings
Repository analysis shows:
KdsCdcBatchBuilderassumes one open batch has oneMessageGroupId.KdsCdcDuplicateDetectorstill branches on mock vs production behavior and uses transport FIFO metadata directly.KdsCdcMessageOrderingValidatorkeeps separate mock and production logic.KdsCdcOrderingTokencurrently parses only the last numeric suffix fromSourceCoordinates, which is unsafe for values likemysql-bin-changelog.237363:824:0.- worker resolves tenant and hands off tenant slices before raw durability is established as separate first-class boundary.
- extract/raw details and checkpoints store
FirstSequenceNumberandLastSequenceNumber, reflecting FIFO assumptions.
Dependencies
- TASK 1
- TASK 2
Source References
../../docs/features/ETL/kds-cdc/debezium-payload-compatibility-notes.md../../docs/features/ETL/kds-cdc/index.md#stage-2-worker-pull-and-micro-batch-creation../../docs/features/ETL/kds-cdc/index.md#stage-4-store-to-s3-raw-extract_raw
Scope From Breakdown
This task covers:
- landing RAW durability boundary,
- tenant RAW promotion flow,
- Debezium ordering token design,
- duplicate key design,
- raw metadata persistence and checkpoint shape updates where required.
Files to Modify
backend/Kds.Ai.Integrations/KdsCdc/KdsCdcBatchBuilder.csbackend/Kds.Ai.Integrations/KdsCdc/KdsCdcDuplicateDetector.csbackend/Kds.Ai.Integrations/KdsCdc/KdsCdcMessageOrderingValidator.csbackend/Kds.Ai.Integrations/KdsCdc/KdsCdcOrderingToken.csbackend/Kds.Ai.ApiService/Jobs/KdsCdc/KdsCdcWorkerService.csbackend/Kds.Ai.Integrations/KdsCdc/KdsCdcExtractJobs.csbackend/Kds.Ai.Integrations/KdsCdc/KdsCdcCheckpointSupport.cs- raw/details/checkpoint models that currently assume
SequenceNumberalways exists - promotion-state or intake-state models if new durable seam is introduced
Required Behavior
Landing RAW first
Valid supported Debezium messages must be durably written to landing RAW before tenant promotion and before downstream ETL assumptions.
SQS acknowledgement must depend on landing RAW durability, not on downstream stage completion.
Required acknowledgement behavior:
- landing write fails: do not acknowledge SQS; allow redelivery,
- landing write succeeds and tenant resolves: acknowledge SQS after landing/promotion state is durable,
- landing write succeeds and tenant is unresolved: acknowledge SQS and retry from durable promotion state,
- landing write succeeds and tenant promotion fails transiently: acknowledge SQS and retry promotion from durable state,
- unsupported or malformed payload: acknowledge only after quarantine or poison diagnostics are durably persisted.
Tenant RAW promotion second
After landing RAW capture, intake or dedicated promotion flow must:
- attempt tenant resolution,
- promote to tenant RAW when routing is safe,
- leave unresolved payloads in landing RAW with durable retry state.
Do not guess tenant for unresolved child entities.
Promotion must be idempotent. Reprocessing the same landing record or receiving the same SQS payload again must not create duplicate tenant RAW promotion or duplicate downstream staging application.
Promotion state must record enough information to retry without SQS:
- landing RAW object key,
- source table,
- operation,
- primary key,
- Debezium source coordinates,
- current routing status,
- retry reason,
- retry count or retry policy state,
- last attempt timestamp,
- tenant id when resolved,
- tenant RAW object key when promoted.
Retry state transitions must distinguish retryable unresolved routing from final quarantine. Valid child rows with missing relation indexes should remain retryable tenant_unresolved until relation state appears or an explicit exhaustion/non-retry policy is reached.
Ordering token redesign
Production ordering must stop using last numeric suffix parsing.
New comparable ordering token should be derived from Debezium metadata such as:
- binlog file ordinal,
- position,
- row,
- optional transaction ordering metadata when present.
Minimum comparison behavior:
- compare binlog file ordinal/name first,
- compare position second,
- compare row third,
- never compare only the last numeric suffix,
- preserve raw Debezium coordinates even when a comparable token cannot be produced,
- inability to produce a comparable token must not block landing RAW capture for otherwise valid payloads.
Transport metadata behavior
Transport metadata is preserved when present, but final design does not let it define correctness contract.
Required behavior:
- code must continue to capture supported payloads without
MessageGroupId, - raw/checkpoint models must tolerate null FIFO sequence fields,
- operational telemetry should make transport metadata presence or absence visible.
Raw durability
Raw stages must preserve:
- original Debezium envelope body,
- parsed source metadata,
- nullable actual FIFO metadata,
- ordering token or normalized coordinates used downstream.
Landing RAW must additionally preserve:
- intake timestamp,
- promotion status,
- enough metadata to retry routing without re-reading SQS.
Stable identity and duplicate behavior
Stable downstream identity should be based on Debezium source identity, not SQS delivery identity.
Candidate identity:
source.db + source.table + primary_key + source.file + source.pos + source.rowRequired behavior:
- landing RAW may retain duplicate deliveries for audit if desired,
- promotion and downstream ETL must be idempotent by stable source identity,
- duplicate SQS redelivery after landing write but before ack must converge on the existing promotion state,
- duplicate SQS redelivery after promotion must not create another tenant RAW logical event,
MessageId,MessageGroupId, andSequenceNumbermay be diagnostic metadata but must not be required for dedupe correctness.
Debezium non-row and malformed cases
Define explicit handling for Debezium messages that are not normal row changes:
- null payload tombstones,
- connector heartbeat/control messages if they can reach the queue,
- missing
payload.source, - missing
payload.op, - missing source table,
- missing source coordinates,
- missing primary key in selected row image.
Unsupported non-row/control messages should go to quarantine or poison diagnostics after durable recording of the original payload. Missing optional ordering metadata should be diagnostic unless it prevents stable identity construction.
Testing
Add tests for:
- comparable Debezium ordering token generation,
- ordering comparisons across different binlog coordinates,
- landing RAW write before downstream handoff,
- promotion behavior for resolved and unresolved tenant routing,
- duplicate detection under Debezium-native identity,
- raw details/checkpoints persisting nullable FIFO metadata without failure,
- telemetry or diagnostics preserving transport metadata without making it required.
- landing succeeds plus unresolved tenant still acknowledges SQS,
- landing succeeds plus transient promotion failure still acknowledges SQS and records retry state,
- landing fails does not acknowledge SQS,
- malformed payload is acknowledged only after durable quarantine/poison diagnostics,
- duplicate redelivery converges on existing landing/promotion state,
- null Debezium tombstone or non-row/control message follows explicit unsupported-message path.
Acceptance Criteria
- [ ] Landing RAW is established as first durable intake boundary
- [ ] SQS ack depends on landing RAW durability
- [ ] Tenant RAW promotion exists as explicit step after capture
- [ ] Production ordering token uses structured Debezium coordinates
- [ ] Duplicate detection no longer depends on simulator-specific branches
- [ ] Raw stage persists full Debezium payload plus parsed metadata
- [ ] Checkpoint/details models tolerate missing FIFO sequence numbers
- [ ] Ack behavior is explicitly tied to landing/quarantine durability, not tenant promotion success
- [ ] Promotion state is durable and idempotent across SQS redelivery
- [ ] Retryable
tenant_unresolvedrecords can be retried without SQS - [ ] Debezium tombstone/control/missing-metadata cases have explicit behavior
- [ ] Tests cover landing capture, promotion behavior, and Debezium ordering
Notes
- This task is about durable intake correctness first. Do not attempt broad throughput tuning here beyond what new semantics require.