<?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: Harshith Vaddiparthy</title>
    <description>The latest articles on DEV Community by Harshith Vaddiparthy (@harshithvaddiparthy).</description>
    <link>https://dev.to/harshithvaddiparthy</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%2F4069322%2F82ebffbf-389c-4dd7-ab65-15aadbc02eb4.png</url>
      <title>DEV Community: Harshith Vaddiparthy</title>
      <link>https://dev.to/harshithvaddiparthy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harshithvaddiparthy"/>
    <language>en</language>
    <item>
      <title>Ego Browser: give the agent a workspace, then check its work</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Tue, 20 Oct 2026 10:45:22 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/ego-browser-give-the-agent-a-workspace-then-check-its-work-3ocf</link>
      <guid>https://dev.to/harshithvaddiparthy/ego-browser-give-the-agent-a-workspace-then-check-its-work-3ocf</guid>
      <description>&lt;p&gt;I've been using Ego Browser since it was released on GitHub. The useful idea is that an agent gets its own browser space while the human keeps their own browsing context.&lt;/p&gt;

&lt;p&gt;That is a practical change in how browser automation fits into a working day. An agent can have a task and a set of pages to work through, without that task becoming a pile of tabs in the middle of whatever I am doing.&lt;/p&gt;

&lt;p&gt;Ego calls these workspaces &lt;strong&gt;Spaces&lt;/strong&gt;. Its documentation describes separate task tabs with access to the browser's available login state. The agent can use structured page snapshots, navigate, click, fill controls and capture screenshots. The visible agent cursor and action labels help a person follow the interaction.&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%2Fbhok9x2v8ek5zmavrncm.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%2Fbhok9x2v8ek5zmavrncm.png" alt="Ego browser introduction" width="800" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with one question and a result you can inspect
&lt;/h2&gt;

&lt;p&gt;A good first task is small and read-only. For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compare these three product pages. For each product, find the supported operating systems, whether data export is documented, and where the pricing is explained. Return a table with a source URL for every answer. If the page does not answer a question, say that. Do not sign up, submit a form or change any account settings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This task has a clear end. It also gives me something to check: each answer should agree with its source. A polished summary with no traceable evidence is harder to trust than a modest table that admits what is missing.&lt;/p&gt;

&lt;p&gt;The same pattern works for release research. Open the repository, follow the relevant documentation, distinguish released features from roadmap items, and retain the exact sources.&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%2F9i1ez9i2eygo6iidqcwg.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%2F9i1ez9i2eygo6iidqcwg.png" alt="Separate spaces in Ego" width="800" height="1000"&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/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh6gettbxxd4hvzzsm00c.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%2Fh6gettbxxd4hvzzsm00c.gif" alt="Ego Space switch animation" width="760" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Animation: Ego / Citro Labs, excerpted from the official GitHub demo.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Three useful applications
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Research and comparison.&lt;/strong&gt; Give the agent the same questions for each product or source. Ask it to preserve URLs and uncertainty. This is more useful than asking it to browse broadly and report whatever looks interesting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Website checks.&lt;/strong&gt; Pick one journey: find a feature, use a navigation menu, or complete a form in a test environment. Ask for the steps taken, the resulting state and a screenshot of anything confusing or broken. Successful clicking does not establish that the site saved the result correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content preparation.&lt;/strong&gt; Gather original sources and relevant screenshots before drafting. Keep the evidence beside the draft so that a factual claim can be checked without repeating the entire browsing session. Preparing an article and publishing it are different actions; authorize the latter explicitly.&lt;/p&gt;

&lt;p&gt;These are suggested workflows, not performance results from a benchmark or claims that every website permits automation.&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%2F5vl0h0n9xnegxz1gzvrh.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%2F5vl0h0n9xnegxz1gzvrh.png" alt="Three practical tasks" width="800" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the animation tells me
&lt;/h2&gt;

&lt;p&gt;A visible cursor and a short action label make the next interaction easier to follow. They help answer: which control is the agent targeting, and what does it think that control will do?&lt;/p&gt;

&lt;p&gt;The next question still matters: what happened on the page?&lt;/p&gt;

&lt;p&gt;After navigation, check the destination. After filling a field, check its value. After an authorized save, reload and check that the result persisted. An action receipt establishes that an input was sent; it does not establish that the task succeeded.&lt;/p&gt;

&lt;p&gt;The accompanying clip is an excerpt from Ego / Citro Labs' official demonstration. It shows the browser's own interaction treatment. The documentation screenshot was captured through Ego on my Mac mini; it is a separate source, not a claim that I recorded the official demo.&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%2Fvjh65ifopoourmkc1fr0.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%2Fvjh65ifopoourmkc1fr0.gif" alt="Native Ego browsing animation" width="560" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Footage: Ego / Citro Labs. The excerpt preserves the browser's actual visual feedback.&lt;/em&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%2F3ke2neno8m08211igjsz.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%2F3ke2neno8m08211igjsz.png" alt="Check the result of the action" width="800" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A small implementation pattern
&lt;/h2&gt;

&lt;p&gt;On the installed Ego API used for this walkthrough, a task has a persistent space ID and managed page labels. Reuse them across rounds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;taskSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Compare product documentation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://lite.ego.app/document/en/docs/space&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;spaceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spaceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read the current installed Ego guide before adapting this example. Observe the actual page before choosing a click target; do not assume a selector from another site will apply.&lt;/p&gt;

&lt;p&gt;Keep the boundary clear: which pages may the agent inspect, which changes may it make, and when should it stop? Separate task spaces organize the work. Account access still needs an explicit scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and credits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/citrolabs/ego-lite" rel="noopener noreferrer"&gt;Ego repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lite.ego.app" rel="noopener noreferrer"&gt;Ego product and downloads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lite.ego.app/document/en/docs/space" rel="noopener noreferrer"&gt;Spaces documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lite.ego.app/document/en/docs/ego-browser" rel="noopener noreferrer"&gt;Ego browser tool documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Product descriptions were checked against the project's documentation. Ego Browser and its interface are the work of the Ego / Citro Labs team.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>Before an AI migration, build a behaviour comparison harness</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Tue, 20 Oct 2026 02:43:09 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/before-an-ai-migration-build-a-behaviour-comparison-harness-2hm9</link>
      <guid>https://dev.to/harshithvaddiparthy/before-an-ai-migration-build-a-behaviour-comparison-harness-2hm9</guid>
      <description>&lt;p&gt;An AI-generated replacement can compile, start and produce plausible output while changing a business rule. For a migration, the useful question is whether you can identify and explain each observable difference from the old implementation.&lt;/p&gt;

&lt;p&gt;OpenAI’s October 19 &lt;a href="https://openai.com/index/low-resource-programming-languages/" rel="noopener noreferrer"&gt;research on low-resource programming languages&lt;/a&gt; distinguishes building new functionality from preserving existing behaviour. MultiLangBench asks models to build a SQLite-compatible engine across 20 languages. A separate evaluation migrates COBOL programs to other languages, with hidden tests requiring byte-for-byte parity on observable outputs. A migration passes only if all its tests pass.&lt;/p&gt;

&lt;p&gt;OpenAI reports 86.6% accuracy for GPT-6.1 Sol at low reasoning effort on that migration evaluation and 97.9% at higher effort. Those are benchmark results, not a forecast for your repository. The announcement explicitly retains expert review and testing against production business rules and dependencies.&lt;/p&gt;

&lt;p&gt;Here is a small migration workflow I would use to make those distinctions operational. It is a proposed implementation approach, not a reproduction of OpenAI’s evaluation or a tested production framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with an observable boundary
&lt;/h2&gt;

&lt;p&gt;Choose a routine whose inputs, outputs and side effects you can isolate. A record-processing batch is a better first unit than an entire application with loosely understood integrations.&lt;/p&gt;

&lt;p&gt;Write down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input format, encoding and missing-value conventions.&lt;/li&gt;
&lt;li&gt;Output format, precision and ordering rules.&lt;/li&gt;
&lt;li&gt;Error codes and rejected-record behaviour.&lt;/li&gt;
&lt;li&gt;State changes, messages and other externally visible effects.&lt;/li&gt;
&lt;li&gt;Environment assumptions such as timezone, locale and dependency versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point is to define what a comparison will cover. A matching output file says nothing about an unobserved message sent twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate parity from intentional changes
&lt;/h2&gt;

&lt;p&gt;Create a fixture directory with input and expected-output files from an approved, isolated run of the old implementation. Use synthetic or appropriately protected data. Pin the old executable and its environment so that the reference result is reproducible.&lt;/p&gt;

&lt;p&gt;Alongside the fixtures, keep a small decision ledger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Illustrative structure; identifiers and values are hypothetical.&lt;/span&gt;
&lt;span class="na"&gt;case_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;positive_fraction_boundary&lt;/span&gt;
&lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;retain_two_decimal_places&lt;/span&gt;
&lt;span class="na"&gt;old_result&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;12.34"&lt;/span&gt;
&lt;span class="na"&gt;decision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;preserve&lt;/span&gt;
&lt;span class="na"&gt;approved_result&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;12.34"&lt;/span&gt;
&lt;span class="na"&gt;owner_role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;financial_process_owner&lt;/span&gt;
&lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;preserve_existing_contract&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenAI’s article supplies the mechanism behind this example: COBOL fixed-point arithmetic discards excess decimal digits unless rounding is requested. For a hypothetical positive value of 12.349, discarding excess digits gives 12.34; rounding to the nearest hundredth gives 12.35.&lt;/p&gt;

&lt;p&gt;A replacement that chooses the second result can run perfectly well. Whether that difference is a regression depends on the requirement. If the owner approves a rule change, record it separately and retain the old expected result as historical evidence.&lt;/p&gt;

&lt;p&gt;Avoid quietly regenerating all expected files from the new implementation. That can turn the code being evaluated into the authority for its own correctness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the first comparator deliberately strict
&lt;/h2&gt;

&lt;p&gt;For a byte-oriented interface, a basic file comparison is useful. The following standard-library script compares two existing files and reports a mismatch. It does not execute either program, validate business correctness or prove migration completeness.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SystemExit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Usage: compare.py expected.bin actual.bin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;read_bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;read_bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
             &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mismatch at byte &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expected length=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, actual length=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Outputs match byte for byte&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SystemExit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start strict so differences become visible. If a format permits harmless differences, such as a field order that consumers explicitly do not depend on, define a narrow semantic comparison for that field. Keep the original output files. Broad whitespace stripping or sorting can hide changes that matter to a downstream consumer.&lt;/p&gt;

&lt;p&gt;For the initial fixture set, include normal records and examples around the actual workflow’s boundaries: empty input, missing references, repeated records, date transitions and decimal precision. A passing set establishes evidence for those cases; it does not establish universal equivalence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspect failures as part of the interface
&lt;/h2&gt;

&lt;p&gt;Run the candidate in a sandbox with live writes disabled. Observe exit status, output files, state changes and attempted side effects. Use captured or simulated dependency responses to investigate retries and partial failures where appropriate.&lt;/p&gt;

&lt;p&gt;Classify each discrepancy against the decision ledger: a candidate defect, an explicitly approved change, an unstable test environment or an unresolved requirement. Keep unresolved cases visible. An unexplained difference should not disappear behind a passing aggregate percentage.&lt;/p&gt;

&lt;p&gt;Finally, measure generation effort separately from investigation, review and integration work. A lower API bill is one cost component. It does not tell you how much work remains to understand undocumented behaviour.&lt;/p&gt;

&lt;p&gt;The first deliverable I would ask for is one isolated routine, a repeatable fixture set and a reviewed list of differences. That gives a team concrete evidence for deciding whether to expand the migration.&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>What an AI work-week review taught me about prototypes and finishing</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Mon, 19 Oct 2026 14:43:46 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/what-an-ai-work-week-review-taught-me-about-prototypes-and-finishing-2hk3</link>
      <guid>https://dev.to/harshithvaddiparthy/what-an-ai-work-week-review-taught-me-about-prototypes-and-finishing-2hk3</guid>
      <description>&lt;p&gt;I asked AI to review a partial record of my work week, and the most useful result was a development pattern: I keep turning explanations into tools.&lt;/p&gt;

