<?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: Mustafa Sercan Sak</title>
    <description>The latest articles on DEV Community by Mustafa Sercan Sak (@mustafa_sercan_sak).</description>
    <link>https://dev.to/mustafa_sercan_sak</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%2F4101315%2F2b543a5a-e92a-4990-a175-c246a7dd00d4.jpg</url>
      <title>DEV Community: Mustafa Sercan Sak</title>
      <link>https://dev.to/mustafa_sercan_sak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mustafa_sercan_sak"/>
    <language>en</language>
    <item>
      <title>Can You Trust an LLM to Fix a Broken Locator? I Measured It.</title>
      <dc:creator>Mustafa Sercan Sak</dc:creator>
      <pubDate>Sun, 30 Aug 2026 11:37:50 +0000</pubDate>
      <link>https://dev.to/mustafa_sercan_sak/can-you-trust-an-llm-to-fix-a-broken-locator-i-measured-it-4och</link>
      <guid>https://dev.to/mustafa_sercan_sak/can-you-trust-an-llm-to-fix-a-broken-locator-i-measured-it-4och</guid>
      <description>&lt;p&gt;&lt;em&gt;A measured study of multi-provider LLM consensus as a locator-healing signal — and why &lt;a href="https://github.com/mustafasercansak/automation-sandbox" rel="noopener noreferrer"&gt;Automation Sandbox&lt;/a&gt; keeps the LLM out of the decision. Originally published &lt;a href="https://mustafasercansak.github.io/automation-sandbox/docs/blog/llm-false-heal-study.html" rel="noopener noreferrer"&gt;on the project site&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;When a UI refactor &lt;strong&gt;deletes&lt;/strong&gt; an element, a self-healing engine must decline and ask a human — not latch onto a neighbouring button. I tested whether asking several independent LLMs and requiring them to agree can act as that "the element is gone" detector.&lt;/p&gt;

&lt;p&gt;Across &lt;strong&gt;four live multi-provider runs&lt;/strong&gt; (2026-08-16 to 2026-08-18, 133 usable scenarios):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On elements that &lt;strong&gt;still existed&lt;/strong&gt; (moved/relabelled), unanimous provider agreement was &lt;strong&gt;correct 52 / 52 times&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;On elements that had been &lt;strong&gt;deleted&lt;/strong&gt;, unanimous agreement was &lt;strong&gt;wrong 34 / 34 times&lt;/strong&gt; — every single time, a confident pick of the wrong neighbour.&lt;/li&gt;
&lt;li&gt;In 7 of those 34, &lt;strong&gt;three independently-sourced model families&lt;/strong&gt; (Cloudflare/Qwen, Mistral, OpenRouter/gpt-oss) agreed on the &lt;em&gt;same&lt;/em&gt; non-existent element at once.&lt;/li&gt;
&lt;li&gt;Widening the provider pool from 3 to 7 did &lt;strong&gt;not&lt;/strong&gt; reduce the failure rate (25% → 45% → 58% → 40% agreement on deleted elements, no downward trend; 100% wrong throughout).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The consensus check is real protection — but it comes from providers &lt;em&gt;disagreeing&lt;/em&gt; with each other, not from any model recognising that the element is gone.&lt;/strong&gt; When they happen to agree on a deleted element, they are unanimously, confidently wrong. That is why in Automation Sandbox the LLM is an opt-in fallback gated by an independent-agreement quorum, and a heal is only ever committed after the retried action actually succeeds — the model is never the decision maker.&lt;/p&gt;

&lt;p&gt;Full data, methodology, and the trade-off curves live in the &lt;a href="https://mustafasercansak.github.io/automation-sandbox/docs/benchmark-calibration.html" rel="noopener noreferrer"&gt;Benchmark &amp;amp; Calibration guide&lt;/a&gt; (§3, §4, §6). This post is the standalone story; that page is the source of truth for every number.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The problem: a deleted element has no right answer
&lt;/h2&gt;

&lt;p&gt;Locator healing handles the easy 90%: an &lt;code&gt;AutomationId&lt;/code&gt; changes, a label is reworded, a control moves 100px in a layout pass. The engine re-resolves the element from structural evidence — control type, parent, sibling position, name similarity, geometry — and retries.&lt;/p&gt;

