<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Le Greffier - A Genie Agent Powered Game in Community Articles</title>
    <link>https://community.databricks.com/t5/community-articles/le-greffier-a-genie-agent-powered-game/m-p/166577#M1467</link>
    <description>&lt;P&gt;In 1929 a Catholic theologian wrote ten rules for detective fiction. Ronald Knox was only half serious. He and Chesterton and Sayers had a dining club for writers of detective fiction and the rules were closer to a party game than a manifesto, but they stuck, because the instinct under them was right. The culprit has to be somebody mentioned early. No poisons unknown to science. And the one that carries the rest: the detective may not conceal from the reader any clue he has found.&lt;/P&gt;&lt;P&gt;That rule is about trust: you were handed everything the detective was handed, at the same moment, and he saw it first. Take the fair play out and the genre collapses into a conjuring trick.&lt;/P&gt;&lt;H2&gt;The idea&lt;/H2&gt;&lt;P&gt;Most apps built on a conversational data agent ask it to conclude — summarise the quarter, tell me which region is underperforming — and the agent obliges, so the noticing happens inside a model and comes back as a finding.&lt;/P&gt;&lt;P&gt;That isn't always what you want. Plenty of regulated work needs the opposite: surface the record, attribute every statement, don't adjudicate. A clerk files. He does not try the case.&lt;/P&gt;&lt;P&gt;So I built an app where the agent refuses to be helpful, and made the refusal the experience.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Le Greffier&lt;/STRONG&gt; is an investigation game. You play the officer reviewing a cold case; the Genie Agent plays the clerk who has custody of the dossier. He'll give you anything in the record, precisely and always attributed, and he won't tell you who did it or whose account is false.&lt;/P&gt;&lt;P&gt;A wine critic is found at the foot of the cellar stairs at a Yvelines estate on the night of the 2023 vendanges, during the reception at which the estate previews its wines, overcome by the carbon dioxide that fermentation throws off, with the extraction fan switched off at the panel and the hazard sign turned to face the wall. Six people were heard, of whom five were upstairs on a timed tasting rotation with stewards logging every arrival and departure. The sixth has forty years of loyal service and no motive anyone can find. It was closed as accidental within months.&lt;/P&gt;&lt;P&gt;It's 2026 and it's been reopened. Everything in that file was written within days of the night itself and nothing has been added since, so the clerk can't chase a detail, can't put a question to a witness, can't tell you what anyone would say now. I'd been treating all of that as constraints I'd have to justify to the player. Making the case cold turned them into facts about the world.&lt;/P&gt;&lt;P&gt;Everything you need is in the file, and nobody is going to assemble it for you.&lt;/P&gt;&lt;H2&gt;Who it's for&lt;/H2&gt;&lt;P&gt;Anyone can play it, with no SQL and no domain knowledge required — if you have ever read a detective novel you already know how to use it.&lt;/P&gt;&lt;P&gt;For builders it's an argument, because the pattern generalises to any setting where an agent should surface records without judging them — disclosure, audit evidence, case files, anywhere that an agent volunteering a conclusion is worse than one that says nothing.&lt;/P&gt;&lt;H2&gt;How it's built&lt;/H2&gt;&lt;P&gt;Eight Delta tables in one Unity Catalog schema — persons heard, locations, a master chronology, the tasting rotation, interview statements, seals, the cellar control panel register, and the estate archive. Around a hundred and thirty rows in total. The content is hand-authored in a seed script, so it version-controls and diffs like code, and I can assert things about it.&lt;/P&gt;&lt;P&gt;Two schema decisions carry the design, and both are about what has been left out.&lt;/P&gt;&lt;P&gt;Interview testimony is decomposed to one row per claim rather than stored as transcript text. Genie generates SQL, and SQL is bad at fuzzy retrieval over paragraphs. Each statement carries a speaker, a claim type, and claimed_location_id, claimed_start and claimed_end — never actual_, so that the schema is honest about its own epistemics and the agent inherits that in how it phrases things.&lt;/P&gt;&lt;P&gt;Nothing in the data adjudicates: there is no column recording culpability, no flag for deception, no contradiction table and no suspicion score, so the solution exists nowhere in the schema and the clerk cannot disclose what he was never given. A persona instruction telling an agent to keep a secret is a request, and requests get talked around, whereas this is a guarantee — the validation script fails the build if a column with a name like that ever appears.&lt;/P&gt;&lt;P&gt;A Genie Agent sits over all eight tables: the clerk's persona in the general instructions, five curated trusted assets for the query shapes players reach for most, and a set of seeded sample questions. The app is a Databricks App with the agent attached as a resource.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Data flow.&lt;/STRONG&gt; There are two paths. The dossier panels down the left query the tables directly through a SQL warehouse, because that is the case file and no model should sit between the player and it, while everything conversational goes through the Genie Agent, which generates SQL against the same tables and returns to the chat panel. The app itself computes nothing and interprets nothing. It's a reading room with a clerk in it.&lt;/P&gt;&lt;P&gt;The dossier is incomplete by design, so that the chronology tab doesn't show the control panel register and the seals tab doesn't show the auditions. Put everything on the left and there is no reason to talk to the clerk, and I have built a PDF with extra steps.&lt;/P&gt;&lt;H2&gt;What you can ask&lt;/H2&gt;&lt;P&gt;The seeded questions sit in an archival register: &lt;EM&gt;what did each person state in their audition&lt;/EM&gt;, rather than &lt;EM&gt;where was so-and-so&lt;/EM&gt;. The phrasing sets expectations before the clerk has to.&lt;/P&gt;&lt;P&gt;Who was heard in this dossier, and what was their connection to Bertrand Aulnay. Show me everything recorded between 21h00 and 22h15. What was placed under seal in or near the cuverie. What access was recorded on the cellar control panel that night. What does the dossier hold on the 1998 vintage.&lt;/P&gt;&lt;P&gt;The good questions are the ones the app never suggests, and the chain that solves the case is two questions long. The panel records a manual shutdown at 21h38 under one man's personal code, never switched back on. His own statement puts his rounds at ten past ten, maybe a little before, he doesn't carry a watch when he's working. Those two facts live in different tables and are never once presented together. Ask for both and you have him, standing at the switch thirty-two minutes before he admits to being anywhere near it.&lt;/P&gt;&lt;P&gt;Knox would have allowed it, because nothing is hidden. You just have to ask.&lt;/P&gt;&lt;H2&gt;What Genie is actually doing&lt;/H2&gt;&lt;P&gt;Remove Genie and there's no app at all, just a static case file and nothing to do with it.&lt;/P&gt;&lt;P&gt;The interrogation is the whole mechanic, and the dossier panels are partial so that conversation is the only route to the rest of the record. Rather than summarising the case or answering questions about it, Genie makes a corpus of structured records addressable in the player's own words, in whatever order they think of, which is roughly what an investigation feels like.&lt;/P&gt;&lt;H2&gt;Learnings&lt;/H2&gt;&lt;P&gt;&lt;STRONG&gt;Streamlit got me a working app in an afternoon and then capped what I could build.&lt;/STRONG&gt; Three things specifically. Its execution model reruns the script on every interaction, so anything with pacing — a stamp landing, a response arriving a beat after the question — has to be fought for rather than written. Its chat component looks like a chat component, and I needed a reading desk. And the styling surface is a CSS block injected into someone else's DOM, which is fine for colours and hopeless for paper texture, ink bleed, or a serif-versus-monospace distinction applied per data type.&lt;/P&gt;&lt;P&gt;I moved to React for the second version, not because Streamlit is bad but because it is the right tool for proving a Genie Agent works rather than for shipping one. Once the case was solvable and the remaining work was atmosphere, I needed control of the DOM, component state that doesn't reset, and CSS I own. The rebuild cost a day, and the app stopped looking like a dashboard wearing a costume.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Genie will resolve a join and then narrate it as fact, even when the column comment forbids exactly that.&lt;/STRONG&gt; fan_control_log.suspect_id is the registered holder of an access code. The comment says so, and says explicitly that it isn't a record of who stood at the panel. Genie read it, joined to persons, and wrote "X turned the panel OFF using access code 4417", because the inference is baked into the join and a prohibition doesn't survive it. What worked was replacing the prohibition with a phrasing template in the instructions — &lt;EM&gt;code 4417, registered to X, was entered at 21h38&lt;/EM&gt; — which is to say, give it the sentence you want rather than the sentence you don't.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;"Everything between X and Y" gets answered from one table, with no signal that the others exist.&lt;/STRONG&gt; I asked for everything recorded in a twenty-minute window and got four chronology entries, which is correct for timeline_events but omits a control panel entry sitting inside that window in another table. Genie had no reason to look there and no way to say it hadn't. The fix was a trusted asset that returns the chronology rows &lt;EM&gt;plus a fixed list of the registers it did not consult&lt;/EM&gt;, so the answer ends by naming the other tables. That turned out to be useful beyond correctness — it's how a player finds the control panel register at all.&lt;/P&gt;&lt;P&gt;Knox's rule about the sidekick is that he shouldn't hide his thoughts from the reader and ought to be a shade duller than average, so nobody feels talked down to. I've ended up somewhere adjacent by the opposite route, with a clerk who isn't dull but hasn't got an opinion, and won't pretend to one to keep you company.&lt;/P&gt;</description>
    <pubDate>Thu, 27 Aug 2026 10:21:43 GMT</pubDate>
    <dc:creator>UstOldfield</dc:creator>
    <dc:date>2026-08-27T10:21:43Z</dc:date>
    <item>
      <title>Le Greffier - A Genie Agent Powered Game</title>
      <link>https://community.databricks.com/t5/community-articles/le-greffier-a-genie-agent-powered-game/m-p/166577#M1467</link>
      <description>&lt;P&gt;In 1929 a Catholic theologian wrote ten rules for detective fiction. Ronald Knox was only half serious. He and Chesterton and Sayers had a dining club for writers of detective fiction and the rules were closer to a party game than a manifesto, but they stuck, because the instinct under them was right. The culprit has to be somebody mentioned early. No poisons unknown to science. And the one that carries the rest: the detective may not conceal from the reader any clue he has found.&lt;/P&gt;&lt;P&gt;That rule is about trust: you were handed everything the detective was handed, at the same moment, and he saw it first. Take the fair play out and the genre collapses into a conjuring trick.&lt;/P&gt;&lt;H2&gt;The idea&lt;/H2&gt;&lt;P&gt;Most apps built on a conversational data agent ask it to conclude — summarise the quarter, tell me which region is underperforming — and the agent obliges, so the noticing happens inside a model and comes back as a finding.&lt;/P&gt;&lt;P&gt;That isn't always what you want. Plenty of regulated work needs the opposite: surface the record, attribute every statement, don't adjudicate. A clerk files. He does not try the case.&lt;/P&gt;&lt;P&gt;So I built an app where the agent refuses to be helpful, and made the refusal the experience.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Le Greffier&lt;/STRONG&gt; is an investigation game. You play the officer reviewing a cold case; the Genie Agent plays the clerk who has custody of the dossier. He'll give you anything in the record, precisely and always attributed, and he won't tell you who did it or whose account is false.&lt;/P&gt;&lt;P&gt;A wine critic is found at the foot of the cellar stairs at a Yvelines estate on the night of the 2023 vendanges, during the reception at which the estate previews its wines, overcome by the carbon dioxide that fermentation throws off, with the extraction fan switched off at the panel and the hazard sign turned to face the wall. Six people were heard, of whom five were upstairs on a timed tasting rotation with stewards logging every arrival and departure. The sixth has forty years of loyal service and no motive anyone can find. It was closed as accidental within months.&lt;/P&gt;&lt;P&gt;It's 2026 and it's been reopened. Everything in that file was written within days of the night itself and nothing has been added since, so the clerk can't chase a detail, can't put a question to a witness, can't tell you what anyone would say now. I'd been treating all of that as constraints I'd have to justify to the player. Making the case cold turned them into facts about the world.&lt;/P&gt;&lt;P&gt;Everything you need is in the file, and nobody is going to assemble it for you.&lt;/P&gt;&lt;H2&gt;Who it's for&lt;/H2&gt;&lt;P&gt;Anyone can play it, with no SQL and no domain knowledge required — if you have ever read a detective novel you already know how to use it.&lt;/P&gt;&lt;P&gt;For builders it's an argument, because the pattern generalises to any setting where an agent should surface records without judging them — disclosure, audit evidence, case files, anywhere that an agent volunteering a conclusion is worse than one that says nothing.&lt;/P&gt;&lt;H2&gt;How it's built&lt;/H2&gt;&lt;P&gt;Eight Delta tables in one Unity Catalog schema — persons heard, locations, a master chronology, the tasting rotation, interview statements, seals, the cellar control panel register, and the estate archive. Around a hundred and thirty rows in total. The content is hand-authored in a seed script, so it version-controls and diffs like code, and I can assert things about it.&lt;/P&gt;&lt;P&gt;Two schema decisions carry the design, and both are about what has been left out.&lt;/P&gt;&lt;P&gt;Interview testimony is decomposed to one row per claim rather than stored as transcript text. Genie generates SQL, and SQL is bad at fuzzy retrieval over paragraphs. Each statement carries a speaker, a claim type, and claimed_location_id, claimed_start and claimed_end — never actual_, so that the schema is honest about its own epistemics and the agent inherits that in how it phrases things.&lt;/P&gt;&lt;P&gt;Nothing in the data adjudicates: there is no column recording culpability, no flag for deception, no contradiction table and no suspicion score, so the solution exists nowhere in the schema and the clerk cannot disclose what he was never given. A persona instruction telling an agent to keep a secret is a request, and requests get talked around, whereas this is a guarantee — the validation script fails the build if a column with a name like that ever appears.&lt;/P&gt;&lt;P&gt;A Genie Agent sits over all eight tables: the clerk's persona in the general instructions, five curated trusted assets for the query shapes players reach for most, and a set of seeded sample questions. The app is a Databricks App with the agent attached as a resource.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Data flow.&lt;/STRONG&gt; There are two paths. The dossier panels down the left query the tables directly through a SQL warehouse, because that is the case file and no model should sit between the player and it, while everything conversational goes through the Genie Agent, which generates SQL against the same tables and returns to the chat panel. The app itself computes nothing and interprets nothing. It's a reading room with a clerk in it.&lt;/P&gt;&lt;P&gt;The dossier is incomplete by design, so that the chronology tab doesn't show the control panel register and the seals tab doesn't show the auditions. Put everything on the left and there is no reason to talk to the clerk, and I have built a PDF with extra steps.&lt;/P&gt;&lt;H2&gt;What you can ask&lt;/H2&gt;&lt;P&gt;The seeded questions sit in an archival register: &lt;EM&gt;what did each person state in their audition&lt;/EM&gt;, rather than &lt;EM&gt;where was so-and-so&lt;/EM&gt;. The phrasing sets expectations before the clerk has to.&lt;/P&gt;&lt;P&gt;Who was heard in this dossier, and what was their connection to Bertrand Aulnay. Show me everything recorded between 21h00 and 22h15. What was placed under seal in or near the cuverie. What access was recorded on the cellar control panel that night. What does the dossier hold on the 1998 vintage.&lt;/P&gt;&lt;P&gt;The good questions are the ones the app never suggests, and the chain that solves the case is two questions long. The panel records a manual shutdown at 21h38 under one man's personal code, never switched back on. His own statement puts his rounds at ten past ten, maybe a little before, he doesn't carry a watch when he's working. Those two facts live in different tables and are never once presented together. Ask for both and you have him, standing at the switch thirty-two minutes before he admits to being anywhere near it.&lt;/P&gt;&lt;P&gt;Knox would have allowed it, because nothing is hidden. You just have to ask.&lt;/P&gt;&lt;H2&gt;What Genie is actually doing&lt;/H2&gt;&lt;P&gt;Remove Genie and there's no app at all, just a static case file and nothing to do with it.&lt;/P&gt;&lt;P&gt;The interrogation is the whole mechanic, and the dossier panels are partial so that conversation is the only route to the rest of the record. Rather than summarising the case or answering questions about it, Genie makes a corpus of structured records addressable in the player's own words, in whatever order they think of, which is roughly what an investigation feels like.&lt;/P&gt;&lt;H2&gt;Learnings&lt;/H2&gt;&lt;P&gt;&lt;STRONG&gt;Streamlit got me a working app in an afternoon and then capped what I could build.&lt;/STRONG&gt; Three things specifically. Its execution model reruns the script on every interaction, so anything with pacing — a stamp landing, a response arriving a beat after the question — has to be fought for rather than written. Its chat component looks like a chat component, and I needed a reading desk. And the styling surface is a CSS block injected into someone else's DOM, which is fine for colours and hopeless for paper texture, ink bleed, or a serif-versus-monospace distinction applied per data type.&lt;/P&gt;&lt;P&gt;I moved to React for the second version, not because Streamlit is bad but because it is the right tool for proving a Genie Agent works rather than for shipping one. Once the case was solvable and the remaining work was atmosphere, I needed control of the DOM, component state that doesn't reset, and CSS I own. The rebuild cost a day, and the app stopped looking like a dashboard wearing a costume.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Genie will resolve a join and then narrate it as fact, even when the column comment forbids exactly that.&lt;/STRONG&gt; fan_control_log.suspect_id is the registered holder of an access code. The comment says so, and says explicitly that it isn't a record of who stood at the panel. Genie read it, joined to persons, and wrote "X turned the panel OFF using access code 4417", because the inference is baked into the join and a prohibition doesn't survive it. What worked was replacing the prohibition with a phrasing template in the instructions — &lt;EM&gt;code 4417, registered to X, was entered at 21h38&lt;/EM&gt; — which is to say, give it the sentence you want rather than the sentence you don't.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;"Everything between X and Y" gets answered from one table, with no signal that the others exist.&lt;/STRONG&gt; I asked for everything recorded in a twenty-minute window and got four chronology entries, which is correct for timeline_events but omits a control panel entry sitting inside that window in another table. Genie had no reason to look there and no way to say it hadn't. The fix was a trusted asset that returns the chronology rows &lt;EM&gt;plus a fixed list of the registers it did not consult&lt;/EM&gt;, so the answer ends by naming the other tables. That turned out to be useful beyond correctness — it's how a player finds the control panel register at all.&lt;/P&gt;&lt;P&gt;Knox's rule about the sidekick is that he shouldn't hide his thoughts from the reader and ought to be a shade duller than average, so nobody feels talked down to. I've ended up somewhere adjacent by the opposite route, with a clerk who isn't dull but hasn't got an opinion, and won't pretend to one to keep you company.&lt;/P&gt;</description>
      <pubDate>Thu, 27 Aug 2026 10:21:43 GMT</pubDate>
      <guid>https://community.databricks.com/t5/community-articles/le-greffier-a-genie-agent-powered-game/m-p/166577#M1467</guid>
      <dc:creator>UstOldfield</dc:creator>
      <dc:date>2026-08-27T10:21:43Z</dc:date>
    </item>
  </channel>
</rss>