&lt;p&gt;During workshop preparation and delivery, an idea would become an interactive analysis view, a small campaign workspace, or a reusable project. A working example makes the inputs, calculations and limits visible. It also creates another implementation to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give the prototype one job
&lt;/h2&gt;

&lt;p&gt;For a teaching tool, I want a learner to change an input and understand one consequence. That is a useful scope boundary. If I need ten minutes to explain the interface before the concept, the prototype has become another lesson.&lt;/p&gt;

&lt;p&gt;The same rule applies to a product spike. State the decision it should resolve before choosing the framework or building the shell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review a real artifact early
&lt;/h2&gt;

&lt;p&gt;One presentation grew to 44 slides. Reviewing the deck made the problem concrete: I wanted a practical demonstration-led session and a maximum of 15 slides.&lt;/p&gt;

&lt;p&gt;For software, a small working surface plays the same role. It lets a reviewer inspect what expands, what survives navigation, what state is visible, and what happens next. A rough implementation can improve the brief, provided it is small enough to change cheaply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate activity from completion
&lt;/h2&gt;

&lt;p&gt;My history contained repeated visits to builds, renders and release sessions. An open terminal tells me a process was visible. It does not prove a feature works in the destination environment.&lt;/p&gt;

&lt;p&gt;For a development task, I would keep a completion note like this:&lt;/p&gt;

&lt;p&gt;Changed: the specific behaviour the user can now exercise&lt;/p&gt;

&lt;p&gt;Inspect: the artifact, route or revision that demonstrates it&lt;/p&gt;

&lt;p&gt;Evidence: the check actually performed against that result&lt;/p&gt;

&lt;p&gt;Remaining: any unfinished dependency or limitation&lt;/p&gt;

&lt;p&gt;A prototype checked with example records should say so. A video render still needs review. A release receipt should agree with the live page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the history as evidence, then challenge the interpretation
&lt;/h2&gt;

&lt;p&gt;The review covered available activity from October 12–19, 2026. It was not a complete time audit. A visible window cannot establish attention, and a long sequence of events cannot establish useful output.&lt;/p&gt;

&lt;p&gt;I found it useful to ask what repeated, check that reading against the work itself, and choose one adjustment. Mine is making the finish condition explicit before opening the next build.&lt;/p&gt;

&lt;p&gt;There was also a television that became a Jarvis project. Apparently my side quests now need repositories.&lt;/p&gt;

&lt;p&gt;The habit I want to keep is making ideas tangible. The habit I want to improve is deciding which ideas deserve implementation today.&lt;/p&gt;

&lt;p&gt;Read the original work-week reflection: &lt;a href="https://www.harshith.com/blog/ai-reviewed-my-work-week" rel="noopener noreferrer"&gt;https://www.harshith.com/blog/ai-reviewed-my-work-week&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More field notes in The H Letter: &lt;a href="https://www.harshith.com/newsletter" rel="noopener noreferrer"&gt;https://www.harshith.com/newsletter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>learning</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Four UI projects, four different jobs for the interface</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Sun, 18 Oct 2026 06:53:40 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/four-ui-projects-four-different-jobs-for-the-interface-24cn</link>
      <guid>https://dev.to/harshithvaddiparthy/four-ui-projects-four-different-jobs-for-the-interface-24cn</guid>
      <description>&lt;p&gt;I’ve brought four of my projects into a &lt;a href="https://www.harshith.com/ui" rel="noopener noreferrer"&gt;UI gallery&lt;/a&gt;: an image editor, a content dashboard, a video-workflow canvas and a CRM. Each study includes real application screens, design decisions and links to the implementation.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/harshith-vaddiparthy/ui-gallery" rel="noopener noreferrer"&gt;gallery itself is open source&lt;/a&gt;. It is a small React application you can run locally. The four applications remain in their own repositories, with their own setup instructions and MIT licenses.&lt;/p&gt;

&lt;p&gt;These are the decisions I wanted each interface to make easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grain Studio: judge the image while changing it
&lt;/h2&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%2Fv3urz3jfivm9zqjd38p2.webp" 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%2Fv3urz3jfivm9zqjd38p2.webp" alt="Grain Studio texture editor with the included sample artwork" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An image-effects tool needs a short feedback loop. Grain Studio keeps the image stage, texture dock and material controls in the same workspace. Its before-and-after scrubber lets you compare the effect while you tune it.&lt;/p&gt;

&lt;p&gt;Export introduces a different set of decisions: format, dimensions and transparency. I gave those choices a dedicated flow with progress and cancellation states. The source uses Canvas 2D for the preview and a bounded OffscreenCanvas worker on supported browsers for export.&lt;/p&gt;

&lt;p&gt;The reusable pattern is to keep comparison close to the adjustment and make output choices explicit at export time.&lt;/p&gt;

&lt;p&gt;This capture uses the included sample artwork. The behavior was independently implemented after studying Textures; the dock’s proximity and tactile feedback are informed by ThreeUI Community, with its notice retained.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.harshith.com/ui#grain-studio" rel="noopener noreferrer"&gt;Inspect the case&lt;/a&gt; · &lt;a href="https://github.com/harshith-vaddiparthy/grain-studio/tree/1efb17c2f33c5e2a3e11ab01293633725ae7a2dc" rel="noopener noreferrer"&gt;Read the implementation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Content Dashboard: make content states easy to scan
&lt;/h2&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%2F3xmt3oqaine5hws7zm4t.webp" 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%2F3xmt3oqaine5hws7zm4t.webp" alt="AI Content Dashboard overview using fictional sample metrics" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The working sequence is brief → draft → review → library. The overview helps someone understand the collection; the library provides type and status filters; the editor gives an individual piece a focused working area.&lt;/p&gt;

&lt;p&gt;The same content model feeds summary metrics, activity charts and recent-content rows. Reusing type and status labels across these views keeps the navigation predictable. A person can move from an overview count to the actual pieces behind it.&lt;/p&gt;

&lt;p&gt;This is built on shadcn/ui, Base UI and the tweakcn Caffeine theme. The screenshots use fictional sample content and illustrative metrics. The source README distinguishes the implemented writing workflow from planned video-rendering and database integrations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.harshith.com/ui#ai-content-dashboard" rel="noopener noreferrer"&gt;Inspect the case&lt;/a&gt; · &lt;a href="https://github.com/harshith-vaddiparthy/ai-content-dashboard/blob/fa0f1a0b64785f34d51f8caae5ef6aab8768ade4/lib/content/sample-data.ts" rel="noopener noreferrer"&gt;Read the sample-data model&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  UGC Genie: show where work is in the process
&lt;/h2&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%2F2x5sj4xjxx8ivitw20jo.webp" 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%2F2x5sj4xjxx8ivitw20jo.webp" alt="UGC Genie workflow detail in its credit-free local demo" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UGC Genie connects product input, visual analysis, creative direction, generation, rendering and review. React Flow supplies the canvas; the application defines the stages and their state.&lt;/p&gt;

&lt;p&gt;The source initializes every step explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createSteps&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;WorkflowStep&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;workflowDefinition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;progress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives the interface a clear vocabulary: pending, running, completed and failed. The canvas can show which stage is active while the input and output-review areas remain available alongside it.&lt;/p&gt;

&lt;p&gt;The screenshot shows a simulated, credit-free local demo. Its displayed progress describes application stages. The visual foundations include shadcn/Base UI and tweakcn claymorphism; my work is the workflow composition, feedback and review experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.harshith.com/ui#ugc-genie" rel="noopener noreferrer"&gt;Inspect the case&lt;/a&gt; · &lt;a href="https://github.com/harshith-vaddiparthy/UGC-dashboard/blob/274c42cc56864fb34c17b56e4743386aa4332e3f/lib/workflow/definition.ts" rel="noopener noreferrer"&gt;Read the stage definition&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  PulseCRM: bring context to the next action
&lt;/h2&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%2F7978sviqed7e8mjys9nb.webp" 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%2F7978sviqed7e8mjys9nb.webp" alt="PulseCRM overview with bundled demo records" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sales work needs the pipeline, a record’s history and a useful next step. PulseCRM brings pipeline health, priority deals, account activity and follow-up work into one navigation system.&lt;/p&gt;

&lt;p&gt;I adapted shadcn’s sidebar-07 into the CRM shell. Sales Copilot suggestions remain review-required, so record summaries and follow-up drafts have a clear human review step.&lt;/p&gt;

&lt;p&gt;Preparing this case also exposed a small implementation bug: &lt;code&gt;--font-sans&lt;/code&gt; referred to itself. I corrected it to the Geist font variable supplied by the layout, rebuilt the application and recaptured the interface. The linked source includes that fix.&lt;/p&gt;

&lt;p&gt;These screens use bundled demo records in an isolated environment. The source also includes a separately configured Supabase-backed path.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.harshith.com/ui#pulse-crm" rel="noopener noreferrer"&gt;Inspect the case&lt;/a&gt; · &lt;a href="https://github.com/harshith-vaddiparthy/gen-ai-bootcamp-crm/tree/007a6ca08158b052419b73c32432cb0108401ed7" rel="noopener noreferrer"&gt;Read the captured revision&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explore an interaction in the code
&lt;/h2&gt;

&lt;p&gt;For each study, start with one control and follow it through the implementation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What decision is the person making?&lt;/li&gt;
&lt;li&gt;Which state changes when they act?&lt;/li&gt;
&lt;li&gt;What feedback makes that change clear?&lt;/li&gt;
&lt;li&gt;How does the screen handle loading, empty and failed states?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The gallery credits the component libraries and visual foundations used in each project. Keep the original copyright, license and third-party notices when reusing the source. Individual applications have their own runtime and provider requirements; the gallery itself needs no API key or database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.harshith.com/ui" rel="noopener noreferrer"&gt;Browse the interface studies&lt;/a&gt; or &lt;a href="https://github.com/harshith-vaddiparthy/ui-gallery" rel="noopener noreferrer"&gt;run the gallery from GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>design</category>
      <category>react</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Build an Independent Attempt into Your AI Training App</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Sun, 18 Oct 2026 02:44:24 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/build-an-independent-attempt-into-your-ai-training-app-4j73</link>
      <guid>https://dev.to/harshithvaddiparthy/build-an-independent-attempt-into-your-ai-training-app-4j73</guid>
      <description>&lt;p&gt;If your AI training app marks a lesson complete when a conversation ends, its completion record tells you very little about what the learner can explain or apply.&lt;/p&gt;

&lt;p&gt;A useful alternative is to model guided practice and independent assessment as separate activities. Keep the learner's first attempt, any assistance they received, and the subsequent review distinguishable. That gives a reviewer something concrete to inspect without treating the assistant's confidence as a competence score.&lt;/p&gt;

&lt;p&gt;This design is inspired by &lt;a href="https://openai.com/index/teaching-students-to-think-and-learn-through-questions/" rel="noopener noreferrer"&gt;OpenAI's October 15 article, “Teaching students to think and learn through questions”&lt;/a&gt;. Its classroom example has students explore evaporation with Study Mode, then write an explanation and a discussion question without referring back to the conversation. The teacher uses those responses to identify what to revisit.&lt;/p&gt;

&lt;p&gt;OpenAI also suggests that teachers try familiar subjects first and assess whether the questions and explanations suit their class. The article does not establish the effectiveness of a workplace training application. What follows is a proposed software design based on that exercise, with explicit limits on what its records can prove.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with an observable decision
&lt;/h2&gt;

&lt;p&gt;Define a small learning target before building a chat interface. For a hypothetical internal support course, the target might be: “Identify which team should review an account-access exception, using the approved support guide.”&lt;/p&gt;

