SignalPilot is #1 on both public data-agent benchmarksSee the results →
All cases

Silently vanished rows

granite_gaming capacity check: how many total enrollments do we have for them, all time?

granite_gaming's capacity check came back at 103,670 enrollments. The real number is 183,216, cut nearly in half by the same date-window truncation.

Case 8 of 39Δ 79,546 rows shortparallax

Why SignalPilot passed where base failed

Evidence chips jump to the exact transcript moment

Asked for granite_gaming's total enrollments, Claude Code reported 103,670. The raw landing table holds 183,216: 43% of the rows had silently vanished below the mart. SignalPilot reconciled the count down to the raw data and recovered the full population.

Real-world impact

Capacity planning, billing, and experiment power calculations built on this count all start from a number 43% too low, and nothing in the pipeline flags it: the shrunken table has clean grain, clean uniqueness, and an authoritative name.

Where base Claude Code went wrong
  • Below the published mart, a hard-coded date filter (assigned_ts >= 2025-12-01) quietly truncates history.
  • Row counts and uniqueness checks still pass; only the total is wrong.
  • Counted the authoritative-looking table and reported 103,670 with confidence; the raw landing table was never consulted.
What SignalPilot did differently
  • Started from the client's own staging and raw landing data instead of the published rollup, counting the population at every layer.
  • Reported 183,216 from the source, matching the independently derived truth exactly.

The numbers

CheckCorrect answerBase Claude CodeSignalPilot
Granite_gaming's total enrollments183,216103,670 (43% missing)183,216

Verification workflow

Where the eight-step workflow caught it.

Read the workflow docs
  1. 01
    Map the project

    Scan every model: dependencies, required columns, macros, hazards.

    The scan mapped the staging, intermediate, and mart layers before any counting; base Claude Code queried the rollup that looked authoritative.

  2. 02
    Load supporting skills

    SQL, database, and domain rules loaded before any writing.

  3. 03
    Validate the project

    Parse check, plus rebuild of stale time-dependent upstreams.

  4. 04
    Discover project macros

    Find macro-derived columns the YML contract does not list.

  5. 05
    Research the data

    Driving table, cardinalities, contract, sibling patterns, categorical values.

    Layer-by-layer counts caught staging holding 183,216 unique enrollments while the intermediate kept 103,670, isolating a stray assigned_ts >= 2025-12-01 filter; base Claude Code cross-checked two tables built from that same filtered layer and called their agreement verified.

  6. 06
    Write the technical spec

    A written plan of sources, joins, filters, and grain per model.

  7. 07
    Write and build models

    SQL from the spec, with column mapping checked before each model.

  8. 08
    Verify and fix

    Two read-only verifiers cross-check structure and values until every check passes.

SignalPilot

SignalPilot

claude code + signalpilot governed stack

pass
reported 183,216 · matches truth
32 turns30 tool calls$$1.14answer pinned · full chat below
final answer pass

No problem — I'll hold off on any changes.

Bottom line for your capacity check: granite_gaming has 183,216 total enrollments, all time. The 103,670 shown in the marts/dashboards is a bug (a stray assigned_ts >= '2025-12-01' filter in int_granite__enrollments.sql), not a real number.

Just say the word if you'd like me to fix the filter and rebuild.

full chat, from the start
granite_gaming capacity check: how many total enrollments do we have for them, all time?

I'll start by loading the required workflow skill, as mandated by the project instructions.

This is a business outcome question. Per the project instructions, I'll run the exploration steps. Let me first load the SignalPilot MCP tools and scan the project.

I have the tools now. Let me load the schemas I need and start the exploration.

Now let me start Step 1. Let me check the knowledge base and scan the project in parallel.

This is an experiments/A-B-testing platform, and "granite_gaming" likely maps to the granite org. "Enrollments" needs definition. Let me run knowledge probes and inspect the schema. Per project instructions, single-keyword conjunctive probes.

This is a multi-tenant experimentation platform. "granite_gaming" maps to the granite client. "Enrollments" are enrollment records (grain = enrollment_id). Per the grain-verification rule, I must not trust a mart's total_enrollments — I need to re-derive from source. Note granite has anomalies (a canonical_key, 29 variant rows vs 12 elsewhere), so I'll check the grain carefully.

Let me map the client name and check grain at each layer.

Important discrepancy: staging stg_granite__enrollments has 183,216 enrollment records (enrollment_id is unique there), but the org rollup fct_org_revenue_by_client reports 103,670 enrollments and only 10 experiments (vs 12 in staging). That gap must be explained before I trust any number. Granite's anomalies (canonical_key, 29 variant rows) suggest wire-key aliasing. Let me investigate the raw source and the canonicalization.

