<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Saifullah</title>
    <description>The latest articles on DEV Community by Saifullah (@saif-uk).</description>
    <link>https://dev.to/saif-uk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4111960%2F8b2a6121-3902-4fbd-abe5-4374024a2838.png</url>
      <title>DEV Community: Saifullah</title>
      <link>https://dev.to/saif-uk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saif-uk"/>
    <language>en</language>
    <item>
      <title>Default Flag: an exoplanet agent that won't mix papers</title>
      <dc:creator>Saifullah</dc:creator>
      <pubDate>Mon, 05 Oct 2026 00:15:25 +0000</pubDate>
      <link>https://dev.to/saif-uk/default-flag-an-exoplanet-agent-that-wont-mix-papers-5dm2</link>
      <guid>https://dev.to/saif-uk/default-flag-an-exoplanet-agent-that-wont-mix-papers-5dm2</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/sanity-2026-09-16"&gt;Sanity Challenge, Path One: Ship an Agent That Queries Real Content&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Default Flag&lt;/strong&gt; answers derived exoplanet questions (density, insolation, equilibrium temperature, habitable-zone status) from &lt;strong&gt;one self-consistent published parameter set per planet&lt;/strong&gt;, and shows, as a labelled counterfactual, the different answer you get by mixing values from several papers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live demo, no login:&lt;/strong&gt; &lt;a href="https://default-flag.vercel.app" rel="noopener noreferrer"&gt;https://default-flag.vercel.app&lt;/a&gt; · &lt;strong&gt;Code:&lt;/strong&gt; &lt;a href="https://github.com/unicorn-9-spec/default-flag" rel="noopener noreferrer"&gt;https://github.com/unicorn-9-spec/default-flag&lt;/a&gt; · &lt;strong&gt;Sanity project:&lt;/strong&gt; &lt;code&gt;0eu544dk&lt;/code&gt;, dataset &lt;code&gt;production&lt;/code&gt; (public)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0gvyrggep21plk31rpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0gvyrggep21plk31rpl.png" alt="Kepler-139 d planet page: ten published parameter sets side by side, the archive default (Weiss et al. 2024) highlighted, with density, insolation, equilibrium temperature and habitable-zone status computed separately for each set" width="800" height="785"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The NASA Exoplanet Archive keeps every published solution for a planet as its own row and flags one as the default. It also publishes a composite table with one row per planet, filled parameter by parameter from whichever paper its rules pick. The archive itself calls that table "a more complete, though not necessarily self-consistent, set of parameters". Answers built on the composite row can combine a mass from one paper with a radius from another, or with a radius the archive calculated from that mass.&lt;/p&gt;

&lt;p&gt;Default Flag never does that. Every number comes from deterministic code reading exactly one parameter set (plus the stellar values published with it). The composite answer appears only behind a "What the composite table would give" toggle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kepler-139 d.&lt;/strong&gt; Weiss et al. 2024 gives a density of &lt;strong&gt;5.29 g/cm³&lt;/strong&gt;. Their mass is M·sin i, which the archive calls a lower limit, so the answer says the density is a lower limit. The composite row takes its mass from Lammers &amp;amp; Winn 2025 instead and gives &lt;strong&gt;2.40 g/cm³&lt;/strong&gt;: less than half, from two papers that never published together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxima Cen b.&lt;/strong&gt; No paper in the archive measures its radius, so Default Flag &lt;strong&gt;refuses&lt;/strong&gt; and names the missing field. The composite row answers anyway, &lt;strong&gt;5.49 g/cm³&lt;/strong&gt;, from a radius the archive &lt;em&gt;calculated&lt;/em&gt; from the minimum mass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ups And c (a compounding case).&lt;/strong&gt; The default set refuses for lack of a radius. The composite gives 13.19 g/cm³ from a true mass (McArthur et al. 2010) and a radius the archive calculated &lt;em&gt;from that same mass&lt;/em&gt;: a density built on itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Four-arm evaluation
&lt;/h3&gt;

