<?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: Tuấn Trần</title>
    <description>The latest articles on DEV Community by Tuấn Trần (@zuratran).</description>
    <link>https://dev.to/zuratran</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%2F4160694%2F37576ae3-7483-4097-ac06-dd3623142180.jpg</url>
      <title>DEV Community: Tuấn Trần</title>
      <link>https://dev.to/zuratran</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zuratran"/>
    <language>en</language>
    <item>
      <title>WhatBin: Source-Backed Waste Guidance with Sanity Context MCP</title>
      <dc:creator>Tuấn Trần</dc:creator>
      <pubDate>Sun, 04 Oct 2026 07:52:38 +0000</pubDate>
      <link>https://dev.to/zuratran/whatbin-source-backed-waste-guidance-with-sanity-context-mcp-5dha</link>
      <guid>https://dev.to/zuratran/whatbin-source-backed-waste-guidance-with-sanity-context-mcp-5dha</guid>
      <description>&lt;p&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;/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%2Fdtmwlneweowahnjf1d4p.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%2Fdtmwlneweowahnjf1d4p.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;WhatBin helps people in Hanoi and Ho Chi Minh City figure out how to dispose of household items properly.&lt;/p&gt;

&lt;p&gt;It sounds like a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How should I dispose of this?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the answer can get complicated pretty quickly.&lt;/p&gt;

&lt;p&gt;An old mattress, a household battery, and a broken fluorescent tube all need different handling. The answer can also change depending on the city and which local rules are currently in effect.&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%2F2cfdbhjz9aj6qz35ox4v.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%2F2cfdbhjz9aj6qz35ox4v.png" alt=" " width="799" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built WhatBin to make that process easier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Describe an item or upload a photo.&lt;/li&gt;
&lt;li&gt;Choose Hanoi or Ho Chi Minh City and confirm the identified item.&lt;/li&gt;
&lt;li&gt;See the reviewed disposal guidance and the sources behind it.&lt;/li&gt;
&lt;li&gt;Ask follow-up questions about the evidence or compare the same item between the two cities.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One decision shaped most of the project: the AI should explain the guidance, not decide what the guidance is.&lt;/p&gt;

&lt;p&gt;Published content in Sanity determines which disposal instruction applies. A server-side agent uses Sanity Context MCP to retrieve the supporting evidence and explain the result.&lt;/p&gt;

&lt;p&gt;It cannot replace the reviewed instruction with its own recommendation.&lt;/p&gt;

&lt;p&gt;WhatBin can return three results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MATCHED&lt;/strong&gt; — there is a reviewed rule for this item, city, and date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UNKNOWN&lt;/strong&gt; — WhatBin does not currently have enough reviewed content for this combination.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CONFLICT&lt;/strong&gt; — there is an unresolved conflict or overlap between active records.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;code&gt;UNKNOWN&lt;/code&gt; and &lt;code&gt;CONFLICT&lt;/code&gt;, WhatBin does not show a disposal instruction.&lt;/p&gt;

&lt;p&gt;I think this is important. Missing coverage does not mean there is no valid disposal route. It only means WhatBin does not have enough reviewed information to give one.&lt;/p&gt;

&lt;p&gt;The goal was never to make the agent answer everything. I wanted the app to make it clear when the evidence supports an answer and when it does not.&lt;/p&gt;




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

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

&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://bin.zura.tr" rel="noopener noreferrer"&gt;https://bin.zura.tr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;English&lt;/strong&gt; from the language menu in the top-right corner.&lt;/p&gt;

&lt;p&gt;A good example to start with is an old mattress.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose Hanoi and confirm the item.&lt;/li&gt;
&lt;li&gt;Open the disposal guidance and source links.&lt;/li&gt;
&lt;li&gt;Ask: &lt;strong&gt;"Why does this rule apply?"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Then ask: &lt;strong&gt;"How does this differ in Ho Chi Minh City?"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This example shows why location and source history matter.&lt;/p&gt;

&lt;p&gt;The reviewed mattress guidance for Hanoi is different from the guidance for Ho Chi Minh City. In Ho Chi Minh City, a later decision also removed provisions related to local collection-point arrangements.&lt;/p&gt;

&lt;p&gt;WhatBin does not try to fill that gap by making up an address, collection schedule, or fee.&lt;/p&gt;

&lt;p&gt;You can also try:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a used household battery&lt;/li&gt;
&lt;li&gt;a standalone rechargeable lithium-ion battery&lt;/li&gt;
&lt;li&gt;a fluorescent lamp&lt;/li&gt;
&lt;li&gt;a mercury thermometer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are useful examples because item identification matters too. A standalone lithium-ion battery, for example, should not automatically be treated the same way as an entire power bank.&lt;/p&gt;

