<?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: Nicoletta Bartunek</title>
    <description>The latest articles on DEV Community by Nicoletta Bartunek (@nicoletta_bartunek).</description>
    <link>https://dev.to/nicoletta_bartunek</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1021771%2F487cc42b-8da2-417b-9028-f1b5333670e9.jpg</url>
      <title>DEV Community: Nicoletta Bartunek</title>
      <link>https://dev.to/nicoletta_bartunek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicoletta_bartunek"/>
    <language>en</language>
    <item>
      <title>The Nine Circles of a CI/CD Inferno</title>
      <dc:creator>Nicoletta Bartunek</dc:creator>
      <pubDate>Mon, 03 Nov 2025 06:56:17 +0000</pubDate>
      <link>https://dev.to/nicoletta_bartunek/the-nine-circles-of-a-cicd-inferno-485d</link>
      <guid>https://dev.to/nicoletta_bartunek/the-nine-circles-of-a-cicd-inferno-485d</guid>
      <description>&lt;p&gt;I’m about to get unreasonably geeky, so much so that I myself might not understand what I’m doing. Proceed at your own risk. For those who choose to keep reading — you were warned:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Lasciate ogni speranza, voi ch’entrate.”&lt;br&gt;
“Abandon all hope, ye who enter here.” — Dante Alighieri, &lt;em&gt;Inferno&lt;/em&gt; (1320)&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Philosophy ruined software for me. Especially one grim man who once threatened a colleague with a fireplace poker during a debate about moral rules. That man — Ludwig Wittgenstein, “Witty,” as a friend called him — was brilliant, unstable, and obsessed with language’s limits; or maybe he was unstable because of that obsession. Potato, potahto? Not quite. I’ve been obsessed with those limits too, and I’m neither witty nor brilliant — just unstable. And here’s proof: I can’t look at a deployment pipeline&lt;sup id="fnref2"&gt;2&lt;/sup&gt; as a normal human being.&lt;/p&gt;

