|
67 | 67 | "valid": false, |
68 | 68 | "reason": "no 'job' or 'urn' — the message has no identity" |
69 | 69 | } |
70 | | - ] |
| 70 | + ], |
| 71 | + "sqs": { |
| 72 | + "description": "Amazon SQS binding conformance (broker-bindings.md §3). Every SDK that ships an SQS transport must satisfy these. The envelope body stays byte-identical (the 'cases' above); these lock the native projection + reconciliation the binding adds. Per-message values reuse fixtures/order-created.json so the expected attributes are deterministic.", |
| 73 | + "attribute_projection": { |
| 74 | + "description": "On produce, the transport MUST project these native MessageAttributes from the envelope (a redundant, routable view of the body; ids/strings are DataType String, counters are DataType Number). Applies to every SQS-producing SDK.", |
| 75 | + "envelope_file": "fixtures/order-created.json", |
| 76 | + "message_attributes": { |
| 77 | + "bq-job": { "DataType": "String", "StringValue": "urn:babel:orders:created" }, |
| 78 | + "bq-trace-id": { "DataType": "String", "StringValue": "7b3f9c2a-e41d-4f88-9b2a-1c0d5e6f7a8b" }, |
| 79 | + "bq-message-id": { "DataType": "String", "StringValue": "f1e2d3c4-b5a6-4789-90ab-cdef01234567" }, |
| 80 | + "bq-schema-version": { "DataType": "Number", "StringValue": "1" }, |
| 81 | + "bq-source-lang": { "DataType": "String", "StringValue": "php" }, |
| 82 | + "bq-created-at": { "DataType": "Number", "StringValue": "1749132727000" } |
| 83 | + } |
| 84 | + }, |
| 85 | + "attempts_reconciliation": { |
| 86 | + "description": "On consume, attempts = max(body.attempts, ApproximateReceiveCount - 1): a first delivery reads 0, an absent/garbage count is ignored, a runtime-incremented count is never lowered. Applies to SDKs that reconcile the envelope body on consume (the framework-less/runtime transports). A drop-in driver that surfaces the broker's native delivery count instead (e.g. Laravel's SqsJob.attempts() = ApproximateReceiveCount) is exempt — it documents that divergence.", |
| 87 | + "cases": [ |
| 88 | + { "name": "first-delivery", "body_attempts": 0, "approximate_receive_count": "1", "expected_attempts": 0 }, |
| 89 | + { "name": "third-delivery", "body_attempts": 0, "approximate_receive_count": "3", "expected_attempts": 2 }, |
| 90 | + { "name": "native-exceeds-body", "body_attempts": 2, "approximate_receive_count": "5", "expected_attempts": 4 }, |
| 91 | + { "name": "never-lower-runtime", "body_attempts": 5, "approximate_receive_count": "1", "expected_attempts": 5 }, |
| 92 | + { "name": "garbage-count-ignored", "body_attempts": 4, "approximate_receive_count": "not-a-number", "expected_attempts": 4 }, |
| 93 | + { "name": "absent-count", "body_attempts": 3, "approximate_receive_count": null, "expected_attempts": 3 } |
| 94 | + ] |
| 95 | + } |
| 96 | + } |
71 | 97 | } |
0 commit comments