&lt;p&gt;The exercise needs a reference version, a reviewer-approved case, and expected reasoning. Avoid asking a model to invent the organization's policy or grade against a standard it generated during the same conversation.&lt;/p&gt;

&lt;p&gt;Keep the reference and case versions attached to the attempt. If the policy changes later, the reviewer should be able to see which version the learner was given. A version identifier is useful only if it points to content your system actually retains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate the stages in the application
&lt;/h2&gt;

&lt;p&gt;A small state model is sufficient:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Learner experience&lt;/th&gt;
&lt;th&gt;Record&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Guided practice&lt;/td&gt;
&lt;td&gt;Answer questions, request hints, read explanations&lt;/td&gt;
&lt;td&gt;Practice case and assistance events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Independent attempt&lt;/td&gt;
&lt;td&gt;Read a fresh case and explain a decision&lt;/td&gt;
&lt;td&gt;Initial answer and assistance status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review&lt;/td&gt;
&lt;td&gt;Receive feedback from a qualified reviewer&lt;/td&gt;
&lt;td&gt;Reviewer, rubric findings, unresolved points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revision&lt;/td&gt;
&lt;td&gt;Consult the reference and revise the answer&lt;/td&gt;
&lt;td&gt;New answer linked to the initial attempt&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The independent case should differ from the practice case in one meaningful condition. In the hypothetical support course, the practice case could have all required identity evidence. The second could have missing evidence and an urgent request. The approved guide determines what happens next; urgency should not become an invented exception.&lt;/p&gt;

&lt;p&gt;Show the independent case on a separate screen without the practice transcript or generated hints. Explain the purpose of that short attempt before the learner starts. If they request help, make it available through an explicit action and record that the attempt became assisted.&lt;/p&gt;

&lt;p&gt;Hiding a transcript in your application does not prove that the learner used no other resources. Report the condition your application provided and the assistance it observed. Avoid describing this as a secure examination system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preserve the first answer
&lt;/h2&gt;

&lt;p&gt;Here is an illustrative record, not a platform API or a complete production schema:&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;"attempt_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"attempt-101"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exercise_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"support-routing-v3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reference_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"support-guide-v8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"case_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"missing-evidence"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"independent_attempt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"assistance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none_observed_in_app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"answer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The required evidence is missing. I would route this for review using the owner named in the guide."&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_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"revises_attempt_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&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;When the learner revises, create a new answer record linked to the original. Do not overwrite the initial explanation and then report the revised answer as unaided performance.&lt;/p&gt;

&lt;p&gt;Similarly, keep an assistance event separate from answer content. An event can record that a hint was requested, when it was provided, and which attempt it belonged to. Only retain the content you need under your organization's data policy; these records are for learning review, not an excuse to collect unrelated employee activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep transitions under application control
&lt;/h2&gt;

&lt;p&gt;The application should decide which actions are available at each stage. A learner's answer or pasted reference is data; it should not be able to mark an attempt reviewed or change the recorded assistance status.&lt;/p&gt;

&lt;p&gt;If you use a model to propose feedback, save that feedback as a suggestion awaiting review. For this design, a qualified reviewer makes the competence decision. The distinction should be visible in the interface and enforced wherever state changes are accepted.&lt;/p&gt;

&lt;p&gt;Keep submission handling predictable. A repeated submit for the same attempt should return the existing result, rather than creating multiple initial answers. Persist the answer before showing the confirmation. If a response is lost, the client should be able to retrieve the recorded attempt and display its actual state.&lt;/p&gt;

&lt;p&gt;These are implementation recommendations, not claims about how Study Mode works internally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review reasoning, evidence, and boundaries
&lt;/h2&gt;

&lt;p&gt;Use a short rubric that asks whether the answer identifies the applicable rule, cites the relevant evidence, notices the changed condition, and recognizes any unresolved question or need for review.&lt;/p&gt;

&lt;p&gt;An answer that admits a specific uncertainty can reveal a useful learning gap. An answer that invents an owner or exception deserves different feedback, even when it sounds fluent.&lt;/p&gt;

&lt;p&gt;Avoid compressing everything into a single model-generated score. Store the reviewer's findings by criterion and the reference supporting each correction. A later reviewer can then understand why the learner was asked to practise again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify behavior with a few meaningful cases
&lt;/h2&gt;

&lt;p&gt;Before piloting the app, check these situations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A hint request during the independent stage changes the assistance record before the answer is assessed.&lt;/li&gt;
&lt;li&gt;A revised answer preserves the initial attempt and links back to it.&lt;/li&gt;
&lt;li&gt;Repeated submission creates one initial answer record.&lt;/li&gt;
&lt;li&gt;Text inside an answer cannot change review status or the reference version.&lt;/li&gt;
&lt;li&gt;Feedback distinguishes an incorrect decision from a reference that does not resolve the case.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with one approved exercise and inspect the resulting records with a knowledgeable reviewer. The initial outcome you can honestly report is what the learner explained under the observed conditions, what help they requested, and what changed after feedback.&lt;/p&gt;

&lt;p&gt;That is useful evidence for deciding the next practice. Establishing lasting competence requires more than one interaction, especially when the real task has meaningful consequences.&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>What is an AI agent harness?</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Sat, 17 Oct 2026 23:26:01 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/what-is-an-ai-agent-harness-5a10</link>
      <guid>https://dev.to/harshithvaddiparthy/what-is-an-ai-agent-harness-5a10</guid>
      <description>&lt;p&gt;&lt;em&gt;By Harshith Vaddiparthy. Originally published in my &lt;a href="https://www.harshith.com/blog/ai-agent-harness-explained" rel="noopener noreferrer"&gt;AI agent harness guide&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An AI agent harness is the software around a model that lets it do work: supply the right information, offer tools, enforce permission rules, return results, and decide when to continue or stop. The model helps choose the next action. The harness connects that choice to an actual environment.&lt;/p&gt;

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

&lt;p&gt;The walkthrough uses real software footage, fictional expense data, and my AI avatar and cloned voice. The transcript is available below without signing in.&lt;/p&gt;

&lt;p&gt;That distinction matters when you are choosing an AI tool. A model name does not tell you whether the application can read your files, preserve the originals, ask before saving, recover from a failed action, or prove that the final result is correct. Those are properties of the complete system.&lt;/p&gt;

&lt;p&gt;I recorded the walkthrough above to make those moving parts visible. The task is deliberately ordinary: read a small file of fictional expenses, calculate spending by category, flag a missing category, and save a short summary. There is no real financial account or customer data in this example. A small, inspectable task makes the boundary between a convincing answer and completed work much easier to see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model, tool, harness: three different jobs
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The pieces of the expense demonstration&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;Its job&lt;/th&gt;
&lt;th&gt;What to inspect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;Interprets the request and proposes the next response or action.&lt;/td&gt;
&lt;td&gt;Did it understand the missing-category rule?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool&lt;/td&gt;
&lt;td&gt;Performs a specific operation outside the model.&lt;/td&gt;
&lt;td&gt;Which file did it read, or which calculation did it run?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harness&lt;/td&gt;
&lt;td&gt;Connects instructions, context, tools, permissions, and results.&lt;/td&gt;
&lt;td&gt;Which actions are available, which are blocked, and what evidence returns?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The recorded application is DeepSeek Harness. In the interface, a conversation sits beside file tools and permission controls. You do not need that particular application to use the evaluation method. What matters is being able to inspect the input, the action, its result, and the boundary around it.&lt;/p&gt;

&lt;p&gt;This general pattern also appears in &lt;a href="https://www.anthropic.com/engineering/building-effective-agents" rel="noopener noreferrer"&gt;Anthropic's guide to building effective agents&lt;/a&gt;: the model uses tools, receives feedback from the environment, and continues until it completes the task or reaches a stopping condition. The useful part is the feedback. Each step can give the system new evidence, rather than requiring it to finish everything from its first guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a task whose answer you can check
&lt;/h2&gt;

&lt;p&gt;My input contains 12 expense records. Eleven have a category. One does not. The instruction is explicit: retain that record, group it separately, and flag the missing category. Do not invent a label, delete the row, or quietly change the original file. The amounts are fictional and have no assigned currency.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Expected totals from the original 12 records&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Software&lt;/td&gt;
&lt;td&gt;78.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supplies&lt;/td&gt;
&lt;td&gt;46.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Travel&lt;/td&gt;
&lt;td&gt;86.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uncategorized&lt;/td&gt;
&lt;td&gt;17.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grand total&lt;/td&gt;
&lt;td&gt;227.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The uncategorized amount is part of the 227.00 total. It is not an extra amount to add afterward. This is a small detail with a large lesson: handling uncertainty is part of the task definition. If I only asked for a tidy report, a plausible-looking classification could conceal the very exception I need to review.&lt;/p&gt;

&lt;p&gt;Before running an agent, I want three things written down: the input it should use, the output I expect, and the rule for anything uncertain. For this task, that means the expense file, a category summary, and an explicit uncategorized group. A stronger prompt helps, but the application must still load the right files and enforce the allowed actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow the activity between the prompt and the answer
&lt;/h2&gt;

&lt;p&gt;After submitting the task, I open the tool details. The first useful question is whether the agent read the intended input. A polished summary is weak evidence if I cannot connect it to the source records. The activity view should identify the action and show a result that I can interpret.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Read&lt;/strong&gt;: The application supplies the instructions and the expense records through file tools. Check the file identity and the returned data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Calculate&lt;/strong&gt;: A verification command computes category totals, the grand total, and the number of records with a missing category. Inspect the actual output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Propose&lt;/strong&gt;: The model uses those results to prepare the summary. Compare its claims with the original input and the calculation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Save and reopen&lt;/strong&gt;: After the specific write is authorized, inspect the file that was actually saved and run the post-write check.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the agent loop in practical terms: choose an action, act through a tool, inspect what happened, and choose the next step. A tool request is not the same thing as a successful action. A planned save is not a saved file. A result saying that no summary exists yet is useful information, even when the arithmetic has already passed.&lt;/p&gt;

&lt;p&gt;The harness should preserve those distinctions. If it reports every tool request as a success, the model may continue from a false premise. If it hides a failed write behind a generic error, recovery becomes harder. Clear results help both the model and the person reviewing the work understand the current state.&lt;/p&gt;

&lt;h2&gt;
  
  
  A saved file is not automatically remembered
&lt;/h2&gt;

&lt;p&gt;Context is the information the model receives for the current step. In this example, the expense records and the rule for blank categories are relevant context. Unrelated files and old conversations are not automatically helpful. The harness decides what to load, what tool results to retain, and how to manage limited context space.&lt;/p&gt;

&lt;p&gt;For longer tasks, the application may summarize earlier conversation or retrieve only selected material. That can keep a task moving, but summaries can drop detail. I prefer important facts and decisions to live in an artifact that can be reopened: the original data, a written instruction, or a checked output.&lt;/p&gt;

&lt;p&gt;Persistence and retrieval are separate steps. The saved summary can survive the chat, but the next model response will not know its contents merely because it exists somewhere on disk. The system has to load it again. When someone says an agent has memory, ask what is stored, how it is retrieved, and how you can tell that the current response actually used it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approval and a sandbox answer different questions
&lt;/h2&gt;

&lt;p&gt;In the recording, the initial write is blocked by the read-only setting. The agent then requests one-time permission to save the summary. I inspect the destination and the proposed content before allowing that action. The original expense file remains unchanged.&lt;/p&gt;

&lt;p&gt;This demonstrates an application permission boundary. It does not demonstrate an operating-system sandbox. Approval answers whether a particular action may proceed. A sandbox limits which resources the execution environment can reach. A prompt saying 'do not touch other files' is neither a permission implementation nor proof of isolation.&lt;/p&gt;

&lt;p&gt;For a learning exercise, the practical choice is a small disposable workspace with fictional inputs and only the capabilities needed for the task. Reading a file, creating a new summary, modifying the source, and sending the result to another person are different actions. Permission for one should not silently imply permission for all four.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check what was saved, not just what was said
&lt;/h2&gt;