&lt;p&gt;The dangerous case is the other kind of change: the element is &lt;strong&gt;deleted outright&lt;/strong&gt;. A checkout button is removed; the test that clicked it should now &lt;em&gt;fail loudly&lt;/em&gt; so a human looks at it. What it must not do is quietly heal onto the "Cancel" button next to where "Submit" used to be, pass green, and hide a real regression — a "false heal".&lt;/p&gt;

&lt;p&gt;A pure-heuristic scorer cannot solve this case on its own, and &lt;a href="https://mustafasercansak.github.io/automation-sandbox/docs/benchmark-calibration.html#5-offline-absence-signal-investigation-95" rel="noopener noreferrer"&gt;I proved that rigorously&lt;/a&gt;: a surviving sibling in a deleted control's container is structurally &lt;strong&gt;indistinguishable&lt;/strong&gt; from a control that genuinely moved next to that sibling. Their similarity-score distributions overlap (&lt;code&gt;[0.665, 0.955]&lt;/code&gt; for deleted-element decoys vs &lt;code&gt;[0.749, 0.874]&lt;/code&gt; for true compound drift), so &lt;strong&gt;no confidence threshold, runner-up margin, cluster-density, or control-type filter can draw a line between them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That negative result is what motivated the LLM experiment. Semantic reasoning asks a different question than geometry does — maybe independent models, forced to agree, could tell "moved" from "gone".&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Method: controlled multi-signal ablation
&lt;/h2&gt;

&lt;p&gt;Natural locator drift across real releases is too sparse to benchmark. So I invert it: take a real, organically-built application UI tree and &lt;strong&gt;systematically mutate&lt;/strong&gt; its authored locators.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source tree:&lt;/strong&gt; HandBrake 1.8.2 (WPF), captured live — 149 nodes, 42 unique authored locators. A second application, ShareX v21.0.0 (WinForms), checks that findings are not HandBrake-specific.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Five mutation tiers:&lt;/strong&gt; pure rename (opaque ID), name/label drift, position shift, compound (text + layout), and &lt;strong&gt;element removal&lt;/strong&gt; (whole subtree deleted).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The two questions:&lt;/strong&gt; for tiers 1–4 the engine should find the successor; for &lt;strong&gt;removal&lt;/strong&gt; it should decline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Leakage protection.&lt;/strong&gt; Every candidate &lt;code&gt;AutomationId&lt;/code&gt; in a mutated tree is rewritten to the &lt;em&gt;same&lt;/em&gt; opaque format (&lt;code&gt;ablation-&lt;/code&gt; + SHA-256 hex), not just the target. Otherwise a model could solve the scenario by spotting the "odd one out". IDs carry no semantic hint — which means these scores are a &lt;strong&gt;lower bound&lt;/strong&gt;: in production, a descriptive &lt;code&gt;btnSaveDocument&lt;/code&gt; gives the model more to work with than a synthetic hash does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM evaluation protocol.&lt;/strong&gt; Temperature 0. Every provider's raw vote recorded alongside the agreement telemetry. A scenario counts as &lt;strong&gt;usable&lt;/strong&gt; only when ≥ 2 providers actually returned an answer — one opinion can neither agree nor disagree with anything. Token cost is managed by targeting the two informative subsets: 25 compound-drift + 42 removed-element scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The heuristic baseline (no LLM)
&lt;/h2&gt;

&lt;p&gt;Running the deterministic scorer at the shipped default (&lt;code&gt;MinimumConfidence = 0.50&lt;/code&gt;) over all 176 HandBrake scenarios:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mutation tier&lt;/th&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;th&gt;Correct&lt;/th&gt;
&lt;th&gt;False heals&lt;/th&gt;
&lt;th&gt;Missed (review)&lt;/th&gt;
&lt;th&gt;Score range&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Renamed AutomationId&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[1.000, 1.000]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Name drift&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0.877, 0.950]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Position shift&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0.832, 0.955]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compound drift&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0.749, 0.874]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Removed element&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;42&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;17&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0.344, 0.955]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;40.5% of deleted elements are false-healed&lt;/strong&gt; at the default threshold. On ShareX the same figure is &lt;strong&gt;57.1%&lt;/strong&gt;. Raising the threshold trades this away against auto-heal recall linearly — at &lt;code&gt;0.90&lt;/code&gt; the false-heal rate on removed elements is still 5.5% while three-quarters of &lt;em&gt;all&lt;/em&gt; locators are forced to manual review. There is no free setting.&lt;/p&gt;

