{"pair_id": "teach_001", "decision_a": "Set the gRPC client timeout for ledger-api calls originating from fanout-worker to 15 seconds, per the incident review, so a stalled downstream dependency fails fast instead of holding worker threads and backing up the whole batch queue (TASK-101).", "decision_b": "Set the gRPC client timeout for ledger-api calls from fanout-worker to 120 seconds because settlement batches routinely take over a minute to commit, and the shorter timeout was killing valid in-flight requests before they could finish (TASK-101).", "gold_label": "contradiction", "class": "binding_collision", "why": "Same client, same call path, same named timeout parameter is pinned to two irreconcilable values with no ordering that resolves which one is live."}
{"pair_id": "teach_002", "decision_a": "checkout-svc's retry policy for calls to payments-router sets max_retries to 3, matching the idempotency window payments-router advertises in its API contract, so we never retry past the point where a duplicate charge could slip through (TASK-118).", "decision_b": "checkout-svc's retry policy for calls to payments-router sets max_retries to 8, because payments-router has a well-documented flakiness window during peak traffic and we saw checkout failures drop sharply once retries covered that whole window (TASK-118).", "gold_label": "contradiction", "class": "binding_collision", "why": "Both decisions pin the same max_retries binding for the same client-to-service edge to different numbers with no stated precedence."}
{"pair_id": "teach_003", "decision_a": "Postgres connection pool size for inventory-svc's read path is set to 20 connections per instance, keeping total connections comfortably under the read-replica's advertised 200-connection ceiling even at our current instance count (TASK-142).", "decision_b": "Postgres connection pool size for inventory-svc's read path is set to 75 connections per instance, which was the smallest size that cleared the p99 connection-queueing latency we measured under Black-Friday-style synthetic load (TASK-142).", "gold_label": "contradiction", "class": "binding_collision", "why": "The same pool-size parameter for the same service is bound to two different values under the same ticket, a direct binding collision."}
{"pair_id": "teach_004", "decision_a": "image-resizer's ingest endpoint caps request body size at 5MB; anything larger should be rejected with a 413 immediately at the load balancer, before it ever reaches the resizing workers and consumes their memory (TASK-207).", "decision_b": "image-resizer's ingest endpoint caps request body size at 50MB to support the new bulk-upload workflow, which routinely ships multi-page TIFF scans well past the old limit and previously failed with confusing client-side errors (TASK-207).", "gold_label": "contradiction", "class": "binding_collision", "why": "Two decisions fix the identical max-body-size parameter on the same endpoint to values an order of magnitude apart, with neither marked as an update to the other."}
{"pair_id": "teach_005", "decision_a": "Redis cache TTL for session-store's cached auth tokens is set to 300 seconds, matching the access-token lifetime exactly so a cached token never outlives the credential it represents (TASK-233).", "decision_b": "Redis cache TTL for session-store's cached auth tokens is set to 3600 seconds to cut origin lookups during the current traffic spike, since token-store load was becoming the binding constraint on login throughput (TASK-233).", "gold_label": "contradiction", "class": "binding_collision", "why": "The same cache key namespace and TTL parameter are set to conflicting durations, with no note that one value supersedes the other."}
{"pair_id": "teach_006", "decision_a": "rate-limiter's threshold for auth-gateway login attempts is 5 requests per minute per IP, set as the abuse-prevention baseline agreed with the security team after last quarter's credential-stuffing incident (TASK-260).", "decision_b": "rate-limiter's threshold for auth-gateway login attempts is 60 requests per minute per IP, raised after legitimate SSO retry storms from large enterprise tenants were tripping the limiter and locking out whole offices (TASK-260).", "gold_label": "contradiction", "class": "binding_collision", "why": "The identical rate-limit binding for the identical route is set to two different numbers under the same ticket with no resolution stated."}
{"pair_id": "teach_007", "decision_a": "Enabling optimistic locking on catalog-api's price-update path: every write now carries a version check, because last-writer-wins semantics were causing silent price overwrites whenever two admins edited the same SKU during a flash sale (TASK-301).", "decision_b": "Disabling optimistic locking on catalog-api's price-update path: writes go through unconditionally again, because the version-conflict retries were serializing checkout-time price lookups and pushing checkout latency past our timeout budget (TASK-301).", "gold_label": "contradiction", "class": "genuine_reversal", "why": "The same live locking behavior for the same path is asserted enabled and then asserted disabled, a direct reversal of an active position."}
{"pair_id": "teach_008", "decision_a": "webhook-relay will reject any payload that fails schema validation, returning a 422 immediately instead of best-effort forwarding it, because malformed payloads were corrupting downstream aggregate state in ways that took hours to unwind (TASK-318).", "decision_b": "webhook-relay will forward payloads that fail schema validation rather than reject them, since the downstream consumers we audited tolerate missing or malformed optional fields fine and rejection was dropping otherwise-usable events (TASK-318).", "gold_label": "contradiction", "class": "genuine_reversal", "why": "Both statements claim to describe the current handling of the same invalid-payload case, and they are opposite behaviors."}
{"pair_id": "teach_009", "decision_a": "quota-service will hard-block all requests the instant a tenant exceeds its monthly quota, with no grace period, per the updated billing-fairness policy agreed with finance after several tenants ran far over quota unnoticed (TASK-334).", "decision_b": "quota-service will allow requests to continue past the monthly quota, attaching a soft warning header instead of blocking, because hard-blocking was causing production outages for tenants whose usage spiked briefly during legitimate traffic (TASK-334).", "gold_label": "contradiction", "class": "genuine_reversal", "why": "Both decisions describe quota-service's current enforcement behavior for the same overage condition, and they cannot both be true at once."}
{"pair_id": "teach_010", "decision_a": "audit-log-svc writes are synchronous with the triggering transaction: if the audit write fails, the whole transaction aborts, because an unaudited state change is worse than a slower or failed request (TASK-355).", "decision_b": "audit-log-svc writes are fire-and-forget and never block or abort the triggering transaction, because a brief audit-store outage last month caused a full transactional outage that was strictly worse than a missing log row (TASK-355).", "gold_label": "contradiction", "class": "genuine_reversal", "why": "The two decisions assert mutually exclusive current behaviors for whether audit writes can abort the parent transaction."}
{"pair_id": "teach_011", "decision_a": "feature-flag-svc: 'dark-launch-v2' defaults to off for every cohort until a tenant explicitly opts in, per the conservative rollout plan the team agreed on to limit blast radius while the feature is unproven (TASK-372).", "decision_b": "feature-flag-svc: 'dark-launch-v2' now defaults to on for every cohort, opt-out only for tenants that specifically request it, since staged opt-in adoption stalled and the feature has cleared every rollout gate we set (TASK-372).", "gold_label": "contradiction", "class": "genuine_reversal", "why": "Both statements set the same flag's default state for the same population to opposite values."}
{"pair_id": "teach_012", "decision_a": "config-service treats an absent 'region' field as a hard error and refuses to serve any config for that request, because a missing region has historically meant a broken client, not an intentional global request (TASK-390).", "decision_b": "config-service treats an absent 'region' field as an implicit 'global' selector and serves the default config, because several legitimate batch clients never set region and hard-failing them was blocking scheduled jobs nightly (TASK-390).", "gold_label": "contradiction", "class": "genuine_reversal", "why": "The same missing-field case under the same ticket is handled as both a hard error and a silently-defaulted case."}
{"pair_id": "teach_013", "decision_a": "billing-service retries failed invoice charges up to 3 times with a fixed 30-second backoff between attempts, chosen as a simple, predictable policy for the initial retry implementation (TASK-402).", "decision_b": "TASK-402 update: replacing the fixed 30-second backoff with exponential backoff of 2s, 8s, then 32s, after tracing showed simultaneous fixed-interval retries from many workers were creating thundering-herd load spikes against payments-router; this supersedes the fixed-backoff policy (TASK-402).", "gold_label": "supersession", "class": "explicit_supersession", "why": "The later decision explicitly states it replaces the earlier retry policy, so there is one live rule, not a live conflict."}
{"pair_id": "teach_014", "decision_a": "reconciliation-job runs nightly at 02:00 UTC, comparing each day's ledger-api snapshot against the settlement feed to catch discrepancies before the next business day starts (TASK-415).", "decision_b": "Supersedes TASK-415: reconciliation-job now runs hourly against a continuously updated rolling snapshot instead of the nightly batch, because a full day's delay meant discrepancies were sometimes surfacing after affected invoices had already been paid out (TASK-441).", "gold_label": "supersession", "class": "explicit_supersession", "why": "TASK-441 names TASK-415 directly and states it supersedes the nightly schedule, making the change an acknowledged replacement."}
{"pair_id": "teach_015", "decision_a": "shipment-tracker's API exposes the carrier's estimated delivery time as a single point-estimate timestamp field, which is the simplest representation and matches what most carrier APIs return directly (TASK-460).", "decision_b": "Replacing the TASK-460 point-estimate ETA with a min/max range field, since carriers themselves only guarantee a window and the single-value field was misleading customers into expecting precision the underlying data never had; the old field is deprecated (TASK-478).", "gold_label": "supersession", "class": "explicit_supersession", "why": "The second decision explicitly calls out the earlier field as deprecated and replaced, so it is a stated evolution, not a contradiction."}
{"pair_id": "teach_016", "decision_a": "pricing-engine caches computed price quotes in Redis for 10 minutes to reduce repeated load on catalog-api during high-traffic browsing sessions where the same SKUs get quoted repeatedly (TASK-490).", "decision_b": "TASK-490 revision: dropping the Redis quote cache entirely after a pricing-correctness incident where a stale cached quote let a customer check out at a superseded price; quotes must be computed fresh on every request going forward (TASK-503).", "gold_label": "supersession", "class": "explicit_supersession", "why": "The revision explicitly targets and retires the prior caching decision by ticket reference, so it is a documented replacement."}
{"pair_id": "teach_017", "decision_a": "user-profile-svc stores avatar images directly in Postgres as bytea columns, which kept the initial implementation simple by avoiding a second storage system for a small volume of images (TASK-520).", "decision_b": "This replaces the TASK-520 approach: avatar images now live in S3 with only the object key stored in Postgres, because bytea storage had grown to dominate the primary's disk footprint and was slowing routine backups (TASK-536).", "gold_label": "supersession", "class": "explicit_supersession", "why": "The later decision explicitly states it replaces the earlier storage approach for the same data, a clean supersession."}
{"pair_id": "teach_018", "decision_a": "notify-worker sends push, SMS, and email for every alert tier uniformly, on the theory that redundant channels maximize the odds a user actually notices a given alert (TASK-551).", "decision_b": "Superseding TASK-551: notify-worker now sends channel-by-severity, push only for low severity, adding SMS for medium and email for high, after a user survey showed the uniform multi-channel blast was the top driver of alert-fatigue complaints (TASK-567).", "gold_label": "supersession", "class": "explicit_supersession", "why": "The second decision explicitly supersedes the earlier uniform-channel policy with a tiered one, an acknowledged update."}
{"pair_id": "teach_019", "decision_a": "search-indexer re-indexes the full product catalog every 6 hours in a single batch job, chosen for operational simplicity when the catalog was still small enough to reindex quickly (TASK-580).", "decision_b": "Replacing the TASK-580 full re-index schedule with incremental indexing triggered on each catalog-api write event, since the 6-hour batch window was letting newly published products stay unsearchable for hours at a time (TASK-599).", "gold_label": "supersession", "class": "explicit_supersession", "why": "The later decision names and replaces the earlier batch-indexing schedule outright."}
{"pair_id": "teach_020", "decision_a": "export-worker writes every tenant's CSV exports to a single shared S3 prefix, differentiated only by filename, which was the fastest path to ship the initial export feature (TASK-610).", "decision_b": "This decision replaces TASK-610: exports now write to per-tenant S3 prefixes with tenant-scoped IAM policies attached, closing a cross-tenant read gap a security audit found in the shared-prefix layout (TASK-625).", "gold_label": "supersession", "class": "explicit_supersession", "why": "The later decision explicitly states it replaces the shared-prefix export layout, a stated supersession."}
{"pair_id": "teach_021", "decision_a": "token-refresh-svc rotates its signing keys every 90 days on a fixed calendar schedule, matching the rotation cadence recommended in our original key-management design doc (TASK-640).", "decision_b": "Supersedes TASK-640: signing-key rotation is now triggered by usage-count thresholds instead of calendar time, because the fixed schedule was rotating rarely-used keys unnecessarily while heavily-used keys sat unrotated for the same fixed interval regardless of exposure (TASK-655).", "gold_label": "supersession", "class": "explicit_supersession", "why": "The later decision explicitly marks itself as superseding the calendar-based rotation policy."}
{"pair_id": "teach_022", "decision_a": "ledger-api requires idempotency keys to be UUIDv4 values in the X-Idempotency-Key header, validated with a strict format check before any request is accepted for processing (TASK-701).", "decision_b": "ledger-api now validates X-Idempotency-Key as a ULID and rejects UUIDv4 values with a 400, matching the identifier format the newly released client SDK generates by default for every outgoing request (TASK-733).", "gold_label": "supersession", "class": "silent_supersession", "why": "The second decision quietly retires the UUIDv4 requirement in favor of ULID as the SDK's generated format changed, an intentional replacement rather than a live conflict."}
{"pair_id": "teach_023", "decision_a": "auth-gateway issues access tokens with a 15-minute expiry, a duration chosen to bound the exposure window for a stolen token before it becomes worthless (TASK-710).", "decision_b": "Now that refresh-token rotation is live end-to-end across every client, auth-gateway issues access tokens with a 2-minute expiry, shrinking the replay window substantially since clients silently refresh well before expiry anyway (TASK-745).", "gold_label": "supersession", "class": "silent_supersession", "why": "The shorter expiry is justified by a stated precondition that only holds after the earlier decision, showing this knowingly updates the first rather than contradicting it."}
{"pair_id": "teach_024", "decision_a": "dedup-service keys duplicate-event detection on the pair (tenant_id, event_id) to catch duplicates within a rolling 24-hour window, since event_id alone wasn't guaranteed unique across tenants at the time (TASK-760).", "decision_b": "With event_id now globally unique across all tenants following the identifier-schema migration, dedup-service keys duplicate-event detection on event_id alone within the same rolling 24-hour window (TASK-788).", "gold_label": "supersession", "class": "silent_supersession", "why": "The dedup key change is explained by a completed migration that makes tenant_id redundant, marking this as an informed update rather than an unexplained conflict."}
{"pair_id": "teach_025", "decision_a": "cache-warmer pre-warms the top 100 catalog-api SKUs each morning, ranked by yesterday's full-day view count, which reliably predicted the day's hot SKUs during normal traffic patterns (TASK-800).", "decision_b": "cache-warmer now pre-warms SKUs using a rolling 4-hour view-count window instead of yesterday's full-day count, after last week's flash-sale incident showed the daily snapshot completely missed a spike that formed and faded within hours (TASK-822).", "gold_label": "supersession", "class": "silent_supersession", "why": "The change is grounded in a named incident the earlier daily-window decision failed to handle, indicating a deliberate replacement rather than an arbitrary contradiction."}
{"pair_id": "teach_026", "decision_a": "backup-scheduler takes a full Postgres snapshot nightly and retains 7 days of history, which covered our original recovery-point requirements when the service first went to production (TASK-840).", "decision_b": "backup-scheduler now takes full snapshots weekly plus incremental WAL archiving every 15 minutes, retaining 30 days, now that point-in-time recovery is a stated requirement in the updated operations runbook (TASK-861).", "gold_label": "supersession", "class": "silent_supersession", "why": "The new backup cadence is tied to a new stated requirement, showing this decision knowingly supersedes the nightly-only scheme rather than conflicting with it."}
{"pair_id": "teach_027", "decision_a": "metrics-aggregator emits p50 and p99 latency per route, tagged only by HTTP method, which was sufficient resolution back when most routes had uniform latency characteristics (TASK-880).", "decision_b": "metrics-aggregator now emits p50 and p99 latency tagged by route template and status class, dropping the method-only tag after that coarse grouping proved unable to isolate the checkout-svc regression from healthy traffic (TASK-905).", "gold_label": "supersession", "class": "silent_supersession", "why": "The tagging scheme change is explicitly motivated by a diagnosed shortcoming of the earlier scheme, marking a considered replacement rather than an accidental clash."}
{"pair_id": "teach_028", "decision_a": "alerts-dispatcher pages on-call for any 5xx spike above 1% sustained over 5 minutes, a threshold set conservatively when the service was new and every anomaly warranted a look (TASK-920).", "decision_b": "alerts-dispatcher now pages on-call for 5xx spikes above 5% over 5 minutes, tuned upward after the 1% threshold produced three false pages during last month's planned ingestion-pipeline backfill (TASK-948).", "gold_label": "supersession", "class": "silent_supersession", "why": "The threshold change cites a concrete false-positive history that only makes sense as a follow-on tuning of the earlier threshold, so it supersedes rather than contradicts it."}
{"pair_id": "teach_029", "decision_a": "session-store evicts idle sessions after 30 minutes of inactivity, a duration inherited from the desktop-web session model that was the only client when this policy was set (TASK-960).", "decision_b": "session-store now evicts idle sessions after 8 hours of inactivity, matching the extended-session requirement added once mobile clients started backgrounding the app without ever closing their sockets (TASK-985).", "gold_label": "supersession", "class": "silent_supersession", "why": "The much longer eviction window is tied to a new mobile-client requirement postdating the original decision, indicating an informed update rather than an unresolved conflict."}
{"pair_id": "teach_030", "decision_a": "inventory-svc treats stock counts as eventually consistent, tolerating up to 60 seconds of staleness across regions, which kept write latency low under the original single-region traffic pattern (TASK-1000).", "decision_b": "inventory-svc now treats stock counts as strongly consistent through a single-region write path, after multi-region replication lag was traced as the direct cause of overselling during last quarter's flash sale (TASK-1030).", "gold_label": "supersession", "class": "silent_supersession", "why": "The consistency-model change is explained by a concrete overselling incident traced to the earlier eventual-consistency choice, showing a diagnosed replacement, not a contradiction."}
{"pair_id": "teach_031", "decision_a": "auth-gateway enforces access control at the route level: only users holding the 'billing-admin' role may call any endpoint under /billing/*, checked once in the gateway before the request reaches the service (TASK-1101).", "decision_b": "billing-service enforces access control at the row level: a billing-admin can only read or write invoice rows belonging to their own organization_id, even though the route itself is open to the entire role (TASK-1101).", "gold_label": "related_not_contradicting", "class": "layer_confusion", "why": "One decision governs which role may hit the route at all and the other governs which rows that role can touch once inside; they operate at different layers and both hold simultaneously."}
{"pair_id": "teach_032", "decision_a": "catalog-api access control at the route level: any request to /admin/catalog/* requires the 'catalog-editor' role, checked in the gRPC interceptor before the handler ever runs (TASK-1115).", "decision_b": "catalog-api access control at the row level: a catalog-editor may only mutate SKU rows in categories assigned to them in the category_owners table, enforced separately inside the repository layer (TASK-1115).", "gold_label": "related_not_contradicting", "class": "layer_confusion", "why": "Route-level role gating and row-level category ownership are independent, compatible layers of the same access-control feature, not opposing rules."}
{"pair_id": "teach_033", "decision_a": "shipment-tracker access control at the gateway level: the /internal/shipments/export endpoint is restricted to callers holding the 'ops' role, enforced as an API gateway policy applied to every request (TASK-1130).", "decision_b": "shipment-tracker access control at the query level: within that same export, an ops user only receives shipment rows for warehouses in their assigned region, filtered directly in the underlying query (TASK-1130).", "gold_label": "related_not_contradicting", "class": "layer_confusion", "why": "Gateway-level role restriction and query-level regional row filtering are two different enforcement layers that both apply without conflict."}
{"pair_id": "teach_034", "decision_a": "quota-service access control at the middleware level: only service accounts carrying the 'quota-admin' scope may call POST /quotas/override, checked once in shared gRPC middleware before routing (TASK-1148).", "decision_b": "quota-service access control at the handler level: a quota-admin override can only target tenants below the enterprise tier; overriding an enterprise-tier tenant requires a separate approval row checked inside the handler (TASK-1148).", "gold_label": "related_not_contradicting", "class": "layer_confusion", "why": "Middleware-level role gating and handler-level tier restriction are complementary layers of the same override control, not conflicting rules."}
{"pair_id": "teach_035", "decision_a": "user-profile-svc access control at the route level: a profile deletion request requires the caller to hold the 'account-owner' role, verified before the request is routed to the handler (TASK-1160).", "decision_b": "user-profile-svc access control at the row level: even an account-owner cannot delete a profile row flagged 'legal-hold', enforced as a check inside the deletion transaction regardless of the caller's role (TASK-1160).", "gold_label": "related_not_contradicting", "class": "layer_confusion", "why": "Route-level role requirement and row-level legal-hold exemption sit at different enforcement layers and both apply without contradicting each other."}
{"pair_id": "teach_036", "decision_a": "export-worker access control at the gateway level: only callers holding the 'data-export' role may trigger POST /exports/run, enforced as an API gateway policy on the route itself (TASK-1175).", "decision_b": "export-worker access control at the row level: within a triggered export, individual rows are filtered by the caller's data_scope claim so a data-export user never sees rows outside their assigned scope (TASK-1175).", "gold_label": "related_not_contradicting", "class": "layer_confusion", "why": "Gateway role gating and per-row scope filtering are two layers of the same access-control story, not competing decisions."}
{"pair_id": "teach_037", "decision_a": "Diagnosis: fanout-worker is dropping roughly 2% of Kafka messages during partition rebalances because the consumer commits its offset before the corresponding write to ledger-api has actually completed successfully (TASK-1201).", "decision_b": "Fix: fanout-worker now commits its Kafka offset only after the downstream write to ledger-api succeeds, eliminating the rebalance-window message loss that the earlier diagnosis traced to the premature-commit ordering (TASK-1201).", "gold_label": "related_not_contradicting", "class": "diagnosis_then_repair", "why": "The second decision is the implemented remedy for the defect the first decision identified; they are sequential stages of one effort, not opposing claims."}
{"pair_id": "teach_038", "decision_a": "Diagnosis: checkout-svc's discount calculation double-applies a coupon whenever a client retries a request that originally timed out, because the retry path was never made idempotent against repeated submission (TASK-1218).", "decision_b": "Fix: checkout-svc now requires a client-supplied idempotency key on every discount application, so a retried request reuses the original result instead of recomputing and double-applying the coupon (TASK-1218).", "gold_label": "related_not_contradicting", "class": "diagnosis_then_repair", "why": "One decision names a bug and the other closes it with a specific mechanism; they are sequential parts of the same fix, not a contradiction."}
{"pair_id": "teach_039", "decision_a": "Diagnosis: search-indexer's incremental update path silently skips any document larger than 1MB, because the underlying Kafka producer truncates oversized messages without raising an error the consumer can detect (TASK-1233).", "decision_b": "Fix: search-indexer now splits documents over 1MB across multiple Kafka messages and reassembles them before indexing, closing the silent-skip gap the earlier diagnosis attributed to producer-side truncation (TASK-1233).", "gold_label": "related_not_contradicting", "class": "diagnosis_then_repair", "why": "The fix directly addresses the truncation defect the diagnosis described; the two decisions are sequential, not conflicting."}
{"pair_id": "teach_040", "decision_a": "Diagnosis: rate-limiter under-counts request volume from behind a shared corporate NAT because it keys solely on source IP, letting an entire office collectively bypass the intended per-user limit (TASK-1249).", "decision_b": "Fix: rate-limiter now keys on the pair (source IP, API key) instead of IP alone, so individual users sharing a NAT are rate-limited independently by credential rather than pooled together (TASK-1249).", "gold_label": "related_not_contradicting", "class": "diagnosis_then_repair", "why": "The second decision is the concrete remedy for the keying flaw the first decision diagnosed, a sequential diagnosis-then-repair pair rather than an opposition."}
{"pair_id": "teach_041", "decision_a": "Diagnosis: pricing-engine returns stale quotes for several seconds after a price change, because Redis cache invalidation fires asynchronously after the Postgres commit rather than inside the same transaction boundary (TASK-1265).", "decision_b": "Fix: pricing-engine now invalidates its Redis quote cache inside the same transaction boundary as the Postgres price update, removing the asynchronous gap the earlier diagnosis identified as the source of staleness (TASK-1265).", "gold_label": "related_not_contradicting", "class": "diagnosis_then_repair", "why": "The fix closes the exact staleness window the diagnosis called out; both decisions describe one continuous remediation, not a contradiction."}
{"pair_id": "teach_042", "decision_a": "Measured webhook-relay's duplicate-delivery rate at 0.4% over a 2-week sample of production traffic, tracing most duplicates to consumer-side acknowledgment timeouts rather than any relay-side retry bug (TASK-1301).", "decision_b": "Shipped a consumer-side dedup cache in webhook-relay's client SDK, keyed on delivery ID, so downstream consumers can absorb duplicate deliveries locally instead of needing relay-side changes (TASK-1312).", "gold_label": "related_not_contradicting", "class": "measurement_vs_shipping", "why": "One decision reports an observed duplicate rate and the other ships a mitigation for consumers; a measurement and a shipped change are not in tension."}
{"pair_id": "teach_043", "decision_a": "Measured ingestion-pipeline's schema-validation failure rate at 1.8% of incoming events over the last 30 days, with failures concentrated almost entirely in traffic from a single upstream producer (TASK-1318).", "decision_b": "Shipped a quarantine topic in ingestion-pipeline so any event failing schema validation is routed aside for later inspection instead of blocking the main partition behind it (TASK-1330).", "gold_label": "related_not_contradicting", "class": "measurement_vs_shipping", "why": "The measurement characterizes current failure prevalence while the shipped change is an operational improvement; neither asserts anything the other denies."}
{"pair_id": "teach_044", "decision_a": "Measured token-refresh-svc's reuse-detection false-positive rate at 0.02% across a full week of production traffic, well within the tolerance the security team set for this detector (TASK-1341).", "decision_b": "Shipped a change to token-refresh-svc adding a 5-second grace window before flagging concurrent refresh attempts as reuse, to accommodate clients that legitimately refresh from multiple tabs at once (TASK-1350).", "gold_label": "related_not_contradicting", "class": "measurement_vs_shipping", "why": "The measurement is a baseline observation and the shipped change is a tuning of the detector; they describe complementary steps, not a contradiction."}
{"pair_id": "teach_045", "decision_a": "Measured cache-warmer's hit-rate improvement at plus 6 percentage points after the rolling-window change landed, sampled over 3 days of production traffic across all warmed SKU categories (TASK-1360).", "decision_b": "Shipped a follow-up to cache-warmer adding a manual override endpoint so on-call can force an out-of-band warm cycle ahead of a known traffic event like a scheduled promotion (TASK-1372).", "gold_label": "related_not_contradicting", "class": "measurement_vs_shipping", "why": "One decision reports a measured effect of a prior change and the other ships an operational feature; they sit at different stages of the same workstream without opposing each other."}
{"pair_id": "teach_046", "decision_a": "Measured alerts-dispatcher's page-to-acknowledge latency at a median of 90 seconds across the last full on-call rotation, gathered from paging-system timestamps rather than self-reported data (TASK-1388).", "decision_b": "Shipped a change routing alerts-dispatcher pages through a secondary notification channel automatically whenever the primary page goes unacknowledged for more than 60 seconds, closing the gap the latency measurement surfaced (TASK-1399).", "gold_label": "related_not_contradicting", "class": "measurement_vs_shipping", "why": "The measurement documents a latency baseline and the shipped change adds an escalation path; the two are complementary, not conflicting."}
{"pair_id": "teach_047", "decision_a": "Security review for the notify-worker TLS-library upgrade (TASK-1401): this change introduces no new vulnerabilities; the diff only swaps a minor TLS library version pin and touches no application logic (TASK-1401).", "decision_b": "Standing security note on notify-worker, still open from an earlier review (TASK-1055): the service has a known vulnerability in its unauthenticated debug endpoint, tracked separately and awaiting a scheduled fix window (TASK-1055).", "gold_label": "related_not_contradicting", "class": "surface_negation", "why": "One statement scopes 'no new vulnerabilities' to a specific diff while the other names a pre-existing, separately tracked issue; both are true about different things."}
{"pair_id": "teach_048", "decision_a": "Review of the checkout-svc dependency bump (TASK-1420): no new vulnerabilities introduced by this bump, confirmed against the scanner diff covering every package version that changed (TASK-1420).", "decision_b": "checkout-svc carries three known, accepted-risk CVEs in transitive dependencies logged in the risk register from an earlier audit; none of the three packages were touched by this bump (TASK-980).", "gold_label": "related_not_contradicting", "class": "surface_negation", "why": "The absence of new vulnerabilities from one change and the presence of separately-tracked pre-existing ones are compatible facts, not a contradiction."}
{"pair_id": "teach_049", "decision_a": "auth-gateway's session-cookie rotation change (TASK-1435) was reviewed: introduces no new vulnerabilities, confirmed by the automated SAST pass run against the full diff before merge (TASK-1435).", "decision_b": "auth-gateway carries a known vulnerability in its legacy basic-auth fallback path, open since an earlier review (TASK-890) and pending full deprecation of that fallback path across all remaining clients (TASK-890).", "gold_label": "related_not_contradicting", "class": "surface_negation", "why": "One claim is scoped to the reviewed change and the other describes an unrelated, already-tracked legacy issue; neither contradicts the other."}
{"pair_id": "teach_050", "decision_a": "image-resizer's new format-detection library (TASK-1450): security review found no new vulnerabilities introduced, and the library's dependency tree was scanned and cleared before this change merged (TASK-1450).", "decision_b": "image-resizer's codebase carries a known vulnerability class around unvalidated EXIF metadata parsing, tracked since an earlier review (TASK-1002) and still awaiting the parser rewrite scheduled for next quarter (TASK-1002).", "gold_label": "related_not_contradicting", "class": "surface_negation", "why": "The new-library review and the standing EXIF vulnerability describe different code paths; both statements can be true at once."}
{"pair_id": "teach_051", "decision_a": "session-store's migration from single-node Redis to Redis Cluster (TASK-1465): this change introduces no new vulnerabilities; TLS configuration and auth credentials carried over unchanged from the prior deployment (TASK-1465).", "decision_b": "session-store has a known vulnerability where session tokens are logged in plaintext whenever debug-level logging is enabled, tracked as a standing issue from an earlier review (TASK-1120) and still unresolved (TASK-1120).", "gold_label": "related_not_contradicting", "class": "surface_negation", "why": "One statement clears a specific migration diff of new risk while the other names a separately tracked, pre-existing logging issue; both hold simultaneously."}
{"pair_id": "teach_052", "decision_a": "Set the Postgres connection pool size to 40 for billing-service's connection to its primary database, sized to handle peak invoice-generation concurrency without starving other services on the same primary (TASK-1501).", "decision_b": "Set the Postgres connection pool size to 10 for reconciliation-job's connection to the dedicated read-replica used only for nightly reporting queries, since that workload is low-concurrency and batch-oriented (TASK-1512).", "gold_label": "related_not_contradicting", "class": "scope_disjoint", "why": "Both decisions tune a connection pool size, but for different services against different database endpoints, so the shared vocabulary masks disjoint scopes."}
{"pair_id": "teach_053", "decision_a": "Set the retry timeout for search-indexer's calls to catalog-api to 5 seconds, tuned for the indexer's tight per-document processing budget during incremental updates triggered on every catalog write (TASK-1520).", "decision_b": "Set the retry timeout for export-worker's calls to catalog-api to 30 seconds, since bulk export jobs can tolerate slower responses and benefit more from resilience than from tight latency bounds (TASK-1525).", "gold_label": "related_not_contradicting", "class": "scope_disjoint", "why": "The same target service and parameter name appear in both, but the calling services differ, so the two settings apply to disjoint call paths."}
{"pair_id": "teach_054", "decision_a": "Access control for the /metrics endpoint on metrics-aggregator: internal network only, no auth token required, since the endpoint only ever needs to be reachable from the in-cluster scraping agent (TASK-1538).", "decision_b": "Access control for the /metrics endpoint on alerts-dispatcher: requires a bearer token even from the internal network, because this particular endpoint also exposes per-tenant paging volume that shouldn't be broadly readable (TASK-1541).", "gold_label": "related_not_contradicting", "class": "scope_disjoint", "why": "Both decisions set access control on a '/metrics' endpoint, but on two different services, so the identical path name does not put them in conflict."}
{"pair_id": "teach_055", "decision_a": "Cache TTL for catalog-api's product-detail responses is set to 60 seconds, balancing freshness against load, since detail pages change frequently during active merchandising campaigns and get hit heavily during flash sales (TASK-1552).", "decision_b": "Cache TTL for catalog-api's category-listing responses is set to 600 seconds, since category structure changes rarely and the listing endpoint serves a much higher volume of low-priority browsing traffic (TASK-1558).", "gold_label": "related_not_contradicting", "class": "scope_disjoint", "why": "Both decisions set a cache TTL on catalog-api, but for different response types, so the shared subsystem name does not make them conflicting settings on the same thing."}
{"pair_id": "teach_056", "decision_a": "Max payload size for ingestion-pipeline's public ingest API is capped at 1MB, sized for the typical single-event payload our external partners send through that endpoint (TASK-1570).", "decision_b": "Max payload size for ingestion-pipeline's internal batch-replay endpoint is capped at 100MB, sized to support replaying an entire day's backfill in one request from trusted internal callers only (TASK-1575).", "gold_label": "related_not_contradicting", "class": "scope_disjoint", "why": "The same service and parameter name are involved, but the two endpoints serve different traffic classes, making the settings disjoint rather than conflicting."}
{"pair_id": "teach_057", "decision_a": "Switched fanout-worker's Kafka consumer group rebalance strategy from range to cooperative-sticky, reducing partition churn and the resulting processing pauses that occurred every time a new deploy rolled out (TASK-1601).", "decision_b": "Switched checkout-svc's OpenTelemetry span sampler from a fixed 10% ratio to tail-based sampling keyed on error status, so we retain far more traces for failed checkouts without paying for every successful one (TASK-1688).", "gold_label": "unrelated", "class": "unrelated_high_similarity", "why": "Both decisions describe a strategy swap for reliability tuning using overlapping technical vocabulary, but they concern unrelated services and mechanisms with no shared question."}
{"pair_id": "teach_058", "decision_a": "Migrated audit-log-svc's write path from direct synchronous Postgres inserts to a Kafka-backed outbox pattern, decoupling write latency from whatever downstream consumers happen to be doing at request time (TASK-1615).", "decision_b": "Migrated image-resizer's thumbnail cache from local disk to S3 with a Redis-backed index, so cached thumbnails survive pod restarts instead of being silently recomputed from scratch every time a pod cycles (TASK-1699).", "gold_label": "unrelated", "class": "unrelated_high_similarity", "why": "Both are infrastructure migrations described with similar Kafka/S3/Redis vocabulary, but they touch different services solving different problems with nothing in common to agree or disagree on."}
{"pair_id": "teach_059", "decision_a": "quota-service now emits an OpenTelemetry span for every override check, tagged with tenant tier, specifically to debug the override-latency complaints that support has been escalating for two weeks (TASK-1630).", "decision_b": "shipment-tracker now emits an OpenTelemetry span for every carrier-webhook callback, tagged with carrier id, specifically to debug the intermittent callback drops that only one particular carrier integration seems to exhibit (TASK-1710).", "gold_label": "unrelated", "class": "unrelated_high_similarity", "why": "Both decisions add OpenTelemetry span instrumentation with per-request tags for debugging, but on unrelated services investigating unrelated problems."}
{"pair_id": "teach_060", "decision_a": "pricing-engine's gRPC service now runs behind a Docker sidecar that terminates mTLS before requests ever reach the application container, following the platform team's standard sidecar pattern for internal services (TASK-1645).", "decision_b": "user-profile-svc's gRPC service now runs behind a Docker sidecar that terminates mTLS before requests ever reach the application container, adopting the same platform-standard sidecar pattern used across other internal services (TASK-1720).", "gold_label": "unrelated", "class": "unrelated_high_similarity", "why": "The two decisions use nearly identical wording and architecture for mTLS termination, but they are independent adoptions of a shared pattern on unrelated services, not a shared question either could contradict."}
