<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Big-Picture on Ocarina — manual</title>
    <link>https://mojo-molotov.github.io/from-ocarina-to-igor/series/big-picture/</link>
    <description>Recent content in Big-Picture on Ocarina — manual</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    <lastBuildDate>Thu, 04 Jun 2026 17:04:59 +0200</lastBuildDate>
    <atom:link href="https://mojo-molotov.github.io/from-ocarina-to-igor/series/big-picture/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>00.01 — Ecosystem cartography</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/00-big-picture/01-ecosystem-map/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/00-big-picture/01-ecosystem-map/</guid>
      <description>&lt;h1 id=&#34;0001ecosystem-cartography&#34;&gt;00.01 — Ecosystem cartography&lt;a class=&#34;anchor&#34; href=&#34;#0001ecosystem-cartography&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;The Ocarina ecosystem is &lt;strong&gt;six public repos&lt;/strong&gt; under the &lt;a href=&#34;https://github.com/mojo-molotov&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;mojo-molotov&lt;/code&gt;&lt;/a&gt; GitHub account. They cover &lt;strong&gt;five distinct roles&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Role&lt;/th&gt;&#xA;          &lt;th&gt;Repo&lt;/th&gt;&#xA;          &lt;th&gt;Form&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Framework&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Python library on PyPI&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Public System Under Test (SUT)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;igoristan&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;React + Vike SPA, GitHub Pages&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Coordination backend&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;tests-workers&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Vercel Edge API + Upstash Redis&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Example suites&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina-example&lt;/code&gt; (canonical), &lt;code&gt;ocarina-with-ai-example&lt;/code&gt; (AI)&lt;/td&gt;&#xA;          &lt;td&gt;Python e2e suites driving Igoristan / CURA&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Public documentation&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina-holy-book&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;VitePress site (EN + FR + RU), PDFs, AI skills&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;the-big-picture&#34;&gt;The big picture&lt;a class=&#34;anchor&#34; href=&#34;#the-big-picture&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────────────────────┐&#xA;│                              OCARINA (BIG PICTURE)                              │&#xA;└─────────────────────────────────────────────────────────────────────────────────┘&#xA;&#xA;   ┌──────────────────────────────┐         ┌──────────────────────────────────┐&#xA;   │  [PACKAGE]  ocarina          │ ──────► │  [PACKAGE]  ocarina-example      │&#xA;   │  Python framework 3.14+      │   pip   │  e2e suite against the Igoristan │&#xA;   │  ROP / DSL / orchestration   │ install │  (Selenium + Firefox + Redis)    │&#xA;   └──────────────────────────────┘         └──────────────────────────────────┘&#xA;            │  │                                       │  ▲   │&#xA;            │  │                                       │  │  uses&#xA;            │  │ pip install ocarina                   │  │  IGOR_API_KEY&#xA;            │  ▼                                       ▼  │   │&#xA;            │  ┌────────────────────────────────────┐  drives │&#xA;            │  │ [PACKAGE]  ocarina-with-ai-example │  ┌──────┴──────────────────┐&#xA;            │  │ e2e suite against CURA Healthcare  │  │ [WEBSITE]  igoristan    │&#xA;            │  │ Claude Code, 99% machine-written   │  │ React 19 + Vike         │&#xA;            │  └────────────────────────────────────┘  │ GitHub Pages            │&#xA;            │              │                           └──────┬──────────────────┘&#xA;            │              │ drives                           │ fetches OTP&#xA;            │              ▼                                  ▼&#xA;            │   ┌──────────────────────────────┐    ┌──────────────────────────────┐&#xA;            │   │ [WEBSITE]  CURA Healthcare   │    │ [BACKEND]  tests-workers     │&#xA;            │   │ Heroku, open-source PHP      │    │ Vercel Edge Functions        │&#xA;            │   └──────────────────────────────┘    │ + Upstash Redis              │&#xA;            │                                       │ /api/otp, /otp-history,      │&#xA;            │                                       │ /api/corsicadex              │&#xA;            │                                       └──────────────────────────────┘&#xA;            │                                                 ▲&#xA;            │                                                 │ x-api-key&#xA;            │                                                 │ (IGOR_API_KEY ≡ API_SECRET)&#xA;            │                                                 │&#xA;            ▼&#xA;   ┌──────────────────────────────┐&#xA;   │  [DOCS]  ocarina-holy-book   │&#xA;   │  VitePress EN + FR + RU      │&#xA;   │  AI skills, PDFs, llms.txt   │&#xA;   │  GitHub Pages                │&#xA;   └──────────────────────────────┘&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;code&gt;ocarina&lt;/code&gt; → example suites&lt;/strong&gt;: plain pip dependency (&lt;code&gt;pip install ocarina&lt;/code&gt;).&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Example suites → SUT (Igoristan / CURA)&lt;/strong&gt;: browser automation through Selenium.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Igoristan suite ↔ &lt;code&gt;tests-workers&lt;/code&gt;&lt;/strong&gt;: HTTP calls (OTP, Corsicadex). Shared secret: &lt;code&gt;IGOR_API_KEY&lt;/code&gt; client-side ≡ &lt;code&gt;API_SECRET&lt;/code&gt; server-side.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;responsibilities&#34;&gt;Responsibilities&lt;a class=&#34;anchor&#34; href=&#34;#responsibilities&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Role&lt;/th&gt;&#xA;          &lt;th&gt;Contract&lt;/th&gt;&#xA;          &lt;th&gt;Constraint&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Framework&lt;/td&gt;&#xA;          &lt;td&gt;Ships the DSL, the orchestration, the driver pool, the reporters&lt;/td&gt;&#xA;          &lt;td&gt;Stays small, auditable, no hidden deps&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Public SUT&lt;/td&gt;&#xA;          &lt;td&gt;A deliberately chaotic playground (random errors, OTP, finicky forms)&lt;/td&gt;&#xA;          &lt;td&gt;Lives on GitHub Pages forever, no heavy backend&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Coordination backend&lt;/td&gt;&#xA;          &lt;td&gt;Coordinates workers on OTP, surfaces data for parallel tests&lt;/td&gt;&#xA;          &lt;td&gt;Stateless code, state in Redis (Upstash)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Example suites&lt;/td&gt;&#xA;          &lt;td&gt;Show how Ocarina actually gets used — without AI (canonical) and with AI (CURA)&lt;/td&gt;&#xA;          &lt;td&gt;Public, runnable, complete, in CI&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Documentation&lt;/td&gt;&#xA;          &lt;td&gt;The why, the how, and the AI part&lt;/td&gt;&#xA;          &lt;td&gt;EN + FR + RU (Corso-Russian tradition), LLM-friendly files like &lt;code&gt;llms.txt&lt;/code&gt;, plus PDFs&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;three-licenses&#34;&gt;Three licenses&lt;a class=&#34;anchor&#34; href=&#34;#three-licenses&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;License&lt;/th&gt;&#xA;          &lt;th&gt;Where&lt;/th&gt;&#xA;          &lt;th&gt;Why&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;MIT&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina&lt;/code&gt;, &lt;code&gt;ocarina-example&lt;/code&gt;, &lt;code&gt;ocarina-with-ai-example&lt;/code&gt;, &lt;code&gt;ocarina-holy-book&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Python code or docs. Transmissible as-is. Sovereign. See &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/11-independence/&#34;&gt;&lt;code&gt;../11-independence/&lt;/code&gt;&lt;/a&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;ISC&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;tests-workers&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Vercel Edge scaffold default. Kept as-is.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;em&gt;(unlicensed)&lt;/em&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;igoristan&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Public demo app. Treat it as WTFPL.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;deliberate-friction-between-repos&#34;&gt;Deliberate friction between repos&lt;a class=&#34;anchor&#34; href=&#34;#deliberate-friction-between-repos&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;The design is &lt;strong&gt;intentionally asymmetric&lt;/strong&gt; along certain axes. The friction is the testing tool:&lt;/p&gt;</description>
    </item>
    <item>
      <title>00.02 — Stack / responsibility / license matrix</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/00-big-picture/02-stack-matrix/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/00-big-picture/02-stack-matrix/</guid>
      <description>&lt;h1 id=&#34;0002stack--responsibility--license-matrix&#34;&gt;00.02 — &lt;em&gt;Stack / responsibility / license&lt;/em&gt; matrix&lt;a class=&#34;anchor&#34; href=&#34;#0002stack--responsibility--license-matrix&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Repository&lt;/th&gt;&#xA;          &lt;th&gt;Role&lt;/th&gt;&#xA;          &lt;th&gt;Language&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;Version&lt;/th&gt;&#xA;          &lt;th&gt;Primary stack&lt;/th&gt;&#xA;          &lt;th&gt;Tooling stack&lt;/th&gt;&#xA;          &lt;th&gt;Distribution&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;License&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Browser e2e test framework&lt;/td&gt;&#xA;          &lt;td&gt;Python&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;3.14+&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;hatchling&lt;/code&gt;, &lt;code&gt;python-docx&lt;/code&gt; (sole runtime dependency), &lt;code&gt;selenium&lt;/code&gt; + &lt;code&gt;playwright&lt;/code&gt; (dev only)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ruff&lt;/code&gt; (ALL), &lt;code&gt;mypy&lt;/code&gt; strict, &lt;code&gt;pytest&lt;/code&gt;, &lt;code&gt;hypothesis&lt;/code&gt;, &lt;code&gt;pytest-mypy-plugins&lt;/code&gt;, &lt;code&gt;syrupy&lt;/code&gt;, &lt;code&gt;prysk&lt;/code&gt; (cram), &lt;code&gt;allure-pytest&lt;/code&gt;, &lt;code&gt;pre-commit&lt;/code&gt;, &lt;code&gt;twine&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;PyPI, v&lt;strong&gt;1.1.10&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;MIT&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina-example&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Canonical e2e suite against the Igoristan&lt;/td&gt;&#xA;          &lt;td&gt;Python&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;3.14+&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina&lt;/code&gt;, &lt;code&gt;selenium ≥ 4.40&lt;/code&gt;, &lt;code&gt;python-dotenv&lt;/code&gt;, &lt;code&gt;dogpile.cache&lt;/code&gt;, &lt;code&gt;redis&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ruff&lt;/code&gt;, &lt;code&gt;mypy&lt;/code&gt;, &lt;code&gt;pre-commit&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Source only&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;MIT&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina-with-ai-example&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;e2e suite against CURA Healthcare, co-written with Claude Code&lt;/td&gt;&#xA;          &lt;td&gt;Python&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;3.14+&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina ≥ 1.0.3&lt;/code&gt;, &lt;code&gt;selenium ≥ 4.40&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ruff&lt;/code&gt;, &lt;code&gt;mypy&lt;/code&gt;, &lt;code&gt;mypy-extensions&lt;/code&gt;, &lt;code&gt;typing-extensions&lt;/code&gt;, &lt;code&gt;pre-commit&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Source only&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;MIT&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;igoristan&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Public SUT, deliberately chaotic web app&lt;/td&gt;&#xA;          &lt;td&gt;TypeScript&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;6.0.x&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;React 19.2&lt;/strong&gt;, &lt;strong&gt;Vike 0.4.258&lt;/strong&gt; (SSG), &lt;strong&gt;Vite 7.3&lt;/strong&gt;, &lt;strong&gt;TailwindCSS 4&lt;/strong&gt; (alpha), &lt;code&gt;valibot&lt;/code&gt;, &lt;code&gt;react-hook-form&lt;/code&gt;, &lt;code&gt;react-dropzone&lt;/code&gt;, &lt;code&gt;usehooks-ts&lt;/code&gt;, &lt;code&gt;throttleit&lt;/code&gt;, &lt;code&gt;lucide-react&lt;/code&gt;, &lt;code&gt;uuid&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;pnpm 11&lt;/code&gt;, &lt;strong&gt;Node 24&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;wireit&lt;/code&gt;&lt;/strong&gt; (orchestrator), &lt;code&gt;eslint 9&lt;/code&gt; (flat), &lt;code&gt;prettier 3.5&lt;/code&gt;, &lt;code&gt;husky&lt;/code&gt;, &lt;code&gt;lint-staged&lt;/code&gt;, &lt;code&gt;commitlint&lt;/code&gt;, &lt;code&gt;commitizen&lt;/code&gt;, &lt;code&gt;terser&lt;/code&gt;, &lt;code&gt;rollup-plugin-visualizer&lt;/code&gt;, &lt;code&gt;vite-plugin-compression&lt;/code&gt;, &lt;code&gt;@qalisa/vike-plugin-sitemap&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;GitHub Pages (&lt;code&gt;/igoristan/&lt;/code&gt;)&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;em&gt;none&lt;/em&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;tests-workers&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;OTP / Corsicadex backend, the substrate that exercises &lt;strong&gt;parallelization&lt;/strong&gt; and &lt;strong&gt;API tests&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;TypeScript&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;5.9.3&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Vercel Edge Functions&lt;/strong&gt; (&lt;code&gt;runtime: &amp;quot;edge&amp;quot;&lt;/code&gt;), &lt;code&gt;@upstash/redis&lt;/code&gt;, &lt;code&gt;otplib&lt;/code&gt;, &lt;code&gt;next&lt;/code&gt; types (&lt;code&gt;NextRequest&lt;/code&gt;)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;pnpm 11.x&lt;/code&gt;, &lt;code&gt;@vercel/node&lt;/code&gt; (types)&lt;/td&gt;&#xA;          &lt;td&gt;Vercel: &lt;code&gt;https://tests-workers.vercel.app&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;ISC&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina-holy-book&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Public documentation + AI skills + PDFs&lt;/td&gt;&#xA;          &lt;td&gt;TypeScript&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;6.0.x&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;VitePress 2 alpha&lt;/strong&gt;, &lt;code&gt;@sugarat/theme&lt;/code&gt;, &lt;code&gt;vue 3.5&lt;/code&gt;, &lt;code&gt;pagefind&lt;/code&gt;, &lt;code&gt;vitepress-plugin-image-optimize&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;pnpm 11&lt;/code&gt;, Node 24, &lt;code&gt;eslint 9&lt;/code&gt;, &lt;code&gt;prettier 3.8&lt;/code&gt;, &lt;code&gt;husky&lt;/code&gt;, &lt;code&gt;lint-staged&lt;/code&gt;, &lt;code&gt;commitlint&lt;/code&gt;, &lt;code&gt;sass-embedded&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;GitHub Pages (&lt;code&gt;/ocarina-holy-book/&lt;/code&gt;)&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;MIT&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;python-early-adopter&#34;&gt;Python early adopter&lt;a class=&#34;anchor&#34; href=&#34;#python-early-adopter&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Python 3.12+ feature&lt;/th&gt;&#xA;          &lt;th&gt;Use in Ocarina&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;PEP 695&lt;/strong&gt; (&lt;code&gt;class Foo[T]:&lt;/code&gt;)&lt;/td&gt;&#xA;          &lt;td&gt;Generic signatures everywhere (&lt;code&gt;TestSuite[Driver]&lt;/code&gt;, &lt;code&gt;Watcher[Driver]&lt;/code&gt;, &lt;code&gt;Test[Driver]&lt;/code&gt;, &lt;code&gt;Result[T]&lt;/code&gt;, &lt;code&gt;Ok[T]&lt;/code&gt;, &lt;code&gt;Thunk[T]&lt;/code&gt;, etc.)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;PEP 695 type aliases&lt;/strong&gt; (&lt;code&gt;type X = ...&lt;/code&gt;)&lt;/td&gt;&#xA;          &lt;td&gt;Every alias: &lt;code&gt;type Result[T] = Ok[T] | Fail&lt;/code&gt;, &lt;code&gt;type Effect = Callable[[], None]&lt;/code&gt;, &lt;code&gt;type Thunk[T] = Callable[[], T]&lt;/code&gt;, &lt;code&gt;type Mode = Literal[...]&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;code&gt;TypeGuard&lt;/code&gt;&lt;/strong&gt; (Python 3.10+)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;is_ok&lt;/code&gt;, &lt;code&gt;is_fail&lt;/code&gt;, &lt;code&gt;is_test_result_ok&lt;/code&gt;, &lt;code&gt;is_test_result_fail&lt;/code&gt;, &lt;code&gt;is_test_result_skipped&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;code&gt;Self&lt;/code&gt;&lt;/strong&gt; (3.11+)&lt;/td&gt;&#xA;          &lt;td&gt;Fluent returns from POMs, loggers, invariants&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;code&gt;@final&lt;/code&gt;&lt;/strong&gt; (3.8+)&lt;/td&gt;&#xA;          &lt;td&gt;Locks critical classes (&lt;code&gt;Watcher&lt;/code&gt;, &lt;code&gt;Test&lt;/code&gt;, &lt;code&gt;TestCycle&lt;/code&gt;, &lt;code&gt;ChainRunner&lt;/code&gt;, &lt;code&gt;Ok&lt;/code&gt;, &lt;code&gt;Fail&lt;/code&gt;, …)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;code&gt;Unpack&lt;/code&gt;&lt;/strong&gt; (3.11+)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;HumanizedDriver&lt;/code&gt; signature in &lt;code&gt;ocarina-example&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;code&gt;Protocol&lt;/code&gt;&lt;/strong&gt; (3.8+)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ScreenshotDriver&lt;/code&gt;, &lt;code&gt;SupportsWrite[str]&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;code&gt;Literal&lt;/code&gt;&lt;/strong&gt; (3.8+)&lt;/td&gt;&#xA;          &lt;td&gt;All enums (&lt;code&gt;SeleniumCliStoreKeys&lt;/code&gt;, &lt;code&gt;LOGGERS_CHOICES&lt;/code&gt;, &lt;code&gt;Mode&lt;/code&gt;)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;code&gt;Never&lt;/code&gt;&lt;/strong&gt; (3.11+)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;_SilentArgumentParser.error&lt;/code&gt; signature&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;&lt;strong&gt;Practical consequence&lt;/strong&gt;: there is a dedicated CI workflow &lt;code&gt;unstable_python_full_build.yml&lt;/code&gt; that pushes Python &lt;strong&gt;3.15-dev&lt;/strong&gt; monthly (&lt;code&gt;cron: &amp;quot;0 3 1 * *&amp;quot;&lt;/code&gt;), because Ocarina aims to be ready for the next interpreter as soon as it ships. See &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/10-cicd/02-ocarina-workflows/&#34;&gt;&lt;code&gt;../10-cicd/02-ocarina-workflows.md&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>00.03 — End-to-end execution flow of an e2e campaign</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/00-big-picture/03-global-execution-flow/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/00-big-picture/03-global-execution-flow/</guid>
      <description>&lt;h1 id=&#34;0003end-to-end-execution-flow-of-an-e2e-campaign&#34;&gt;00.03 — End-to-end execution flow of an e2e campaign&lt;a class=&#34;anchor&#34; href=&#34;#0003end-to-end-execution-flow-of-an-e2e-campaign&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;Run &lt;code&gt;python -u src/main.py …&lt;/code&gt; on either suite (&lt;code&gt;ocarina-example&lt;/code&gt; or &lt;code&gt;ocarina-with-ai-example&lt;/code&gt;) and this chain kicks off:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;USER  ────────────────────────────────────────────────────────────────────&#xA;       python -u src/main.py --browser firefox --workers 3 [...]&#xA;              │&#xA;              ▼&#xA;       (1) parse CLI&#xA;           CliStoreSingleton.push(create_selenium_auto_cli_store())&#xA;              │&#xA;              ▼&#xA;       (2) build pool&#xA;           create_selenium_drivers_pool(max_size=N)&#xA;              │&#xA;              ▼&#xA;       (3) warm up external dependencies&#xA;           - Redis (ocarina-example)&#xA;           - Heroku dyno (ai-example, via curl --retry 6)&#xA;              │&#xA;              ▼&#xA;       (4) bootstrap(&#xA;              test_cycle  = create_e2e_test_cycle(drivers_pool),&#xA;              run_plugins = lambda results: run_plugins(&#xA;                                generate_docx_proof, generate_json_results,&#xA;                                exceptions_logger=...),&#xA;              post_exec   = pretty_print_results + sys.exit(1) on fail&#xA;           )&#xA;              │&#xA;OCARINA  ─────┼──────────────────────────────────────────────────────────&#xA;              │&#xA;              ▼&#xA;       (5) TestCycle.run_all (saturate_workers=True)&#xA;              ├─ smoke_tests_campaigns      [mode: fail-fast | wait-for-all]&#xA;              │     └─ TestCampaign.run_all&#xA;              │           └─ TestSuite.run (max_workers, saturate_workers)&#xA;              │                 └─ ThreadPoolExecutor → TestFlow.run&#xA;              │                       └─ pool.acquire() → TestExecutor.execute&#xA;              │                             ├─ setup()                  (optional)&#xA;              │                             ├─ watchers.start()         (daemon threads)&#xA;              │                             ├─ chain_runners            (Railway DSL)&#xA;              │                             ├─ watchers.stop()&#xA;              │                             └─ teardown()               (always)&#xA;              ├─ campaigns (main)&#xA;              │  (skipped if a smoke failed)&#xA;              │&#xA;SUT   ────────┼────────────────────────────────────────────────────────────&#xA;              │&#xA;              ▼&#xA;       Selenium WebDriver ⇄ real browser&#xA;       sometimes: OTP HTTP GET + Redis (on the ocarina-example side)&#xA;              │&#xA;              ▼&#xA;       (6) run_plugins(results)&#xA;              ├─ generate_docx_proof  (reads the log tree, builds .docx files)&#xA;              ├─ generate_json_results (serializes results to .json)&#xA;              ├─ others if declared (parallelized via ThreadPoolExecutor)&#xA;              │&#xA;              ▼&#xA;       (6&amp;#39;) post_exec(results)&#xA;              ├─ pretty_print_results (ANSI, hierarchical)&#xA;              └─ has_test_cycle_failed → sys.exit(1) if applicable&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;step-by-step&#34;&gt;Step-by-step&lt;a class=&#34;anchor&#34; href=&#34;#step-by-step&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-parse-cli&#34;&gt;(1) Parse CLI&lt;a class=&#34;anchor&#34; href=&#34;#1-parse-cli&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;p&gt;&lt;code&gt;create_selenium_auto_cli_store()&lt;/code&gt; detects the OS via &lt;code&gt;platform.system()&lt;/code&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>00.04 — Relations between the six repositories</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/00-big-picture/04-repo-relations/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/00-big-picture/04-repo-relations/</guid>
      <description>&lt;h1 id=&#34;0004relations-between-the-six-repositories&#34;&gt;00.04 — Relations between the six repositories&lt;a class=&#34;anchor&#34; href=&#34;#0004relations-between-the-six-repositories&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;Every edge of the graph is a &lt;em&gt;contract&lt;/em&gt; — a secret, a URL, a payload type, or a version. One pair per section below.&lt;/p&gt;&#xA;&lt;h2 id=&#34;ocarina--ocarina-example&#34;&gt;&lt;code&gt;ocarina&lt;/code&gt; ↔ &lt;code&gt;ocarina-example&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#ocarina--ocarina-example&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Direction&lt;/th&gt;&#xA;          &lt;th&gt;Mechanism&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina&lt;/code&gt; → &lt;code&gt;ocarina-example&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;pip install ocarina&lt;/code&gt; from PyPI&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina-example&lt;/code&gt; → &lt;code&gt;ocarina&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;None (the example pushes nothing)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;The example &lt;strong&gt;writes its own adapters&lt;/strong&gt; on top of the framework:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;lib/ext/ocarina/adapters/agnostic/act.py&lt;/code&gt; → adds an &lt;code&gt;on_failure&lt;/code&gt; hook that turns an HTTP error page (title matched by &lt;code&gt;ERROR_PAGE_REGEX&lt;/code&gt;) into &lt;code&gt;HttpErrorPageReachedError&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;lib/ext/ocarina/adapters/agnostic/match_page.py&lt;/code&gt; → &lt;code&gt;create_match_page(raised_exceptions=transient_errors)&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;lib/ext/ocarina/adapters/agnostic/env_getters.py&lt;/code&gt; → typed &lt;code&gt;EnvGetters[_CredsKeys, _ValuesKeys]&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;lib/ext/ocarina/adapters/selenium/test_suite.py&lt;/code&gt; → pins &lt;code&gt;max_retries_per_test=8&lt;/code&gt;, &lt;code&gt;transient_errors=...&lt;/code&gt;, &lt;code&gt;autoscreen_on_fail=True&lt;/code&gt;, propagates &lt;code&gt;--only&lt;/code&gt;/&lt;code&gt;--exclude&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;lib/ext/ocarina/adapters/selenium/test_campaign.py&lt;/code&gt; → pins &lt;code&gt;max_workers=get_max_workers()&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;ocarina--ocarina-with-ai-example&#34;&gt;&lt;code&gt;ocarina&lt;/code&gt; ↔ &lt;code&gt;ocarina-with-ai-example&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#ocarina--ocarina-with-ai-example&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;pip install . ruff mypy mypy-extensions typing-extensions pre-commit&lt;/code&gt; — the AI example pins its dep in &lt;code&gt;pyproject.toml&lt;/code&gt;: &lt;code&gt;ocarina&amp;gt;=1.0.3&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;act&lt;/code&gt; adapter is &lt;strong&gt;minimal&lt;/strong&gt; here. No &lt;code&gt;on_failure&lt;/code&gt; (CURA doesn&amp;rsquo;t throw deliberately random HTTP error pages). See &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/08-ai-example/&#34;&gt;&lt;code&gt;../08-ai-example/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;create_drivers_pool&lt;/code&gt; adapter is &lt;strong&gt;overridden&lt;/strong&gt; to build a &lt;em&gt;clean&lt;/em&gt; Chrome (password manager off, leak detection off). See &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/08-ai-example/06-data-gaps/&#34;&gt;&lt;code&gt;../08-ai-example/06-data-gaps.md&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;ocarina-example--igoristan&#34;&gt;&lt;code&gt;ocarina-example&lt;/code&gt; ↔ &lt;code&gt;igoristan&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#ocarina-example--igoristan&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Direction&lt;/th&gt;&#xA;          &lt;th&gt;Contract&lt;/th&gt;&#xA;          &lt;th&gt;Detail&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;ocarina-example&lt;/code&gt; → &lt;code&gt;igoristan&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Public URLs&lt;/td&gt;&#xA;          &lt;td&gt;Everything goes through &lt;code&gt;https://mojo-molotov.github.io/igoristan/&amp;lt;route&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;igoristan&lt;/code&gt; → &lt;code&gt;ocarina-example&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;none (the SUT doesn&amp;rsquo;t know it&amp;rsquo;s being tested)&lt;/td&gt;&#xA;          &lt;td&gt; — &lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;&lt;code&gt;src/constants/pages/&lt;/code&gt;:&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
