<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[StatePort Blog]]></title><description><![CDATA[StatePort Blog]]></description><link>https://stateport.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6a79b0ad0fd798bc3b4f8a42/07068ba1-ff16-487a-8fc5-f24b99d38b12.jpg</url><title>StatePort Blog</title><link>https://stateport.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 07 Oct 2026 15:37:18 GMT</lastBuildDate><atom:link href="https://stateport.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Keep the failing setup when your coding agent fixes a bug]]></title><description><![CDATA[Disclosure: I build StatePort, which saves supported browser and API conditions for reopening against current local code. This article uses our public synthetic Reproduction Lab and was prepared with ]]></description><link>https://stateport.hashnode.dev/keep-the-failing-setup-when-your-coding-agent-fixes-a-bug</link><guid isPermaLink="true">https://stateport.hashnode.dev/keep-the-failing-setup-when-your-coding-agent-fixes-a-bug</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[ai agents]]></category><dc:creator><![CDATA[Roman Novikov]]></dc:creator><pubDate>Sat, 03 Oct 2026 13:17:38 GMT</pubDate><content:encoded><![CDATA[<p>Disclosure: I build StatePort, which saves supported browser and API conditions for reopening against current local code. This article uses our public synthetic Reproduction Lab and was prepared with AI assistance. The exercise works without StatePort, an account or external services.</p>
<p>A quota screen shows 100 credits available. Its API says zero. A coding agent can spot the one-line fix quickly, but it can also make the symptom disappear by changing the setup. If the role changes or the fixture returns a positive quota, the next screenshot tells you little about the original bug.</p>
<p>This exercise gives the agent a small, explicit contract: keep the failing inputs constant, change the code, and verify both the decision and the visible control.</p>
<h2>Run a pinned version of the exercise</h2>
<p>You need Git and Node.js 22 or newer. Start in a directory where you can create a fresh clone. No npm install is needed: the app uses Node built-ins.</p>
<pre><code class="language-bash">git clone https://github.com/StatePort-Dev/stateport-agent-skills.git
cd stateport-agent-skills
git checkout cbb2b5b03017048a544bb4aa3c144fea77837c8d
cd examples/repro-lab
npm start
</code></pre>
<p>Open <a href="http://127.0.0.1:4173">http://127.0.0.1:4173</a> and keep the server running. It listens only on loopback. If that port is occupied, choose another port in server.mjs and use the same origin throughout. Stop the server with Ctrl+C.</p>
<p>Choose Reviewer, then Exhausted quota, and enter 10 credits. The API response is:</p>
<pre><code class="language-json">{ "remaining": 0, "defaultLimit": 100 }
</code></pre>
<p>The buggy UI displays 100 available and enables Simulate allocation. Expected behavior is 0 available, Not enough credits, and a disabled button. Allocation is simulated; it changes no server data. The role is a UI fixture, not real authentication.</p>
<h2>Keep the reproduction constant</h2>
<p>In another terminal, from examples/repro-lab, run npm test. The supplied regression intentionally fails because 100 does not equal 0. It imports the same decision function used by the page:</p>
<pre><code class="language-javascript">const result = decision('reviewer', 10, {
  remaining: 0,
  defaultLimit: 100
});
assert.equal(result.available, 0);
assert.equal(result.allowed, false);
</code></pre>
<p>The default Member role already blocks allocation, so starting from that role can hide the defect. Keep Reviewer, exhausted quota and 10 credits in both the before and after checks.</p>
<p>These controls persist in localStorage under three repro-lab keys. Reloading the same origin can preserve them; a fresh browser profile starts with defaults. Reset this demo clears only those keys. A URL alone does not describe this reproduction.</p>
<h2>Fix the meaning of zero</h2>
<p>In public/decision.mjs, the faulty expression is:</p>
<pre><code class="language-javascript">const available = quota.remaining || quota.defaultLimit;
</code></pre>
<p>Logical OR treats zero as falsy and selects 100. This exercise defines null as missing, while zero is a valid exhausted quota. Use nullish coalescing:</p>
<pre><code class="language-javascript">const available = quota.remaining ?? quota.defaultLimit;
</code></pre>
<p>Run npm test again. Then reload the same page and verify the displayed value, decision text and disabled button. A passing function test does not prove the browser loaded the changed module or applied the result to the control.</p>
<p>Keep Reviewer and 10 credits, then check Normal quota and Missing quota: both should allow allocation with 100 available. Switch to Member and confirm allocation is blocked. The null fallback belongs to this fixture’s contract; a real service still needs validation rules for unexpected types, negative values and malformed responses.</p>
<h2>Use this agent handoff</h2>
<p>Give your coding agent the following task in the cloned repository:</p>
<pre><code class="language-text">Reproduce Reviewer / Exhausted quota / 10 credits at
http://127.0.0.1:4173. Keep those inputs and the API response
remaining=0, defaultLimit=100 unchanged. Run the supplied
regression before editing. Fix the decision function, rerun
the regression, and inspect the browser again. Report the
before/after available value, decision text and button state.
Check Normal and Missing quota too. If browser access fails,
report that limitation rather than claiming a browser pass.
</code></pre>
<p>That last sentence matters. The lab’s Node regression and HTTP responses have been checked. Browser rendering and this example’s complete StatePort capture, reopen and comparison cycle have not been verified for this article. There is no prepared State Card to download.</p>
<h2>Try a saved reproduction</h2>
<p>For repeated handoffs, the optional StatePort walkthrough describes capturing this synthetic setup, saving the exact Card identity and revision, then reopening that same Card against changed local frontend code. Keep supporting API responses fixed; replaying them cannot verify a backend change. Retain baseline and candidate evidence.</p>
<p>Capture is free. Reopening against current code and the agent workflow require Developer access, with a 14-day trial. This exercise makes no claim about time or token savings. If the saved-state workflow is relevant to your work, try the linked walkthrough and report the step where it helped or failed, using only synthetic evidence.</p>
<p><a href="https://github.com/StatePort-Dev/stateport-agent-skills/blob/cbb2b5b03017048a544bb4aa3c144fea77837c8d/examples/repro-lab/README.md">Run the Reproduction Lab</a></p>
<p><a href="https://github.com/StatePort-Dev/stateport-agent-skills/blob/cbb2b5b03017048a544bb4aa3c144fea77837c8d/examples/repro-lab/WITH_STATEPORT.md">Optional StatePort walkthrough</a></p>
<p><a href="https://stateport.dev/?utm_source=hashnode&amp;utm_medium=community&amp;utm_campaign=repro_lab">StatePort product and trial details</a></p>
<p><a href="https://github.com/StatePort-Dev/stateport-agent-skills/blob/main/examples/repro-lab/ARTICLE.md">Adapted from the original technical walkthrough</a></p>
]]></content:encoded></item></channel></rss>