&lt;p&gt;The video also shows what happens when WhatBin cannot safely return a disposal instruction.&lt;/p&gt;

&lt;p&gt;Instead of asking the model to improvise, the system keeps the result as &lt;code&gt;UNKNOWN&lt;/code&gt; or &lt;code&gt;CONFLICT&lt;/code&gt;.&lt;/p&gt;


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

&lt;p&gt;&lt;strong&gt;GitHub repository:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/Zura1555/whatbin" rel="noopener noreferrer"&gt;https://github.com/Zura1555/whatbin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A browser UI for text input, photos, item confirmation, and follow-up questions.&lt;/li&gt;
&lt;li&gt;A Node.js API for item recognition, deterministic rule resolution, and streamed explanations.&lt;/li&gt;
&lt;li&gt;Sanity Studio for managing reviewed rules, supporting evidence, and conflicts.&lt;/li&gt;
&lt;li&gt;An explanation agent built with the AI SDK and &lt;code&gt;@ai-sdk/mcp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main MCP integration is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Zura1555/whatbin/blob/main/app/context-agent.mjs" rel="noopener noreferrer"&gt;https://github.com/Zura1555/whatbin/blob/main/app/context-agent.mjs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Sanity content models are here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Zura1555/whatbin/tree/main/studio/schemaTypes" rel="noopener noreferrer"&gt;https://github.com/Zura1555/whatbin/tree/main/studio/schemaTypes&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  How I Used Sanity
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Sanity holds the reviewed decision model
&lt;/h3&gt;

&lt;p&gt;I am not using Sanity only as a place to store text for the LLM to search.&lt;/p&gt;

&lt;p&gt;The records in Sanity decide whether WhatBin is allowed to show disposal guidance in the first place.&lt;/p&gt;

&lt;p&gt;Each &lt;code&gt;disposalRule&lt;/code&gt; contains information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;canonical item ID&lt;/li&gt;
&lt;li&gt;human-readable item name&lt;/li&gt;
&lt;li&gt;jurisdiction&lt;/li&gt;
&lt;li&gt;disposal category&lt;/li&gt;
&lt;li&gt;reviewed instruction&lt;/li&gt;
&lt;li&gt;effective start date&lt;/li&gt;
&lt;li&gt;optional end date&lt;/li&gt;
&lt;li&gt;official source references&lt;/li&gt;
&lt;li&gt;article or clause citations&lt;/li&gt;
&lt;li&gt;supporting passages&lt;/li&gt;
&lt;li&gt;source versions&lt;/li&gt;
&lt;li&gt;related sources needed to understand the evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means the application can work out whether a rule applies before the explanation agent runs.&lt;/p&gt;

&lt;p&gt;The model does not have to infer applicability from a collection of loosely related paragraphs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Source roles matter
&lt;/h3&gt;

&lt;p&gt;I also keep different source roles separate.&lt;/p&gt;

&lt;p&gt;For example, a source can represent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a binding rule&lt;/li&gt;
&lt;li&gt;an agency clarification&lt;/li&gt;
&lt;li&gt;a record used to confirm whether another source is still current&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters because an official logistics note may be useful evidence, but that does not automatically make it equivalent to a binding disposal requirement.&lt;/p&gt;
&lt;h3&gt;
  
  
  Currentness is handled before the agent runs
&lt;/h3&gt;

&lt;p&gt;The resolver reads published content only and checks each rule against the selected city's local date.&lt;/p&gt;

&lt;p&gt;Draft rules do not count.&lt;/p&gt;

&lt;p&gt;Future rules do not count yet.&lt;/p&gt;

&lt;p&gt;Expired rules no longer authorize current guidance.&lt;/p&gt;

&lt;p&gt;This part is handled in normal application logic rather than by the LLM.&lt;/p&gt;


&lt;h2&gt;
  
  
  What I Pointed Sanity Context At
&lt;/h2&gt;