&lt;p&gt;This is the gap the LLM was asked to close.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The result: consensus separates the bands — then fails as a gate
&lt;/h2&gt;

&lt;p&gt;Four runs, 2026-08-16 to 2026-08-18, as the provider pool grew from 3 to 7 and Groq's model was swapped twice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Usable (n)&lt;/th&gt;
&lt;th&gt;Compound-drift unanimous&lt;/th&gt;
&lt;th&gt;Removed-element unanimous&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 (08-16)&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;6 / 7&lt;/td&gt;
&lt;td&gt;3 / 12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2 (08-16)&lt;/td&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;td&gt;16 / 17&lt;/td&gt;
&lt;td&gt;10 / 22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3 (08-16)&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;14 / 14&lt;/td&gt;
&lt;td&gt;11 / 19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4 (08-18)&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;16 / 17&lt;/td&gt;
&lt;td&gt;10 / 25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;133&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;52 / 55&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;34 / 78&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Providers reached unanimous agreement on &lt;strong&gt;94.5%&lt;/strong&gt; of scenarios where a successor existed, and on &lt;strong&gt;43.6%&lt;/strong&gt; where the element was gone. That gap is real — it is the &lt;em&gt;only&lt;/em&gt; signal in the entire project that separates the two populations at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But unanimity is not a safe acceptance gate:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every one of the &lt;strong&gt;52&lt;/strong&gt; unanimous verdicts on a surviving element was correct.&lt;br&gt;
Every one of the &lt;strong&gt;34&lt;/strong&gt; unanimous verdicts on a deleted element was a false heal.&lt;br&gt;
Zero exceptions in either direction, across four runs with four different provider sets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An earlier draft of this analysis reported "33%" wrong — that figure pooled both mutation types into one denominator and understated the real rate. Read per type, &lt;strong&gt;the deleted-element rate is 100%: agreement never once happened to be right about an absence.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Why: the mechanism is disagreement, not recognition
&lt;/h2&gt;

&lt;p&gt;The hypothesis predicted two safe outcomes on a deleted element — providers decline, or providers scatter across different decoys. In practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Declining essentially never happens.&lt;/strong&gt; Across all 78 usable removed-element scenarios, "all providers declined" occurred exactly &lt;strong&gt;once&lt;/strong&gt;. Every other provider that answered pointed at a specific — wrong — candidate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every correct rejection came from providers contradicting each other&lt;/strong&gt;, not from any model saying "that element is gone". The models do not know the control was deleted; each confidently names a &lt;em&gt;different&lt;/em&gt; neighbour, and the engine rejects the heal only because the votes fail to match.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Widening the pool made this clearer, not better. One run recorded 10 unanimous false heals; &lt;strong&gt;7 of those 10 had three independent model families agreeing on the same non-existent element&lt;/strong&gt; — three vendors, three architectures, one wrong answer, unanimously. Going 3 → 7 providers moved the removed-element agreement rate 25% → 45% → 58% → 40% with no downward trend and 100% wrong throughout.&lt;/p&gt;

&lt;p&gt;The protection is a &lt;strong&gt;byproduct of independence&lt;/strong&gt;, and independence alone does not bound the failure rate: a genuinely capable, independent reasoner finds a deleted control's surviving neighbour a &lt;em&gt;convincing&lt;/em&gt; answer often enough that adding more reasoners does not reliably break the tie. It also cannot be strengthened by asking for more confidence — the failing cases are already maximally confident.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What this means for the design
&lt;/h2&gt;

&lt;p&gt;Automation Sandbox is built around this result rather than despite it:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Design choice&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Heuristic-first, deterministic.&lt;/strong&gt; A pure C# structural scorer decides on its own, ~23ms for 3,000 controls, zero tokens.&lt;/td&gt;
&lt;td&gt;The LLM is never on the default path. Most healing never touches a model.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;LLM is opt-in and quorum-gated&lt;/strong&gt; (≥ 2 providers must independently name the same candidate).&lt;/td&gt;
&lt;td&gt;A single model's confidence is worthless here. Agreement is &lt;em&gt;permission&lt;/em&gt; to consider a pick — never evidence it is correct.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;A heal commits only after the retried action succeeds&lt;/strong&gt;; the shipped default mode changes no locators and only routes candidates to a report.&lt;/td&gt;
&lt;td&gt;A wrong pick that cannot actually perform the test step is caught before it is persisted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Every decision is written to an audit report&lt;/strong&gt; (JSON + HTML) — which signal contributed what weight, which providers voted, what the outcome was.&lt;/td&gt;
&lt;td&gt;"The AI healed it" is not an acceptable answer. You can see exactly why.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The honest bottom line:&lt;/strong&gt; unassisted absence detection is mathematically bounded by the structural score overlap. Automation Sandbox does not claim to have solved it. It makes the failure &lt;em&gt;visible and declinable&lt;/em&gt; instead of silent and green.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Reproduce this yourself
&lt;/h2&gt;

