DB Olympics

Queries · q285 · Head of Risk and Payments · week 2, night 4

Pre-2023 data subject requests: status and completion check

“Do the 12 data_subject_requests rows with received_at before 2023-01-01 represent any hidden backlog or unresolved risk, outside the window we've otherwise been reporting on?”

Manager · asked the questionAylin DemirHead of Risk and Payments. Previously in fraud operations at a bank. Responsible for payment performance and for keeping bad actors out.
Analyst · planned the reportClaire DuboisTime-series minded: weekly and daily trends, before and after, seasonality.
Engineer · wrote the SQLGraceWrites tidy, layered CTEs with descriptive names, one step per CTE, then a final select.

Fictional people at a fictional company, each played by a language-model agent. Who they are and what they are told

  1. A business event lands on the Head of Risk and Payments's desk

    Week 1; shared with Rosa Van den Berg, Head of Data

    An enterprise prospect sent a security and compliance questionnaire covering account security, access control, privacy requests, data retention and audit trails. Sales wants answers backed by evidence from our own systems, not by policy documents.

  2. Aylin Demir writes to Claire Dubois

    The manager, at the start of week 2

    Subject: Re: Questionnaire memo — good work, a few threads to pull

    Claire,

    This is a strong memo, and the gaps you flagged are exactly the kind of thing I'd rather surface now than have a prospect's security team find later. A few things stand out and I want to understand them better before we finalize anything.

    The February 2025 login spike is the one that worries me most. A 10x jump in failures with no corresponding rise in flagged suspicious activity is a real detection gap, not just a reporting curiosity — if that was a credential-stuffing attempt, I need to know whether it actually got anywhere.

    Questions for this week:

    1. On the February 2025 spike — did it cluster around a handful of accounts, merchants, or sources, or was it spread evenly? And did any of the accounts that failed repeatedly go on to log in successfully shortly after? That tells us whether this was noise or an actual near-miss.
    2. On the three unresolved rejection dates — rather than retrying the same technical path, can we establish, using whatever reliable timestamp we do have, roughly when each decision was made relative to the request date? I don't need the exact figure if it's not retrievable — I need to know whether we were plausibly within the deadline or not, so we can decide how to word that answer.
    3. On flagged incidents (the one we deferred) — now that we're another week in, I want this one: how many incidents have been flagged, how severe, how long they typically take to close, and whether anything has sat open a long time. This is likely to come up in the same breath as the login spike.
    4. On the tables with no retention policy — before I escalate this as a gap, I want to know how exposed we actually are: roughly how far back does that data go today? If it's a few months, this is a minor cleanup; if it's three years, it's a bigger conversation with Rosa.

    Keep the role/permission logging gap and the broken query as noted — no need to keep spending slots chasing those; I'll raise the first with engineering myself and we can note the second as a known limitation in the memo.

    Thanks, Aylin

  3. Claire Dubois plans the night

    The analyst · week 2, night 4, request 1 of 2

    Night 3 results round out the picture nicely:

    Report 1 (pre-2023 anomaly): change_history (2 outlier rows out of ~31,099) and compliance_events (1 outlier row out of 9) are clearly negligible noise. data_subject_requests is different: 12 of 60 total rows (20%) predate 2023-01-01 (1 in 2020, 4 in 2021, 7 in 2022) — not negligible. Reassuringly, the 2023-2025 rows sum to exactly 48 (10+23+15), matching the "~48 requests since 2023" figure I've already reported, so that number is internally consistent and unaffected — but I want to quickly check whether any of those 12 pre-2023 rows represent unresolved/backlog risk before I close this out, since they're sitting entirely outside the window I've been reporting on.

    Reports 2 and 3 (Feb 2025 pattern + quarterly history) make the spike's character much clearer: 17/11/8 distinct user agents at the three merchants respectively with no single user agent dominating (~25-27% share) — not bot-like; and the quarterly history shows every other quarter at all three merchants sits at a stable 4.8-7.3% fail rate, with Q1 2025 alone spiking to 61-68% — a clean, isolated one-quarter event, not a recurring problem. One more thing worth nailing down before I write the memo: at each merchant individually, ~74-75% of failures cluster in just 3 days — I want to check whether it's the same 3 days across all three merchants, which would point to one shared platform-level cause rather than three coincidentally-timed separate issues, and whether access_denied logging was silent specifically on those days (not just the month overall).

    This is the last night, so I'm keeping it tight: (1) a quick status check on the 12 pre-2023 DSAR rows, to close out any residual backlog question; (2) a day-by-day breakdown for February 2025 across the three merchants (failed logins per merchant plus access_denied events) to test the shared-cause hypothesis precisely. I'm leaving the third slot unused — I have what I need to write a confident memo and don't have a well-justified third question tonight.

    Pre-2023 data subject requests: status and completion check
    Question
    Do the 12 data_subject_requests rows with received_at before 2023-01-01 represent any hidden backlog or unresolved risk, outside the window we've otherwise been reporting on?
    One row per
    status value, restricted to data_subject_requests rows with received_at < 2023-01-01
    Columns
    • status
    • count
    • count_with_completed_at
    • min_received_at
    • max_received_at
  4. Grace writes the SQL

    The engineer · 1 dry run on the empty schema, then the submission

    Dry run 1 · STATUS: COMPILES (dry run on the empty schema, no data read)
    select
      status,
      count(*) as count,
      count(completed_at) as count_with_completed_at,
      min(received_at) as min_received_at,
      max(received_at) as max_received_at
    from data_subject_requests
    where received_at < date '2023-01-01'
    group by status
    order by status

    “Query compiles cleanly. Submitting.”

    Submitted · the SQL of the last dry run, unchanged · Submitted to tonight's batch. Your work on this request is done.

    “Submitted. The report groups the 12 pre-2023 data_subject_requests rows by status, showing count, how many have completed_at populated, and the min/max received_at per status — Claire can use this to check for any open/unresolved statuses among them.”

  5. The report comes back overnight

    As Claire Dubois saw it, from the small dataset the agents worked on

    status    | count | count_with_completed_at | min_received_at            | max_received_at           
    ----------+-------+-------------------------+----------------------------+---------------------------
    completed |    12 |                      12 | 2020-04-24 22:06:57.286184 | 2022-11-20 04:39:40.390136
    (1 rows)
  6. What came of it

    The memo and the queries that followed; links found by title, so inferred

    It builds on:

  7. It becomes benchmark query q285

    Changed only where the benchmark needs the same result on every system

    • determinismthe standard leaves the place of NULLs in a sort to the implementation: NULLS LAST ascending, NULLS FIRST descending, as in the reference results
    The benchmark text, against the submitted SQL
    select  status,  count(*) as count,  count(completed_at) as count_with_completed_at,  min(received_at) as min_received_at,  max(received_at) as max_received_atfrom data_subject_requestswhere received_at < date '2023-01-01'group by statusorder by statusorder by status NULLS LAST
    select
      status,
      count(*) as count,
      count(completed_at) as count_with_completed_at,
      min(received_at) as min_received_at,
      max(received_at) as max_received_at
    from data_subject_requests
    where received_at < date '2023-01-01'
    group by status
    order by status NULLS LAST
    1 ms10 ms100 msHyper3.8 msDuckDB3.7 msGizmoSQL4.0 msclickhouse_brew25.1 msFirebolt10.6 msDataFusion30.9 msClickHouse9.8 ms
  8. Everything, as recorded

    The agents' own records, as the role play wrote them; only the personal data of the person who ran it is redacted

    Grace's whole session, 7 turns
    • The request, as Grace received it
      Report request from Claire Dubois (analyst for the Head of Risk and Payments):
      
      Title: Pre-2023 data subject requests: status and completion check
      Question: Do the 12 data_subject_requests rows with received_at before 2023-01-01 represent any hidden backlog or unresolved risk, outside the window we've otherwise been reporting on?
      Grain: one row per status value, restricted to data_subject_requests rows with received_at < 2023-01-01
      Columns:
      - status
      - count
      - count_with_completed_at
      - min_received_at
      - max_received_at
      Details: Source: data_subject_requests, filtered to received_at < 2023-01-01 (expect 12 rows total across statuses). Purpose: these rows predate the system's stated 2023-01-01 history start and are likely migration/seed artifacts, but before treating them as pure noise I want to confirm none of them show an open/unresolved status that would be backlog we haven't accounted for. Order by status.
      
      Check your query with the warehouse's dry_run tool, then hand it in with submit.
    • Grace calls dry_run
      select
        status,
        count(*) as count,
        count(completed_at) as count_with_completed_at,
        min(received_at) as min_received_at,
        max(received_at) as max_received_at
      from data_subject_requests
      where received_at < date '2023-01-01'
      group by status
      order by status
    • The warehouse answers
      STATUS: COMPILES (dry run on the empty schema, no data read)
      COLUMNS: status, count, count_with_completed_at, min_received_at, max_received_at
    • GraceQuery compiles cleanly. Submitting.
    • Grace calls submit
      select
        status,
        count(*) as count,
        count(completed_at) as count_with_completed_at,
        min(received_at) as min_received_at,
        max(received_at) as max_received_at
      from data_subject_requests
      where received_at < date '2023-01-01'
      group by status
      order by status
    • The warehouse answers
      Submitted to tonight's batch. Your work on this request is done.
    • GraceSubmitted. The report groups the 12 pre-2023 `data_subject_requests` rows by status, showing count, how many have `completed_at` populated, and the min/max `received_at` per status — Claire can use this to check for any open/unresolved statuses among them.