&lt;p&gt;I pointed Sanity Context at the structured content in my own Sanity project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project ID:&lt;/strong&gt; &lt;code&gt;xqeddep2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dataset:&lt;/strong&gt; &lt;code&gt;production&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dataset visibility:&lt;/strong&gt; Public published content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Base:&lt;/strong&gt; &lt;code&gt;WhatBin disposal guidance.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Base ID:&lt;/strong&gt; &lt;code&gt;kbvvvJAbi13v&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context source:&lt;/strong&gt; Sanity dataset import&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Knowledge Base has a dataset import using this GROQ projection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*[_type in ["disposalRule", "disposalConflict"]]{
  _id,
  _type,
  canonicalItemId,
  jurisdiction,
  validFrom,
  validUntil,
  itemName,
  disposalCategory,
  instruction,
  sourceReferences,
  supportingPassages,
  summary,
  claims
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configured import currently reports &lt;strong&gt;10 successfully distilled documents&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The agent works with WhatBin's structured rule and conflict records, including their source references and curated supporting passages.&lt;/p&gt;

&lt;p&gt;I did not separately import every linked government website or PDF into the Knowledge Base.&lt;/p&gt;

&lt;p&gt;Instead, the Sanity records keep the source URLs, citations, source versions, and relevant passages needed to explain where the reviewed guidance came from.&lt;/p&gt;




&lt;h2&gt;
  
  
  How the Agent Uses Sanity Context MCP
&lt;/h2&gt;

&lt;p&gt;The server connects to the Sanity Context MCP endpoint over HTTPS using a server-side Context Viewer token.&lt;/p&gt;

&lt;p&gt;When someone asks for an explanation, the integration checks which MCP tools are available and follows a controlled retrieval sequence.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;How WhatBin uses it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;initial_context&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Establishes the endpoint context first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;knowledge_base_read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reads Knowledge Base content when available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;schema_explorer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspects the Sanity content structure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;groq_query&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Queries relevant structured records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;array_field_reader&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reads nested fields when needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The exact sequence depends on the tools exposed by the endpoint.&lt;/p&gt;

&lt;p&gt;For required steps, I expose only the tool needed for that step. This prevents the model from skipping ahead and choosing another retrieval method simply because it is available.&lt;/p&gt;

&lt;p&gt;Before starting an explanation, the server resolves the selected item and city again.&lt;/p&gt;

&lt;p&gt;The agent receives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user's question&lt;/li&gt;
&lt;li&gt;a limited amount of conversation history&lt;/li&gt;
&lt;li&gt;the selected item&lt;/li&gt;
&lt;li&gt;the relevant city&lt;/li&gt;
&lt;li&gt;the date&lt;/li&gt;
&lt;li&gt;the verified resolver result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It then retrieves evidence for that specific scope.&lt;/p&gt;

&lt;p&gt;The agent does not decide which disposal rule should apply.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Agent Does With the Evidence
&lt;/h2&gt;

&lt;p&gt;For a &lt;code&gt;MATCHED&lt;/code&gt; result, the agent explains why the reviewed rule applies and which evidence supports it.&lt;/p&gt;

&lt;p&gt;For a &lt;code&gt;CONFLICT&lt;/code&gt;, it can explain the competing claims and their citations, but it cannot choose which one is correct.&lt;/p&gt;

&lt;p&gt;For an &lt;code&gt;UNKNOWN&lt;/code&gt;, it explains that WhatBin does not currently have enough reviewed coverage.&lt;/p&gt;

&lt;p&gt;It does not invent a fallback disposal route.&lt;/p&gt;

&lt;p&gt;The agent can cite source titles and article or clause names in its explanation.&lt;/p&gt;

&lt;p&gt;Verified URLs are displayed separately by the app rather than generated by the model.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparing Hanoi and Ho Chi Minh City
&lt;/h2&gt;

&lt;p&gt;WhatBin only allows a clean cross-city comparison when the same item independently resolves to &lt;code&gt;MATCHED&lt;/code&gt; in both cities.&lt;/p&gt;

&lt;p&gt;The Hanoi result and the Ho Chi Minh City result are resolved separately.&lt;/p&gt;

&lt;p&gt;The agent cannot take a valid Hanoi rule and treat it as valid guidance for Ho Chi Minh City.&lt;/p&gt;

&lt;p&gt;If one city returns &lt;code&gt;UNKNOWN&lt;/code&gt;, that uncertainty stays visible.&lt;/p&gt;

&lt;p&gt;If one city returns &lt;code&gt;CONFLICT&lt;/code&gt;, the agent can explain the conflict but does not turn it into a confident answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Main Result Does Not Depend on the LLM
&lt;/h2&gt;

&lt;p&gt;I also wanted the reviewed disposal result to remain usable when the AI explanation layer is unavailable.&lt;/p&gt;

&lt;p&gt;If the model provider or Sanity Context service fails, an existing &lt;code&gt;MATCHED&lt;/code&gt; result still works.&lt;/p&gt;

&lt;p&gt;Users can still see the reviewed instruction and direct source links. They only lose the additional explanation.&lt;/p&gt;

&lt;p&gt;An LLM outage should not make already reviewed guidance disappear.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Keyword Search Wasn't Enough
&lt;/h2&gt;

&lt;p&gt;Finding a paragraph containing the word "mattress" does not tell me whether that paragraph should be shown to someone in Hanoi today.&lt;/p&gt;

&lt;p&gt;There are still several questions to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does it apply to Hanoi or Ho Chi Minh City?&lt;/li&gt;
&lt;li&gt;When did it become effective?&lt;/li&gt;
&lt;li&gt;Has it expired?&lt;/li&gt;
&lt;li&gt;Was it changed by a later decision?&lt;/li&gt;
&lt;li&gt;What type of source is it?&lt;/li&gt;
&lt;li&gt;Is there an active conflict recorded by a reviewer?&lt;/li&gt;
&lt;li&gt;Is it actually about the same item?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These relationships are represented directly in Sanity.&lt;/p&gt;

&lt;p&gt;Canonical item IDs prevent similar products from automatically being treated as the same thing.&lt;/p&gt;

&lt;p&gt;Jurisdictions keep local rules separate.&lt;/p&gt;

&lt;p&gt;Effective dates distinguish current guidance from future or expired content.&lt;/p&gt;

&lt;p&gt;Source roles and supporting passages make the basis of the guidance easier to inspect.&lt;/p&gt;

&lt;p&gt;Conflict records make disagreement explicit instead of hiding it behind a confident AI answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Handling Conflicting Evidence
&lt;/h2&gt;

&lt;p&gt;Conflicts have their own Sanity document type: &lt;code&gt;disposalConflict&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A conflict can contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the affected item&lt;/li&gt;
&lt;li&gt;jurisdiction&lt;/li&gt;
&lt;li&gt;competing claims&lt;/li&gt;
&lt;li&gt;source URLs&lt;/li&gt;
&lt;li&gt;source versions&lt;/li&gt;
&lt;li&gt;exact citations&lt;/li&gt;
&lt;li&gt;review status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A published active conflict takes priority over an otherwise matching disposal rule.&lt;/p&gt;

&lt;p&gt;The agent can explain the different claims and where they came from.&lt;/p&gt;

&lt;p&gt;It cannot decide which claim wins.&lt;/p&gt;

&lt;p&gt;That remains a human review decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  Research and Publication Are Separate
&lt;/h2&gt;

&lt;p&gt;Sanity Studio also includes a source-research workflow for coverage gaps.&lt;/p&gt;

&lt;p&gt;The workflow can help an editor investigate possible sources and produce a preview or gap report.&lt;/p&gt;

&lt;p&gt;It does not automatically publish the result as disposal guidance.&lt;/p&gt;

&lt;p&gt;A human still has to review the evidence and publish the record.&lt;/p&gt;

&lt;p&gt;I wanted to keep that boundary clear because finding a potentially relevant source and deciding that residents should act on it are two different things.&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;xqeddep2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dataset:&lt;/strong&gt; &lt;code&gt;production&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dataset visibility:&lt;/strong&gt; Public published content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content models:&lt;/strong&gt; &lt;code&gt;disposalRule&lt;/code&gt;, &lt;code&gt;disposalConflict&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Base:&lt;/strong&gt; &lt;code&gt;WhatBin disposal guidance.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Base ID:&lt;/strong&gt; &lt;code&gt;kbvvvJAbi13v&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context source:&lt;/strong&gt; Sanity dataset import&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can inspect published disposal rules through the public Sanity API:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://xqeddep2.api.sanity.io/v2025-02-19/data/query/production?query=*%5B_type%20%3D%3D%20%22disposalRule%22%5D%7BcanonicalItemId%2Cjurisdiction%2CvalidFrom%2CvalidUntil%7D" rel="noopener noreferrer"&gt;https://xqeddep2.api.sanity.io/v2025-02-19/data/query/production?query=*%5B_type%20%3D%3D%20%22disposalRule%22%5D%7BcanonicalItemId%2Cjurisdiction%2CvalidFrom%2CvalidUntil%7D&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository also contains the schemas, resolver, MCP integration, and the architecture behind the separation between reviewed guidance and agent-generated explanations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Notes
&lt;/h2&gt;

&lt;p&gt;The most important design question for me was not how much the agent could do.&lt;/p&gt;

&lt;p&gt;It was what I should &lt;em&gt;not&lt;/em&gt; let it do.&lt;/p&gt;

&lt;p&gt;WhatBin does not ask the model to decide which disposal instruction is legally or operationally correct for a resident.&lt;/p&gt;

&lt;p&gt;That decision comes from reviewed and published Sanity content plus deterministic application logic.&lt;/p&gt;

&lt;p&gt;The agent has a smaller job: retrieve the relevant evidence and explain it in a way that is easier to understand.&lt;/p&gt;

&lt;p&gt;And when WhatBin does not have enough reviewed evidence, it says so.&lt;/p&gt;

&lt;p&gt;Sometimes &lt;code&gt;UNKNOWN&lt;/code&gt; is the better answer.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>sanitychallenge</category>
      <category>sanity</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