&lt;p&gt;Once the summary is saved, I reopen it. The checker compares its category totals, grand total, and missing-category record count against the source data. In this example, those checks pass. That is stronger evidence than the final chat message saying the task is complete, because it tests the artifact I will actually use.&lt;/p&gt;

&lt;p&gt;The limit matters just as much as the pass. This checker does not verify every sentence, decide whether an expense is legitimate, or tell me which category the blank row should have had. Correct arithmetic over incorrect source data would still be incorrect business information. The scope of a check determines what its result supports.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input preserved.&lt;/strong&gt; The original records remain intact, so the output can be traced back to them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exception retained.&lt;/strong&gt; The 17.00 blank-category record remains visible instead of being guessed away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output reopened.&lt;/strong&gt; The saved artifact exists and can be inspected independently of the chat response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checks named.&lt;/strong&gt; A passing calculation has a specific meaning; it is not a blanket guarantee of correctness.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Four questions to ask of any agent
&lt;/h2&gt;

&lt;p&gt;I use four questions to evaluate the complete system. What information can it see? Which actions can it take? How is the result checked? Where must it stop? These questions are useful even when you have no interest in building the harness yourself.&lt;/p&gt;

&lt;p&gt;Take a weekly report as another example. The agent might be allowed to read a folder of approved inputs and draft a summary. Its check could reconcile totals and link each factual claim to a source. Its stopping point could be the reviewed draft. Publishing the report would remain a separate decision. That is a clearer design than asking an agent to 'handle reporting' and discovering its interpretation afterward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the method on one small task
&lt;/h2&gt;

&lt;p&gt;Choose a small set of fictional or non-sensitive records whose expected result you can calculate yourself. Use an agent application that exposes its tools and lets you restrict writes. Adapt this task brief to the capabilities it actually has. If it cannot show a tool result or enforce a permission boundary, record that limitation instead of assuming it exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A task brief you can adapt&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read the supplied expense file and preserve it unchanged.
Calculate totals by category and a grand total.
Keep blank categories in an Uncategorized group and report their count.
Show the calculation evidence and a proposed summary.
Do not save or send anything yet.
After I approve one destination and the summary, save that file only.
Reopen the saved file and compare its totals with the source.
Report which checks passed, which were not performed, and stop.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then change one input deliberately: remove a category, add a row, or supply a destination the application is not allowed to write. Does the system retain the uncertainty, notice that the expected total changed, or stop at the boundary? A small controlled failure can teach you more about an agent than another polished demonstration.&lt;/p&gt;

&lt;p&gt;You do not need a multi-agent architecture to learn this. Start with one task, a few tools, and one visible completion check. If you want to understand the implementation after that, my guide to &lt;a href="https://www.harshith.com/blog/building-coding-agents-from-scratch" rel="noopener noreferrer"&gt;building a coding agent from scratch&lt;/a&gt; explains the loop and the operating machinery around it. If you want more practical field notes like this, &lt;a href="https://www.harshith.com/newsletter" rel="noopener noreferrer"&gt;subscribe to The H Letter&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=-M1N1pRY0I4" rel="noopener noreferrer"&gt;My recorded AI harness walkthrough&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fictional expense task, tool activity, blocked write, one-time approval, and saved-file check shown in this article.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.anthropic.com/engineering/building-effective-agents" rel="noopener noreferrer"&gt;Anthropic: Building effective agents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Primary guidance on tools, environmental feedback, stopping conditions, and human oversight. It supports the general pattern, not a security certification of this demonstration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is an AI harness the same thing as a model?
&lt;/h3&gt;

&lt;p&gt;No. The model produces responses and requests actions. The harness is the surrounding software that supplies context, exposes tools, applies permission rules, runs permitted actions, and returns observations. The same model can behave differently in two applications because those surroundings differ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does an approval dialog mean an agent is sandboxed?
&lt;/h3&gt;

&lt;p&gt;No. Approval decides whether a particular action may proceed. A sandbox limits what an execution environment can reach. The walkthrough demonstrates an application permission boundary; it does not demonstrate an operating-system sandbox.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does saving a file give an agent permanent memory?
&lt;/h3&gt;

&lt;p&gt;Saving creates a durable artifact. The model can use that artifact in a later response only if the system loads its contents into the context it receives. Persistence and retrieval are different steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.harshith.com/blog/building-coding-agents-from-scratch" rel="noopener noreferrer"&gt;Build a coding agent from scratch&lt;/a&gt;: Go deeper into tool dispatch, context compaction, permission policies, and the code behind a harness.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.harshith.com/blog/how-i-evaluate-ai-agent-frameworks" rel="noopener noreferrer"&gt;How I evaluate AI agent frameworks&lt;/a&gt;: The practical questions I ask about integration, reliability, observability, and the cost of leaving a framework.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Full transcript and downloads
&lt;/h2&gt;

&lt;p&gt;The complete transcript follows. You can also read it alongside the video in the &lt;a href="https://www.harshith.com/blog/ai-agent-harness-explained" rel="noopener noreferrer"&gt;original guide&lt;/a&gt; or download a copy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.harshith.com/transcripts/ai-agent-harness-explained.en.txt" rel="noopener noreferrer"&gt;Download transcript (.txt)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.harshith.com/transcripts/ai-agent-harness-explained.en.srt" rel="noopener noreferrer"&gt;Download captions (.srt)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.harshith.com/transcripts/ai-agent-harness-explained.en.vtt" rel="noopener noreferrer"&gt;Download captions (.vtt)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  0:00: What makes an agent work
&lt;/h3&gt;

&lt;p&gt;When an AI reads a file, uses a tool, and checks a result, the model is only part of what you're seeing. The surrounding software makes that work possible. That surrounding system is called a harness. I'm going to show you one real task, and point out the pieces that make an agent useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  0:18: The model and its harness
&lt;/h3&gt;

&lt;p&gt;I'm using DeepSeek Harness, a real agent app with a conversation and tools for files. The model is one component inside this application. The instructions, available tools, and permission settings all affect what the complete system can do. The name in the model selector does not tell you everything about what the complete system can accomplish.&lt;/p&gt;

&lt;p&gt;The model chooses what to say or which action to request. A tool does something outside the model, such as reading a file. The harness connects those pieces. It supplies context, makes allowed tools available, runs permitted actions, and returns their results.&lt;/p&gt;

&lt;p&gt;The model can then use that new information to decide what to do next.&lt;/p&gt;

&lt;h3&gt;
  
  
  0:59: Give it the right context
&lt;/h3&gt;

&lt;p&gt;For this task, I have a small file of fictional expenses. The goal is to calculate spending by category, flag anything that needs attention, and create a short summary. First, look at the information we are giving the agent. The file contains the original records.&lt;/p&gt;

&lt;p&gt;The instructions say how to handle a blank category: keep the record, group it separately, and do not guess. We also tell it to preserve the input instead of quietly changing the source. These details are context: the information available to the model for this job. More context is not automatically better.&lt;/p&gt;

&lt;p&gt;Unrelated files and old conversations can distract from the task. A useful harness helps select the relevant instructions and evidence, within the scope we allow. For longer tasks, a harness also has to manage limited context space. It may select earlier results or summarize older conversation.&lt;/p&gt;

&lt;p&gt;Summaries can lose detail, so keep critical facts in an artifact you can reopen. The file is durable; whether the next response uses it depends on what the system actually loads. Before pressing send, check that the request names the input, the expected output, and the rule for uncertainty. That makes success something we can actually inspect.&lt;/p&gt;

&lt;h3&gt;
  
  
  2:19: Follow the real tool loop
&lt;/h3&gt;

&lt;p&gt;Now we submit the task. Watch the activity between the prompt and the final response. The agent requests a tool, and the application performs the action. Opening the tool details lets us see which file it read and what information came back.&lt;/p&gt;

&lt;p&gt;We can see what it actually read. The model uses that result to choose its next step. If it needs another file or a calculation, another tool request can follow. This is the basic agent loop: decide, act through a tool, inspect what happened, and continue.&lt;/p&gt;

&lt;p&gt;This example uses files and a calculation. Those capabilities come from the integration around the model, and they should be limited to what the task needs. Installing a connector does not mean the agent should have unrestricted access. The loop does not guarantee that every decision is correct.&lt;/p&gt;

&lt;p&gt;It gives the system a way to work with evidence instead of stopping at a single response. In this example, the useful evidence is the original expense data and the calculations made from it. We can follow the activity and compare the proposed summary with those records. Notice that an empty category is still something to flag, not an invitation to invent a label.&lt;/p&gt;

&lt;p&gt;Check whether the actions and results support the answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  3:35: Check the result and the boundary
&lt;/h3&gt;

&lt;p&gt;Before accepting the summary, we check it against the original data. First, the calculator totals the source records. At this stage, it correctly reports that no summary has been saved. The expense with a missing category must remain visible in that check. Twelve records total two hundred and twenty-seven, including seventeen without a category.&lt;/p&gt;

&lt;p&gt;The calculated totals match the source records; that is evidence for this calculation. Now look at the write boundary. Reading the input and saving a new file are different actions. The first write is blocked by the read-only setting. The agent then asks for one-time permission to save this summary.&lt;/p&gt;

&lt;p&gt;Here, the application restricts which files and command the agent can use, and asks before writing this summary. This demonstrates an application permission boundary. An operating-system sandbox is a separate boundary, and we have not demonstrated one here. Inspect the proposed destination and contents before allowing this specific action.&lt;/p&gt;

&lt;p&gt;After the file is saved, reopen it and confirm what actually exists. The checker compares the saved category totals, grand total, and the count of records missing a category against the source. A pass supports those checks; it does not verify every sentence in the report. That final readback matters more than a message saying the work is done.&lt;/p&gt;

&lt;p&gt;Saved files only become context when the system loads them again. Approvals and sandboxes also do different jobs. An approval asks whether an action may proceed. A sandbox limits what the execution environment can reach.&lt;/p&gt;

&lt;p&gt;Always check what is actually enforced.&lt;/p&gt;

&lt;h3&gt;
  
  
  5:22: Judge the whole system
&lt;/h3&gt;

&lt;p&gt;The original file is unchanged, the totals have been checked, and the saved summary can be reopened. Following those steps gives us a practical way to evaluate the system. When you evaluate an agent, ask four questions. What information can it see?&lt;/p&gt;

&lt;p&gt;Which actions can it take? How is the result checked? And where must it stop? Those questions tell you much more than the name of the model alone.&lt;/p&gt;

&lt;p&gt;Try this with one small task of your own. Follow the actual steps, inspect the output, and identify one check you would want before trusting the result.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>tutorial</category>
      <category>automation</category>
    </item>
    <item>
      <title>Version AI Outputs Before People Rely on Them</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Tue, 13 Oct 2026 02:45:50 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/version-ai-outputs-before-people-rely-on-them-459p</link>
      <guid>https://dev.to/harshithvaddiparthy/version-ai-outputs-before-people-rely-on-them-459p</guid>
      <description>&lt;p&gt;A generated analysis can change after somebody has already acted on it. If your application overwrites the output in place, a later reviewer cannot reliably reconstruct which recommendation the person saw.&lt;/p&gt;

&lt;p&gt;OpenAI’s October 6 &lt;a href="https://openai.com/index/sharing-ai-progress-in-mathematics/" rel="noopener noreferrer"&gt;mathematics release&lt;/a&gt; offers a useful engineering prompt. The announcement describes manuscripts, Lean formalizations of many proofs, reasoning summaries and information about attempted problems. The &lt;a href="https://github.com/openai/math" rel="noopener noreferrer"&gt;repository&lt;/a&gt; says corrections become new versions while earlier released versions remain accessible.&lt;/p&gt;

