<?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: Zachariah M</title>
    <description>The latest articles on DEV Community by Zachariah M (@zachariah_m).</description>
    <link>https://dev.to/zachariah_m</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%2F4185555%2Fc4f273f9-e33f-4aa2-b629-699419ecd504.png</url>
      <title>DEV Community: Zachariah M</title>
      <link>https://dev.to/zachariah_m</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zachariah_m"/>
    <language>en</language>
    <item>
      <title>A calculator tool should return its assumptions, not just a payback number</title>
      <dc:creator>Zachariah M</dc:creator>
      <pubDate>Tue, 27 Oct 2026 18:02:00 +0000</pubDate>
      <link>https://dev.to/zachariah_m/a-calculator-tool-should-return-its-assumptions-not-just-a-payback-number-3mag</link>
      <guid>https://dev.to/zachariah_m/a-calculator-tool-should-return-its-assumptions-not-just-a-payback-number-3mag</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: Prepared with AI assistance from the current implementation and live checks using fictional inputs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We exposed Aplos's automation-budget arithmetic as a small MCP tool. The useful design decision was separating cash expenditure from the assigned value of people's time.&lt;/p&gt;

&lt;p&gt;Those values can be added in a model, but they should not be presented as the same thing. A workflow might free staff capacity while leaving payroll unchanged.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make the assumptions explicit
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;calculate_automation_budget&lt;/code&gt; tool accepts seven numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"setup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rollout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"software"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"support"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"review"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hours"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;setup&lt;/code&gt; is the one-time cash cost. &lt;code&gt;rollout&lt;/code&gt; is internal rollout time in hours. &lt;code&gt;software&lt;/code&gt; and &lt;code&gt;support&lt;/code&gt; are monthly cash costs. &lt;code&gt;review&lt;/code&gt; is monthly review and maintenance time. &lt;code&gt;rate&lt;/code&gt; assigns a value to an hour, and &lt;code&gt;hours&lt;/code&gt; is gross monthly time expected to be freed.&lt;/p&gt;

&lt;p&gt;Every input is required. Use zero for an inapplicable cost, and use one currency consistently. The tool validates finite numbers from zero to one million and rejects additional fields. That keeps a caller from silently supplying an unsupported tax rate or another assumption the calculation ignores.&lt;/p&gt;

&lt;h3&gt;
  
  
  Return the components
&lt;/h3&gt;

&lt;p&gt;For the example above, the calculation is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Monthly cash cost = 200 + 100 = 300
Monthly economic cost = 300 + (5 × 40) = 500
Upfront economic cost = 5000 + (10 × 40) = 5400
Monthly net capacity value = (40 × 40) - 500 = 1100
Simple economic payback = 5400 / 1100 = 4.91 months
First-year cash outlay = 5000 + (12 × 300) = 8600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes these components and echoes the assumptions in structured content. The caller can show where the headline number came from and which inputs the user should challenge.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test the uncertain assumption
&lt;/h3&gt;

&lt;p&gt;Holding the costs constant and changing gross time freed from 40 to 15 hours reduces monthly net capacity value to 100. Simple payback becomes 54 months. At 10 hours, modeled monthly net value is negative, so the tool returns &lt;code&gt;null&lt;/code&gt; for payback.&lt;/p&gt;

&lt;p&gt;That null matters. Returning a negative payback period would make a losing scenario look like a valid schedule. A client should explain that the current assumptions produce no positive monthly net value.&lt;/p&gt;

&lt;p&gt;The calculation does not establish that a project will free the forecast hours. That evidence has to come from observing the workflow. It also excludes taxes, financing, discounting and currency conversion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep the tool's claims narrow
&lt;/h3&gt;

&lt;p&gt;The server performs arithmetic. It does not read accounting records, remove expenses, purchase software or promise savings. Its tool annotations describe it as read-only, non-destructive and idempotent, with no open-world actions.&lt;/p&gt;

&lt;p&gt;Invalid values produce an explicit tool error. Valid responses include an interpretation explaining that time-valued capacity becomes cash savings only if a real expense is removed. This makes the limitation available to the client alongside the numeric result.&lt;/p&gt;

&lt;p&gt;We checked initialization, tool discovery and eight fictional valid/invalid cases against the live endpoint. Those checks verify the examples and input behavior; they are not evidence of economic returns or ChatGPT directory approval.&lt;/p&gt;

&lt;p&gt;Try the &lt;a href="https://aplosai.com/blog/how-much-does-automation-cost?utm_source=dev&amp;amp;utm_medium=article&amp;amp;utm_campaign=seo_distribution_2026_10&amp;amp;utm_content=budget_method#budget" rel="noopener noreferrer"&gt;browser calculator&lt;/a&gt;, or see the &lt;a href="https://aplosai.com/automation-budget-mcp" rel="noopener noreferrer"&gt;MCP connection details&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>An extraction result should not also be permission to export</title>
      <dc:creator>Zachariah M</dc:creator>
      <pubDate>Wed, 14 Oct 2026 21:48:27 +0000</pubDate>
      <link>https://dev.to/zachariah_m/an-extraction-result-should-not-also-be-permission-to-export-3g22</link>
      <guid>https://dev.to/zachariah_m/an-extraction-result-should-not-also-be-permission-to-export-3g22</guid>
      <description>&lt;p&gt;In Aplos Document Desk, the model produces a draft. A separate state transition decides whether that draft can become a CSV.&lt;/p&gt;