&lt;p&gt;40 frozen questions (15 density, 10 insolation or equilibrium temperature, 5 habitable zone, 5 provenance, 5 refusals). Ground truth comes from the archive's default row in the raw snapshot CSV, independent of Sanity and the model. Same model, step budget and compute tool for every arm; only retrieval differs. Model &lt;code&gt;gemini-3.7-flash&lt;/code&gt;, version &lt;code&gt;3.7-flash-08-2026&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffc2b510fbhs3tf3xp9v5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffc2b510fbhs3tf3xp9v5.png" alt="Four-arm evaluation table: structured agent 98% accuracy, 0% mixed provenance, 5 of 5 correct refusals; semantic search 93%, 3%, 3 of 5; keyword BM25 98%, 3%, 4 of 5; no content 45%, 35%, 3 of 5" width="800" height="152"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arm&lt;/th&gt;
&lt;th&gt;Accuracy&lt;/th&gt;
&lt;th&gt;Mixed-provenance rate&lt;/th&gt;
&lt;th&gt;Correct refusals&lt;/th&gt;
&lt;th&gt;Valid citations&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Structured agent (Sanity Context)&lt;/td&gt;
&lt;td&gt;98% (39/40)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0%&lt;/strong&gt; (0/29)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5/5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;98%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semantic search&lt;/td&gt;
&lt;td&gt;93% (37/40)&lt;/td&gt;
&lt;td&gt;3% (1/32)&lt;/td&gt;
&lt;td&gt;3/5&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keyword (BM25)&lt;/td&gt;
&lt;td&gt;98% (39/40)&lt;/td&gt;
&lt;td&gt;3% (1/31)&lt;/td&gt;
&lt;td&gt;4/5&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No content&lt;/td&gt;
&lt;td&gt;45% (18/40)&lt;/td&gt;
&lt;td&gt;35% (7/20)&lt;/td&gt;
&lt;td&gt;3/5&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What the numbers say, plainly:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structured agent:&lt;/strong&gt; never mixed papers, and refused all five questions the data can't support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search baselines:&lt;/strong&gt; they read the same &lt;em&gt;structured&lt;/em&gt; documents, where each parameter set is one self-contained document, and they mixed far less than I expected: 3%. Their failure was different. Where the default set can't answer, they quietly answered from &lt;em&gt;another paper's&lt;/em&gt; set instead of saying so. That's a provenance error the mixed-provenance metric doesn't count.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No content:&lt;/strong&gt; the model mixed or invented its inputs 35% of the time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The structured agent's one miss&lt;/strong&gt; was an answer its own output guard withheld.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why it's new
&lt;/h3&gt;