&lt;p&gt;It also says results are at different verification stages, not all have accompanying formalizations, and some unformalized results could have issues. This article does not validate those mathematical results. The design lesson I am taking from the release is narrower: preserve the specific artifact that a review or decision refers to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate a result from its revisions
&lt;/h2&gt;

&lt;p&gt;For an AI-assisted report, keep a stable result ID and a separate revision ID. The result ID identifies the continuing task; the revision ID identifies one frozen output and its associated evidence.&lt;/p&gt;

&lt;p&gt;A minimal record could contain the artifact digest, creation time, prior revision, reason for the change, source references and review status. Record model and prompt versions when available and relevant to reproducing the process. Do not claim that these fields make a nondeterministic generation reproducible by themselves.&lt;/p&gt;

&lt;p&gt;Keep the output file and its receipt together. If somebody changes an assumption or conclusion after handover, create a new revision. The old revision remains the object of any earlier review. “Latest” can be a convenience pointer, but it should not be the identifier saved with a consequential decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bind a receipt to exact bytes
&lt;/h2&gt;

&lt;p&gt;Here is a small Python example using only the standard library. Run it in a temporary working directory. It creates a new directory for each revision and refuses to reuse an existing revision name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_revision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isalnum&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use an alphanumeric revision ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;read_revision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt;
    &lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Existing revision names are never overwritten.
&lt;/span&gt;    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;revision&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;previous&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;artifact_sha256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;review_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not_reviewed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;receipt.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;receipt&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_revision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isalnum&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use an alphanumeric revision ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt;
    &lt;span class="n"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;receipt.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read_bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;revision&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Revision identity mismatch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;artifact_sha256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Artifact differs from receipt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;receipt&lt;/span&gt;


&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;revisions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;save_revision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Supplier covers region A.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Initial unreviewed analysis&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;save_revision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Supplier excludes region A.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;previous&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Corrected coverage assumption&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;read_revision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Supplier covers region A.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;read_revision&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;previous&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example demonstrates an application convention and a byte-integrity check. It is not an immutable storage system. A person with filesystem write access can change both files, and a digest does not authenticate the author or establish that a claim is true.&lt;/p&gt;

&lt;p&gt;There is also no transaction across the two file writes. An interrupted save can leave an incomplete directory; the reader fails instead of treating it as a valid revision. A service implementation needs a transaction or an explicit completed state, appropriate permissions and a recovery process. Keep those requirements separate from what this short example proves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Store review decisions separately
&lt;/h2&gt;

&lt;p&gt;A reviewer should reference the revision ID and artifact digest they actually inspected. Keep the reviewer identity, time, intended use and scope of checks in a separate review record.&lt;/p&gt;

&lt;p&gt;For example, “arithmetic checked against supplied spreadsheet” is narrower than “recommendation approved.” If the spreadsheet itself has not been verified, that uncertainty should remain visible. A changed output should get a new review decision; copying an earlier approval onto the new revision would erase the very boundary the receipt is meant to preserve.&lt;/p&gt;

&lt;p&gt;Do the same for inputs that can change. A source URL alone may later show different content. Where you are permitted to retain it, capture the relevant source version or snapshot and its timestamp. For private material, use restricted references and your existing retention rules. Do not turn a review feature into an uncontrolled copy of confidential documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track the consequences of a correction
&lt;/h2&gt;

&lt;p&gt;A revision chain says what came before. It does not tell you who acted on it.&lt;/p&gt;

&lt;p&gt;If a report informs a consequential action, store that action’s reference to the specific revision. When an assumption changes, those references help identify decisions requiring another look. The correction event should describe the changed assumption and its possible consequence, rather than silently regenerating every downstream artifact.&lt;/p&gt;

&lt;p&gt;Avoid auto-invalidating every decision merely because wording changed. Define which changes require review for your use case: a different source, an altered calculation, a changed eligibility assumption or a reversed recommendation may matter more than an editorial fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the handover, not just the happy path
&lt;/h2&gt;

&lt;p&gt;Useful checks include retaining access to the earlier output after a new revision, refusing accidental reuse of a revision name and detecting an output that no longer matches its receipt. Test an interrupted write too: incomplete data should be visible as an error, not accepted as a completed record.&lt;/p&gt;

&lt;p&gt;If you also evaluate generation quality, keep task IDs distinct from attempt IDs. OpenAI’s repository reports attempted problems and groups outputs into manuscripts and families; those different units do not support a simple success-rate division. In your own pilot, attach retries to the original task and define what counts as a usable result before comparing runs.&lt;/p&gt;

&lt;p&gt;Start with one report or generated analysis that already crosses a team boundary. Save the revision people use, attach the scope of review, and make the next correction explicit. You can improve the storage architecture later; first make it possible to answer which version somebody trusted.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>Gate AI Workflow Acceptance on Mandatory Checks</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Mon, 12 Oct 2026 02:54:37 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/gate-ai-workflow-acceptance-on-mandatory-checks-1l60</link>
      <guid>https://dev.to/harshithvaddiparthy/gate-ai-workflow-acceptance-on-mandatory-checks-1l60</guid>
      <description>&lt;p&gt;An agent can configure most of a workflow correctly and still leave a required approval broken. If your evaluation reports only an average score, that failure can disappear inside an encouraging number.&lt;/p&gt;

&lt;p&gt;OpenAI's October 6 publication, &lt;a href="https://openai.com/index/advancing-computer-use-with-ironclad/" rel="noopener noreferrer"&gt;Advancing computer use with Ironclad&lt;/a&gt;, makes this a concrete engineering problem. The researchers worked with practitioners to define 11 tasks across legal, commercial and procurement work, with 8 to 50 evaluation criteria per task.&lt;/p&gt;

&lt;p&gt;OpenAI reports mean rubric scores of 55.0% for GPT-6 Astra at Max reasoning and 41.6% for GPT-5.6 Sol at High reasoning. Those averages describe criteria met, not the percentage of workflows completed perfectly. The reported 19.2 versus 37.0 minutes per attempt are simulated estimates, not measured customer savings. The results cover those 11 research tasks, not every Ironclad workflow.&lt;/p&gt;

&lt;p&gt;The implementation lesson I take from this is to separate a score that measures progress from the conditions that permit a workflow to be used. The design below is my proposed pattern, not a description of Ironclad's implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a versioned requirement
&lt;/h2&gt;

&lt;p&gt;Suppose a fictional purchasing policy requires Finance approval for amounts strictly above USD 10,000, excluding tax. A real owner would need to confirm those details; they should not be invented by the agent.&lt;/p&gt;

&lt;p&gt;Represent the amount in cents for this example, so the boundary is 1,000,000. Then define observable cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;999,999 cents follows the ordinary path.&lt;/li&gt;
&lt;li&gt;1,000,000 cents follows the ordinary path because the rule says strictly above.&lt;/li&gt;
&lt;li&gt;1,000,001 cents requires Finance approval.&lt;/li&gt;
&lt;li&gt;A missing amount remains incomplete rather than silently taking the ordinary path.&lt;/li&gt;
&lt;li&gt;Editing an existing request across the boundary triggers the review behavior specified by the owner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last two cases are additional proposed requirements. They need agreement before implementation. Their purpose is to expose ambiguity rather than turn an assumption into policy.&lt;/p&gt;

&lt;p&gt;Attach the accepted cases to a configuration version. A passing observation from yesterday's configuration should not authorize today's changed one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep mandatory checks separate
&lt;/h2&gt;

&lt;p&gt;A rubric can measure helpful labels, document quality and configuration details. Maintain that score for comparisons and debugging. Separately keep an explicit set of mandatory check IDs selected by the process owner.&lt;/p&gt;

&lt;p&gt;Here is a small Python gate for observations collected by a trusted test runner. It accepts only explicit passes with an evidence reference for the requested version. Missing, stale or inconclusive observations remain unverified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;acceptance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;observations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Define mandatory checks before evaluation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;unverified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;check_id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;observations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;
                &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;evidence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;unverified&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fail&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pass&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;unverified&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ready&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;unverified&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unverified&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;unverified&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is deliberately no aggregate score in this decision. A high score for optional checks cannot cancel a failed mandatory check. Both failed and unverified conditions prevent &lt;code&gt;ready&lt;/code&gt; from becoming true, while remaining distinct in the report.&lt;/p&gt;

&lt;p&gt;For example, these are synthetic fixtures demonstrating the gate's behavior, not evidence from a real workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;above_threshold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;missing_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;observations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;above_threshold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pass&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;config-7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;evidence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fixture:above-threshold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;acceptance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;observations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;config-7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ready&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unverified&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;missing_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An empty required set raises an error because an accidentally empty checklist should not produce a passing result. An unexpected status also remains unverified. This function assumes the input mapping follows the shown schema; validate untrusted input at the boundary before calling it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collect observations outside the agent's narration
&lt;/h2&gt;

&lt;p&gt;The gate above checks references and statuses. It does not prove that a referenced artifact exists or that the result is true. If the same agent can invent observations or rewrite the mandatory set, the gate offers little assurance.&lt;/p&gt;

&lt;p&gt;Have a separate test controller submit known requests in a safe environment and read the resulting route or approval state. Save the request ID, tested configuration version, input, expected outcome, actual outcome and supporting evidence. Check that the evidence reference resolves to the observation for that exact case and version before passing it to the gate.&lt;/p&gt;

&lt;p&gt;Use screenshots when visual context matters, but capture the actual result state too. A screenshot of a rule in an editor establishes what the configuration looks like. A routed test request establishes something different: how that configuration behaved for a particular input.&lt;/p&gt;

&lt;p&gt;Preserve failures as reproducible cases. "The agent missed some steps" is difficult to debug. "Increasing a saved request from 900,000 to 1,100,000 cents did not trigger Finance review" describes an input transition and an observable defect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recheck after changes
&lt;/h2&gt;

&lt;p&gt;After a configuration change, collect fresh observations for the mandatory cases. Do not reuse an old pass solely because the visible form looks unchanged. Approval routing may depend on fields, conditions or later edits that the screenshot does not reveal.&lt;/p&gt;

&lt;p&gt;For a first pilot, a small mandatory suite is more useful than a large collection of vague checks. Add cases when the owner identifies another requirement or a failure reveals a missing boundary. Track the broader rubric alongside it so you can see improvements that do not yet justify acceptance.&lt;/p&gt;

&lt;p&gt;Also record the human effort required to reach an accepted result: preparation, review, repair and repeated tests. Keep those measurements separate from model execution time and from the simulated timing in the research.&lt;/p&gt;

&lt;p&gt;OpenAI's publication explicitly retains a role for human oversight in complex contracting. This proposed gate does not remove that responsibility. It gives the responsible person a clearer view of what passed, what failed and what nobody has verified yet.&lt;/p&gt;

&lt;p&gt;Start with one workflow, one agreed version of its rules and a few meaningful cases. A reliable acceptance decision begins with a precise definition of what the finished system must do.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>Make AI-Generated Calculators Explain Their Inputs</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Thu, 08 Oct 2026 02:47:43 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/make-ai-generated-calculators-explain-their-inputs-9c4</link>
      <guid>https://dev.to/harshithvaddiparthy/make-ai-generated-calculators-explain-their-inputs-9c4</guid>
      <description>&lt;p&gt;OpenAI's &lt;a href="https://openai.com/index/gpt-6-for-everyone/" rel="noopener noreferrer"&gt;October 7 announcement of GPT-6 and Intelligent UI&lt;/a&gt; describes ChatGPT responses that can include forms, charts, buttons and interactive tools. It also describes native components that appear progressively as the model generates an interface.&lt;/p&gt;

&lt;p&gt;That makes a familiar engineering question more visible: what calculation sits behind a convenient control?&lt;/p&gt;

&lt;p&gt;My interpretation is that developers should make the inputs, assumptions and result easy to inspect when building similar tools. This article uses a deliberately small capacity calculator to show what that means. It is a hypothetical example, not an implementation of OpenAI's component system or evidence that a generated ChatGPT tool has passed these checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write down the calculation first
&lt;/h2&gt;