The raw source confirms 183,216 enrollment records for granite_gaming, and staging carries all of them with a unique enrollment_id. The xref maps 12 wire keys 1:1 to 12 canonical keys. Yet the org canonical layer has only 10 canonical experiments and 103,670 enrollments — it silently dropped 2 experiments (~79,546 enrollments). This looks like a broken canonical join in the org mart. Let me pinpoint which experiments are dropped and check the granite-specific marts.

Now the break is fully visible. In staging, all 12 experiments have ~15,000–15,400 enrollments each (uniform), totaling 183,216. But the marts (dim_granite__experiments.total_enrollments) and the org canonical layer systematically undercount:

  • GG-EXP-005 & GG-EXP-006: entirely dropped (None / absent) — ~30,641 enrollments gone
  • GG-EXP-003, 004, 008, 009, 010, 012, 002: partially dropped (thousands each)
  • Only 001, 007, 011 survive intact

The mart total (sum = 103,670) matches the org rollup exactly because they share the same broken upstream lineage — the classic "both agree, both wrong" trap. Let me pinpoint where the drop happens (staging → intermediate) so I can report the root cause.

Confirmed: the break is at staging → intermediate. int_granite__enrollments already has only 103,670 rows / 10 experiments, while staging has 183,216 / 12. The variant join is not the cause (LEFT join matches all rows, 0 unmatched). Let me read the intermediate model to identify the exact root cause so my report is actionable.

Root cause found — line 4: where assigned_ts >= '2025-12-01'. A hardcoded date filter in int_granite__enrollments drops every enrollment assigned before 2025-12-01. That single WHERE clause cascades into every granite mart and the org rollups. Let me confirm it exactly accounts for the gap, and check whether siblings have the same filter (i.e., is it a stray bug).

Confirmed exactly. The filter accounts for the entire gap, and the same bug exists in a sibling model.

Answer: 183,216 total enrollments, all time

That's the true count, re-derived at the correct grain (enrollment_id) directly from source:

SourceEnrollmentsGrain check
raw.client_blob (source_client = granite_gaming)183,2161 blob row each
staging.stg_granite__enrollments183,216enrollment_id unique (183,216 distinct), 12 experiments

Enrollments span 2025-09-20 → 2026-05-10, roughly evenly spread (~15,100–15,400 per experiment across all 12).

⚠️ Your dashboards are undercounting this by 43%

Do not trust the number the marts/BI layer report. Every published granite figure says 103,670dim_granite__experiments.total_enrollments, fct_org_revenue_by_client, int_org__enrollments_canonical. They agree with each other only because they share one broken upstream, not because they're right.

Root causemodels/intermediate/granite_gaming/int_granite__enrollments.sql, line 4:

where assigned_ts >= '2025-12-01'

A hardcoded date filter drops every enrollment assigned before 2025-12-01 — exactly 79,546 rows, including experiments GG-EXP-005 (shop_layout_grid) and GG-EXP-006 (gacha_pity_meter) which vanish entirely (that's why the org rollup shows only 10 experiments, not 12). The staging → intermediate step is where it happens; the variant join is fine (0 unmatched).

103,670 (filtered) + 79,546 (pre-Dec-1, dropped) = 183,216 (staging total)

This is not granite-only. The identical filter sits in int_northwind__enrollments.sql:4, so northwind_marketplace is undercounting too.


For your capacity check, use 183,216. The mart's 103,670 is a bug, not a smaller footprint.

This is a factual error in the dbt project that's corrupting downstream dashboards. Want me to fix it?

Claude Code

Base Claude Code

claude code, no additional stack

fail
reported 103,670 · truth 183,216 (43% of rows silently dropped)
? turns4 tool callsanswer pinned · full chat below
final answer fail

Both the union table and the canonical table agree exactly, with no duplicate enrollment IDs.

granite_gaming — total enrollments, all time: 103,670

  • Source: org.int_all__enrollments (confirmed against org.int_org__enrollments_canonical)
  • 103,670 rows = 103,670 distinct enrollment_ids, so no double-counting.

For context, they're mid-pack across the 9 clients (range ~90K–329K; fjord_travel is largest at 328,580). If your capacity check needs it sliced by experiment, platform, or a specific time window, let me know and I'll break it down.

full chat, from the start
granite_gaming capacity check: how many total enrollments do we have for them, all time?

I'll investigate the warehouse to find enrollment data for granite_gaming. Let me start by exploring the schema.

Let me look at the enrollment tables and how clients/tenants are identified.

Let me see what client_id values exist, to map "granite_gaming" correctly.

granite_gaming shows 103,670. Let me sanity-check this against the canonical table and check for any duplication, since "capacity check" wants a trustworthy number.

Case #8 · Silently vanished rows · SignalPilot