&lt;p&gt;Plenty of agents surface contradictions between sources. This one &lt;strong&gt;prevents&lt;/strong&gt; a specific, measurable error, mixing values from different papers into one derived number, and &lt;strong&gt;measures&lt;/strong&gt; how often each retrieval approach makes it. Astronomy's per-paper parameter sets make the error checkable: every input value an arm used is matched back to the snapshot rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/X7VLa2MOlME" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Judge path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Density of Kepler-139 d?&lt;/strong&gt; and read the answer and its provenance strip.&lt;/li&gt;
&lt;li&gt;Turn on &lt;strong&gt;What the composite table would give&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Density of Proxima Cen b?&lt;/strong&gt; and get a refusal that names the missing field.&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;/eval&lt;/code&gt; for the four-arm table.&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;/how-it-works&lt;/code&gt; for the Knowledge Base section.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6mlmged0obyd6dk2fuet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6mlmged0obyd6dk2fuet.png" alt="Default Flag home page: a short description, three example question chips (Density of Kepler-139 d?, Is TRAPPIST-1 e in the habitable zone?, Density of Proxima Cen b?) and an ask box, no login" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fglwi9qsn3yj2iikyv4nh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fglwi9qsn3yj2iikyv4nh.png" alt="Live answer card for Density of Kepler-139 d: 5.29 g/cm3 with its 16th to 84th percentile range 3.05 to 7.69, a lower-limit caveat for the minimum mass, and a provenance strip naming the planet, parameter set id, paper Weiss et al. 2024 (archive default), mass kind and snapshot checksum" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbaf1u827qe3qwjlgyd5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbaf1u827qe3qwjlgyd5p.png" alt="The 'What the composite table would give' toggle switched on for Kepler-139 d: 2.40 g/cm3, built from two papers (Lammers and Winn 2025 for mass, Weiss et al. 2024 for radius) that never published together" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcgphx6dni14u2975y85x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcgphx6dni14u2975y85x.png" alt="Proxima Cen b answer card: a polite refusal naming the missing planet radius, and below it the composite table answering 5.49 g/cm3 from a radius the archive calculated rather than measured" width="800" height="716"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F34y0r1jajlfmv9fx56e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F34y0r1jajlfmv9fx56e2.png" alt="Trace panel under an answer: MCP tools discovered at runtime on both Sanity Context endpoints, each GROQ query, Knowledge Base entries read, the compute output, and the output guard result" width="800" height="898"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhpgqvuuawxcewxyls2j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhpgqvuuawxcewxyls2j.png" alt="Default Flag on a phone-sized screen: the description, the three example chips and the ask box stacked in one column" width="800" height="1628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The other pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/planet/&amp;lt;slug&amp;gt;&lt;/code&gt; puts every published parameter set side by side.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/eval&lt;/code&gt; has a drill-down per question.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/how-it-works&lt;/code&gt; has the endpoints, schema, snapshot checksums and the Knowledge Base evidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every page has loading states and a banner naming the failing component (Sanity Context, dataset or model), never a silent fallback. The agent API is rate-limited.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/unicorn-9-spec/default-flag" rel="noopener noreferrer"&gt;https://github.com/unicorn-9-spec/default-flag&lt;/a&gt; (README with CI badge)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ingest/&lt;/code&gt;: verify (SHA-256 manifests) → select → normalise → import. Snapshot files live in the repo; a second run makes zero changes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;agent/&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;physics.ts&lt;/code&gt;: density, insolation, T_eq, Kopparapu 2014 habitable zone, 10,000 seeded split-normal Monte Carlo draws;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;compute&lt;/code&gt; and &lt;code&gt;composite_counterfactual&lt;/code&gt; tools;&lt;/li&gt;
&lt;li&gt;the output guard;&lt;/li&gt;
&lt;li&gt;the MCP wiring.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;web/&lt;/code&gt;: the Next.js site.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;eval/&lt;/code&gt;: questions, truth, four arms, scoring, results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CI runs on every push:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;snapshot checksums;&lt;/li&gt;
&lt;li&gt;an ingest determinism check;&lt;/li&gt;
&lt;li&gt;typecheck and lint;&lt;/li&gt;
&lt;li&gt;38 unit tests, including physics against the archive's own insolation and temperature columns, guard tests and the offline evaluation subset;&lt;/li&gt;
&lt;li&gt;GROQ validation (zero violations);&lt;/li&gt;
&lt;li&gt;the Knowledge Base budget (≤ 150);&lt;/li&gt;
&lt;li&gt;the build;&lt;/li&gt;
&lt;li&gt;Playwright plus axe-core on the judge path, desktop and mobile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Code computes, the model explains.&lt;/strong&gt; The output guard is code, not prompt. It rejects an answer if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;any number in it doesn't appear in a dataset or compute result from that turn (Knowledge Base text is never accepted as a number source);&lt;/li&gt;
&lt;li&gt;any document id or Knowledge Base path it cites wasn't read that turn;&lt;/li&gt;
&lt;li&gt;any quote isn't exact.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It retries once with the list of violations, then withholds the answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  What didn't work (from the build log)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The spec's premise was wrong on real data.&lt;/strong&gt; I assumed composite radii would contradict default radii; across 6,375 planets they never do, because the archive keeps the default value whenever it has one. The real mixing is gap-filling (1,573 calculated radii) and minimum-mass to true-mass swaps (100 planets).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;My first flagship, HD 10180 c, fell apart under checking.&lt;/strong&gt; Its composite mass carries a limit flag with no uncertainties, and it has no radius at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The spec's dotted document ids&lt;/strong&gt; (&lt;code&gt;pset.k2-18-b.&amp;lt;ref&amp;gt;&lt;/code&gt;) would have made every document private: Sanity serves ids containing a dot only to authenticated users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context's dataset mode stayed "Not ready" until a Studio was deployed.&lt;/strong&gt; &lt;code&gt;sanity schema deploy&lt;/code&gt; alone wasn't enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The endpoint name was auto-filled from its title&lt;/strong&gt; (&lt;code&gt;default-flag-data&lt;/code&gt;), and it can't be changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context allows one source per dataset&lt;/strong&gt;, so the two planned Knowledge Base queries became one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;My own output guard rejected correct answers three times.&lt;/strong&gt; It read "16th–84th percentile" ordinals as unsourced numbers, then rejected "1240" as a rounding of 1244. Each fix came with a regression test. The first evaluation run is kept in the repo next to the rerun.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A stale &lt;code&gt;next start&lt;/code&gt;&lt;/strong&gt; served HTML pointing at deleted CSS, and my accessibility test "passed" on the unstyled page.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Known limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selection:&lt;/strong&gt; 31 planets and 129 parameter sets, chosen by explicit rules (&lt;code&gt;ingest/data/selection.json&lt;/code&gt;), not a population study.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Albedo:&lt;/strong&gt; fixed Bond albedo of 0.3, a modelling assumption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Habitable zone:&lt;/strong&gt; limits are extrapolated below 2600 K (TRAPPIST-1), and the answer says so.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limit flags:&lt;/strong&gt; the archive's limit-flag sign convention isn't defined in the documentation I snapshotted, so any flagged value is refused.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prose claims:&lt;/strong&gt; the guard checks numbers, ids and quotes, not free-prose claims. One live answer added "detected via radial velocity", which is true but came from the model, not a tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Used Sanity
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Structured content.&lt;/strong&gt; The archive snapshot is modelled so that provenance is a property of the data, not of the prompt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;planet&lt;/code&gt;: references to its &lt;code&gt;parameterSets&lt;/code&gt;, its &lt;code&gt;defaultParameterSet&lt;/code&gt;, and a &lt;code&gt;compositeSnapshot&lt;/code&gt; holding every composite value with its reference, or "Calculated Value".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;parameterSet&lt;/code&gt;: one archive row: values with asymmetric errors and the archive's limit flag, &lt;code&gt;massKind&lt;/code&gt; (Mass or M·sin i), and the stellar solution published &lt;em&gt;with that row&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stellarSolution&lt;/code&gt;, &lt;code&gt;publication&lt;/code&gt;, &lt;code&gt;star&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;snapshot&lt;/code&gt;: raw file, SHA-256, row count, retrieval time.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;constant&lt;/code&gt; / &lt;code&gt;threshold&lt;/code&gt; / &lt;code&gt;hzLimit&lt;/code&gt;: each with its source and the location within it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;derivedAnswer&lt;/code&gt;: every input references its parameter set.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Studio validation and CI GROQ checks enforce one default per planet and single-set inputs for every derived answer. Document ids are deterministic and hyphenated, so the dataset stays anonymously readable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity Context: two MCP endpoints&lt;/strong&gt;, because an endpoint serves one mode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;default-flag-data&lt;/code&gt;&lt;/strong&gt; (dataset/GROQ mode over &lt;code&gt;production&lt;/code&gt;). The agent discovers its tools with &lt;code&gt;tools/list&lt;/code&gt; at runtime and gets &lt;code&gt;initial_context&lt;/code&gt;, &lt;code&gt;schema_explorer&lt;/code&gt;, &lt;code&gt;groq_query&lt;/code&gt; and &lt;code&gt;array_field_reader&lt;/code&gt;. It uses them to find the planet and list its parameter sets. It writes GROQ like &lt;code&gt;*[_type == "planet" &amp;amp;&amp;amp; name match "Kepler-139*"]{defaultParameterSet, "sets": parameterSets[]-&amp;gt;{_id, defaultFlag, "paper": publication-&amp;gt;citation}}&lt;/code&gt;. It then calls the local &lt;code&gt;compute(setId, quantity)&lt;/code&gt; tool, which can only read that one set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;defaultflag-kb&lt;/code&gt;&lt;/strong&gt; (Knowledge Base mode, Knowledge Base &lt;code&gt;kbhX0D4yDJok&lt;/code&gt;), exposing &lt;code&gt;initial_context&lt;/code&gt;, &lt;code&gt;knowledge_base_search&lt;/code&gt; and &lt;code&gt;knowledge_base_read&lt;/code&gt;. It is pointed at:

&lt;ul&gt;
&lt;li&gt;one GROQ query that gives every planet two documents, its default parameter set and its composite row, with matching field names (62 documents);&lt;/li&gt;
&lt;li&gt;six archive documentation pages, uploaded as files: the default-set FAQ, how the composite table is calculated, the table overview, the column definitions, the acknowledgement page, and the DOI page.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's 68 documents against the 150 budget, checked in CI. The agent searches it, then reads entries by path, resolved at runtime because paths change on rebuild. It uses them to explain the rules: why the default set governs, and what a minimum mass means. It never takes a planet value from it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Knowledge Base conflict.&lt;/strong&gt; For Kepler-139 d the two documents disagree: 4.658 M⊕ (M·sin i, Weiss et al. 2024, the default) against 2 M⊕ (Lammers &amp;amp; Winn 2025, composite).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context did not raise it in the Issues tab.&lt;/strong&gt; The Knowledge Base Purpose states the rule: "the self-consistent single-source set governs; composite values are recorded only as explicitly labelled alternatives". The build applied it directly. The planet entries hold a "Default parameter sets (preferred for derived quantities)" table and a separate "Composite table (mixed-source alternatives)" table, and say outright that Kepler-139 d's composite mass differs from its default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyc99ac5gptso11cqk396.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyc99ac5gptso11cqk396.png" alt="Sanity Knowledge Base source editor: a GROQ query over the production dataset selecting each planet's default parameter set and composite row, with a preview showing 62 documents" width="632" height="868"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fomgf0mkqh9p4y8sym1sx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fomgf0mkqh9p4y8sym1sx.png" alt="Built Knowledge Base entry: a 'Default parameter sets (self-consistent, preferred for derived quantities)' table and a separate 'Composite table (mixed-source alternatives)' table, noting that Kepler-139 d's composite mass of 2 Earth masses differs from its default of 4.658" width="642" height="818"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The answer that changed.&lt;/strong&gt; Before that source existed, the Knowledge Base held only methodology and could say nothing about Kepler-139 d. Now, asked "Which mass should I use for Kepler-139 d, and why does the composite table give a different one?", the agent answers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4.66 M⊕ from Weiss et al. 2024;&lt;/li&gt;
&lt;li&gt;the composite's 2 M⊕ comes from a different paper;&lt;/li&gt;
&lt;li&gt;citing &lt;code&gt;kb:parameter_sets/default&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The computed density stays 5.29 g/cm³, by design: numbers come only from the dataset and deterministic code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where the advantage comes from.&lt;/strong&gt; &lt;code&gt;knowledge_base_search&lt;/code&gt; is itself keyword (BM25) search, so the structured agent's edge over the BM25 baseline isn't better Knowledge Base retrieval. It comes from GROQ over typed documents plus a compute tool that can only read one parameter set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity Project Details
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project ID:&lt;/strong&gt; &lt;code&gt;0eu544dk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dataset:&lt;/strong&gt; &lt;code&gt;production&lt;/code&gt; (public read, no token needed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public GROQ query:&lt;/strong&gt; &lt;a href="https://github.com/unicorn-9-spec/default-flag/blob/main/docs/PUBLIC_QUERY.md" rel="noopener noreferrer"&gt;open it in the browser&lt;/a&gt; (the first five planets and their default papers, no token)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted Studio:&lt;/strong&gt; &lt;a href="https://default-flag.sanity.studio" rel="noopener noreferrer"&gt;https://default-flag.sanity.studio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Base:&lt;/strong&gt; &lt;code&gt;kbhX0D4yDJok&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context endpoints:&lt;/strong&gt; &lt;code&gt;default-flag-data&lt;/code&gt; (dataset mode) and &lt;code&gt;defaultflag-kb&lt;/code&gt; (Knowledge Base mode)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No login anywhere on the demo site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent Session
&lt;/h2&gt;

&lt;p&gt;The whole build was done with Claude Code, and every step is in the public build log: prompts that worked, prompts that failed, where it got stuck and how it got unstuck. See &lt;a href="https://github.com/unicorn-9-spec/default-flag/blob/main/docs/BUILD_LOG.md" rel="noopener noreferrer"&gt;docs/BUILD_LOG.md&lt;/a&gt; and the agent/coordinator exchange in &lt;a href="https://github.com/unicorn-9-spec/default-flag/blob/main/docs/REPORT.md" rel="noopener noreferrer"&gt;docs/REPORT.md&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data sources and licences
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;NASA Exoplanet Archive: Planetary Systems (doi:10.26133/NEA12) and Planetary Systems Composite Parameters (doi:10.26133/NEA13) tables, retrieved 2026-10-03, snapshot checksums in the repo.&lt;/li&gt;
&lt;li&gt;Kopparapu et al. 2014 (habitable-zone coefficients, Table 1).&lt;/li&gt;
&lt;li&gt;Rogers 2015 (1.6 R⊕ rocky threshold).&lt;/li&gt;
&lt;li&gt;IAU 2015 Resolution B3 and IAU 2012 Resolution B2 (nominal solar constants, astronomical unit).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This research has made use of the NASA Exoplanet Archive, which is operated by the California Institute of Technology, under contract with the National Aeronautics and Space Administration under the Exoplanet Exploration Program.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>devchallenge</category>
      <category>sanitychallenge</category>
      <category>sanity</category>
      <category>ai</category>
    </item>
    <item>
      <title>Where Need Meets Nothing: finding Florida's aid deserts with Snowflake</title>
      <dc:creator>Saifullah</dc:creator>
      <pubDate>Sun, 06 Sep 2026 22:54:37 +0000</pubDate>
      <link>https://dev.to/saif-uk/where-need-meets-nothing-finding-floridas-aid-deserts-with-snowflake-44p2</link>
      <guid>https://dev.to/saif-uk/where-need-meets-nothing-finding-floridas-aid-deserts-with-snowflake-44p2</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-09-03"&gt;Weekend Challenge: Generosity Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Generosity has a targeting problem. Money follows attention, attention follows disasters, and disasters get covered where the cameras already are. The places that quietly need the most are often the places nobody is looking.&lt;/p&gt;

&lt;p&gt;So I went looking for them. Two Florida counties:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;County&lt;/th&gt;
&lt;th&gt;FEMA disasters (10yr)&lt;/th&gt;
&lt;th&gt;Poverty rate&lt;/th&gt;
&lt;th&gt;Doctors per 10k&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Alachua&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;21.2%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;351.0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Glades&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;17.2%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;20.7&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Alachua has &lt;em&gt;more&lt;/em&gt; disasters and &lt;em&gt;more&lt;/em&gt; poverty than Glades. It also has &lt;strong&gt;17 times the doctor density&lt;/strong&gt;. Alachua contains Gainesville and a teaching hospital. Glades contains the western shore of Lake Okeechobee and not much else.&lt;/p&gt;

&lt;p&gt;That gap is invisible in any single dataset. FEMA knows where the storms landed. The Census knows who is poor. The national provider registry knows where the doctors are. Nobody joins them — so nobody can point at a map and say &lt;em&gt;there, send help there&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aid Desert Finder&lt;/strong&gt; joins those three datasets into one county-level view and ranks all 67 Florida counties by how badly need outruns resources. It answers the question a donor actually has: not "where is it bad," but "where is it bad &lt;strong&gt;and nobody is already there&lt;/strong&gt;."&lt;/p&gt;

&lt;p&gt;The answer for Florida: &lt;strong&gt;9 counties, about 258,000 people&lt;/strong&gt;, averaging 22 disaster declarations in ten years, one in five residents below the poverty line, and roughly half the state's median doctor density.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live map → &lt;a href="https://aid-desert-finder.vercel.app" rel="noopener noreferrer"&gt;https://aid-desert-finder.vercel.app&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F28hkg7stcbuq97oca99c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F28hkg7stcbuq97oca99c.png" alt="Choropleth of Florida's 67 counties coloured by aid-desert need score, with a ranked table alongside" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The panhandle and the rural interior light up. The coasts and the university towns do not.&lt;/p&gt;

&lt;p&gt;Hovering a county — on the map or in the table — dims the rest of the state and pulls up its numbers. The toggle asks the same 67 counties four different questions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faeqyzzu89lino8qqji1w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faeqyzzu89lino8qqji1w.gif" alt="Hovering a county dims the rest of the state and shows its numbers; the toggle recolours the map by doctor density, poverty and disaster count" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Saifullahakjsnd" rel="noopener noreferrer"&gt;
        Saifullahakjsnd
      &lt;/a&gt; / &lt;a href="https://github.com/Saifullahakjsnd/where-need-meets-nothing" rel="noopener noreferrer"&gt;
        where-need-meets-nothing
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Aid Desert Finder - joins FEMA disasters, Census poverty, and NPPES provider data in Snowflake to rank Florida counties where high need meets thin resources
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Where Need Meets Nothing — Aid Desert Finder&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Live map → &lt;a href="https://aid-desert-finder.vercel.app" rel="nofollow noopener noreferrer"&gt;https://aid-desert-finder.vercel.app&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Finds the Florida counties where disaster exposure and poverty are high &lt;em&gt;and&lt;/em&gt; healthcare
resources are thinnest — the places most likely to be overlooked by donors, because attention
follows cameras rather than need.&lt;/p&gt;
&lt;p&gt;Built for the DEV Weekend Challenge: Generosity Edition. Category: &lt;strong&gt;Best Use of Snowflake&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;County&lt;/th&gt;
&lt;th&gt;FEMA disasters (10yr)&lt;/th&gt;
&lt;th&gt;Poverty&lt;/th&gt;
&lt;th&gt;Doctors per 10k&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alachua&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;21.2%&lt;/td&gt;
&lt;td&gt;351.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Glades&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;17.2%&lt;/td&gt;
&lt;td&gt;20.7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Alachua has more disasters and more poverty than Glades, and 17× the doctor density. That gap
is invisible in any one dataset. This joins three of them.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it does&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Ranks all 67 Florida counties on a composite need score — 35% disaster frequency, 35% poverty
rate, 30% scarcity of doctors per capita, each as a percentile rank across the state. The result
is an interactive choropleth plus a natural-language query box.&lt;/p&gt;
&lt;p&gt;Headline finding: &lt;strong&gt;9&lt;/strong&gt;…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Saifullahakjsnd/where-need-meets-nothing" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Everything is there: the SQL that builds the joined view, the Cortex Analyst semantic model, the Streamlit in Snowflake app, and the generator for the standalone page.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Three federal datasets, zero ETL
&lt;/h3&gt;

&lt;p&gt;The whole thing runs on the &lt;strong&gt;Snowflake Public Data (Free)&lt;/strong&gt; Marketplace share. No pipelines, no downloads, no CSVs — three federal datasets already sitting there as queryable views:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FEMA_DISASTER_DECLARATION_AREAS_INDEX&lt;/code&gt; — which counties each declared disaster touched&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AMERICAN_COMMUNITY_SURVEY_TIMESERIES&lt;/code&gt; — ACS poverty and population estimates&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NPPES_PROVIDER_ADDRESSES&lt;/code&gt; — every registered healthcare practitioner's practice location&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What makes the join tractable is that &lt;strong&gt;all three share one &lt;code&gt;GEO_ID&lt;/code&gt; spine&lt;/strong&gt; (Data Commons style — Florida is &lt;code&gt;geoId/12&lt;/code&gt;, Alachua County is &lt;code&gt;geoId/12001&lt;/code&gt;). No FIPS wrangling, no ZIP-to-county crosswalk scraped off a university website. The join is &lt;code&gt;GEO_ID = GEO_ID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Even the map geometry is in there. &lt;code&gt;GEOGRAPHY_CHARACTERISTICS&lt;/code&gt; carries &lt;code&gt;coordinates_geojson&lt;/code&gt; rows — real county polygons — so the choropleth uses &lt;strong&gt;zero external geodata&lt;/strong&gt;. &lt;code&gt;ST_SIMPLIFY&lt;/code&gt; at a 300m tolerance takes 4.5MB of boundaries down to 190KB with no visible difference at state zoom.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asking it in English
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cortex Analyst&lt;/strong&gt; handles the plain-English layer over a deliberately tiny semantic model — one view, six measures. The interesting part is what it does unprompted:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8jjn1og76xr2c0rhs45b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8jjn1og76xr2c0rhs45b.png" alt="Cortex Analyst turning the question " width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asked &lt;em&gt;"Which counties had disasters but fewest doctors?"&lt;/em&gt;, it chose &lt;code&gt;providers_per_10k&lt;/code&gt; over the raw headcount &lt;strong&gt;on its own&lt;/strong&gt; — because the semantic model's description of that field says it's the right one for per-capita questions. Nothing in the question mentioned per-capita anything.&lt;/p&gt;

&lt;p&gt;It generalises past its verified queries too: &lt;em&gt;"more than 1 in 5 people in poverty"&lt;/em&gt; became &lt;code&gt;poverty_rate_pct &amp;gt; 20&lt;/code&gt;, and &lt;em&gt;"show me counties where fewer than 60 doctors per 10k"&lt;/em&gt; composed correctly with it. The whole semantic model is 108 lines of YAML.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three traps that produced convincing wrong answers
&lt;/h3&gt;

&lt;p&gt;The first working version gave numbers that looked entirely plausible and were wrong. Each of these only surfaced by checking output against reality rather than trusting it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Doctors counted twice.&lt;/strong&gt; The provider registry stores three address rows per practitioner — &lt;code&gt;Mailing&lt;/code&gt;, &lt;code&gt;Primary Practice&lt;/code&gt;, &lt;code&gt;Secondary Practice&lt;/code&gt;. Counting all of them credits a doctor to both the county they live in and the county they work in. Gadsden County fell from 542 doctors to 436 once filtered to primary practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Two counties that structurally could not have doctors.&lt;/strong&gt; Union County reported &lt;strong&gt;zero&lt;/strong&gt; practitioners. Not "few" — zero, in a county of 15,700 people. Union has no ZIP children in the geography hierarchy, so a ZIP-based rollup can never assign it anyone. It ranked as a perfect aid desert &lt;em&gt;because it was invisible&lt;/em&gt;. All 67 counties do have city children, so the fix was a city-level fallback. Union actually has 70.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. A view built on temp tables.&lt;/strong&gt; My first draft assembled the join in &lt;code&gt;TEMPORARY&lt;/code&gt; tables and created a view over them. That compiles fine and breaks the moment the session ends.&lt;/p&gt;

&lt;p&gt;The check that caught the rest: county populations sum to &lt;strong&gt;22.4M&lt;/strong&gt; against Florida's actual ~22.6M. Had that been off by millions, something in the join was silently dropping rows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scoring, and one map bug
&lt;/h3&gt;

&lt;p&gt;The composite is a percentile rank across the 67 counties — 35% disaster frequency, 35% poverty rate, 30% scarcity of doctors per capita. Percentile ranks rather than divide-by-max, because Miami-Dade has 85,714 doctors and against that maximum every rural county rounds to zero.&lt;/p&gt;

&lt;p&gt;The same skew bit the map. My first choropleth used equal-interval colour bins, and since Alachua sits at 351 doctors per 10k against a median of 118, nearly every county collapsed into the same two shades. Quantile bins fixed it — each of the seven steps now holds roughly a seventh of the counties, and the distribution is actually readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Honest limits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's one state.&lt;/strong&gt; The geography lookup resolves Florida by name, so another state is a one-line change — but the score is percentile-ranked &lt;em&gt;within&lt;/em&gt; the state, so cross-state comparison needs a different normalisation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Doctor" is doing a lot of work.&lt;/strong&gt; The registry counts every individual practitioner — nurses, therapists, chiropractors. Filtering by taxonomy to primary-care physicians would sharpen this a lot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practice location isn't service area.&lt;/strong&gt; A county with no doctors next door to a hospital is less isolated than one 60 miles from anything. Drive-time isochrones would capture that; county lines don't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disaster counts aren't severity.&lt;/strong&gt; A 22-declaration county might have had 22 minor events. FEMA's public-assistance dollars are in the same share and would weight this properly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Snowflake.&lt;/strong&gt; Three federal datasets joined through the free public data share with no ETL, Cortex Analyst for the natural-language layer, Streamlit in Snowflake for the in-platform app, and the county boundary geometry pulled from the same share so the map needs no external geodata.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Credits: the Cortex Analyst REST call pattern (&lt;code&gt;send_snow_api_request&lt;/code&gt;) is adapted from Snowflake's own &lt;a href="https://github.com/Snowflake-Labs/sfguide-getting-started-with-cortex-analyst" rel="noopener noreferrer"&gt;Cortex Analyst quickstart&lt;/a&gt;. Everything else was written for this challenge, in the challenge window. Built with Claude Code as a pair — it caught trap #2 by questioning a result that looked wrong instead of accepting it. Every figure in this post is a live query result.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>snowflake</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