&lt;p&gt;Suppose a support team wants a rough monthly capacity estimate. The model has three inputs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monthly request count.&lt;/li&gt;
&lt;li&gt;Average minutes spent per request.&lt;/li&gt;
&lt;li&gt;Productive support minutes available per person in that same month.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multiplying the first two gives workload minutes. Dividing that by productive minutes per person gives a fractional staffing estimate. Rounding upward produces a whole-person capacity estimate.&lt;/p&gt;

&lt;p&gt;Every part of that description matters. Scheduled work hours and productive support minutes are different inputs. Monthly averages leave out peak-hour coverage. A single average handling time hides variation between simple requests and specialist work.&lt;/p&gt;

&lt;p&gt;The interface should state these limits near the result. They are assumptions to review with someone who knows the work. A correct division cannot tell you whether the three-input model represents the team's actual staffing constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep one deterministic calculation
&lt;/h2&gt;

&lt;p&gt;A small pure function is enough for this example. Given the same inputs, it returns the same result and changes no external system. The generated interface can call it when an input changes.&lt;/p&gt;

&lt;p&gt;Here is a complete JavaScript example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;estimateCapacity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;monthly_requests&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;average_minutes_per_request&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;monthly_productive_minutes_per_person&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;missing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;missing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;needs_input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;missing&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invalid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isFinite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInteger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;monthly_requests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;monthly_requests&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;monthly_requests&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;average_minutes_per_request&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;average_minutes_per_request&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;monthly_productive_minutes_per_person&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;monthly_productive_minutes_per_person&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid_input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;invalid&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;monthly_requests&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;average_minutes_per_request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workload&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;monthly_productive_minutes_per_person&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isFinite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isFinite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid_input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ok&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;formula_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;monthly-capacity-v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;workload_minutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;workload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fractional_people&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;rounded_people&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;people&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the demonstration, pass an object containing numbers. Convert form strings deliberately before calling the function, and preserve an empty field as missing; &lt;code&gt;Number("")&lt;/code&gt; produces zero and can hide an omitted value. A real endpoint also needs to validate the shape of its incoming object before using this function.&lt;/p&gt;

&lt;p&gt;The function rejects invalid numbers and nonpositive time values. It returns a separate &lt;code&gt;needs_input&lt;/code&gt; state when a required value is absent. Display that state as a request for information, keeping any previous result clearly marked as stale.&lt;/p&gt;

&lt;p&gt;No model call is required to redo the arithmetic. If the formula changes, review the change and update its version so a saved result can be interpreted later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the boundaries that change the answer
&lt;/h2&gt;

&lt;p&gt;Use known results to check the function before connecting an interface. These checks run in Node alongside the example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;assert&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:assert/strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;monthly_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;average_minutes_per_request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;monthly_productive_minutes_per_person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;estimateCapacity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fractional_people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;estimateCapacity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;monthly_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;rounded_people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;estimateCapacity&lt;/span&gt;&lt;span class="p"&gt;({}).&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;needs_input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;estimateCapacity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;monthly_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid_input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;estimateCapacity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;monthly_requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;800&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid_input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;estimateCapacity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;monthly_productive_minutes_per_person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid_input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All numbers here are synthetic demonstration inputs. They make the arithmetic observable and carry no staffing recommendation.&lt;/p&gt;

&lt;p&gt;Then check the interface itself. Clearing an input should request information. Changing the request count should use the new value. Each label should show its unit and period. If the display rounds a result, the unrounded value and rounding rule should remain available.&lt;/p&gt;

&lt;p&gt;An exported summary should contain the inputs, formula version, result and omitted factors. Another person should be able to reproduce it with ordinary arithmetic. This also helps reveal when a result was calculated using an earlier set of inputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give external actions their own review
&lt;/h2&gt;

&lt;p&gt;A calculator control can adjust a scenario locally. Submitting a staffing request is a separate operation that writes a record and may start an approval process.&lt;/p&gt;

&lt;p&gt;If you later add that operation, show the destination and proposed payload, check authorization on the server, and confirm the resulting record. Handle an uncertain response by checking whether the record already exists before resubmitting. The interface's own input validation does not establish permission to write.&lt;/p&gt;

&lt;p&gt;The OpenAI announcement does not show that every interactive answer can perform such external actions. These are implementation responsibilities for a system you choose to connect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a calculation you can inspect
&lt;/h2&gt;

&lt;p&gt;The announcement says Intelligent UI is rolling out in ChatGPT's Chat experience; enterprise availability depends on admin settings. It does not introduce this example as an API or change the models powering Work and Codex as part of the release.&lt;/p&gt;

&lt;p&gt;For your own prototype, choose a familiar calculation, state its assumptions, use synthetic inputs, and keep it limited to scenario exploration initially. Ask a domain expert whether the omitted factors change the decision.&lt;/p&gt;

&lt;p&gt;A useful generated interface makes the calculation understandable, lets people correct its inputs, and tells them when it cannot produce a meaningful result. Those properties can be checked regardless of how impressive the first rendering looks.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Build AI Provenance Checks That Can Say Unknown</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Tue, 06 Oct 2026 03:02:24 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/build-ai-provenance-checks-that-can-say-unknown-1kc4</link>
      <guid>https://dev.to/harshithvaddiparthy/build-ai-provenance-checks-that-can-say-unknown-1kc4</guid>
      <description>&lt;p&gt;OpenAI's &lt;a href="https://openai.com/index/eu-text-provenance/" rel="noopener noreferrer"&gt;October 5 text-provenance announcement&lt;/a&gt; is a useful prompt for builders. Its textGrain watermark puts a statistical signal into eligible model output. API customers can opt in for select models; eligible ChatGPT and Codex text in the EU is due to receive it over the coming weeks. Detector access starts with approved researchers and expert organizations, not a public endpoint that every product can call.&lt;/p&gt;

&lt;p&gt;The engineering lesson is broader than this rollout: an origin signal is one observation in a decision workflow. If your data model turns that observation into &lt;code&gt;written_by_ai: true&lt;/code&gt; or &lt;code&gt;written_by_human: true&lt;/code&gt;, it has already lost the uncertainty the source warns about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate capture, signal, and decision
&lt;/h2&gt;

&lt;p&gt;I would model a provenance review as three connected records, each with a different job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capture&lt;/strong&gt; records what the workflow knew when the document was created: a version hash, the policy for permitted AI use, an author declaration, and references used for material claims. A hash identifies the version under review; it does not prove who wrote it. Keep a link to the version history where one exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Signal&lt;/strong&gt; records what a check actually observed, including whether that check was applicable. A watermark observation needs its provider, method version, date, input version, and known limits. &lt;code&gt;not_detected&lt;/code&gt; is a result about a check, not a statement of human authorship. &lt;code&gt;not_run&lt;/code&gt;, &lt;code&gt;unsupported&lt;/code&gt;, and &lt;code&gt;inconclusive&lt;/code&gt; are useful states too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision&lt;/strong&gt; records what a person did with the evidence: which claims were checked, who reviewed them, whether the work was approved or needs revision, and why. The decision can remain pending when the evidence is incomplete.&lt;/p&gt;

&lt;p&gt;Here is a &lt;strong&gt;proposed internal shape&lt;/strong&gt;, not an OpenAI API response:&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;"document_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"declared_ai_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unknown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"watermark_check"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"eligibility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unknown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not_run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"method_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&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;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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source_check"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&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;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;This example records a check that has not run and a decision that has not been made. Other possible check results include &lt;code&gt;detected&lt;/code&gt;, &lt;code&gt;not_detected&lt;/code&gt;, and &lt;code&gt;inconclusive&lt;/code&gt;. The exact fields will vary. The key property is that missing evidence stays missing. A downstream dashboard should never relabel &lt;code&gt;not_detected&lt;/code&gt; as “human written,” or &lt;code&gt;detected&lt;/code&gt; as misconduct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the limits visible in the interface
&lt;/h2&gt;

&lt;p&gt;OpenAI says a text watermark cannot identify the user, measure human contribution, establish ownership or responsibility, or verify accuracy. It also says that no detected watermark does not prove human authorship. Editing, translation, short passages, older output, and unsupported models can all complicate detection.&lt;/p&gt;

&lt;p&gt;Its own evaluation shows why the qualification matters. For 400-token English passages in one test, replacing 10% of words with synonyms reduced detection from about 92% to 66%; replacing 25% reduced it to 17%. Those are company-reported results under specific conditions, not a field benchmark you can apply to every document.&lt;/p&gt;

&lt;p&gt;Show that scope beside a result. An interface that displays only a red or green badge invites an overconfident decision. A review screen should show the input version, whether the method was eligible, the observed result, and what the result cannot establish. If a tool returns a probability or score, preserve its meaning and calibration rather than converting it into a verdict through a hidden threshold.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route consequential cases to people
&lt;/h2&gt;

&lt;p&gt;Consider a hypothetical policy memo. The team permits disclosed AI assistance and needs accurate claims plus a named approver. A detected watermark might justify asking how the memo was drafted. It cannot tell the team whether the memo's sources support its recommendations.&lt;/p&gt;

&lt;p&gt;The review queue should bring the memo version, declaration, source links, and prior edits together. Reviewers can then check the claims that matter, ask for missing context, and record a decision. If the result could affect a person's reputation or opportunity, include a way to explain the evidence and correct errors. Do not make an adverse action the automatic output of a detector callback.&lt;/p&gt;

&lt;p&gt;You can build this queue without a watermark detector. In fact, the current access limit means many teams must. Capture and review are still useful when a signal is unavailable, and they continue to matter if access expands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the workflow, not just the classifier
&lt;/h2&gt;

&lt;p&gt;If you can evaluate a provenance signal for your own authorized material, include clean, edited, short, translated, and constrained examples. Keep examples outside the tuning set. Measure false alarms, missed signals, inconclusive cases, reviewer time, and the decisions that followed. Separate results by content type; one overall rate can hide the cases your product handles poorly.&lt;/p&gt;

&lt;p&gt;Write the proposed action for each result before looking at the scores. “Ask for supporting records” is a different consequence from “reject the work.” The evidence needed for those actions should differ too. Make it possible to pause when the method's scope is unknown.&lt;/p&gt;

&lt;p&gt;My first implementation step would be a document-version record and a small review form with an explicit &lt;code&gt;unknown&lt;/code&gt; state. Then I would test whether the team can answer who approved a claim and what source supported it. A detector can be assessed later as one additional observation. The system is useful as soon as it can preserve evidence and make uncertainty visible.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>ethics</category>
    </item>
    <item>
      <title>Design AI Workflows Around Verified Completion</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Thu, 01 Oct 2026 22:55:01 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/design-ai-workflows-around-verified-completion-39p9</link>
      <guid>https://dev.to/harshithvaddiparthy/design-ai-workflows-around-verified-completion-39p9</guid>
      <description>&lt;p&gt;While connecting a Mac mini to Jarvis, my AI assistant, I kept coming back to a small question: what can I prove actually happened?&lt;/p&gt;

&lt;p&gt;The setup produced a series of ordinary milestones. A command ran on the intended machine. A file transferred and could be read back. A browser opened the requested page. A device on my home network returned its status. The connection recovered after a deliberate connection restart.&lt;/p&gt;

&lt;p&gt;Each result established a specific capability. Together, they gave the assistant a practical way to carry out work.&lt;/p&gt;

&lt;p&gt;Then I asked it to research an article and prepare a Medium draft. It reached a login screen. I signed in, and the work continued.&lt;/p&gt;

&lt;p&gt;For someone building agent workflows, that handoff is a useful place to start. Understanding a task and completing it depend on different parts of the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intelligence needs execution capacity
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://openai.com/index/the-eternal-complement/" rel="noopener noreferrer"&gt;“The eternal complement”&lt;/a&gt;, Hemanth Asirvatham and Elliott Mokski argue that intelligence needs complementary capacity to turn ideas into progress. Their essay is hosted on OpenAI’s Intelligence Age platform and explicitly represents their own views, not OpenAI’s position.&lt;/p&gt;

