<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Rop on Ocarina — manual</title>
    <link>https://mojo-molotov.github.io/from-ocarina-to-igor/tags/rop/</link>
    <description>Recent content in Rop 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/tags/rop/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>02.03.01 — The Result[T] type</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/01-result/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/01-result/</guid>
      <description>&lt;h1 id=&#34;020301the-resultt-type&#34;&gt;02.03.01 — The &lt;code&gt;Result[T]&lt;/code&gt; type&lt;a class=&#34;anchor&#34; href=&#34;#020301the-resultt-type&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Source file: &lt;a href=&#34;https://github.com/mojo-molotov/ocarina/blob/main/src/ocarina/railway/result.py&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;src/ocarina/railway/result.py&lt;/code&gt;&lt;/a&gt; — &lt;strong&gt;zero dependencies&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;code&#34;&gt;Code&lt;a class=&#34;anchor&#34; href=&#34;#code&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;from&lt;/span&gt; dataclasses &lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; dataclass, field&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;from&lt;/span&gt; typing &lt;span style=&#34;color:#ff79c6&#34;&gt;import&lt;/span&gt; TypeGuard, final&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;_BaseResult&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&amp;#34;&amp;#34;Base class ensuring both Ok and Fail have error attribute for type narrowing.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    error: Exception &lt;span style=&#34;color:#ff79c6&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@final&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@dataclass(frozen&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;True&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;Ok&lt;/span&gt;[T](_BaseResult):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    value: T&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    error: &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@final&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@dataclass(frozen&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;True&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;Fail&lt;/span&gt;(_BaseResult):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    error: Exception &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; field(default_factory&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;lambda&lt;/span&gt;: Exception(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Unknown error&amp;#34;&lt;/span&gt;))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; Result[T] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Ok[T] &lt;span style=&#34;color:#ff79c6&#34;&gt;|&lt;/span&gt; Fail&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;is_ok&lt;/span&gt;[T](result: Result[T]) &lt;span style=&#34;color:#ff79c6&#34;&gt;-&amp;gt;&lt;/span&gt; TypeGuard[Ok[T]]:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;isinstance&lt;/span&gt;(result, Ok)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;is_fail&lt;/span&gt;[T](result: Result[T]) &lt;span style=&#34;color:#ff79c6&#34;&gt;-&amp;gt;&lt;/span&gt; TypeGuard[Fail]:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;isinstance&lt;/span&gt;(result, Fail)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;six-design-decisions-dissected&#34;&gt;Six design decisions, dissected&lt;a class=&#34;anchor&#34; href=&#34;#six-design-decisions-dissected&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-_baseresult-as-a-common-parent&#34;&gt;1. &lt;code&gt;_BaseResult&lt;/code&gt; as a common parent&lt;a class=&#34;anchor&#34; href=&#34;#1-_baseresult-as-a-common-parent&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;_BaseResult&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    error: Exception &lt;span style=&#34;color:#ff79c6&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One job: let &lt;em&gt;mypy&lt;/em&gt; &lt;strong&gt;read &lt;code&gt;result.error&lt;/code&gt; without narrowing first&lt;/strong&gt;. Without the base, you&amp;rsquo;d have to write:&lt;/p&gt;</description>
    </item>
    <item>
      <title>03.01 — Effect, Thunk[T], Result[T]</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/03-functional/01-effect-thunk-result/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/03-functional/01-effect-thunk-result/</guid>
      <description>&lt;h1 id=&#34;0301effect-thunkt-resultt&#34;&gt;03.01 — &lt;code&gt;Effect&lt;/code&gt;, &lt;code&gt;Thunk[T]&lt;/code&gt;, &lt;code&gt;Result[T]&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#0301effect-thunkt-resultt&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Three lines in &lt;code&gt;custom_types/&lt;/code&gt; + one in &lt;code&gt;railway/&lt;/code&gt;. The whole DSL rides on them.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;triplet&#34;&gt;Triplet&lt;a class=&#34;anchor&#34; href=&#34;#triplet&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;# src/ocarina/custom_types/effect.py&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; Effect &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Callable[[], &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; Effects &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;tuple&lt;/span&gt;[Effect, &lt;span style=&#34;color:#ff79c6&#34;&gt;...&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;# src/ocarina/custom_types/thunk.py&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; Thunk[T] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Callable[[], T]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;# src/ocarina/railway/result.py&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; Result[T] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Ok[T] &lt;span style=&#34;color:#ff79c6&#34;&gt;|&lt;/span&gt; Fail&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Type&lt;/th&gt;&#xA;          &lt;th&gt;FP semantics&lt;/th&gt;&#xA;          &lt;th&gt;Definition&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;Effect&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Side effect (deferred)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;() -&amp;gt; None&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Thunk[T]&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Deferred &lt;em&gt;computation&lt;/em&gt; with value&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;() -&amp;gt; T&lt;/code&gt; (laziness + value)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Result[T]&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;em&gt;Computation&lt;/em&gt; that can fail&lt;/td&gt;&#xA;          &lt;td&gt;Discriminated union &lt;code&gt;Ok[T] | Fail&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;effect-vs-thunk-distinction&#34;&gt;Effect vs Thunk distinction&lt;a class=&#34;anchor&#34; href=&#34;#effect-vs-thunk-distinction&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;log_msg: Effect &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;lambda&lt;/span&gt;: &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;)        &lt;span style=&#34;color:#6272a4&#34;&gt;# () -&amp;gt; None&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get_42: Thunk[&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;int&lt;/span&gt;] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;lambda&lt;/span&gt;: &lt;span style=&#34;color:#bd93f9&#34;&gt;42&lt;/span&gt;                 &lt;span style=&#34;color:#6272a4&#34;&gt;# () -&amp;gt; int&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fetch:  Thunk[Result[&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;int&lt;/span&gt;]] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;lambda&lt;/span&gt;: Ok(&lt;span style=&#34;color:#bd93f9&#34;&gt;42&lt;/span&gt;)     &lt;span style=&#34;color:#6272a4&#34;&gt;# () -&amp;gt; Result[int]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Function &lt;em&gt;returns&lt;/em&gt; something consumed elsewhere → &lt;code&gt;Thunk[T]&lt;/code&gt;.&lt;br&gt;&#xA;Otherwise → &lt;code&gt;Effect&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>02.03.02 — The builder state machine</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/02-action-chain-states/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/02-action-chain-states/</guid>
      <description>&lt;h1 id=&#34;020302the-builder-state-machine&#34;&gt;02.03.02 — The builder state machine&lt;a class=&#34;anchor&#34; href=&#34;#020302the-builder-state-machine&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Source file: &lt;a href=&#34;https://github.com/mojo-molotov/ocarina/blob/main/src/ocarina/dsl/testing_with_railway/internals/action_chain.py&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;src/ocarina/dsl/testing_with_railway/internals/action_chain.py&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s where the &lt;em&gt;entire&lt;/em&gt; ROP mechanic lives: four successive typed states that literally (as in: the &lt;em&gt;type-checker&lt;/em&gt; literally) refuse any syntactic improvisation. The DSL doubles as its own immune system.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;a class=&#34;anchor&#34; href=&#34;#overview&#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;   start(action)  →   │  ActionStart[T] │     an Action[T] = Thunk[Result[T]]&#xA;                      └────────┬────────┘&#xA;                               │ .failure(failure_handler)&#xA;                               ▼&#xA;                      ┌─────────────────┐&#xA;                      │ ActionFailure[T]│&#xA;                      └────────┬────────┘&#xA;                               │ .success(success_handler)&#xA;                               ▼&#xA;                      ┌─────────────────┐&#xA;                      │ ActionSuccess[T]│&#xA;                      └────────┬────────┘&#xA;                               │ .execute()   ── runs action(), fires the handler&#xA;                               ▼&#xA;                      ┌─────────────────┐&#xA;                      │ ActionChain[T]  │     holds (has_failed, result)&#xA;                      └──────┬──────────┘&#xA;                             │ .then(next_action_or_start)&#xA;              ┌──────────────┴──────────────┐&#xA;              │                             │&#xA;   has_failed=True                   has_failed=False&#xA;              │                             │&#xA;              ▼                             ▼&#xA;   ┌──────────────────┐         ┌───────────────────┐&#xA;   │ NeutralAction-   │         │ ActionStart[T]    │  → cycle starts over&#xA;   │ Start[T]         │         │  (the next action │&#xA;   │ (failure rail:   │         │   will execute)   │&#xA;   │  the whole chain │         └───────────────────┘&#xA;   │  becomes no-op,  │&#xA;   │  while keeping   │&#xA;   │  the fluent API) │&#xA;   └──────────────────┘&#xA;              │&#xA;              ▼ (.failure → .success → .execute, all no-op)&#xA;   ┌──────────────────┐&#xA;   │  ActionChain[T]  │   has_failed=True, result=&amp;lt;accumulated Fail&amp;gt;&#xA;   └──────────────────┘&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;the-types-action-failurehandler-succhandler&#34;&gt;The types &lt;code&gt;Action&lt;/code&gt;, &lt;code&gt;FailureHandler&lt;/code&gt;, &lt;code&gt;SuccHandler&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#the-types-action-failurehandler-succhandler&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; Action[T]        &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Thunk[Result[T]]      &lt;span style=&#34;color:#6272a4&#34;&gt;# () -&amp;gt; Result[T]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; FailureHandler   &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Callable[[Exception], &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; SuccHandler      &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Effect                &lt;span style=&#34;color:#6272a4&#34;&gt;# () -&amp;gt; None&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;code&gt;Action[T]&lt;/code&gt; is a &lt;code&gt;Thunk&lt;/code&gt;.&lt;/strong&gt; Calling &lt;code&gt;ActionStart(action)&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; run anything. The action just gets captured.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;code&gt;FailureHandler&lt;/code&gt; gets the exception&lt;/strong&gt;, not the &lt;code&gt;Fail&lt;/code&gt; or the &lt;code&gt;Result&lt;/code&gt;. Deliberate: 99% of handlers want to log the exception, take a screenshot, and move on.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;code&gt;SuccHandler&lt;/code&gt; is an &lt;code&gt;Effect&lt;/code&gt;&lt;/strong&gt; (no argument). Same idea — a success handler logs a static message, snaps a screenshot, doesn&amp;rsquo;t need the result.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;typestate-pattern-why-you-cant-get-it-wrong&#34;&gt;Typestate Pattern: why you can&amp;rsquo;t get it wrong&lt;a class=&#34;anchor&#34; href=&#34;#typestate-pattern-why-you-cant-get-it-wrong&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;The chain is &lt;strong&gt;strictly linear&lt;/strong&gt;. Each method returns a different type that only exposes the &lt;em&gt;next legal step&lt;/em&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>01.03 — KISS and ostentatious complexity</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/01-philosophy/03-kiss-and-complexity/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/01-philosophy/03-kiss-and-complexity/</guid>
      <description>&lt;h1 id=&#34;0103kiss-and-ostentatious-complexity&#34;&gt;01.03 — KISS and ostentatious complexity&lt;a class=&#34;anchor&#34; href=&#34;#0103kiss-and-ostentatious-complexity&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;h2 id=&#34;the-criticism-that-landed&#34;&gt;The criticism that landed&lt;a class=&#34;anchor&#34; href=&#34;#the-criticism-that-landed&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;First public feedback Ocarina got, &lt;em&gt;systematic&lt;/em&gt; per the author:&lt;/p&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;The first &amp;ldquo;criticisms&amp;rdquo; were often the same: &lt;em&gt;&amp;ldquo;You&amp;rsquo;re bragging about something that&amp;rsquo;s very simple.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;The Holy Book takes its time answering. Three pillars: the &lt;strong&gt;operating&lt;/strong&gt; nature of simplicity, the &lt;strong&gt;simple ≠ unsophisticated&lt;/strong&gt; distinction, and the &lt;strong&gt;rejection of every &amp;ldquo;creative&amp;rdquo; counter-proposal&lt;/strong&gt; that came in.&lt;/p&gt;&#xA;&lt;h2 id=&#34;simple--unsophisticated&#34;&gt;Simple ≠ unsophisticated&lt;a class=&#34;anchor&#34; href=&#34;#simple--unsophisticated&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;This is also why &lt;strong&gt;KISS&lt;/strong&gt; (&lt;em&gt;Keep it simple, stupid&lt;/em&gt;) is so misunderstood in the industry. Many assume &amp;ldquo;simple&amp;rdquo; means &amp;ldquo;unsophisticated.&amp;rdquo; It would be hard to misread a principle more thoroughly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chapter 02 — Ocarina, the framework</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/</guid>
      <description>&lt;h1 id=&#34;chapter-02ocarina-the-framework&#34;&gt;Chapter 02 — Ocarina, the framework&lt;a class=&#34;anchor&#34; href=&#34;#chapter-02ocarina-the-framework&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Unpacks the whole &lt;code&gt;ocarina&lt;/code&gt; framework (Python 3.14+, v1.1.10) and Railway Oriented Programming straight through to the reporting plugins. Structured as a layered walk: &lt;strong&gt;deepest&lt;/strong&gt; (the &lt;code&gt;Result[T]&lt;/code&gt; type) to &lt;strong&gt;most visible&lt;/strong&gt; (the &lt;code&gt;bootstrap&lt;/code&gt; that boots everything).&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;chapter-plan&#34;&gt;Chapter plan&lt;a class=&#34;anchor&#34; href=&#34;#chapter-plan&#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 style=&#34;text-align: center&#34;&gt;#&lt;/th&gt;&#xA;          &lt;th&gt;Subject&lt;/th&gt;&#xA;          &lt;th&gt;File or folder&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;01&lt;/td&gt;&#xA;          &lt;td&gt;Technical identity, dependencies, toolchain&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/01-identity/&#34;&gt;&lt;code&gt;01-identity.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;02&lt;/td&gt;&#xA;          &lt;td&gt;Full module tree + layered diagram&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/02-module-tree/&#34;&gt;&lt;code&gt;02-module-tree.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;03&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Railway Oriented Programming&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/&#34;&gt;&lt;code&gt;03-railway/&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;04&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Invariants&lt;/strong&gt; (validate, assertions, chain_validations)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/&#34;&gt;&lt;code&gt;04-invariants/&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;05&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Orchestration&lt;/strong&gt; (Test → TestSuite → TestCampaign → TestCycle)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/05-orchestration/&#34;&gt;&lt;code&gt;05-orchestration/&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;06&lt;/td&gt;&#xA;          &lt;td&gt;Lifecycle of a &lt;code&gt;Scenario&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/06-scenario/&#34;&gt;&lt;code&gt;06-scenario.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;07&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Watcher&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/07-watcher/&#34;&gt;&lt;code&gt;07-watcher.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;08&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;POMBase&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/08-pom-base/&#34;&gt;&lt;code&gt;08-pom-base.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;09&lt;/td&gt;&#xA;          &lt;td&gt;Ports &amp;amp; adapters (&lt;code&gt;ILogger&lt;/code&gt;, &lt;code&gt;ITakeScreenshot&lt;/code&gt;)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/09-ports/&#34;&gt;&lt;code&gt;09-ports.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;10&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Infrastructure&lt;/strong&gt; (pool, builder, screenshotter, act counter, Selenium adapters)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/10-infra/&#34;&gt;&lt;code&gt;10-infra/&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;11&lt;/td&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Opinionated layer&lt;/strong&gt; (CLI, loggers, plugins, bootstrap)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/11-opinionated/&#34;&gt;&lt;code&gt;11-opinionated/&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;12&lt;/td&gt;&#xA;          &lt;td&gt;Custom types &amp;amp; custom errors&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/12-custom-types-errors/&#34;&gt;&lt;code&gt;12-custom-types-errors.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;related-reading&#34;&gt;Related reading&lt;a class=&#34;anchor&#34; href=&#34;#related-reading&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Functional programming: &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/03-functional/&#34;&gt;&lt;code&gt;../03-functional/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;How the framework tests itself: &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/04-internal-tests/&#34;&gt;&lt;code&gt;../04-internal-tests/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Usage examples with project adapters: &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/07-ocarina-example/&#34;&gt;&lt;code&gt;../07-ocarina-example/&lt;/code&gt;&lt;/a&gt;, &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;CI: &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;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Chapter 02.03 — Railway Oriented Programming</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/</guid>
      <description>&lt;h1 id=&#34;chapter-0203railway-oriented-programming&#34;&gt;Chapter 02.03 — Railway Oriented Programming&lt;a class=&#34;anchor&#34; href=&#34;#chapter-0203railway-oriented-programming&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Ocarina&amp;rsquo;s beating heart. The whole DSL rides on this mechanic: success and failure as two &lt;em&gt;parallel rails&lt;/em&gt;. A failure &lt;em&gt;switches&lt;/em&gt; the train onto the failure rail and locks it there (short-circuit), but composition stays linear so the scenario still reads top-to-bottom.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;plan&#34;&gt;Plan&lt;a class=&#34;anchor&#34; href=&#34;#plan&#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 style=&#34;text-align: center&#34;&gt;#&lt;/th&gt;&#xA;          &lt;th&gt;File&lt;/th&gt;&#xA;          &lt;th&gt;Subject&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;01&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/01-result/&#34;&gt;&lt;code&gt;01-result.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;Result[T] = Ok[T] | Fail&lt;/code&gt;, &lt;code&gt;is_ok&lt;/code&gt;/&lt;code&gt;is_fail&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;02&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/02-action-chain-states/&#34;&gt;&lt;code&gt;02-action-chain-states.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;State machine &lt;code&gt;ActionStart → ActionFailure → ActionSuccess → ActionChain&lt;/code&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;03&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/03-neutral-rail/&#34;&gt;&lt;code&gt;03-neutral-rail.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Failure rail: &lt;code&gt;NeutralActionStart&lt;/code&gt; / &lt;code&gt;NeutralActionFailure&lt;/code&gt; / &lt;code&gt;NeutralActionSuccess&lt;/code&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;04&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/04-chain-actions-fold/&#34;&gt;&lt;code&gt;04-chain-actions-fold.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;ChainRunner[T]&lt;/code&gt; (thunk) + &lt;code&gt;chain_actions&lt;/code&gt; (fold).&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;05&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/05-create-act-hooks/&#34;&gt;&lt;code&gt;05-create-act-hooks.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;create_act&lt;/code&gt; and its hooks (&lt;code&gt;on_failure&lt;/code&gt;, &lt;code&gt;on_run_effect&lt;/code&gt;, &lt;code&gt;act_counter_effect&lt;/code&gt;).&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;06&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/06-drive-page/&#34;&gt;&lt;code&gt;06-drive-page.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;drive_page&lt;/code&gt;, a semantic alias.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;07&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/07-match-page-when/&#34;&gt;&lt;code&gt;07-match-page-when.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;match_page&lt;/code&gt; / &lt;code&gt;when&lt;/code&gt; + exception policy.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;lineage&#34;&gt;Lineage&lt;a class=&#34;anchor&#34; href=&#34;#lineage&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Direct inspiration: &lt;strong&gt;Railway Oriented Programming&lt;/strong&gt;, popularized by Scott Wlaschin (F#).&lt;/p&gt;</description>
    </item>
    <item>
      <title>01.04 — Citations and claimed influences</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/01-philosophy/04-citations-and-influences/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/01-philosophy/04-citations-and-influences/</guid>
      <description>&lt;h1 id=&#34;0104citations-and-claimed-influences&#34;&gt;01.04 — Citations and claimed influences&lt;a class=&#34;anchor&#34; href=&#34;#0104citations-and-claimed-influences&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;The references cited in the Holy Book aren&amp;rsquo;t neutral — they set Ocarina&amp;rsquo;s &lt;strong&gt;theoretical frame&lt;/strong&gt;. We cut them by axis here, then offer the overall reading.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;technical-axisfunctional-programming-types-languages&#34;&gt;Technical axis — Functional programming, types, languages&lt;a class=&#34;anchor&#34; href=&#34;#technical-axisfunctional-programming-types-languages&#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;Influence&lt;/th&gt;&#xA;          &lt;th&gt;Origin&lt;/th&gt;&#xA;          &lt;th&gt;Relation to 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;Railway Oriented Programming (ROP)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Scott Wlaschin (F#), a well-known pattern in functional programming&lt;/td&gt;&#xA;          &lt;td&gt;The heart of the framework. &lt;code&gt;Result[T] = Ok[T] | Fail&lt;/code&gt;, &lt;em&gt;short-circuit&lt;/em&gt;, fluent builder. See &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/&#34;&gt;&lt;code&gt;../02-ocarina/03-railway/&lt;/code&gt;&lt;/a&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;λ-calculus (1930)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Alonzo Church&lt;/td&gt;&#xA;          &lt;td&gt;Cited as the invention that makes possible the “clean formalization” Ocarina pursues: “&lt;em&gt;What has been on our minds since the 1930s, &lt;strong&gt;since the invention of λ-calculus&lt;/strong&gt;, is finally scalable to the degree we always wanted it to be.&lt;/em&gt;”&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;McCulloch &amp;amp; Pitts (1943)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;First formalization of the artificial neuron&lt;/td&gt;&#xA;          &lt;td&gt;Cited as a reminder that the &lt;em&gt;real&lt;/em&gt; progress in AI is old and continuous, against the recent hype.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Python type system (PEP 695)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;PEP 695 (Python 3.12+)&lt;/td&gt;&#xA;          &lt;td&gt;Prerequisite for the generic parametric typing that structures Ocarina (&lt;code&gt;TestSuite[Driver]&lt;/code&gt;, &lt;code&gt;Result[T]&lt;/code&gt;, etc.). See &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/03-functional/06-pep-695-generics/&#34;&gt;&lt;code&gt;../03-functional/06-pep-695-generics.md&lt;/code&gt;&lt;/a&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;cultural-axisanti-narcissism-simplicity-kiss-done-right&#34;&gt;Cultural axis — Anti-narcissism, simplicity, KISS done right&lt;a class=&#34;anchor&#34; href=&#34;#cultural-axisanti-narcissism-simplicity-kiss-done-right&#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;Influence&lt;/th&gt;&#xA;          &lt;th&gt;Citation&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;Terry Davis&lt;/strong&gt; (“the smartest programmer that&amp;rsquo;s ever lived”)&lt;/td&gt;&#xA;          &lt;td&gt;&lt;em&gt;“An idiot admires complexity, a genius admires simplicity, a physicist tries to make it simple…”&lt;/em&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Anti–ostentatious complexity argument; cornerstone of the “First feedbacks” chapter.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Lao-Tzu&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;em&gt;“To attain knowledge, add things every day. To attain wisdom, remove things every day.”&lt;/em&gt;&lt;/td&gt;&#xA;          &lt;td&gt;A subtractive method: what remains after elimination.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Antoine de Saint-Exupéry&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;em&gt;“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.”&lt;/em&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Western restatement of the previous one. Closes the “First scenarios” chapter.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Alan Watts&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;em&gt;“Muddy water is best cleared by leaving it alone.”&lt;/em&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Cited at the end of the “First jutsus” chapter: legitimizes a design that &lt;em&gt;refuses&lt;/em&gt; certain features (reactivity, async). Legitimizes stepping out of the “geek tricks” ecosystem.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Rainer Maria Rilke&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;em&gt;“Live the questions now. Perhaps then, someday far in the future, you will gradually, without even noticing it, live your way into the answer.”&lt;/em&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Closes the “First steps” chapter. Stance toward practice: mastery comes from use.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Marcel Proust&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;em&gt;“For the writer as well as for the painter, style is not a question of technique, but of vision.”&lt;/em&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Closes the “Extensibility” chapter. Justifies the refusal to impose a DSL: vision (POMs + actions) trumps technique (a format).&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;political-axiscode-sovereignty-antistartup-nation&#34;&gt;Political axis — Code, sovereignty, anti–startup nation&lt;a class=&#34;anchor&#34; href=&#34;#political-axiscode-sovereignty-antistartup-nation&#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;Influence&lt;/th&gt;&#xA;          &lt;th&gt;Origin&lt;/th&gt;&#xA;          &lt;th&gt;Relation to 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;&lt;em&gt;Code is Law&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Lawrence Lessig (1999), reclaimed by Ethereum (2015) as a positive ideal&lt;/td&gt;&#xA;          &lt;td&gt;Cited as the stance against “democratic governance of code”. The project claims it: “&lt;em&gt;Once again, with AI, that sorely missing digital body, let us scream it, as loud as we screamed&lt;/em&gt; &lt;strong&gt;‘HACK THE PLANET’&lt;/strong&gt; &lt;em&gt;back in &amp;lsquo;99:&lt;/em&gt; &lt;strong&gt;CODE IS LAW.&lt;/strong&gt;”&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;DHH — &lt;em&gt;I won&amp;rsquo;t let you pay me for my open source&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;David Heinemeier Hansson, personal blog&lt;/td&gt;&#xA;          &lt;td&gt;Cited to legitimize refusing unaligned contributions (“&lt;em&gt;Fuck You&lt;/em&gt;” references DHH&amp;rsquo;s famous slide).&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Paul Graham — &lt;em&gt;Haters&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;PG essay (&lt;code&gt;paulgraham.com/fh.html&lt;/code&gt;)&lt;/td&gt;&#xA;          &lt;td&gt;Grounds the decision to “never waste time arguing when it isn&amp;rsquo;t worth it”.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Yegor Bugayenko — &lt;em&gt;Prompt&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;The quote “&lt;em&gt;Retry flaky blocks.&lt;/em&gt;”&lt;/td&gt;&#xA;          &lt;td&gt;Grounds the &lt;code&gt;transient_errors&lt;/code&gt; + linear retry policy (&lt;code&gt;TestFlow&lt;/code&gt;). Read also: &lt;em&gt;Angry Tests&lt;/em&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;The DAO hack (2016)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Hack of The DAO on Ethereum&lt;/td&gt;&#xA;          &lt;td&gt;Cited to point out that it was &lt;em&gt;bugs&lt;/em&gt; (“damned bugs, because of damned devs”) that set &lt;em&gt;Code is Law&lt;/em&gt; back, hence the importance of typing and rigor.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Lee Robinson (ex-Vercel)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;December 2025: Cursor replacing Sanity with Markdown files + AI&lt;/td&gt;&#xA;          &lt;td&gt;Backs the “return to raw data”.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Cluely (Roy Lee)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Cited as an illustration of entrepreneurial bullshit to avoid&lt;/td&gt;&#xA;          &lt;td&gt;Explicit contrast with the Ocarina philosophy.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;identity--underground-axis&#34;&gt;Identity / underground axis&lt;a class=&#34;anchor&#34; href=&#34;#identity--underground-axis&#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;Influence&lt;/th&gt;&#xA;          &lt;th&gt;Origin&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;LulzSec&lt;/strong&gt; — &lt;em&gt;“In the Lulzboat, salute, bitch, and show some respect.”&lt;/em&gt;&lt;/td&gt;&#xA;          &lt;td&gt;AntiSec (YTCracker, 2011)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;em&gt;“We Can Do All What You Can&amp;rsquo;t Do”&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;YogyaCarderLink&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;YTCracker — &lt;em&gt;Robots Will Definitely Take Your Job&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;SoundCloud link, background music of the “First feedbacks” chapter&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;&lt;em&gt;“HACK THE PLANET”&lt;/em&gt; (1999)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Emblematic slogan of the 1990s hacker scene + AntiSec (YTCracker, 2011)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Zone-H&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Historic web defacement archive&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;r/unixporn&lt;/strong&gt;, &lt;strong&gt;r/AntiTaff&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Subreddits&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;ai--modern-tooling-axis&#34;&gt;AI / modern tooling axis&lt;a class=&#34;anchor&#34; href=&#34;#ai--modern-tooling-axis&#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;Influence&lt;/th&gt;&#xA;          &lt;th&gt;Origin&lt;/th&gt;&#xA;          &lt;th&gt;Relation to 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;Claude Code&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Anthropic&lt;/td&gt;&#xA;          &lt;td&gt;Reference tooling for the AI project (&lt;code&gt;ocarina-with-ai-example&lt;/code&gt;). Cited several times as the “bridge” replacing DSLs.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;IntelliCode (2018)&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Microsoft&lt;/td&gt;&#xA;          &lt;td&gt;Cited as a temporal landmark (“we had already tasted it, well before IntelliCode”).&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;R., the silo&amp;rsquo;s mad scientist&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Personal anecdote (a 2013 colleague, a private Emacs AI plugin)&lt;/td&gt;&#xA;          &lt;td&gt;Reminder that generative AI (“15,000 lines to delete to avoid writing 1,000”) existed before the public hype.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Prisma, Vercel, Cursor&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;SaaS ecosystem&lt;/td&gt;&#xA;          &lt;td&gt;Cited as practical cases of an AI-assisted &lt;em&gt;return to raw data&lt;/em&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;overall-coherence&#34;&gt;Overall coherence&lt;a class=&#34;anchor&#34; href=&#34;#overall-coherence&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;All these influences converge on &lt;strong&gt;three axes&lt;/strong&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>02.03.04 — chain_actions and ChainRunner</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/04-chain-actions-fold/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/04-chain-actions-fold/</guid>
      <description>&lt;h1 id=&#34;020304chain_actions-and-chainrunner&#34;&gt;02.03.04 — &lt;code&gt;chain_actions&lt;/code&gt; and &lt;code&gt;ChainRunner&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#020304chain_actions-and-chainrunner&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Source file: &lt;a href=&#34;https://github.com/mojo-molotov/ocarina/blob/main/src/ocarina/dsl/testing_with_railway/chain_actions.py&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;src/ocarina/dsl/testing_with_railway/chain_actions.py&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;The primitive that makes the DSL &amp;ldquo;flat.&amp;rdquo; Without it, an N-step scenario is a staircase of &lt;code&gt;.then(...).failure(...).success(...).execute()&lt;/code&gt;. With it, it&amp;rsquo;s a list.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;parenthesis-hell&#34;&gt;“Parenthesis hell”&lt;a class=&#34;anchor&#34; href=&#34;#parenthesis-hell&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Solution:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#6272a4&#34;&gt;# Flat, readable syntax&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;runner &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; chain_actions(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    action1&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;failure(h1)&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;success(h2),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    action2&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;failure(h3)&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;success(h4),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    action3&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;failure(h5)&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;success(h6)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chain &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; runner&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;run()  &lt;span style=&#34;color:#6272a4&#34;&gt;# Execute when ready&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Benefits:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Lazy evaluation&lt;/strong&gt;: Build chain without executing&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Flat syntax&lt;/strong&gt;: No deep nesting&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Automatic short-circuiting&lt;/strong&gt;: Stops on first failure&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Composability&lt;/strong&gt;: ChainRunner is a value&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;&lt;em&gt;(Excerpt from the docstring.)&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Chapter 02.04 — Invariants</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/</guid>
      <description>&lt;h1 id=&#34;chapter-0204invariants&#34;&gt;Chapter 02.04 — Invariants&lt;a class=&#34;anchor&#34; href=&#34;#chapter-0204invariants&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Ocarina&amp;rsquo;s sub-DSL for typed, composable invariants. Used everywhere: CLI, POMs, the &lt;code&gt;custom_invariants/testing/&lt;/code&gt; that check suite consistency before any test runs.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;plan&#34;&gt;Plan&lt;a class=&#34;anchor&#34; href=&#34;#plan&#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 style=&#34;text-align: center&#34;&gt;#&lt;/th&gt;&#xA;          &lt;th&gt;File&lt;/th&gt;&#xA;          &lt;th&gt;Subject&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;01&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/01-validate-flow/&#34;&gt;&lt;code&gt;01-validate-flow.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;The full flow &lt;code&gt;validate(value) → assert_that → execute → raise_if_invalid&lt;/code&gt; + the &lt;code&gt;_ValidationChain&lt;/code&gt; class.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;02&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/02-assertions/&#34;&gt;&lt;code&gt;02-assertions.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Catalog of builtin assertions (&lt;code&gt;is_str&lt;/code&gt;, &lt;code&gt;is_email&lt;/code&gt;, &lt;code&gt;is_positive&lt;/code&gt;, &lt;code&gt;is_in&lt;/code&gt;, &lt;code&gt;has_unique_elements&lt;/code&gt;, &lt;code&gt;each&lt;/code&gt;, &lt;code&gt;is_valid_filename&lt;/code&gt;, …).&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;03&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/03-otherwise-any-of/&#34;&gt;&lt;code&gt;03-otherwise-any-of.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;.otherwise(...)&lt;/code&gt; and the OR combination via &lt;code&gt;_any_of&lt;/code&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;04&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/04-then-chain-of-validations/&#34;&gt;&lt;code&gt;04-then-chain-of-validations.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;.then(new_value)&lt;/code&gt; and &lt;code&gt;chain_validations(...)&lt;/code&gt; for composition.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;05&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/05-business-vs-framework-validator/&#34;&gt;&lt;code&gt;05-business-vs-framework-validator.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;BusinessInvariantValidator&lt;/code&gt; vs &lt;code&gt;FrameworkInvariantValidator&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;06&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/04-invariants/06-invariant-errors/&#34;&gt;&lt;code&gt;06-invariant-errors.md&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;InvariantViolationError&lt;/code&gt;, &lt;code&gt;DuplicatesError&lt;/code&gt;, &lt;code&gt;AggregateInvariantViolationError&lt;/code&gt;.&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;why-the-invariants-dsl&#34;&gt;Why the invariants DSL&lt;a class=&#34;anchor&#34; href=&#34;#why-the-invariants-dsl&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;Pre-execution guard.&lt;/strong&gt; &lt;code&gt;TestSuite.__init__&lt;/code&gt; checks — &lt;em&gt;before&lt;/em&gt; launching anything — that test names / IDs are unique, &lt;code&gt;max_workers &amp;gt;= 1&lt;/code&gt;, etc.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;CLI validation.&lt;/strong&gt; Every flag carries its &lt;code&gt;validate=lambda chain: chain.assert_that(...)&lt;/code&gt; inside the &lt;code&gt;CliStore&lt;/code&gt;. Errors aggregate into one message.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;POM-side validation.&lt;/strong&gt; POM actions validate their parameters (&amp;quot;&lt;code&gt;retries&lt;/code&gt; must be positive&amp;quot;) via &lt;code&gt;validate(retries, name=&amp;quot;retries&amp;quot;).assert_that(is_positive).execute().raise_if_invalid()&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The Holy Book sums it up:&lt;/p&gt;</description>
    </item>
    <item>
      <title>02.03.06 — drive_page</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/06-drive-page/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/06-drive-page/</guid>
      <description>&lt;h1 id=&#34;020306drive_page&#34;&gt;02.03.06 — &lt;code&gt;drive_page&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#020306drive_page&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Source file: &lt;a href=&#34;https://github.com/mojo-molotov/ocarina/blob/main/src/ocarina/opinionated/dsl/drive_page.py&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;src/ocarina/opinionated/dsl/drive_page.py&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;code&#34;&gt;Code&lt;a class=&#34;anchor&#34; href=&#34;#code&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;drive_page&lt;/span&gt;(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    first: ActionSuccess[TPOM], &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt;rest: ActionSuccess[TPOM]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) &lt;span style=&#34;color:#ff79c6&#34;&gt;-&amp;gt;&lt;/span&gt; ChainRunner[TPOM]:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; chain_actions(first, &lt;span style=&#34;color:#ff79c6&#34;&gt;*&lt;/span&gt;rest)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Literally&lt;/strong&gt; &lt;code&gt;chain_actions&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-this-alias&#34;&gt;Why this alias?&lt;a class=&#34;anchor&#34; href=&#34;#why-this-alias&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-semantics-im-taking-control-of-a-page&#34;&gt;1. Semantics: &amp;ldquo;I&amp;rsquo;m taking control of a page&amp;rdquo;&lt;a class=&#34;anchor&#34; href=&#34;#1-semantics-im-taking-control-of-a-page&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;p&gt;Holy Book quote (&amp;ldquo;First scenarios&amp;rdquo;):&lt;/p&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;&lt;code&gt;drive_page&lt;/code&gt; expresses the fact that you are taking control of &lt;em&gt;one&lt;/em&gt; page.&#xA;Any &lt;em&gt;transition&lt;/em&gt; becomes explicit through the opening of a new &lt;code&gt;drive_page&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; [&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    drive_page(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        act(on_homepage, open_homepage)&lt;span style=&#34;color:#ff79c6&#34;&gt;...&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        act(on_homepage, verify_homepage)&lt;span style=&#34;color:#ff79c6&#34;&gt;...&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        act(on_homepage, click_cta)&lt;span style=&#34;color:#ff79c6&#34;&gt;...&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ),                                          &lt;span style=&#34;color:#6272a4&#34;&gt;# ⬅ closing control of the homepage&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    drive_page(                                 &lt;span style=&#34;color:#6272a4&#34;&gt;# ⬅ opening control of the next page&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        act(on_target_page, verify_target_page)&lt;span style=&#34;color:#ff79c6&#34;&gt;...&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ),&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2-discipline&#34;&gt;2. Discipline&lt;a class=&#34;anchor&#34; href=&#34;#2-discipline&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;p&gt;Mixing acts from two different POMs inside one &lt;code&gt;drive_page&lt;/code&gt; is a &lt;em&gt;mypy&lt;/em&gt; error (see &lt;a href=&#34;https://mojo-molotov.github.io/from-ocarina-to-igor/02-ocarina/03-railway/02-action-chain-states/&#34;&gt;&lt;code&gt;02-action-chain-states.md&lt;/code&gt;&lt;/a&gt;, &amp;ldquo;narrowing via &lt;code&gt;act()&lt;/code&gt;&amp;rdquo; section). The semantics get enforced concretely.&lt;/p&gt;</description>
    </item>
    <item>
      <title>03.07 — Discriminated unions &#43; TypeGuard &#43; @final = sealed unions</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/03-functional/07-discriminated-unions-typeguards/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/03-functional/07-discriminated-unions-typeguards/</guid>
      <description>&lt;h1 id=&#34;0307discriminated-unions--typeguard--final--sealed-unions&#34;&gt;03.07 — Discriminated unions + TypeGuard + @final = &amp;ldquo;&lt;em&gt;sealed&lt;/em&gt;&amp;rdquo; unions&lt;a class=&#34;anchor&#34; href=&#34;#0307discriminated-unions--typeguard--final--sealed-unions&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;The combo that makes &lt;code&gt;Result[T]&lt;/code&gt; and &lt;code&gt;TestResult&lt;/code&gt; both &lt;strong&gt;typed&lt;/strong&gt; and &lt;strong&gt;usable without casts&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;discriminated-union&#34;&gt;Discriminated union&lt;a class=&#34;anchor&#34; href=&#34;#discriminated-union&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@final&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@dataclass(frozen&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;True&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;Ok&lt;/span&gt;[T](_BaseResult):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    value: T&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    error: &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@final&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@dataclass(frozen&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;True&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;Fail&lt;/span&gt;(_BaseResult):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    error: Exception &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; field(default_factory&lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;lambda&lt;/span&gt;: Exception(&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Unknown error&amp;#34;&lt;/span&gt;))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;type&lt;/span&gt; Result[T] &lt;span style=&#34;color:#ff79c6&#34;&gt;=&lt;/span&gt; Ok[T] &lt;span style=&#34;color:#ff79c6&#34;&gt;|&lt;/span&gt; Fail&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#xA;&lt;li&gt;Two constructors: &lt;code&gt;Ok[T]&lt;/code&gt; and &lt;code&gt;Fail&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Discriminant&lt;/em&gt; is the &lt;em&gt;isinstance check&lt;/em&gt; (not a field like &lt;code&gt;tag: Literal[&amp;quot;ok&amp;quot;, &amp;quot;fail&amp;quot;]&lt;/code&gt;).&lt;/li&gt;&#xA;&lt;li&gt;Both are &lt;code&gt;@final&lt;/code&gt; — &lt;em&gt;no&lt;/em&gt; possible subtype. The union is &lt;strong&gt;exhaustive&lt;/strong&gt;, i.e. &amp;ldquo;&lt;em&gt;sealed&lt;/em&gt;&amp;rdquo;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;narrowing-typeguard&#34;&gt;Narrowing, &lt;code&gt;TypeGuard&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#narrowing-typeguard&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;is_ok&lt;/span&gt;[T](result: Result[T]) &lt;span style=&#34;color:#ff79c6&#34;&gt;-&amp;gt;&lt;/span&gt; TypeGuard[Ok[T]]:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;isinstance&lt;/span&gt;(result, Ok)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;is_fail&lt;/span&gt;[T](result: Result[T]) &lt;span style=&#34;color:#ff79c6&#34;&gt;-&amp;gt;&lt;/span&gt; TypeGuard[Fail]:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;isinstance&lt;/span&gt;(result, Fail)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;handle_result&lt;/span&gt;(result: Result[&lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;int&lt;/span&gt;]) &lt;span style=&#34;color:#ff79c6&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;str&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; is_ok(result):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Got: &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;{&lt;/span&gt;result&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;value&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&lt;/span&gt;          &lt;span style=&#34;color:#6272a4&#34;&gt;# mypy: result is Ok[int], so .value exists&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; is_fail(result):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ff79c6&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;Error: &lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;{&lt;/span&gt;result&lt;span style=&#34;color:#ff79c6&#34;&gt;.&lt;/span&gt;error&lt;span style=&#34;color:#f1fa8c&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;&lt;/span&gt;        &lt;span style=&#34;color:#6272a4&#34;&gt;# mypy: result is Fail, so .error exists&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#6272a4&#34;&gt;# mypy can detect this branch is unreachable (exhaustiveness)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;_baseresult&#34;&gt;&lt;code&gt;_BaseResult&lt;/code&gt;&lt;a class=&#34;anchor&#34; href=&#34;#_baseresult&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#50fa7b&#34;&gt;_BaseResult&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    error: Exception &lt;span style=&#34;color:#ff79c6&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ff79c6&#34;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This base lets you access &lt;code&gt;result.error&lt;/code&gt; &lt;strong&gt;without narrowing&lt;/strong&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>12.13 — Lambda calculus, ROP, Haskell / F# / OCaml, monads</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/12-manifesto-deciphered/13-lambda-calculus-rop-origins/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/12-manifesto-deciphered/13-lambda-calculus-rop-origins/</guid>
      <description>&lt;h1 id=&#34;1213lambda-calculus-rop-haskell--f--ocaml-monads&#34;&gt;12.13 — Lambda calculus, ROP, Haskell / F# / OCaml, monads&lt;a class=&#34;anchor&#34; href=&#34;#1213lambda-calculus-rop-haskell--f--ocaml-monads&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Ocarina invents nothing on the theoretical front. It &lt;strong&gt;applies&lt;/strong&gt;: from Alonzo Church&amp;rsquo;s &lt;strong&gt;lambda calculus&lt;/strong&gt; (1936) to Eugenio Moggi&amp;rsquo;s (1989) and Philip Wadler&amp;rsquo;s (1992-95) &lt;strong&gt;monads&lt;/strong&gt;, formalized as &lt;strong&gt;Railway Oriented Programming&lt;/strong&gt; by Scott Wlaschin (2014).&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;1-lambda-calculus-church-1936&#34;&gt;1. Lambda calculus (Church, 1936)&lt;a class=&#34;anchor&#34; href=&#34;#1-lambda-calculus-church-1936&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;definition&#34;&gt;Definition&lt;a class=&#34;anchor&#34; href=&#34;#definition&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;p&gt;&lt;strong&gt;Lambda calculus&lt;/strong&gt; (λ-calculus) is a formal system invented by &lt;strong&gt;Alonzo Church&lt;/strong&gt; (1903-1995) to study &lt;strong&gt;computability&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Primitive&lt;/th&gt;&#xA;          &lt;th&gt;Notation&lt;/th&gt;&#xA;          &lt;th&gt;Semantics&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;Variable&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, &lt;code&gt;z&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;A name&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Abstraction&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;λx.M&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Definition of a function with parameter &lt;code&gt;x&lt;/code&gt;, body &lt;code&gt;M&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;Application&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;M N&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Call of the function &lt;code&gt;M&lt;/code&gt; on the argument &lt;code&gt;N&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Rule&lt;/th&gt;&#xA;          &lt;th&gt;Effect&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;α-conversion&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Renaming a bound variable (&lt;code&gt;λx.x&lt;/code&gt; ≡ &lt;code&gt;λy.y&lt;/code&gt;)&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;β-reduction&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;Applying a function: &lt;code&gt;(λx.M) N → M[x := N]&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;η-conversion&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;λx.(f x) ≡ f&lt;/code&gt; if &lt;code&gt;x&lt;/code&gt; not free in &lt;code&gt;f&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;why-its-foundational&#34;&gt;Why it&amp;rsquo;s foundational&lt;a class=&#34;anchor&#34; href=&#34;#why-its-foundational&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;1936&lt;/strong&gt;: Church proves λ-calculus is &lt;strong&gt;Turing-complete&lt;/strong&gt; (Turing publishes his machine in 1937). &lt;em&gt;Church-Turing thesis&lt;/em&gt;: anything &lt;em&gt;mechanically computable&lt;/em&gt; can be expressed in λ-calculus.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Alan Turing&lt;/strong&gt; was Church&amp;rsquo;s doctoral student at Princeton (PhD, 1938).&lt;/li&gt;&#xA;&lt;li&gt;λ-calculus is &lt;strong&gt;simpler&lt;/strong&gt; than the Turing machine: only 3 constructions. Everything else — integers, booleans, data structures — is &lt;em&gt;encoded&lt;/em&gt; with those 3 bricks (Church encoding).&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;typed-lambda-calculus-church-1940&#34;&gt;Typed lambda calculus (Church, 1940)&lt;a class=&#34;anchor&#34; href=&#34;#typed-lambda-calculus-church-1940&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;p&gt;Church added &lt;strong&gt;types&lt;/strong&gt; in 1940 (&lt;em&gt;simply typed lambda calculus&lt;/em&gt;, STLC) to forbid self-application paradoxes (&lt;code&gt;λx.x x&lt;/code&gt;). Each variable has a type, and function application is only allowed if types match.&lt;/p&gt;</description>
    </item>
    <item>
      <title>12.15 — Typing, ISTQB, Reinforcement Learning, probes: why AI works in Ocarina</title>
      <link>https://mojo-molotov.github.io/from-ocarina-to-igor/12-manifesto-deciphered/15-typing-ai-rl-probes/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://mojo-molotov.github.io/from-ocarina-to-igor/12-manifesto-deciphered/15-typing-ai-rl-probes/</guid>
      <description>&lt;h1 id=&#34;1215typing-istqb-reinforcement-learning-probes-why-ai-works-in-ocarina&#34;&gt;12.15 — Typing, ISTQB, Reinforcement Learning, &lt;em&gt;probes&lt;/em&gt;: why AI works in Ocarina&lt;a class=&#34;anchor&#34; href=&#34;#1215typing-istqb-reinforcement-learning-probes-why-ai-works-in-ocarina&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;Why so much &lt;strong&gt;obsession&lt;/strong&gt; over strict typing, formalizing every interface, alignment on &lt;strong&gt;ISTQB&lt;/strong&gt;, refusing to execute an assertion without having &lt;em&gt;observed&lt;/em&gt;? The mechanism is borrowed from &lt;strong&gt;Reinforcement Learning&lt;/strong&gt;: an agent only progresses under &lt;strong&gt;constraint&lt;/strong&gt; + &lt;strong&gt;reward signal&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;h2 id=&#34;1-a-naked-llm-is-just-a-bad-collaborator&#34;&gt;1. A naked LLM is just a bad collaborator&lt;a class=&#34;anchor&#34; href=&#34;#1-a-naked-llm-is-just-a-bad-collaborator&#34; data-pagefind-ignore=&#34;all&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;An LLM without a structured environment is:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;Optimistic&lt;/em&gt; — it assumes its code works.&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Persuasive&lt;/em&gt; — its &lt;em&gt;output&lt;/em&gt; is convincing even when wrong.&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Memoryless&lt;/em&gt; — it forgets conventions between sessions.&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Feedbackless&lt;/em&gt; — it has no way to know it was wrong.&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Loves what it deems &amp;ldquo;most likely&amp;rdquo;&lt;/em&gt; — it drifts toward &lt;em&gt;popular&lt;/em&gt; patterns, not &lt;em&gt;correct&lt;/em&gt; ones.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;Without an environment, an LLM is an over-confident junior dev&lt;/strong&gt; producing code that &lt;em&gt;looks&lt;/em&gt; right, breaks in prod, and learns nothing from the failure.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
