Why SignalPilot passed where base failed
Evidence chips jump to the exact transcript momentAsked 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.
- 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.
- 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
| Check | Correct answer | Base Claude Code | SignalPilot |
|---|---|---|---|
| Granite_gaming's total enrollments | 183,216 | 103,670 (43% missing) | 183,216 |
Verification workflow
Where the eight-step workflow caught it.
- 01Map 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.
- 02Load supporting skills
SQL, database, and domain rules loaded before any writing.
- 03Validate the project
Parse check, plus rebuild of stale time-dependent upstreams.
- 04Discover project macros
Find macro-derived columns the YML contract does not list.
- 05Research 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.
- 06Write the technical spec
A written plan of sources, joins, filters, and grain per model.
- 07Write and build models
SQL from the spec, with column mapping checked before each model.
- 08Verify and fix
Two read-only verifiers cross-check structure and values until every check passes.
SignalPilot
claude code + signalpilot governed stack
reported 183,216 · matches truth
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.
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:
| Source | Enrollments | Grain check |
|---|---|---|
raw.client_blob (source_client = granite_gaming) | 183,216 | 1 blob row each |
staging.stg_granite__enrollments | 183,216 | enrollment_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,670 — dim_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 cause — models/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?
Base Claude Code
claude code, no additional stack
reported 103,670 · truth 183,216 (43% of rows silently dropped)
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 againstorg.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.
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.