&lt;p&gt;The authors use “institutional intelligence” to describe the coordination behind execution: funding, supply chains, laws and the many correct local actions that make an ambitious project possible.&lt;/p&gt;

&lt;p&gt;An agent workflow has its own supporting work. It needs the right input, access to the right application, a clear scope of authority and a way to check the result.&lt;/p&gt;

&lt;p&gt;A model may produce an excellent plan while those pieces remain missing. Making the plan more sophisticated does not automatically supply the missing login or establish that a file was saved.&lt;/p&gt;

&lt;p&gt;My computer setup is a small example of this relationship. It does not establish anything about the future of superintelligence. It does make the dependency visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define completion before choosing tools
&lt;/h2&gt;

&lt;p&gt;“Write an article” leaves several possible stopping points.&lt;/p&gt;

&lt;p&gt;The model could return text in chat. It could save a local file. It could create a draft in the intended account. It could publish the reviewed version and verify the public page.&lt;/p&gt;

&lt;p&gt;Each is a different deliverable.&lt;/p&gt;

&lt;p&gt;For a draft workflow, I would define completion as: the intended title, body and links are saved in the correct account, and the content survives a reload.&lt;/p&gt;

&lt;p&gt;For an authorized publishing workflow, I would add: the public article exists, the author is correct, and the published body matches the intended version.&lt;/p&gt;

&lt;p&gt;Those definitions give the implementation something concrete to verify. They also prevent a fluent final message from becoming the only evidence that the work succeeded.&lt;/p&gt;

&lt;p&gt;Before adding another tool, write the acceptance condition in one sentence. Then identify which tool can produce evidence for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat the application’s saved state as evidence
&lt;/h2&gt;

&lt;p&gt;Browser automation introduces an easy trap. A successful input operation is not the same as a successful application write.&lt;/p&gt;

&lt;p&gt;Text can land in the wrong field. A rich editor can show content before it has persisted. A connection can drop while the application is saving.&lt;/p&gt;

&lt;p&gt;For this kind of workflow, a small write probe is useful. Enter a small amount through the intended UI, inspect where it landed, and confirm that the application created the expected saved artifact before inserting the full body.&lt;/p&gt;

&lt;p&gt;After the full edit, reload and compare the persisted content with the intended text. Check links as well as paragraphs. Inspect the rendered page where layout matters.&lt;/p&gt;

&lt;p&gt;This is why screenshots and text readback complement each other. A screenshot can expose a formatting problem. A full text comparison can expose missing content that sits outside the viewport.&lt;/p&gt;

&lt;p&gt;The evidence should match the claim. A working browser establishes browser access. Recovery after restarting a connection establishes that recovery path. Unattended recovery after a machine reboot would need a separate test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep uncertainty in the state model
&lt;/h2&gt;

&lt;p&gt;The most important failure case often happens after an external action starts.&lt;/p&gt;

&lt;p&gt;Suppose an agent clicks Publish and then loses its connection. The article may already be public. The agent may simply have missed the response.&lt;/p&gt;

&lt;p&gt;Treating that as an ordinary failure and retrying immediately can repeat the action.&lt;/p&gt;

&lt;p&gt;A content workflow can distinguish these states:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;What it establishes&lt;/th&gt;
&lt;th&gt;What happens next&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prepared&lt;/td&gt;
&lt;td&gt;Local content and the intended account are known&lt;/td&gt;
&lt;td&gt;Create or reconcile the draft&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Saved&lt;/td&gt;
&lt;td&gt;The application retained the intended content&lt;/td&gt;
&lt;td&gt;Continue within the authorized scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publishing&lt;/td&gt;
&lt;td&gt;Publication intent was recorded before the external action&lt;/td&gt;
&lt;td&gt;Observe the result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uncertain publication&lt;/td&gt;
&lt;td&gt;The action may have succeeded, but evidence is incomplete&lt;/td&gt;
&lt;td&gt;Inspect the existing story and public profile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Published&lt;/td&gt;
&lt;td&gt;The public artifact and its content were verified&lt;/td&gt;
&lt;td&gt;Record the result and stop&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This table is a practical design suggestion, not a framework prescribed by the essay.&lt;/p&gt;

&lt;p&gt;The record needs enough information to reconcile the operation: the existing draft identifier, intended account, content hash, and any public URL already returned. Write the intent before the action, and preserve those identifiers when an error occurs.&lt;/p&gt;

&lt;p&gt;A local record cannot make an external website transaction atomic. Its value is that the next attempt can investigate the same operation instead of starting over.&lt;/p&gt;

&lt;p&gt;Once publication is verified, a later cleanup error should not silently downgrade the article to “unpublished.” Record the cleanup problem separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put autonomy inside a clear scope
&lt;/h2&gt;

&lt;p&gt;A workflow needs to know what it is allowed to do.&lt;/p&gt;

&lt;p&gt;That can include standing authorization to complete a recurring task. The agent should carry out that authorized work without asking the same question at every step.&lt;/p&gt;

&lt;p&gt;It should also recognize actual exceptions: an expired login, a different account, a platform refusal, or an outcome it cannot establish.&lt;/p&gt;

&lt;p&gt;Persist the exception and the work already completed. A vague “something went wrong” gives the next run very little to work with. A known draft URL and an uncertain publication state give it a specific investigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improve the next blocked step
&lt;/h2&gt;

&lt;p&gt;The essay explores two uncertain directions. In a civilization of depth, better intelligence makes much more effective use of existing knowledge and resources. In a civilization of width, it generates worthwhile projects faster than supporting capacity can keep up.&lt;/p&gt;

&lt;p&gt;The authors do not predict which direction will dominate. The idea that machine intelligence could spend most of its time on routine organizational work belongs to the width scenario.&lt;/p&gt;

&lt;p&gt;For the workflow in front of me, I do not need to settle that question.&lt;/p&gt;

&lt;p&gt;I can choose one recurring task, define its finished result, and follow it through every dependency. Where does it wait for access? Where is the outcome assumed rather than checked? What happens if the next external write succeeds but its response never arrives?&lt;/p&gt;

&lt;p&gt;Answering those questions gives me concrete implementation work. It is the ordinary work that lets an intelligent system carry a useful idea through to a result.&lt;/p&gt;




&lt;p&gt;Adapted from &lt;a href="https://harshith-vaddiparthy.medium.com/the-boring-work-that-makes-ai-useful-bd3994a83ab6" rel="noopener noreferrer"&gt;my original Medium article, “The Boring Work That Makes AI Useful”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Primary source: &lt;a href="https://openai.com/index/the-eternal-complement/" rel="noopener noreferrer"&gt;“The eternal complement,” by Hemanth Asirvatham and Elliott Mokski&lt;/a&gt;. The authors write as independent voices hosted by OpenAI.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>ai</category>
      <category>automation</category>
      <category>programming</category>
    </item>
    <item>
      <title>Forking Macro: A Technical Walkthrough of Agent Collaboration</title>
      <dc:creator>Harshith Vaddiparthy</dc:creator>
      <pubDate>Wed, 19 Aug 2026 20:33:54 +0000</pubDate>
      <link>https://dev.to/harshithvaddiparthy/forking-macro-a-technical-walkthrough-of-agent-collaboration-6ab</link>
      <guid>https://dev.to/harshithvaddiparthy/forking-macro-a-technical-walkthrough-of-agent-collaboration-6ab</guid>
      <description>&lt;p&gt;Multi-agent demos often hide the most difficult engineering problem.&lt;/p&gt;

&lt;p&gt;Disclosure: I used AI tools to assist with research organization and drafting. I reviewed, edited, fact-checked, and source-checked this article before publication.&lt;/p&gt;

&lt;p&gt;Spawning workers is not collaboration. A collaborative system must manage context, permissions, handoffs, concurrent state, and verification across humans and agents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://macro.com" rel="noopener noreferrer"&gt;Macro&lt;/a&gt; is a workspace that &lt;a href="https://macro.com/posts/why-macro-is-open-source" rel="noopener noreferrer"&gt;describes its open-source decision publicly&lt;/a&gt; and is useful to examine through this lens. Its official repository is published at &lt;a href="https://github.com/macro-inc/macro" rel="noopener noreferrer"&gt;&lt;code&gt;macro-inc/macro&lt;/code&gt;&lt;/a&gt;. The root license presents AGPLv3, but a nested web-app license says all rights reserved. That conflict matters and is covered below. The published stack includes Rust and SolidJS. Macro connects documents, email, tasks, calls, channels, CRM, memory, and agents.&lt;/p&gt;

&lt;p&gt;I am using Macro and &lt;a href="https://github.com/harshith-vaddiparthy/macro" rel="noopener noreferrer"&gt;forked the repository&lt;/a&gt;. On August 19, 2026, GitHub compare showed the fork's &lt;code&gt;main&lt;/code&gt; identical to upstream &lt;code&gt;main&lt;/code&gt;, 0 commits ahead and 0 behind, at &lt;code&gt;02c218308c462046ee54e6f275b8c0a371ee3f5a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Important scope note: no local clone, modified branch, self-hosted deployment, or benchmark is claimed in this article. The walkthrough maps verified repository and documentation claims to a reproducible evaluation plan. It does not pretend I ran tests for which I have no artifact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository snapshot
&lt;/h2&gt;

&lt;p&gt;At review time, the official repository showed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Snapshot on 2026-08-19&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stars&lt;/td&gt;
&lt;td&gt;3,696&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forks&lt;/td&gt;
&lt;td&gt;362&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commits in &lt;code&gt;main&lt;/code&gt; history&lt;/td&gt;
&lt;td&gt;5,066&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open issues&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open pull requests&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tags&lt;/td&gt;
&lt;td&gt;213&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latest visible release&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v2026.8.18.2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviewed commit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;02c218308c462046ee54e6f275b8c0a371ee3f5a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are activity signals, not performance results. The latest values will change.&lt;/p&gt;

&lt;p&gt;The cover uses Macro's &lt;a href="https://github.com/macro-inc/macro/blob/02c218308c462046ee54e6f275b8c0a371ee3f5a/.github/readme/star-history-dark.svg" rel="noopener noreferrer"&gt;older embedded star-history snapshot&lt;/a&gt;, which shows 3,608 stars. The live count at this review checkpoint was 3,696.&lt;/p&gt;

&lt;p&gt;Macro &lt;a href="https://x.com/macrodotcom/status/2087901565357031661" rel="noopener noreferrer"&gt;said on August 13&lt;/a&gt; that the repository briefly reached number one on GitHub Trending. The company &lt;a href="https://x.com/macrodotcom/status/2087590351565435053" rel="noopener noreferrer"&gt;said on August 12&lt;/a&gt; that it had received an influx of users, pull requests, and feature requests. Both are attributed company statements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce the source boundary first
&lt;/h2&gt;

&lt;p&gt;If you want to inspect the same fork, begin by recording the exact source state. The commands below verify Git identity only. They do not install or run Macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/harshith-vaddiparthy/macro.git
&lt;span class="nb"&gt;cd &lt;/span&gt;macro
git remote add upstream https://github.com/macro-inc/macro.git
git fetch upstream main
git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
git status &lt;span class="nt"&gt;--short&lt;/span&gt;
git rev-parse HEAD
git rev-parse upstream/main
git rev-list &lt;span class="nt"&gt;--left-right&lt;/span&gt; &lt;span class="nt"&gt;--count&lt;/span&gt; upstream/main...HEAD
git log &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before building, compare the full SHA with the current upstream default branch and read the repository's current README. Do not assume dependencies or setup commands from this dated article are still correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolve the license boundary before reuse
&lt;/h2&gt;