&lt;p&gt;That boundary matters because a plausible value can still be wrong. A date may have two interpretations. A total may appear several times. A credit note can become a positive number if a parser loses the sign.&lt;/p&gt;

&lt;p&gt;Here is how the shipped implementation separates extraction, review and export. This is a description of our implementation, not a claim that the approach eliminates document errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Store a candidate and its evidence separately
&lt;/h2&gt;

&lt;p&gt;The extractor returns fields with a value and a source quote. Application code normalizes the candidate and checks whether the quoted text occurs in the extracted source. It retains an anchor for the review interface.&lt;/p&gt;

&lt;p&gt;A matching quote establishes that text exists. It does not establish that the text is the correct field, or that OCR read the original image accurately. The original page preview remains available next to the draft.&lt;/p&gt;

&lt;p&gt;Money fields need more than substring matching. If the document says &lt;code&gt;(156.60)&lt;/code&gt;, finding &lt;code&gt;156.60&lt;/code&gt; inside it does not support a positive amount. Our wrapper inspects the surrounding printed sign and rejects a positive candidate drawn from a negative source amount.&lt;/p&gt;

&lt;p&gt;Ambiguous dates and unsupported currencies remain unresolved. Filling every cell is not a useful goal if doing so requires a guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make review a server-side state transition
&lt;/h2&gt;

&lt;p&gt;Documents begin as queued or processing, then become drafts. A reviewer can save changes, exclude a document or explicitly mark it reviewed. Required-field errors prevent review. Warnings, including possible duplicates and inconsistent totals, require acknowledgement and a review note.&lt;/p&gt;

&lt;p&gt;Every update carries a version. The server rejects stale changes when another update has already changed that document. Saving an edit resets its review state.&lt;/p&gt;

&lt;p&gt;Duplicate decisions also depend on the batch. If a supplier or reference changes and creates a possible duplicate with a previously reviewed document, that earlier review is invalidated. A green check must describe the current data, not an old version of it.&lt;/p&gt;

&lt;p&gt;The simplified transition looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uploaded -&amp;gt; queued -&amp;gt; processing -&amp;gt; draft
draft -&amp;gt; reviewed, after required checks and explicit confirmation
draft -&amp;gt; excluded
reviewed -&amp;gt; draft, after a change that needs renewed review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is explanatory pseudocode. The production implementation also handles interruptions, expiry and bounded retry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seal the artifact before checkout
&lt;/h2&gt;

&lt;p&gt;Preparing an export happens inside a database transaction. Each included document must be reviewed; excluded documents are omitted. The server constructs the CSV once, saves its bytes and hash, and links the batch to that export job.&lt;/p&gt;

&lt;p&gt;A repeated preparation request returns the existing job. Once sealed, the batch cannot silently change the file being purchased.&lt;/p&gt;

&lt;p&gt;Payment fulfillment uses the existing server-side verification path. A successful browser redirect alone does not grant download access. The verified payment must match the intended account, mode, product, price, quantity, amount, currency and export job.&lt;/p&gt;

&lt;p&gt;This separates three facts that are easy to blur together: a model returned fields, a person reviewed those fields, and a payment authorizes access to a particular artifact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the transitions as well as the extractor
&lt;/h2&gt;

&lt;p&gt;The useful cases are not limited to a clean invoice. We check ambiguous dates, negative amounts, duplicate files, supplier/reference collisions, stale updates, edits after review, export before review, download before payment and source access from another session.&lt;/p&gt;

&lt;p&gt;Our development evaluation used owned synthetic documents. That helps expose implementation defects, but it does not establish customer-document accuracy, review speed or performance against another product. Every included document still requires review.&lt;/p&gt;

&lt;p&gt;The public product supports small English invoice, receipt and credit-note batches and exports document totals. It does not extract line items or post accounting entries.&lt;/p&gt;

&lt;p&gt;You can inspect the sample workflow at &lt;a href="https://tools.aplosai.com/documents?utm_source=partner&amp;amp;utm_medium=article&amp;amp;utm_campaign=seo_distribution_2026_10&amp;amp;utm_content=dev_review_state" rel="noopener noreferrer"&gt;Aplos Document Desk&lt;/a&gt;. Preview is free; a reviewed CSV batch of up to twenty documents costs $9.&lt;/p&gt;

&lt;p&gt;Disclosure: I build Aplos. This write-up was prepared with AI assistance and checked against the shipped extraction, review and export code.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