&lt;p&gt;From a clean clone (needs the .NET SDK; the LLM run needs provider API keys):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. The deterministic heuristic baseline and threshold sweep - no keys, no tokens&lt;/span&gt;
dotnet &lt;span class="nb"&gt;test &lt;/span&gt;TestAutomation/ScenarioRunner/ScenarioRunner.csproj &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"FullyQualifiedName~LocatorAblationTests.HandBrakeFixture_RunsEndToEndAndReportsMetrics"&lt;/span&gt;

dotnet &lt;span class="nb"&gt;test &lt;/span&gt;TestAutomation/ScenarioRunner/ScenarioRunner.csproj &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"FullyQualifiedName~LocatorAblationTests.HandBrakeFixture_ThresholdSweep"&lt;/span&gt;

&lt;span class="c"&gt;# 2. Calibrate against your own captured UI tree&lt;/span&gt;
dotnet run &lt;span class="nt"&gt;--project&lt;/span&gt; samples/CalibrationCli &lt;span class="nt"&gt;--&lt;/span&gt; &amp;lt;your-tree.json&amp;gt; &lt;span class="nt"&gt;--app&lt;/span&gt; YourApp

&lt;span class="c"&gt;# 3. The live multi-provider consensus evaluation (set provider keys as env vars first)&lt;/span&gt;
dotnet &lt;span class="nb"&gt;test &lt;/span&gt;TestAutomation/ScenarioRunner/ScenarioRunner.csproj &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"FullyQualifiedName~LocatorAblationTests.HandBrakeFixture_LlmConsensus_LiveEvaluation"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every claim is guarded by a committed regression test — see the "Regression guards" lines throughout the &lt;a href="https://mustafasercansak.github.io/automation-sandbox/docs/benchmark-calibration.html" rel="noopener noreferrer"&gt;Benchmark &amp;amp; Calibration guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. What this study does &lt;em&gt;not&lt;/em&gt; establish
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One dataset family.&lt;/strong&gt; Two real applications, one mutation methodology. The direction is consistent across both; the &lt;em&gt;magnitude&lt;/em&gt; is not portable (40.5% vs 57.1% false-heal on deleted elements at the same setting).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-determinism band.&lt;/strong&gt; A run over 42 removal scenarios carries roughly ±14% statistical uncertainty. The 34/34 result is striking precisely because it left no room for that band to matter, but a fifth run could see a unanimous verdict that is accidentally correct.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production ID fidelity.&lt;/strong&gt; Ablation IDs are opaque hashes; real descriptive IDs would give models more signal. The LLM numbers here are a &lt;em&gt;lower bound&lt;/em&gt; on production performance — which does not change the finding that agreement on a deleted element is unreliable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompting is not exhausted.&lt;/strong&gt; This tests one prompt design (bounded top-N shortlist, temperature 0). It does not prove no prompt could do better — it proves that &lt;em&gt;provider agreement&lt;/em&gt;, as a mechanism, does not carry the safety guarantee people assume it does.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Automation Sandbox&lt;/strong&gt; is MIT, pure C#/.NET, seven packages on nuget.org. It does locator self-healing and intent-driven test generation for Windows desktop (FlaUI/UIA3) and web (Playwright). If you maintain UI tests that break on every refactor, I'd genuinely like your feedback — especially from anyone who has shipped locator self-healing and hit the deleted-element problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/mustafasercansak/automation-sandbox" rel="noopener noreferrer"&gt;https://github.com/mustafasercansak/automation-sandbox&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://mustafasercansak.github.io/automation-sandbox/" rel="noopener noreferrer"&gt;https://mustafasercansak.github.io/automation-sandbox/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>testing</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