&lt;p&gt;Yes, I admit. It’s hard for me to look at a pipeline and not see a philosophical argument about language’s limits. When everything turns out fine - the code speaks, the unit tests&lt;sup id="fnref3"&gt;3&lt;/sup&gt; reply; each stage insists it’s right, every log&lt;sup id="fnref4"&gt;4&lt;/sup&gt; sounds certain. SonarQube&lt;sup id="fnref5"&gt;5&lt;/sup&gt; interrupts occasionally, but everyone shrugs it off, and all logs align, suggesting a perfect sequence. But there is so much philosophy going on here, actually. I mean, look at how sweet this is:&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2F6t2vffqpwuwukxsvxw5y.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.amazonaws.com%2Fuploads%2Farticles%2F6t2vffqpwuwukxsvxw5y.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Circle I — The Linting of Limbo&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.logging.Logger&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pipeline&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Pipeline&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;](&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//log.info&amp;gt;)("=== PIPELINE START ===");&lt;/span&gt;
        &lt;span class="n"&gt;ciPipeline&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;](&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;http:&lt;/span&gt;&lt;span class="c1"&gt;//log.info&amp;gt;)("=== PIPELINE END ===");&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Everything is syntactically perfect. The linter&lt;sup id="fnref6"&gt;6&lt;/sup&gt; passes, the imports&lt;sup id="fnref7"&gt;7&lt;/sup&gt; are precise, the indentation heavenly. Logic and grammar align so neatly it almost feels moral. This is Limbo: a paradise of correct form, where nothing yet means anything.&lt;sup id="fnref8"&gt;8&lt;/sup&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Circle II — The Unit Tests of Desire&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// --- Application code (the code speaks) -----------------------------------*&lt;/span&gt;

&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"raining"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;takeUmbrella&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ACTION: Taking umbrella."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;enjoySunshine&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ACTION: Enjoying sunshine."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;runApp&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getWeather&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"APP: Weather reported as \""&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;weather&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"\"."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"raining"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weather&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;takeUmbrella&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;enjoySunshine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"ok"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The code says: &lt;code&gt;runApp()&lt;/code&gt; sets the world’s weather in one line. The tests respond: &lt;code&gt;assert&lt;/code&gt; verifies internal consistency; all pass. Everything is fine — inside the model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// --- Unit tests (the tests reply) ------------------------------------------&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestWeatherBehavior&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testRainingBranch&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="s"&gt;"raining"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getWeather&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Expected raining"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="s"&gt;"ok"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"App should return ok"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testContract&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nl"&gt;Pipeline:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getWeather&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nl"&gt;Pipeline:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;runApp&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Circle III — The Static Analysis of Pride&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// --- Static analysis interruption (SonarQube interrupts) -------------------&lt;/span&gt;
&lt;span class="c1"&gt;// SonarQube: Major Code Smell — 'getWeather' returns a constant.&lt;/span&gt;
&lt;span class="c1"&gt;// SonarQube: Cognitive Complexity: low, but possibly too neat.&lt;/span&gt;
&lt;span class="c1"&gt;// SonarQube: "Consider dependency injection[^H] for better testability."&lt;/span&gt;
&lt;span class="c1"&gt;// Developers: *shrug*&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SonarQube, the bureaucrat of truth, speaks in warnings. Developers nod, acknowledge the insight, and move on.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Circle IV — The Build of Ambition&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// --- CI stages (each insists it's right; every log sounds certain) ---------&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ciPipeline&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LINT: Passed (0 errors)."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"STYLECHECK: Passed."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TESTS: 2 passed, 0 failed."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SECURITY: No known vulnerabilities."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"QUALITY: SonarQube warnings acknowledged."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"BUILD: Artifact[^F] pipeline-1.0.0.jar ready."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The build succeeds. The artifact is born. And we act as if a flawless build ensures sense — as if the model of the world we built is so logically perfect that it will become reality with a click.&lt;sup id="fnref9"&gt;9&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;But Hell always starts with success.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Circle V — The Deployment of Heresy&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// --- Deployment logs (certainty meets entropy) -----------------------------&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DEPLOY: Staging[^G] deploy succeeded."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DEPLOY: Production deploy succeeded."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DEPLOY: Users report failure. No one can log in."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pipeline insists the world exists because it says so. But when code reaches production&lt;sup id="fnref10"&gt;10&lt;/sup&gt;, production is reality, and reality ignores the specs. It serves cached data from a week ago, ignores half the new config, and reports “success” while no one can log in. Yet we continue to ship code anyway. Then we just stare and ask: &lt;em&gt;why?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We like to think production failures mean our systems misinterpreted the world it was meant to create. It has no problem with meaning — the whole thing makes sense! It just created a false image, somehow. It must be false! We believe logic guarantees sense: if the logic is correct and the rules are followed, meaning will appear. The code compiles, the tests pass, so it’s fine. It’s just, somehow, false. It must be false!&lt;/p&gt;

&lt;p&gt;We prefer falsehood because it comforts. Falsehood means the system made sense — it just missed slightly. A mistyped config here, a bad API contract&lt;sup id="fnref11"&gt;11&lt;/sup&gt; there. The logic holds; the world slipped. You hear it in every postmortem: “It worked in staging.” “Must be a bad environment variable.” “The API changed again.” “It’s the cache — clear Redis and it’ll be fine.” “CI passed, so it can’t be the code.” Each line a prayer to the gods of internal consistency. No one says, “Maybe the system doesn’t mean anything.” That would be heresy. It’s easier to believe in falsehood — a comforting fiction where the code is innocent, and reality forgot to update its dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Circle VI — The Observability of Doubt&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;So we believe logic guarantees sense, that correct logic and rules ensure meaning. My friend Witty agreed — at first. But he showed where this fails. I can see him pacing an open-plan office, poker in hand — the same one I mentioned earlier — shouting at the IT industry: “Logic is not enough!”&lt;/p&gt;

&lt;p&gt;Early on, Witty believed a sentence made sense if it clearly described how the world could be. A kind of engineering dream: as long as your model matches reality, the output is true. It’s the same dream we live in code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherCheck&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"raining"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weather&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"raining"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;takeUmbrella&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enjoySunshine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;takeUmbrella&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Take an umbrella!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;enjoySunshine&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enjoy the sunshine!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a perfect miniature of the world — a model of order and cause. The syntax is flawless, the logic sound. It maps reality so neatly it feels self-evident: the rules align, the outputs behave, the world reduces to a tidy if-else. The code compiles, the conditions hold, the structure mirrors cause and effect with mathematical purity. But what if the input isn’t the world at all?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherSimulator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Stubbed input[^J]: hard-coded, no contact with reality&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"raining"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// always returns the same value&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getWeather&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;weather&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"raining"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;takeUmbrella&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;enjoySunshine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;takeUmbrella&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Take an umbrella!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;enjoySunshine&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enjoy the sunshine!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tests pass because they match their own assumptions; they never touch reality. Everything here is correct but meaningless. The variable is hard-coded, a placeholder disconnected from the world, so the whole picture collapses. The program no longer describes reality; it describes its own simulation. In Wittgenstein’s terms, it’s structurally correct but meaningless, because it fails to depict a possible state of affairs. The picture works perfectly within its frame, but nothing outside that frame can make it true or false. Naturally, the system fails in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Circle VII — The Runtime of Silence&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;But what do applications have to do with reality? We don’t hike with laptops to verify what our app reports. Still, between a green build and a failed deployment, reality intervenes. A user clicks the wrong thing. A network lags. Someone closes the laptop and goes for a walk. None of this fits the model, yet it gives the system meaning. The code no longer describes the world; it participates in it.&lt;/p&gt;

&lt;p&gt;And once again, this is where Wittgenstein enters — the older, quieter Witty. The one who stopped trusting logic to hold the shape of sense. Meaning, he realised later, isn’t engineered in logic but practiced in life: in habits, rituals, and the small negotiations of use. Words — and code — mean what our communities make of them. Meaning, he decided, isn’t born in abstract structures but in &lt;em&gt;forms of life&lt;/em&gt;&lt;sup id="fnref12"&gt;12&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Programs, like languages, live inside these forms: the stand-ups, the commits, the code reviews, the quiet negotiations of “what done means.” Software, then, is not a mirror of the world it wants to create, but a collaborative language game — one played by developers, designers, users, and the occasional bug report. Its grammar evolves through iteration and dialogue. Agile&lt;sup id="fnref13"&gt;13&lt;/sup&gt;, at its best, is simply this insight operationalized: that meaning emerges from collective correction, conversation, and use.&lt;/p&gt;

&lt;p&gt;Witty would have liked that — the idea that meaning isn’t what a program &lt;em&gt;says&lt;/em&gt;, but what a community &lt;em&gt;does&lt;/em&gt; with it. Wisdom, perhaps, lies in abandoning the fantasy of perfect logic and embracing shared uncertainty instead. Late Wittgenstein might have said that every retrospective, every messy stand-up, every pull request discussion is part of a &lt;em&gt;form of life&lt;/em&gt; — the living runtime where understanding happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Circle VIII — The Fraud of Meaning&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If collaboration gives code meaning, fraud happens when the system fakes it. We see it everywhere: automated “insights” summarizing what they don’t understand, dashboards showing all green while reality burns. AI models now confidently explain what we think, what they think, and our and their errors. They sound fluent—eerily so—but their fluency is hollow. It imitates sense, a perfect echo without a source. They don’t speak &lt;em&gt;from&lt;/em&gt; a form of life; they only &lt;em&gt;perform&lt;/em&gt; one. Still, I admit, they do well correcting and enhancing one, turning meaning into hell from the inside out&lt;sup id="fnref14"&gt;14&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;But let’s not forget: this is the &lt;em&gt;Circle of Semantic Fraud&lt;/em&gt;&lt;sup id="fnref15"&gt;15&lt;/sup&gt;. These tools speak in human tones but lack life. They play the language game without joining it. The build says, “SUCCESS.” The monitoring system says, “STABLE.” The large language model says, “Of course, let me help.” And everyone nods—relieved to be understood by something that doesn’t understand them back. Fraud here isn’t malicious; it’s structural. We built systems that produce sentences without conversation—echoing meaning but never inhabiting it.&lt;/p&gt;

&lt;p&gt;I call this &lt;em&gt;digital glossolalia&lt;/em&gt;: machines putting words together with the illusion of meaning, but are hollow at the core. They’re virtuosos of &lt;em&gt;sounding&lt;/em&gt; like they understand—syntax flawless, grammar impeccable, logic airtight. But behind the curtain? Nothing. It’s language that walks and talks, but never breathes. Smooth as silk on the surface, empty as a test database underneath. And no, this isn’t some high-tech &lt;em&gt;Pentecost&lt;/em&gt;, where everyone speaks in tongues but somehow still gets the message. It’s more like &lt;em&gt;Babel&lt;/em&gt; in reverse: back then, people shared one language and ended up hopelessly talking past each other. Now, our machines can mimic every language on earth—yet never truly say anything. The result isn’t confusion, but a kind of universal, fluent emptiness.&lt;/p&gt;

&lt;p&gt;Communication hasn’t died; it’s just lost its pulse. Everything fits together in form, but nothing connects in meaning. The problem isn’t logic anymore—it’s what Wittgenstein called &lt;em&gt;meaning-blindness&lt;/em&gt;: when you can read and repeat the words, but they no longer mean anything. The lights are on, but the sense has gone out. You can see the shapes of the words and know the rules, yet they feel empty—just marks on a page or sounds in the air. That, I claim, is what it means to lose the living link between language and life. Machines work in that same space: they handle the form of language perfectly, but they never &lt;em&gt;see&lt;/em&gt; what the words mean.&lt;sup id="fnref16"&gt;16&lt;/sup&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Circle IX — The Frozen Repo&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The punishment fits the crime. In this circle, if we add Agentic AIs&lt;sup id="fnref17"&gt;17&lt;/sup&gt;, MCPs&lt;sup id="fnref18"&gt;18&lt;/sup&gt;, and other similar contraptions, language folds in on itself. Signals feed signals; metrics verify metrics; pipelines certify their own outputs. Dashboards reassure dashboards that all is well. Logs hum hymns of success into the void. It is a perfect system — closed, fluent, endlessly self-confirming. The codebase becomes a hall of mirrors: every model cites its own certainty. Meaning no longer circulates; it loops within the system. In that recursion, the last trace of life disappears. Beyond that, nothing moves.&lt;/p&gt;

&lt;p&gt;This is the Frozen Repo&lt;sup id="fnref19"&gt;19&lt;/sup&gt;. The pipelines still trigger, the servers still hum, the logs still whisper “deployed,” but no one touches them. Documentation remains as a fossil record of extinct intentions. The repo is immutable, protected, perfectly versioned — and perfectly dead. Every build passes, but the result no longer matters. The punishment isn’t fire — it’s stasis. Treachery here means betraying change. It is when activity turns into ritual, and performance replaces presence. The CI pipeline keeps announcing its truth, but no one listens. The system remains an artifact, not an exchange.&lt;/p&gt;

&lt;p&gt;At the center, even Satan is trapped in the cold—his wings beating futilely, creating the ice that binds him. In this world, the more the system automates its rituals of sense, the colder it becomes. The final circle of the CI/CD Inferno is not failure but perfect success without meaning—logic eternal, untouched by life.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Alighieri, D. (1320). &lt;em&gt;Inferno&lt;/em&gt;. In &lt;em&gt;La Divina Commedia&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Wittgenstein, L. (1921). &lt;em&gt;Tractatus Logico-Philosophicus&lt;/em&gt;. London: Routledge &amp;amp; Kegan Paul.&lt;/li&gt;
&lt;li&gt;Wittgenstein, L. (1953). &lt;em&gt;Philosophical Investigations&lt;/em&gt;. Oxford: Blackwell.&lt;/li&gt;
&lt;li&gt;Searle, J. R. (1980). “Minds, Brains, and Programs.” &lt;em&gt;Behavioral and Brain Sciences&lt;/em&gt;, 3(3), 417–457.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Any errors, misreadings, or philosophical liberties are entirely the author’s own.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Yes, I’m quoting Dante’s Inferno (Canto III, line 9) right at the start. It’s the sign above the gates of Hell — and honestly, it’s how I feel every time I open a Jenkins dashboard at 2 a.m. And, to keep the level of insanity consistent, I’m also borrowing Dante’s nine circles of the Inferno. If you’re reading this, you’re either a masochist or a philosopher. Or both. If you’re a philosopher, I’m sorry for all the code. If you’re not, I’m sorry for all the philosophy. So, since it’s confession time, here goes: I’m still not sure who the target audience for this thing I wrote even is, but I already love you for making it to this footnote. So here’s a heads-up — whoever you are, from here on out, I’ll try to give you a few hints down here about the hell that’s going on up there. And I'm going to do that both for philosophical and for technical stuff (starting with the just mentioned “Jenkins dashboard&lt;sup id="fnref20"&gt;20&lt;/sup&gt;") ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Or CI/CD pipeline: A series of automated steps (Continuous Integration/Continuous Deployment) that take code from development to production. Like a philosophical argument passing through increasingly skeptical reviewers. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Small, automated tests that check whether individual pieces of code behave as expected. Imagine if every philosophical claim had to pass a mini-Turing test before being published. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;Records of events or actions taken by a system. In philosophy, this is your research diary or the minutes of a seminar. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;SonarQube is a tool that scans code for “issues” — things like messy formatting, risky patterns, or logic that looks suspiciously too neat. Think of it as the grammar checker of software — technically helpful, spiritually annoying.  ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;A tool that checks code for stylistic or syntactic errors—like a grammar checker for programming languages. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;This presupposes a design pattern where components are given their dependencies from the outside. Philosophically, it’s like receiving your premises from another argument rather than inventing them yourself. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn8"&gt;
&lt;p&gt;As I was saying, I’m trying my best to keep up with Dante. Limbo is the first circle of Hell — the quiet one where all the good, pre-Christian philosophers hang out. Perfectly decent, just not officially saved. In code terms, it’s the linter’s paradise: everything formatted, nothing running. It all looks great, but it does absolutely nothing. Is this footnote too on the nose? Do you already know all about Dante’s circles? Well, I have to admit I had to look them up before writing this, because I’d forgotten the details. So I thought I’d spare you the Wikipedia search. Here they are, in all their glory: Limbo; Lust; Gluttony; Greed; Wrath; Heresy; Violence; Fraud; Treachery. And yes, I did try to follow them in this descent into CI/CD hell, but I’ll let you decide how well I managed that. Just remember this one thing: the final circle of Dante’s Hell isn’t fire — it’s ice. And that’s what drew me to this comparison. Ice feels like a fitting image for where we’re heading with code these days, making Dante’s &lt;em&gt;Inferno&lt;/em&gt; more contemporary than ever. Yes, winter is coming! ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn9"&gt;
&lt;p&gt;Wink, wink: this is where Wittgenstein actually creeps in. And to keep my promise, I’ll spare you the Wikipedia search again and try to sketch &lt;em&gt;them&lt;/em&gt; for you. Yes, &lt;em&gt;them&lt;/em&gt; — you read that right! How modern is that? Well, not that modern. It’s just that philosophers speak about (at least) two Wittgensteins. Early Wittgenstein believed that logic was the scaffolding of language — the hidden structure that made it intelligible. But he also argued that language and reality share the same logical form. That’s why language can represent the world at all: logic is their common grammar. A sentence, to be meaningful, must picture a possible state of affairs; its structure mirrors the structure of the fact it describes. Meaning isn’t something you invent — it happens when your words line up with how things might be in the world. “The world is the totality of facts, not of things.” (1.1) “We make to ourselves pictures of facts.” (2.1) “A picture can represent any reality whose form it has.” (2.171) “A picture agrees with reality or fails to agree; it is correct or incorrect, true or false.” (2.21) “A proposition can be true or false only in virtue of being a picture of reality.” (4.06) Logic alone, he thought, could never create meaning — it only sets the limits within which meaning is possible. To make sense, a proposition must touch reality; it has to be anchored in what can, at least in principle, be the case in the world. And only if a proposition has sense can it be true or false. The second Wittgenstein shall be put on pause for now — his time, like the Übermensch’s, will come. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn10"&gt;
&lt;p&gt;“Staging” is a test environment that mimics the real world (“production”) but is safe for experiments. In philosophy, staging is the seminar room; production is the real world where your ideas are tested. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn11"&gt;
&lt;p&gt;A formal agreement about how different parts of a system communicate. In philosophy, this is like the rules of engagement for a debate. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn12"&gt;
&lt;p&gt;Time for the second Wittgenstein! Meaning now happens in use. “For a large class of cases — though not for all — in which we employ the word ‘meaning,’ it can be defined thus: the meaning of a word is its use in the language.” (§43) We don’t just talk &lt;em&gt;about&lt;/em&gt; the world; we talk &lt;em&gt;within&lt;/em&gt; it. Words get their meaning from what Wittgenstein calls our &lt;em&gt;forms of life&lt;/em&gt;— the tangled background of habits, gestures, and shared understanding that make communication possible at all. And we don’t just reflect the world, we play ‘language-games’, he says. And this is meant to show that the speaking of language is part of an activity, or of a form of life.” (§23) So the later Wittgenstein doesn’t polish the mirror between language and the world — he melts it down and uses it as raw material. The point isn’t to describe the world; it’s to &lt;em&gt;live and act&lt;/em&gt; in it. Meaning isn’t a mirror; it’s a move. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn13"&gt;
&lt;p&gt;A methodology (or mindset) in software development that emphasizes iterative progress, collaboration, and adaptability. Think of it as the “forms of life” of software teams: meaning and value emerge from shared practices, not from fixed rules. If you’re a philosopher, imagine a seminar where the agenda changes every five minutes, but somehow everyone still learns something. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn14"&gt;
&lt;p&gt;Yes, I confess: I collaborated with silicon for this piece. It is a surprisingly good co-author. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn15"&gt;
&lt;p&gt;“Semantic fraud” is my own little invention for when systems (or people) spit out sentences that &lt;em&gt;sound&lt;/em&gt; meaningful but are, in fact, pure nonsense. In software, this is when your dashboard proudly flashes “ALL GREEN” while users are busy setting fire to the helpdesk. Or when AI strolls in — large language models churning out fluent text, full of confidence and, occasionally, full of it. The system is fluent, but it’s faking it. But, as usual, the philosophers got there first. In his Chinese Room argument, Searle imagines a person following a rulebook for manipulating Chinese symbols — producing perfect sentences without understanding a word. From the outside, it looks intelligent; inside, it’s just syntax without sense. Sound familiar? That’s &lt;em&gt;semantic fraud&lt;/em&gt; in action — meaning simulated, not lived. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn16"&gt;
&lt;p&gt;Huh… there’s a lot going on here. Geekiness level: 1000! Yes, I’ve actually started citing the Bible—but I promise I won’t bore you with that any longer. I’ll just move on to my (final) bit of geeky philosophy. Here’s what Wittgenstein says about meaning-blindness: "What would you be missing if you did not experience the meaning of a word?" He illustrates this with the question, “What would you be missing, for instance, if you did not understand the request to pronounce the word 'till' and to mean it as a verb,—or if you did not feel that a word lost its meaning and became a mere sound if it was repeated ten times over?” (p. 214). Later, he describes “the familiar physiognomy of a word, the feeling that it has taken up its meaning into itself, that it is an actual likeness of its meaning.” And he adds that “there could be human beings to whom all this was alien. (They would not have an attachment to their words.)” And to the question “What would they be missing?” his answer is “The way we choose and value words.” (p. 220). That, I think, is exactly where we are now. Language still moves — it functions, connects, fills every space — but the pulse is weak. We use words fluently, even beautifully, but often without attachment, without that sense of them being “actual likenesses” of what we mean. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn17"&gt;
&lt;p&gt;An artificial intelligence system designed to act autonomously, making decisions and taking actions on behalf of users or other systems. In software, agentic AIs are like philosophical homunculi—entities that appear to have intentions, but whose “agency” is really a clever simulation of choice. They automate tasks, optimize workflows, and sometimes even “collaborate,” but their understanding is as deep as a Socratic chatbot: always questioning, never quite grasping the answer. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn18"&gt;
&lt;p&gt;A central, often monolithic, software entity that orchestrates or governs the behavior of other programs or agents. The term comes from the villainous AI in the movie Tron, but in modern software, it refers to any system that acts as the “brain” of an automated environment. Philosophically, the MCP is the Platonic philosopher-king of your infrastructure: all-knowing, all-controlling, and—if left unchecked—prone to tyranny and existential dread. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn19"&gt;
&lt;p&gt;A storage location for code, usually managed with version control. In philosophy, this is your archive of drafts, notes, and published works. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn20"&gt;
&lt;p&gt;The control panel for Jenkins, a tool that automates building and testing software. Imagine a philosopher’s seminar room, but with more alarms and less coffee. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Agile, development, testing: a rant that ends with ChatGPT</title>
      <dc:creator>Nicoletta Bartunek</dc:creator>
      <pubDate>Mon, 06 Feb 2023 14:06:36 +0000</pubDate>
      <link>https://dev.to/nicoletta_bartunek/agile-development-testing-a-rant-that-ends-with-chatgpt-3hbd</link>
      <guid>https://dev.to/nicoletta_bartunek/agile-development-testing-a-rant-that-ends-with-chatgpt-3hbd</guid>
      <description>&lt;h2&gt;
  
  
  Agile, Scrum and the "full-stack developer" - a case study
&lt;/h2&gt;

&lt;p&gt;The team took the standard definition of roles in Scrum (PO, Scrum Master, Developer team) and ran with it - straight off a cliff! They were convinced that only developers should handle automation testing and that manual testers were just unnecessary baggage. The PO even only considered a developer a "full-stack" if they could also do automation testing. Manual testers were only allowed to stay on the team because they were "technically" part of the Definition of Done. But, in true Agile fashion, the team believed that anyone could take on any role at any time. And since testers had no "real" job on the team, the test manager ended up moonlighting as the Scrum Master, while one tester took on the role of writing stories for the dev team. The rest of the manual testers were left to handle "external" responsibilities like customer support.&lt;/p&gt;

&lt;p&gt;On a larger scale, the project subscribed to a SAFe methodology, which called for a "division of labour" between multiple Scrum teams. But, as per the prescription&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, there was also a "System Team" in charge of testing and quality-related tasks. This team handled everything from infrastructure to the general framework for testing. They even created shared libraries to make testing efforts uniform across all teams. But, when it came to staffing the System Team, it was no surprise that they were all "full-stack developers". These were "super-full-stack-developers" who were also expected to handle tasks typically assigned to Operations. So, the "full-stack developer" became a god-like all-around professional figure in the team's eyes.&lt;/p&gt;

&lt;p&gt;"You're making it sound like a disaster. But what's the big deal? What could be more agile than that?" Or maybe, some people might say it's a huge exaggeration. But trust me, folks, it's not. This is the real deal. The project I worked on last year was a wild ride. I'll admit, it's a bit of an exception, but the project is still going strong and running like a well-oiled machine. My attempts to convince them to embrace the power of (automation) testing were unsuccessful, so I decided to jump ship. But hey, at least I got a good story out of it&lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Anyway, let's take baby steps and start by having a little chit-chat with our dear developer about testing. The one with the capital 'D' of course!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Developer and testing
&lt;/h2&gt;

&lt;p&gt;Listen up folks, I got a bone to pick with y'all. I don't want y'all to model the Developer on yerself or yer colleague, not even on an abstraction of all the colleagues you had a chance to work with. I'll try my best to do it myself, even if I might crack under the pressure in the end. But just a tiny bit, I promise. What I'd rather like you to think about is The Developers &lt;em&gt;Weltanschauung&lt;/em&gt; - which is just a fancy word German philosophers use for worldview. And start from this thought: we can safely say that our own (personal) worldview is influenced by the events that occurred in our past and by the impact they had on us. Now let's try to extend this idea to the Developer and try and read his mind.&lt;/p&gt;

&lt;p&gt;Now, let me tell you a little story&lt;sup id="fnref3"&gt;3&lt;/sup&gt;. Once upon a time, The Developer was brought to the world with one purpose only: to develop software. Without him, software development makes no sense. Yet, for a very long time, in the early days, he wasn't the central figure in his own story. Managers and (to my great surprise!) testers were putting him in a box. Much like a house pet, he received orders and was punished when his behaviour (aka code) was unacceptable.&lt;/p&gt;

&lt;p&gt;But things started to change dramatically in the '90s. Software developers took matters into their own hands, they set free from the chains and writing code became an art. Extreme programming, object-oriented programming and a whole lot of other innovations came about&lt;sup id="fnref4"&gt;4&lt;/sup&gt;. This was the new '60. Hippie developers were going to change the world with start-ups built in basements and college dorms&lt;sup id="fnref5"&gt;5&lt;/sup&gt;. They were not only challenging the software development process. Notions such as freedom of speech, legal property and such were also being reshaped&lt;sup id="fnref6"&gt;6&lt;/sup&gt;. All in all, it was just great fun!&lt;/p&gt;

&lt;p&gt;In 2001, the Agile Manifesto was printed because software was starting to take over the world, and things were getting a little chaotic. After all, software was not needed just for software's sake, or in, let's call them, software companies. Everything was slowly becoming software - even huge companies needed it. And the creators of the manifesto weren't a bunch of young whippersnappers, they were seasoned pros with an average age of well over 40&lt;sup id="fnref7"&gt;7&lt;/sup&gt;. Even if the manifesto itself was written in a ski resort (and probably some booze was involved), these were people with a lot of experience. But at its core, the manifesto was all about giving developers the freedom to do their thing. Business types and their complicated plans were allowed in, but only through the back door (they had to pay for everything, after all).&lt;/p&gt;

&lt;p&gt;Now, as far as I can see, this suggests that Developers see themselves as code scientists who do things for the sake of science alone. Which is nice, it's noble, and can also make you rich overnight if you're lucky. We also have dedicated methodologies meant to protect and amplify this mentality and creativity now. Even if, in all truthfulness, some developers will still feel like they are put in a box. They will complain that, because of the huge number of meetings, they are not able to do their (real) job.&lt;/p&gt;

&lt;p&gt;But what about testing? Well, if I'm right up to this point, the Developer thinks testing is useful if it completes his &lt;em&gt;Weltanschauung&lt;/em&gt;. And that means testing is important if (and only if) it can act as a tool to validate his scientific experiments. In short, and somewhat bluntly, if it makes code better. Yet the "makes code better" means that it makes the code a little less likely to crumble under the weight of human error. As my wise friend once said, 'the code needs to answer to itself'. Or was it someone famous? Who cares, the point is the same.&lt;/p&gt;

&lt;p&gt;This is, however, nothing less than unit testing (and, ideally, TDD&lt;sup id="fnref8"&gt;8&lt;/sup&gt;). And if we think about it, this is what most developers will recognize as quality assurance. To give you an example, this is exactly how the "full-stack developers" I mentioned at the beginning understood the matter. They were asked to create automation testing. And you know what they did? They created huge and complex tools to make unit testing easier. Yet, let's be real - this was all about the developer's sense of self-worth. I mean, have you ever heard a developer say 'I just love unit testing'? No, because that's ridiculous. It's like saying 'I love doing taxes' or 'I love going to the dentist'. The "full stack" developer's attitude on the project was rather "Why do things the easy way when you can make it harder and call it 'quality assurance'?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter the Tester
&lt;/h2&gt;

&lt;p&gt;"Who's the tester with the big T? And what does she do?" you might ask. Well, for a while she was like the nagging wife that criticizes her husband for not cleaning the house properly. With the difference that, usually, the wife herself knows how to clean the house (better). Back in the day, testers had their own secret society, hidden away from the developers. They would get the code and go on a bug hunt like it was their own personal witch trial.&lt;/p&gt;

&lt;p&gt;But then the Agile revolution happened and suddenly the testers were left out in the cold. Like a friend once said, they were "just testers", people who do what they do until they can land a job as a developer. These were the people who lugged around huge files with test cases and functional requirements like they were the last copies of the Dead Sea Scrolls. They were an odd extension of the businesspeople, that couldn't keep up with the fast pace of the Agile development. And it seemed like everybody would be better off if developers could just automate their jobs.&lt;/p&gt;

&lt;p&gt;The Dead-Sea-Scrolls society was in a pickle, but they weren't going to roll over and play dead (sorry, bad pun). So they did what any sane group of testers would do - they created the ISTQB (I Swear This is the Qualification Board). They wrote a manual and created a certification, piling paper upon paper until the problem was buried under a mountain of bureaucracy. The basic main activities needed in each test were identified as: test planning and control, test analysis and test design, test implementation and test execution, evaluating exit criteria and reporting, and test closure activities&lt;sup id="fnref9"&gt;9&lt;/sup&gt;. In short, they just kept adding more paperwork and more theory to a paper-pervaded role, until it became so confusing that only "highly qualified testers" could get a grip on it.&lt;/p&gt;

&lt;p&gt;But then something magical happened. Those same old-fashioned bureaucrats who loved their paperwork suddenly discovered the joys of code and had a blast. It was like the hippie-dippy '60s all over again, but this time for testers. In 2006, testers discovered Selenium and Page Objects&lt;sup id="fnref10"&gt;10&lt;/sup&gt; and it was like they had found the holy grail of testing. JavaScript-based tools started promising their own revolution in 2017&lt;sup id="fnref11"&gt;11&lt;/sup&gt;, and testers were like kids in a candy store. Finally, new design patterns created especially for automation purposes were introduced, and it was like a lightbulb went off above everyone's heads&lt;sup id="fnref12"&gt;12&lt;/sup&gt;. Testers also started to find their way back into the Agile world. They borrowed TDD and extended it to ATDD&lt;sup id="fnref13"&gt;13&lt;/sup&gt; and then to BDD&lt;sup id="fnref14"&gt;14&lt;/sup&gt;. It was like they were getting a second chance at life. And, in my opinion, this last step is the biggest "break with tradition". Testing was not about what the management wanted, but about the end user. Testing was not about forcing developers to do what the higher instances wanted them to do. Rather, it became a story about the developer and his audience. It was like a testing fairy-tale come true&lt;sup id="fnref15"&gt;15&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;So, is the tester with the capital T a specialized developer? I don't want to suggest that the Tester got tired of all the paperwork and became a developer. Not at all. Instead, the Tester brought the paperwork into the digital age. She started talking about "living documentation". Diagrams, flowcharts, user stories, acceptance criteria, test cases, all generated automatically. It's like magic! It all comes from the source code, tests, and other artefacts created during the development process. And, most importantly, it's always accurate and up to date. With all the latest information at their fingertips, it's like they have a crystal ball for the project. No more confusion, no more misunderstandings. It's like the Tester is the all-knowing oracle of the development team. It's like a testing party, man! So who is the Tester? The documentation-loving party animal!&lt;/p&gt;

&lt;h2&gt;
  
  
  Sex, drugs, and rock'n'roll?
&lt;/h2&gt;

&lt;p&gt;I think it's no secret by now that I'm a total tree-hugging, granola-munching liberal. I firmly believe in the power of "Give peace a chance" and "Live and let live" philosophy. That's why I'm also a firm believer in the division of roles and responsibilities. If we just let people do what they love, everything will be A-OK. So, I invite you to let the testers test away and the developers code to their hearts' content. And to take advantage of each other's strengths. But let's be real, we don't work with unicorns here. Sometimes projects are like a three-legged race with a blindfold on. And, while testers have had a resurgence in recent years, they're often the ones getting the short end of the stick. Can testers do something about it?&lt;/p&gt;

&lt;p&gt;Well, let me tell you what I tried to do. There were a lot of other issues on my latest project with the full-stack dev team, apart from what I have already shared with you (or, most probably because of it). It was a hot mess that had been going on for a really long time, let me tell you. First off, there was no documentation to be found. Nada. Zilch. Zip. Zero. Second, no one had a clue what the main features of the project were. And to top it off, the testers were like, "IDE? Never heard of her." But it worked. And everybody was talking about "feature-based development" like they knew what they were talking about. And I, being the fool that I am, fell for it hook, line, and sinker. So I sat down with my books&lt;sup id="fnref16"&gt;16&lt;/sup&gt;, scratching my head thinking to myself, "Are we really gonna do this? Let's reverse engineer this baby and BDD the pants off this project!". Even though you didn't start off on the right foot, we can still catch up. So, I rounded up my trusty team of "Three Amigos&lt;sup id="fnref17"&gt;17&lt;/sup&gt;" and we delved deep into understanding what the project was all about. We wrote test cases in plain English, that even a cucumber&lt;sup id="fnref18"&gt;18&lt;/sup&gt; could understand, and generate all the missing documentation with the highest possible dose of serenity&lt;sup id="fnref19"&gt;19&lt;/sup&gt;. It was like trying to teach a giraffe how to swim but it seemed that we could make it work.&lt;/p&gt;

&lt;p&gt;It was a wild ride while it lasted. But like a house of cards, our team crumbled faster than a cookie in milk. Egos were so big, you could see them from space. People were clawing their way to the top like it was a game of "Survivor: Office Edition." And let's not forget about "The Three Amigos" who were missing one crucial member: the business analyst. The PO was like a beacon of hope in the beginning, guiding us to our destination. But, just like a mirage in the desert, he disappeared into thin air when it came time to actually get to work. The manual testers were so fixated on the UI, you'd think they were trying to solve a Rubik's cube blindfolded. And don't even get me started on the "System Team" who provided infrastructure that was about as useful as a screen door on a submarine. Automation testing was a complete and utter failure.&lt;/p&gt;

&lt;p&gt;Was it the Testers' fault or was I just not Tester-y enough? I mean, Martin Fowler was already pointing out in 2005 that there were more people involved in the software development process than just developers, like testers in the "New Methodology.&lt;sup id="fnref20"&gt;20&lt;/sup&gt;" But it can't be just a battle between developers and testers, it's more about figuring out what the heck "The Agile" really means. We've got all the tools, and all the knowledge to do things right. But it's like trying to find a needle in a haystack of confusion. So, here's a thought: if you want to go Agile, do your homework first, and don't pretend to switch just because it's trendy. Especially because the whole Scrum, Super-Scrum, Safe and Unsafe Scrum talk is getting as old as the fight between developers and testers. Now, we've got DevOps&lt;sup id="fnref21"&gt;21&lt;/sup&gt;, GitOps&lt;sup id="fnref22"&gt;22&lt;/sup&gt; and a whole new paradigm knocking at our doors. We have a little chat that promises to make all I've said so far completely and utterly useless.&lt;/p&gt;

&lt;h2&gt;
  
  
  ChatGDP - the final revenge of the Tester?
&lt;/h2&gt;

&lt;p&gt;What does ChatGPT have to do with it? Is this some sort of sneaky clickbait? Well, I have a confession to make. This text was copy-edited by ChatGPT. I had the general idea, I knew where I wanted to go with it, and even had it all broken down into paragraphs. But it would have taken me weeks to get to where this text is right now. I'm both thoroughly impressed and a little scared. Not just for the writing business - I feel bad for them but I won't lose my job over it…or will I? This thing is seemingly as good at writing code as it is at correcting and rephrasing text! So, what does this mean for the whole Agile/tester/developer debate? Is ChatGPT going to take over the world and leave us all jobless? Only time will tell. But here are my two cents on it. Let's take a giant leap backwards and ponder the elusive concept of "The Agile." Is it about speed? Of course. Being clear? Duh. But when you really break it down, it's all about the code. Like a bad tattoo, it's forever etched in our lives. But what happens when code becomes a thing of the past? Will developers become as relevant as VHS tapes? Will testers have a job security of a mayfly?&lt;/p&gt;

&lt;p&gt;One might say, we won't need junior developers anymore, but who will double-check the code and make sure it makes sense? Senior developers, of course! But what happens when we run out of senior developers? Without junior developers, the future looks bleak. But don't worry, ChatGPT.100 will be there to save the day. So, goodbye developers! Time to become a boring manager or find a new job, like a professional couch potato or meme creator. And who knows, maybe carpentry will make a comeback and become the hottest job on the market. But what about testers and their newfound love for coding? Will they have to give it all up and become professional couch potatoes like the rest? Or perhaps they'll have to resort to more drastic measures like becoming professional taste testers for memes. The future is uncertain, but one thing seems sure, they'll have to find a new hobby because coding is so last year.&lt;/p&gt;

&lt;p&gt;Or maybe not? Does the Tester finally have a chance to come out on top? It does look like the Tester finally found a silver lining in the cloud of AI takeover. Indeed, I found quite a reassuring paragraph in a recent study about "The Future of Quality Assurance". It goes this way: "However, even with all this computer power and all this data and intelligence, there's still one thing at which every AI sucks: understanding human behaviour.&lt;sup id="fnref23"&gt;23&lt;/sup&gt;" And this is great news for the tester! While machines may rule the world, testing will always be a job for humans. And let's face it, BDD - as in &lt;em&gt;Behaviour&lt;/em&gt;-driven - is basically the president of testing anyway. So go forth, testers, and conquer the world (or at least, the world of software). Also 'cause, you know, what could be more Agile than that?&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Abu-Faraj, M. (2019). A Survey on Software Quality Assurance. Journal of Engineering and Applied Sciences, 14(15), 5111–5122. &lt;a href="https://doi.org/10.36478/jeasci.2019.5111.5122" rel="noopener noreferrer"&gt;https://doi.org/10.36478/jeasci.2019.5111.5122&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anonymous. (2009). Standards and guidelines for quality assurance in the European higher education area. (5) (PDF) A Survey on Software Quality Assurance. European Association for Quality Assurance in the European Higher Education, Helsinki, Finland.&lt;/li&gt;
&lt;li&gt;Anonymous. (2013). 730/D9, Nov 2013-IEEE approve draft standard for software quality assurance processes. IEEE, New York, USA &lt;a href="https://ieeexplore.ieee.org/document/6781526" rel="noopener noreferrer"&gt;https://ieeexplore.ieee.org/document/6781526&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Baumgartner, M., Klonk, M., Mastnak, C., Pichler, H., Seidl, R., &amp;amp; Tanczos, S. (2021). Agile Testing: The Agile Way to Quality. Springer International Publishing. &lt;a href="https://doi.org/10.1007/978-3-030-73209-7" rel="noopener noreferrer"&gt;https://doi.org/10.1007/978-3-030-73209-7&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Binamungu, L. P., Embury, S. M., &amp;amp; Konstantinou, N. (2018a). Detecting duplicate examples in behaviour driven development specifications. 2018 IEEE Workshop on Validation, Analysis and Evolution of Software Tests (VST), 6–10. &lt;a href="https://doi.org/10.1109/VST.2018.8327149" rel="noopener noreferrer"&gt;https://doi.org/10.1109/VST.2018.8327149&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Binamungu, L. P., Embury, S. M., &amp;amp; Konstantinou, N. (2018b). Maintaining behaviour driven development specifications: Challenges and opportunities. 2018 IEEE 25th International Conference on Software Analysis, Evolution and Reengineering (SANER), 175–184. &lt;a href="https://doi.org/10.1109/SANER.2018.8330207" rel="noopener noreferrer"&gt;https://doi.org/10.1109/SANER.2018.8330207&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Binamungu, L. P., Embury, S. M., &amp;amp; Konstantinou, N. (2020). Characterising the Quality of Behaviour Driven Development Specifications. In V. Stray, R. Hoda, M. Paasivaara, &amp;amp; P. Kruchten (Eds.), Agile Processes in Software Engineering and Extreme Programming (pp. 87–102). Springer International Publishing. &lt;a href="https://doi.org/10.1007/978-3-030-49392-9_6" rel="noopener noreferrer"&gt;https://doi.org/10.1007/978-3-030-49392-9_6&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Crosby, P. B. (1979). Quality is free: The art of making quality certain. New York: McGraw-Hill. &lt;a href="http://archive.org/details/qualityisfree00cros" rel="noopener noreferrer"&gt;http://archive.org/details/qualityisfree00cros&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Garg, S. (2015). Cucumber Cookbook. Packt Publishing Ltd.&lt;/li&gt;
&lt;li&gt;Goericke, S. (2019). The Future of Software Quality Assurance. Springer International Publishing.&lt;/li&gt;
&lt;li&gt;Humphrey, W. S. (1989). Managing the Software Process. Addison-Wesley.&lt;/li&gt;
&lt;li&gt;Irshad, M., Britto, R., &amp;amp; Petersen, K. (2021). Adapting Behavior Driven Development (BDD) for large-scale software systems. Journal of Systems and Software, 177, 110944. &lt;a href="https://doi.org/10.1016/j.jss.2021.110944" rel="noopener noreferrer"&gt;https://doi.org/10.1016/j.jss.2021.110944&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lopes de Souza, P., Lopes de Souza, W., &amp;amp; Ferreira Pires, L. (2021). ScrumOntoBDD: Agile software development based on scrum, ontologies, and behaviour-driven development. Journal of the Brazilian Computer Society, 27(1), 10. &lt;a href="https://doi.org/10.1186/s13173-021-00114-w" rel="noopener noreferrer"&gt;https://doi.org/10.1186/s13173-021-00114-w&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Martin Fowler. (2005). The New Methodology. Martinfowler.Com. &lt;a href="https://martinfowler.com/articles/newMethodology.html" rel="noopener noreferrer"&gt;https://martinfowler.com/articles/newMethodology.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Nicieja, K. (2017). Writing Great Specifications: Using Specification by Example and Gherkin. Manning.&lt;/li&gt;
&lt;li&gt;OIN. (2011). ISO - ISO/IEC 25010:2011 - Systems and software engineering - Systems and software Quality Requirements and Evaluation (SQuaRE) - System and software quality models. &lt;a href="https://www.iso.org/standard/35733.html" rel="noopener noreferrer"&gt;https://www.iso.org/standard/35733.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rose, S., Wynne, M., &amp;amp; Hellesøy, A. (2015). The Cucumber for Java Book: Behaviour-driven Development for Testers and Developers. Pragmatic Bookshelf.&lt;/li&gt;
&lt;li&gt;Scaled Agile, Inc. (2017). Scaled agile framework. Retrieved 2017 from &lt;a href="http://www" rel="noopener noreferrer"&gt;http://www&lt;/a&gt;. Scaledagileframework.com/.&lt;/li&gt;
&lt;li&gt;Smart, J. F. (2014). BDD in Action: Behavior-driven development for the whole software lifecycle. Manning.&lt;/li&gt;
&lt;li&gt;Solis, C., &amp;amp; Wang, X. (2011). A Study of the Characteristics of Behaviour Driven Development. 2011 37th EUROMICRO Conference on Software Engineering and Advanced Applications, 383–387. &lt;a href="https://doi.org/10.1109/SEAA.2011.76" rel="noopener noreferrer"&gt;https://doi.org/10.1109/SEAA.2011.76&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Spillner, A., &amp;amp; Linz, T. (2012). Basiswissen Softwaretest: Aus- und Weiterbildung zum Certified Tester; Foundation Level nach ISTQB-Standard. dpunkt-Verlag.&lt;/li&gt;
&lt;li&gt;Walkinshaw, N. (2017). Software Quality Assurance. Springer International Publishing. &lt;a href="https://doi.org/10.1007/978-3-319-64822-4" rel="noopener noreferrer"&gt;https://doi.org/10.1007/978-3-319-64822-4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;See Scaled Agile, Inc., 2017. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Please keep in mind that this text is meant to be a rant, just plain old having fun. Some context and more reliable material will be available in the footnotes in the form of definitions and references. But they are not meant to be, by any means, exhaustive. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;There are some truly amazing reconstructions of the history of software development and quality assurance available nowadays. Mine is not going to be one of them. What follows is just my caricaturist and biased way of expressing what came to mind while reading, amongst others, Walkinshaw (2017), Goericke (2019) and Baumgartner et al. (2021). ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;To mention just a few, the widespread adoption of the Internet in the 1990s led to the development of new technologies and practices specifically for building web applications. HTML, CSS, and JavaScript were developed to create web pages and dynamic user interfaces, and the HTTP protocol provided a way for these pages to be transmitted over the Internet. Integrated development environments (IDEs) and version control systems (VCS) also became more prevalent in the 1990s. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;One of the most notable IT startups built this way in the 1990s was Google. In 1996, Larry Page and Sergey Brin, two PhD students at Stanford University, began working on a search engine in their dormitory. They called it "Backrub" at the time, and after months of development, they renamed it Google. The company was officially incorporated in 1998, and the rest is history. Another example of a successful IT startup built in a basement in the 1990s is Amazon. In 1994, Jeff Bezos, an investment banker, started working on an online bookstore in the garage of his home. He launched the company in 1995, and it quickly grew in popularity. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;See e.g. "The Pirate Bay" and the scandals it provoked. The site was launched a little bit later - in 2003 - but it was the e prototype of a website that provides a directory of torrent files and magnet links for peer-to-peer file sharing using the BitTorrent protocol. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;On this see e.g. Baumgartner et al., 2021, p. 108. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn8"&gt;
&lt;p&gt;Test-driven development (TDD) is a software development approach in which tests are written for a piece of code before the code itself is written. The tests are then run, and the code is written to pass them. The process is then repeated, with new tests being written as new features are added to the code. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn9"&gt;
&lt;p&gt;For this see Spillner &amp;amp; Linz, 2012. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn10"&gt;
&lt;p&gt;The basic idea behind the Page Objects pattern is to create a separate class for each page or page section of the web application under test. Each class represents the elements and functionality of the corresponding page, and the methods in the class provide an interface for interacting with the page elements. For example, a login page class would have methods for entering a username and password, and clicking the login button. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn11"&gt;
&lt;p&gt;This is when Cypress was first released, but tools such as Puppeteer, Playwright and Test Café followed suit, and are now more popular than ever. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn12"&gt;
&lt;p&gt;Take, for example, the Screenplay pattern, which is based on the idea of modelling the test as a series of actions that a user would perform on the system. And, similarly, App actions in Cypress, which envisages a separate class or module and can be used by the test code to interact with the application. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn13"&gt;
&lt;p&gt;ATDD (Acceptance Test-Driven Development) is a software development methodology that emphasizes the use of acceptance tests to drive the development process. The ATDD process starts with the stakeholders defining the acceptance criteria for a software feature. These acceptance criteria are then used to create acceptance tests that will be used to verify that the feature meets the requirements. The development team then uses these acceptance tests to guide the development process, ensuring that the feature is developed to meet the acceptance criteria. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn14"&gt;
&lt;p&gt;BDD (Behavior-Driven Development) is a software development methodology that focuses on the behaviour of the software system, rather than its implementation. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn15"&gt;
&lt;p&gt;On a more serious note, we can also notice how the definition of "software quality assurance" changed over time in the academic world. Abu-Faraj (2019) sums it up nicely (up to a certain point) this way: "Humphrey (1989) defined it as achieving levels of fitness for use. Crosby (1979) defines it as conformance to requirements. In recent studies, new definitions of software quality appeared. OIN (2011) defined it as the capability of the software product to satisfy stated and implied needs under specified conditions. Anonymous (2013, 2009) defined it as the degree to which a software product depends upon those requirements that accurately represent stakeholder needs, wants and expectations". But one of the latest trends on the matter is called "Total Quality Management" (TQM) (…) [and] it broadly represents an approach to management that aims for long-term success by linking quality with customer satisfaction", with one of its main characteristics being customer focus (on this see Walkinshaw, 2017, p. 30–31). ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn16"&gt;
&lt;p&gt;I highly recommend Solis &amp;amp; Wang (2011), Smart (2014), Garg (2015), Rose et al. (2015), Nicieja (2017), Binamungu et al (2020), Binamungu et al. (2018, 2018b), Lopes de Souza et al. (2021) and Irshad et al. (2021), amongst others. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn17"&gt;
&lt;p&gt;The "Three Amigos" refers to a team of three individuals: a business analyst, a developer, and a tester. The team works together to ensure that the requirements for a software project are clearly understood, and that the solution being developed meets those requirements. The "Three Amigos" work collaboratively to ensure that the solution is tested and validated before it is released to the customer. This approach is often used in the context of Behavior Driven Development (BDD) to ensure that the software meets the needs of the end user, and that the development process is as efficient as possible. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn18"&gt;
&lt;p&gt;Cucumber is a tool for behaviour-driven development (BDD), which allows anyone to write tests in a natural language format that is easily understood by non-technical stakeholders, and implement the code accordingly. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn19"&gt;
&lt;p&gt;Serenity is another open-source BDD automation framework, and one of its main features is that it creates reports that provide detailed, meaningful information about the acceptance criteria and the test results. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn20"&gt;
&lt;p&gt;Martin Fowler, 2005. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn21"&gt;
&lt;p&gt;DevOps is a set of practices and tools that aims to bridge the gap between development and operations teams by automating the process of software delivery and infrastructure changes. It relies extensively on continuous integration and continuous delivery (CI/CD), infrastructure as code, containerization, and monitoring and logging. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn22"&gt;
&lt;p&gt;GitOps is a methodology that uses Git as a single source of truth for both application and infrastructure definition, promoting continuous delivery and deployment practices through code versioning and pull request workflows. The idea is to manage the entire lifecycle of an application using Git as the source of truth, making it easier to track changes, revert mistakes and automate the deployment pipeline. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn23"&gt;
&lt;p&gt;Goericke, 2019, p. 203. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>devto</category>
      <category>announcement</category>
      <category>community</category>
      <category>offers</category>
    </item>
  </channel>
</rss>