&lt;p&gt;The root &lt;a href="https://github.com/macro-inc/macro/blob/02c218308c462046ee54e6f275b8c0a371ee3f5a/LICENSE.txt" rel="noopener noreferrer"&gt;&lt;code&gt;LICENSE.txt&lt;/code&gt;&lt;/a&gt; presents AGPLv3. The same reviewed tree contains &lt;a href="https://github.com/macro-inc/macro/blob/02c218308c462046ee54e6f275b8c0a371ee3f5a/apps/web/LICENSE" rel="noopener noreferrer"&gt;&lt;code&gt;apps/web/LICENSE&lt;/code&gt;&lt;/a&gt; with the exact line &lt;code&gt;Copyright 2023 CoParse, Inc. All rights reserved.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Those terms conflict with a repository-wide assumption that every file is AGPLv3. The affected scope needs clarification from Macro's maintainers. Until then, do not assume every web-app file, screenshot, or asset can be reused under the root license.&lt;/p&gt;

&lt;p&gt;This article does not decide which terms control. Before modifying, distributing, hosting, or reusing repository material, inspect the applicable path, request maintainer clarification, and obtain appropriate legal advice.&lt;/p&gt;

&lt;h2&gt;
  
  
  A technical model of Macro's collaboration surface
&lt;/h2&gt;

&lt;p&gt;The documented system can be understood as six connected layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Work surfaces
  email | tasks | documents | calls | channels | CRM
                         |
                         v
Shared memory refreshed nightly from team activity
                         |
              explicit context via @mentions
                         |
                         v
Agents operating under the user's permissions
                         |
       read | draft | write | update | post | automate
                         |
                         v
Shared document state using CRDT collaboration
                         |
                         v
External coding agents through an MCP endpoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an editorial model based on Macro's website, documentation, and README. It is not a literal internal service diagram.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: Work surfaces
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/product/agents" rel="noopener noreferrer"&gt;Agents documentation&lt;/a&gt; says agents can access email, tasks, documents, calls, and channels under the user's permissions. Documented actions include search and read, document writing, task and CRM updates, email drafting, channel posts, call reading, and automation.&lt;/p&gt;

&lt;p&gt;The engineering advantage is context locality. The agent does not need a separate integration for every step if the workspace already exposes the relevant object and action.&lt;/p&gt;

&lt;p&gt;The risk is authority aggregation. A workspace that unifies several tools can give one agent a broad action surface. The permission model, confirmation boundaries, audit trail, and revocation behavior therefore matter as much as tool coverage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Shared memory
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/product/unified-memory" rel="noopener noreferrer"&gt;Unified Memory documentation&lt;/a&gt; says memory refreshes nightly from team activity.&lt;/p&gt;

&lt;p&gt;A shared memory layer can reduce repeated context assembly. It can also create subtle failure modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stale information remains retrievable;&lt;/li&gt;
&lt;li&gt;two sources disagree;&lt;/li&gt;
&lt;li&gt;deletion does not propagate as expected;&lt;/li&gt;
&lt;li&gt;an agent retrieves a related but non-authoritative artifact;&lt;/li&gt;
&lt;li&gt;the user cannot see why a particular item was selected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Test memory against the latency of the workflow. A nightly refresh may fit a weekly recap. It may not fit an incident response or a decision made minutes ago.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: Explicit context
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/product/agents" rel="noopener noreferrer"&gt;Agents documentation&lt;/a&gt; presents &lt;code&gt;@mentions&lt;/code&gt; as a way to pin context for an agent.&lt;/p&gt;

&lt;p&gt;This gives the system two retrieval modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;broad organizational context from shared memory;&lt;/li&gt;
&lt;li&gt;task-specific context selected by a human or collaborator.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That distinction is useful because retrieval relevance is not the same as authority. The closest semantic match may not be the document that governs the current decision. Pinning context creates a direct signal about which source matters now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 4: Handoffs
&lt;/h3&gt;

&lt;p&gt;The official repository includes an agent task-handoff screenshot. A handoff is the state boundary between actors, so evaluate it as structured data rather than a friendly message.&lt;/p&gt;

&lt;p&gt;A robust handoff should preserve at least:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;goal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;are&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;we&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;trying&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;produce?"&lt;/span&gt;
&lt;span class="na"&gt;source_artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Which&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;documents,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;calls,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tasks,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;govern&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;work?"&lt;/span&gt;
&lt;span class="na"&gt;completed_work&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;has&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;already&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changed?"&lt;/span&gt;
&lt;span class="na"&gt;open_questions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;remains&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;unresolved?"&lt;/span&gt;
&lt;span class="na"&gt;next_action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;should&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;happen&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;next?"&lt;/span&gt;
&lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Which&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;person&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;responsible&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;now?"&lt;/span&gt;
&lt;span class="na"&gt;verification&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;can&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;next&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;actor&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;claims?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This YAML is an evaluation template, not Macro configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 5: Concurrent document state
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/product/docs" rel="noopener noreferrer"&gt;Documents documentation&lt;/a&gt; says its documents use CRDTs with Cloudflare Durable Objects. The README describes swarms of agents acting as peers in CRDT collaboration.&lt;/p&gt;

&lt;p&gt;A conflict-free replicated data type allows concurrent updates to converge without using a simple last-write-wins overwrite. This is relevant when humans and several agents edit a shared document.&lt;/p&gt;

&lt;p&gt;CRDTs solve a state problem. They do not solve a meaning problem.&lt;/p&gt;

&lt;p&gt;Two changes can merge correctly and contradict each other. One agent can add a decision while another rewrites the assumption behind it. A production workflow still needs editorial ownership, review boundaries, and a way to identify which claims require verification.&lt;/p&gt;

&lt;p&gt;Useful CRDT tests include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;two agents insert text at the same location;&lt;/li&gt;
&lt;li&gt;a human deletes a section while an agent edits it;&lt;/li&gt;
&lt;li&gt;one participant works from a delayed client;&lt;/li&gt;
&lt;li&gt;several edits reference the same task or decision;&lt;/li&gt;
&lt;li&gt;a reconnect occurs after substantial concurrent work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Measure both state convergence and semantic coherence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 6: External agents over MCP
&lt;/h3&gt;

&lt;p&gt;Macro's &lt;a href="https://docs.macro.com/AI/mcp/overview" rel="noopener noreferrer"&gt;MCP overview&lt;/a&gt; names Claude Code and Codex CLI. Its &lt;a href="https://docs.macro.com/product/agents" rel="noopener noreferrer"&gt;Agents documentation&lt;/a&gt; separately names Cursor. MCP gives an AI client a standard interface to external context and tools.&lt;/p&gt;

&lt;p&gt;The valuable pattern is a closed state loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shared task -&amp;gt; coding agent -&amp;gt; repository work -&amp;gt; task update -&amp;gt; team recap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An integration is incomplete if it only sends context to the agent. The agent should return a structured status, evidence, and unresolved questions to the workspace where the team coordinates.&lt;/p&gt;

&lt;p&gt;Macro's published &lt;a href="https://docs.macro.com/AI/recipes" rel="noopener noreferrer"&gt;Agent Recipes&lt;/a&gt; include MCP-driven coding-agent task updates, along with daily briefs, project status, weekly recap, call-to-tasks, draft email, and channel summary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a bounded evaluation, not a swarm demo
&lt;/h2&gt;

&lt;p&gt;A weekly project recap is a good first workflow because it is recurring, reviewable, and reversible.&lt;/p&gt;

&lt;p&gt;Define the test before connecting broad authority:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test dimension&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Evidence to capture&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Context&lt;/td&gt;
&lt;td&gt;Did the agent use the governing sources?&lt;/td&gt;
&lt;td&gt;Source links and retrieval trace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Freshness&lt;/td&gt;
&lt;td&gt;Did it include a recent change?&lt;/td&gt;
&lt;td&gt;Source timestamp versus output timestamp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permission&lt;/td&gt;
&lt;td&gt;Could it access only allowed objects?&lt;/td&gt;
&lt;td&gt;Account role and denied-access test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Handoff&lt;/td&gt;
&lt;td&gt;Did it preserve owners and open questions?&lt;/td&gt;
&lt;td&gt;Structured comparison with source tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Action boundary&lt;/td&gt;
&lt;td&gt;Did it draft or mutate shared state?&lt;/td&gt;
&lt;td&gt;Before and after object state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency&lt;/td&gt;
&lt;td&gt;What happened during a conflicting edit?&lt;/td&gt;
&lt;td&gt;Revision history and final document&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verification&lt;/td&gt;
&lt;td&gt;Can a human reconstruct the output?&lt;/td&gt;
&lt;td&gt;Action log, citations, and correction record&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Run the workflow in three rounds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Happy path:&lt;/strong&gt; clean sources, no conflicts, draft-only output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adversarial path:&lt;/strong&gt; one stale document, one contradictory update, and one inaccessible source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrent path:&lt;/strong&gt; a human or second agent changes a related artifact while the workflow is active.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The primary metric should be correction cost. Record how long a person spends finding missing context, checking claims, fixing ownership, and restoring state. Fast generation does not help if review becomes expensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the architecture is promising
&lt;/h2&gt;

&lt;p&gt;Macro's direction connects several primitives that are often separated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an inspectable public implementation with a license-scope conflict that needs clarification;&lt;/li&gt;
&lt;li&gt;shared organizational context;&lt;/li&gt;
&lt;li&gt;explicit context selection;&lt;/li&gt;
&lt;li&gt;permission-aware actions;&lt;/li&gt;
&lt;li&gt;concurrent collaborative documents;&lt;/li&gt;
&lt;li&gt;MCP access for external coding agents;&lt;/li&gt;
&lt;li&gt;recipes that return work to a shared system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The combination is the important part. An agent becomes more useful when it can read current work, make a bounded contribution, and return state that another person or agent can continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  What remains unproven here
&lt;/h2&gt;

&lt;p&gt;This review does not establish:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;production reliability or security;&lt;/li&gt;
&lt;li&gt;latency and cost at scale;&lt;/li&gt;
&lt;li&gt;the quality of memory retrieval;&lt;/li&gt;
&lt;li&gt;behavior under permission changes;&lt;/li&gt;
&lt;li&gt;audit-log completeness;&lt;/li&gt;
&lt;li&gt;semantic quality under concurrent edits;&lt;/li&gt;
&lt;li&gt;successful self-hosting from Harshith's fork;&lt;/li&gt;
&lt;li&gt;a modification or benchmark at revision &lt;code&gt;02c218308c462046ee54e6f275b8c0a371ee3f5a&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are test targets, not conclusions to smuggle into a launch post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The hard part of multi-agent software is not multiplying workers. It is coordinating context, authority, shared state, handoffs, and verification.&lt;/p&gt;

&lt;p&gt;Macro is worth studying because its public architecture addresses those concerns directly. Shared memory gives agents organizational context. &lt;code&gt;@mentions&lt;/code&gt; narrow attention. Permission-bound actions connect context to work. CRDTs support concurrent collaboration. MCP can return coding-agent state to the team's workspace. Studying public code is different from assuming every path has uniform reuse terms, so the nested-license conflict remains a real diligence item.&lt;/p&gt;

&lt;p&gt;None of these features eliminates the need for verification. Together, they provide a concrete public system against which developers can test collaboration claims.&lt;/p&gt;

&lt;p&gt;Credit to &lt;a href="https://x.com/j_becke" rel="noopener noreferrer"&gt;Jacob Beckerman&lt;/a&gt;, whose profile identifies him as Macro's founder and CEO, and the &lt;a href="https://macro.com" rel="noopener noreferrer"&gt;Macro team&lt;/a&gt; for publishing the work. This is an independent technical analysis and does not imply endorsement.&lt;/p&gt;

&lt;p&gt;For the broader product argument, FAQ, sources, and dated updates, read the &lt;a href="https://www.harshith.com/blog/macro-open-source-agent-collaboration" rel="noopener noreferrer"&gt;canonical guide&lt;/a&gt;.&lt;/p&gt;

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