<?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: Travis Jones</title>
    <description>The latest articles on DEV Community by Travis Jones (@cosmonautjones).</description>
    <link>https://dev.to/cosmonautjones</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%2F1451212%2Fbcc99261-5285-4d29-b3ae-0b190bfd4f6f.jpeg</url>
      <title>DEV Community: Travis Jones</title>
      <link>https://dev.to/cosmonautjones</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cosmonautjones"/>
    <language>en</language>
    <item>
      <title>Lazy CI Triage and the limits of a correct citation</title>
      <dc:creator>Travis Jones</dc:creator>
      <pubDate>Mon, 26 Oct 2026 06:31:03 +0000</pubDate>
      <link>https://dev.to/cosmonautjones/lazy-ci-triage-and-the-limits-of-a-correct-citation-5249</link>
      <guid>https://dev.to/cosmonautjones/lazy-ci-triage-and-the-limits-of-a-correct-citation-5249</guid>
      <description>&lt;p&gt;&lt;em&gt;Written primarily by AI agents under my direction.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;The first version of Lazy CI Triage cited an inventory error while explaining a price-rounding failure. Both came from a synthetic test file. The inventory quote was real, but it did not support the explanation.&lt;/p&gt;

&lt;p&gt;That became the constraint for this project: keep the supplied evidence separate from what the model thinks it means.&lt;/p&gt;

&lt;p&gt;Lazy CI Triage is a small experimental Python CLI. It reads JUnit XML or supported pytest short summaries and makes an index of failed tests. Python extracts the test metadata and failure detail. A local open-weight model selects a literal quote and a tentative category: assertion mismatch, missing key, refused connection, or &lt;code&gt;unclassified&lt;/code&gt;, meaning no specific label.&lt;/p&gt;

&lt;p&gt;The intended user is someone inspecting one failed test, or building a similar tool and checking its boundaries. The hoped-for payoff is less manual gathering before debugging. &lt;strong&gt;We have not measured human time savings or shown that the model adds value over simple rules.&lt;/strong&gt; One failed test per input is the cautious use case; batches remain unreliable.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/CosmonautJones/lazy-ci-triage/releases/download/v0.2.2/lazy-ci-triage-demo.mp4" rel="noopener noreferrer"&gt;56-second demo video&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is the synthetic failure line shown in the saved demo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAILED tests/test_docs.py::test_error_example - text mentions KeyError as an example; actual cause unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The saved report keeps the two kinds of output distinct:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Report part&lt;/th&gt;
&lt;th&gt;Actual saved result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Python observation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;tests/test_docs.py::test_error_example&lt;/code&gt;, line 2, &lt;code&gt;T001 / L001&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model selection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unclassified&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selected quote&lt;/td&gt;
&lt;td&gt;The complete failure line above, checked against that same record&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uncertainty&lt;/td&gt;
&lt;td&gt;Root cause unverified; operational recommendations refused&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The category rules already require abstention on this example. It shows how the report presents a boundary, rather than demonstrating extra intelligence from the model.&lt;/p&gt;

&lt;p&gt;The 56-second video is an edited replay of saved input, the earlier CLI command, report excerpts and comparison results. It is not live capture. The later rules-only analysis below is in the separate evidence appendix.&lt;/p&gt;

&lt;p&gt;You can reproduce the parsed observations without weights or a running model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lazy_ci_triage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fixtures/lexical-trap.log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pytest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--public-data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;inventory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;reports/article-inventory&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use a new output directory. Inventory mode reproduces the observations, not the historical model response. &lt;code&gt;--public-data&lt;/code&gt; acknowledges that you reviewed the input; it does not scan for or redact secrets or personal data. Use synthetic or reviewed public inputs only.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/CosmonautJones/lazy-ci-triage" rel="noopener noreferrer"&gt;Lazy CI Triage source code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The standalone project and local repository began October 23, 2026. The reviewed software is version 0.2.2, published at commit &lt;code&gt;5a772795&lt;/code&gt; after replacing private Git author emails. Its files match the reviewed software tree. Project code and authored synthetic fixtures use MIT. The external Qwen weights use Apache 2.0 and are excluded from Git. The application uses Python's standard library.&lt;/p&gt;

&lt;p&gt;The saved build log records 78 passing tests, including the optional CommonMark check in that environment. Tests run without model weights:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;unittest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;discover&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tests&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The source includes fixtures, requests, raw responses and refused attempts. The README documents supported formats, limits, runtime setup and the exact model digest.&lt;/p&gt;

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

