<?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: Chathusha Mendis</title>
    <description>The latest articles on DEV Community by Chathusha Mendis (@mendisofficial).</description>
    <link>https://dev.to/mendisofficial</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%2F2945731%2Fd73a77b5-5d47-40b9-a966-8f52f7d9322c.jpg</url>
      <title>DEV Community: Chathusha Mendis</title>
      <link>https://dev.to/mendisofficial</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mendisofficial"/>
    <language>en</language>
    <item>
      <title>StallSheet: a Sunday price desk that does not let the model invent the price</title>
      <dc:creator>Chathusha Mendis</dc:creator>
      <pubDate>Wed, 14 Oct 2026 16:18:55 +0000</pubDate>
      <link>https://dev.to/mendisofficial/stallsheet-a-sunday-price-desk-that-does-not-let-the-model-invent-the-price-50ne</link>
      <guid>https://dev.to/mendisofficial/stallsheet-a-sunday-price-desk-that-does-not-let-the-model-invent-the-price-50ne</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;StallSheet&lt;/strong&gt; is a Sunday-morning desk for a home baker or craft-stall seller.&lt;/p&gt;

&lt;p&gt;They keep a small history of what they made, what they charged, and what actually sold. The app tells them what to bake this weekend, what to charge, and hands them price tags plus a caption they can post.&lt;/p&gt;

&lt;p&gt;Someone would pay for this because over-prep wastes ingredients and under-prep loses the day's profit. A general chatbot is a bad fit. The useful part is a forecast on a few dozen of &lt;em&gt;their&lt;/em&gt; rows, and those rows include margins they should not have to paste into a closed chat log.&lt;/p&gt;

&lt;p&gt;The demo stall is Hearth &amp;amp; Rye, a fictional bakery with twelve Saturdays of history stored on Tiger Cloud. A constraint such as "I only have enough butter for 18 cinnamon buns" caps that item before anything is written down.&lt;/p&gt;

&lt;p&gt;The model writes. The forecast counts. Gemma is not allowed to invent a price.&lt;/p&gt;

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

&lt;p&gt;Clone the repo, copy &lt;code&gt;.env.example&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt;, and point &lt;code&gt;DATABASE_URL&lt;/code&gt; at a Postgres database with pgvector (the project runs against Tiger Cloud). Add a TabPFN token and a Gemma key, then &lt;code&gt;npm start&lt;/code&gt; and open &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On a sunny Saturday in Portland, with the butter constraint, TabPFN-3.5 priced cinnamon buns at $5.00 and capped the bake at 18. Gemma wrote the caption: "Enjoy the sunny Portland weather at the market. Our cinnamon bun supply is limited by the butter available." The price tags on the page came from the forecast, not from that sentence.&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/mendisofficial" rel="noopener noreferrer"&gt;
        mendisofficial
      &lt;/a&gt; / &lt;a href="https://github.com/mendisofficial/stallsheet" rel="noopener noreferrer"&gt;
        stallsheet
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      StallSheet is a Sunday-morning desk for a home baker or craft-stall seller.
    &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;StallSheet&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;StallSheet is a Sunday-morning desk for a home baker or craft-stall seller. Upload a small sales history and it tells you what to make, what to charge, and gives you a caption you can post.&lt;/p&gt;
&lt;p&gt;The numbers come from a forecast. Gemma only writes the words, and the server throws away any price the model tries to slip into the caption.&lt;/p&gt;
&lt;p&gt;This is a new project for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12" rel="nofollow"&gt;Hacktoberfest Open-Source AI Challenge: Week 2&lt;/a&gt; (Side Hustle).&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why someone would pay&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Over-prep wastes ingredients. Under-prep loses the day's profit. A general chatbot is a poor fit: the useful part is a prediction on a few dozen of the seller's own rows, and those rows include margins they do not want in a closed chat log.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How a sheet is built&lt;/h2&gt;
&lt;/div&gt;

  &lt;div class="js-render-enrichment-target"&gt;
    &lt;div class="render-plaintext-hidden"&gt;
      &lt;pre&gt;flowchart LR
  csv[Sales CSV] --&amp;gt; tiger[Postgres with pgvector]
  tiger --&amp;gt; tabpfn[TabPFN 3.5]
  tiger --&amp;gt; similar[Similar weekends]
  events[SerpApi events] --&amp;gt; confirm[Seller&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mendisofficial/stallsheet" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;One Mastra workflow, pinned at &lt;code&gt;@mastra/core&lt;/code&gt; 1.77.0 and &lt;code&gt;@mastra/libsql&lt;/code&gt; 1.26.1. It suspends so the seller can change quantities before the sheet is written. Snapshots sit in a local LibSQL file, so that pause survives a restart of the process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sales live in Tiger Cloud. A hashed bag-of-words embedding stays in Postgres, so notes are not sent to an embedding API. Hybrid search fuses that pgvector rank with keyword rank. If &lt;code&gt;pg_textsearch&lt;/code&gt; is installed, the keyword side is BM25. Otherwise it uses &lt;code&gt;tsvector&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;TabPFN-3.5 (&lt;code&gt;v3.5_default&lt;/code&gt;) predicts &lt;code&gt;qty_sold&lt;/code&gt; at each price the seller has actually charged. Expected revenue, the chosen price, and the quantity are computed in code.&lt;/li&gt;
&lt;li&gt;The workflow suspends on &lt;code&gt;confirm-quantities&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Gemma (&lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt; through Google's OpenAI-compatible endpoint) writes the prep list and the caption. Dollar amounts are stripped from the caption. The price tags are printed from the forecast.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Saving the finished sheet uses the Mastra run id as an idempotency key. A restarted step can run a side effect twice. &lt;a href="https://dev.to/devopsdaily/we-built-an-on-call-agent-in-mastra-where-it-won-and-where-it-would-not-obi"&gt;DevOps Daily measured that on an on-call agent&lt;/a&gt;: recovery is at-least-once, and the fix is a key that survives the restart.&lt;/p&gt;

&lt;p&gt;I did not build another freelance quote writer. &lt;a href="https://dev.to/ishaanchowdhury_ic10/briefbill-turning-vague-client-briefs-into-clear-freelance-quotes-with-local-gemma-3-448h"&gt;BriefBill&lt;/a&gt; already turns a messy brief into a proposal with Gemma 3, and it keeps the money in ordinary code. StallSheet keeps that rule and puts the forecast in TabPFN.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;The sales table stays on a Postgres database the seller can point at themselves. The embedding never leaves it. Gemma is an open-weight model behind a swappable endpoint, so a Sunday sheet does not depend on one vendor's closed chat API. That closed API would bill every weekend and keep a copy of the margins. TabPFN is the part a general model is bad at: a few dozen rows from this stall, not the internet.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma.&lt;/strong&gt; &lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt; writes the prep list and the caption. Prices are removed from that text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of TabPFN.&lt;/strong&gt; TabPFN-3.5 regresses &lt;code&gt;qty_sold&lt;/code&gt; inside the Mastra workflow. The dollars are computed in code from that forecast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Mastra.&lt;/strong&gt; The confirm step is a real suspend and resume, pinned at Mastra 1.77.0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Tiger Data.&lt;/strong&gt; Sales and the finished sheet are stored on Tiger Cloud, with pgvector hybrid search over past weekends.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