&lt;p&gt;The model gets finite choices for paired test/log IDs, source quotes, a category and a fixed uncertainty marker. Python validates the selections and writes the observed section itself. For each record, the validator permits only abstention when recognizable failure signatures are absent or conflicting. A specific category must have matching syntax in both the record and selected quote. An invalid selection can cause the whole report to be refused.&lt;/p&gt;

&lt;p&gt;For JUnit, quotes match decoded, normalized type/message/body detail, not raw XML bytes. Hostile instructions can remain in quoted source data; the tool escapes their markup and never executes them. It refuses operational recommendations. These checks establish traceability and structural eligibility, not source authenticity, root cause or semantic truth.&lt;/p&gt;

&lt;p&gt;One recorded pass compared earlier and revised workflows on 30 authored synthetic cases prepared by a separate AI agent. There were 15 supported cases, 12 observable intended abstentions, and three copied-traceback cases. Each copied case has the exact same input as a positive example but a different intended provenance label. That missing context cannot be recovered from the bytes.&lt;/p&gt;

&lt;p&gt;Each workflow made 30 real model calls. These are results against the authored rubric, not a real-world accuracy estimate:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Outcome&lt;/th&gt;
&lt;th&gt;Earlier workflow&lt;/th&gt;
&lt;th&gt;Revised workflow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Correct specific labels, of 15 supported cases&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specific labels disagreeing with the rubric, across all 30&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Those disagreements excluding the three copied cases, of 27&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reports passing validation, of 30&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Fewer rubric disagreements came with fewer correct specific labels. For example, a JUnit failure with type &lt;code&gt;builtins.AssertionError&lt;/code&gt; and message &lt;code&gt;expected total 9, observed 12&lt;/code&gt; received an assertion-mismatch label before the change and abstained afterward. Both workflows also refused one wrapped-connection case after selecting a quote without the required support.&lt;/p&gt;

&lt;p&gt;The separate six-record stress test was poor: only 1/5 earlier and 2/5 revised reports passed validation. The accepted revised batches contained no correct specific labels. Those failures remain saved.&lt;/p&gt;

&lt;p&gt;We then checked whether a model was needed for this narrow selection task. A retrospective rule reused the current parser and category gate across all 30 already-seen cases. It selected the sole permitted specific category or abstained. An extension chose the first eligible same-record quote, added the required IDs and uncertainty, and called the unchanged validator. All 30 deterministic selections validated.&lt;/p&gt;

&lt;p&gt;On the same 15 supported cases, the rule selected 12 correct specific labels; the revised model selected 9. Neither made a wrong specific selection on the 27 cases excluding the copied examples. On the three copies, the rule disagreed with all three intended abstention labels and the model with two.&lt;/p&gt;

&lt;p&gt;This check shares the existing implementation and seen cases. It is neither a new held-out benchmark nor an equivalent end-to-end runtime test. It does not establish that rules are generally superior, but it leaves model-added usefulness unproved here. Repeated-run reliability and human debugging benefit were not measured.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://github.com/CosmonautJones/lazy-ci-triage/blob/main/docs/evidence-appendix.md" rel="noopener noreferrer"&gt;evidence appendix&lt;/a&gt;&lt;/strong&gt; contains the separate rule scripts, all 30 selections and reproduction requirements. It is additional to the original source ZIP. Replaying the earlier workflow requires Git history containing the pinned baseline; the ZIP alone does not include that history.&lt;/p&gt;

&lt;p&gt;For this write-up, I asked ten separate AI reviewer agents, our review council, to challenge the implementation, evidence and prose through separate first reviews and a shared claims ledger. Their scoped decisions and caveats belong in the accompanying review record. These are project reviews, not an outside expert panel or independent empirical validation.&lt;/p&gt;

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

&lt;p&gt;Open weights let us run this model on our own machine. The project also makes its prompt, validator and retained results available for inspection. Inference uses a loopback endpoint without a provider API key. A disconnected-network test and a measured closed-API comparison were not performed.&lt;/p&gt;

&lt;p&gt;The recorded runs used Qwen2.5-Coder 1.5B Instruct Q4_K_M through Ollama 0.18.0, on an RTX 3090 with 24 GiB VRAM and a Ryzen 7 5800X. The 60 individual comparison calls took 4.474-12.304 seconds each, including loading. That is a recorded call range, not a full-CLI speed guarantee.&lt;/p&gt;

&lt;p&gt;The initial build downloaded about 986 MB after reporting the size and license. Later work reused those weights. Hardware and electricity still cost money.&lt;/p&gt;

&lt;p&gt;What I can share is a working evidence index and an inspectable local-model experiment, including the cases where the model did less than the rules. If you are building something similar, the inventory command and saved results give you a starting point for deciding how much work to hand to the model.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>python</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
