00.01 — Ecosystem cartography

00.01 — Ecosystem cartography#

The Ocarina ecosystem is six public repos under the mojo-molotov GitHub account. They cover five distinct roles:

RoleRepoForm
FrameworkocarinaPython library on PyPI
Public System Under Test (SUT)igoristanReact + Vike SPA, GitHub Pages
Coordination backendtests-workersVercel Edge API + Upstash Redis
Example suitesocarina-example (canonical), ocarina-with-ai-example (AI)Python e2e suites driving Igoristan / CURA
Public documentationocarina-holy-bookVitePress site (EN + FR + RU), PDFs, AI skills

The big picture#

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              OCARINA (BIG PICTURE)                              │
└─────────────────────────────────────────────────────────────────────────────────┘

   ┌──────────────────────────────┐         ┌──────────────────────────────────┐
   │  [PACKAGE]  ocarina          │ ──────► │  [PACKAGE]  ocarina-example      │
   │  Python framework 3.14+      │   pip   │  e2e suite against the Igoristan │
   │  ROP / DSL / orchestration   │ install │  (Selenium + Firefox + Redis)    │
   └──────────────────────────────┘         └──────────────────────────────────┘
            │  │                                       │  ▲   │
            │  │                                       │  │  uses
            │  │ pip install ocarina                   │  │  IGOR_API_KEY
            │  ▼                                       ▼  │   │
            │  ┌────────────────────────────────────┐  drives │
            │  │ [PACKAGE]  ocarina-with-ai-example │  ┌──────┴──────────────────┐
            │  │ e2e suite against CURA Healthcare  │  │ [WEBSITE]  igoristan    │
            │  │ Claude Code, 99% machine-written   │  │ React 19 + Vike         │
            │  └────────────────────────────────────┘  │ GitHub Pages            │
            │              │                           └──────┬──────────────────┘
            │              │ drives                           │ fetches OTP
            │              ▼                                  ▼
            │   ┌──────────────────────────────┐    ┌──────────────────────────────┐
            │   │ [WEBSITE]  CURA Healthcare   │    │ [BACKEND]  tests-workers     │
            │   │ Heroku, open-source PHP      │    │ Vercel Edge Functions        │
            │   └──────────────────────────────┘    │ + Upstash Redis              │
            │                                       │ /api/otp, /otp-history,      │
            │                                       │ /api/corsicadex              │
            │                                       └──────────────────────────────┘
            │                                                 ▲
            │                                                 │ x-api-key
            │                                                 │ (IGOR_API_KEY ≡ API_SECRET)
            │                                                 │
            ▼
   ┌──────────────────────────────┐
   │  [DOCS]  ocarina-holy-book   │
   │  VitePress EN + FR + RU      │
   │  AI skills, PDFs, llms.txt   │
   │  GitHub Pages                │
   └──────────────────────────────┘
  1. ocarina → example suites: plain pip dependency (pip install ocarina).
  2. Example suites → SUT (Igoristan / CURA): browser automation through Selenium.
  3. Igoristan suite ↔ tests-workers: HTTP calls (OTP, Corsicadex). Shared secret: IGOR_API_KEY client-side ≡ API_SECRET server-side.

Responsibilities#

RoleContractConstraint
FrameworkShips the DSL, the orchestration, the driver pool, the reportersStays small, auditable, no hidden deps
Public SUTA deliberately chaotic playground (random errors, OTP, finicky forms)Lives on GitHub Pages forever, no heavy backend
Coordination backendCoordinates workers on OTP, surfaces data for parallel testsStateless code, state in Redis (Upstash)
Example suitesShow how Ocarina actually gets used — without AI (canonical) and with AI (CURA)Public, runnable, complete, in CI
DocumentationThe why, the how, and the AI partEN + FR + RU (Corso-Russian tradition), LLM-friendly files like llms.txt, plus PDFs

Three licenses#

LicenseWhereWhy
MITocarina, ocarina-example, ocarina-with-ai-example, ocarina-holy-bookPython code or docs. Transmissible as-is. Sovereign. See ../11-independence/.
ISCtests-workersVercel Edge scaffold default. Kept as-is.
(unlicensed)igoristanPublic demo app. Treat it as WTFPL.

Deliberate friction between repos#

The design is intentionally asymmetric along certain axes. The friction is the testing tool:

00.02 — Stack / responsibility / license matrix

00.02 — Stack / responsibility / license matrix#

RepositoryRoleLanguageVersionPrimary stackTooling stackDistributionLicense
ocarinaBrowser e2e test frameworkPython3.14+hatchling, python-docx (sole runtime dependency), selenium + playwright (dev only)ruff (ALL), mypy strict, pytest, hypothesis, pytest-mypy-plugins, syrupy, prysk (cram), allure-pytest, pre-commit, twine, buildPyPI, v1.1.10MIT
ocarina-exampleCanonical e2e suite against the IgoristanPython3.14+ocarina, selenium ≥ 4.40, python-dotenv, dogpile.cache, redisruff, mypy, pre-commitSource onlyMIT
ocarina-with-ai-examplee2e suite against CURA Healthcare, co-written with Claude CodePython3.14+ocarina ≥ 1.0.3, selenium ≥ 4.40ruff, mypy, mypy-extensions, typing-extensions, pre-commitSource onlyMIT
igoristanPublic SUT, deliberately chaotic web appTypeScript6.0.xReact 19.2, Vike 0.4.258 (SSG), Vite 7.3, TailwindCSS 4 (alpha), valibot, react-hook-form, react-dropzone, usehooks-ts, throttleit, lucide-react, uuidpnpm 11, Node 24, wireit (orchestrator), eslint 9 (flat), prettier 3.5, husky, lint-staged, commitlint, commitizen, terser, rollup-plugin-visualizer, vite-plugin-compression, @qalisa/vike-plugin-sitemapGitHub Pages (/igoristan/)none
tests-workersOTP / Corsicadex backend, the substrate that exercises parallelization and API testsTypeScript5.9.3Vercel Edge Functions (runtime: "edge"), @upstash/redis, otplib, next types (NextRequest)pnpm 11.x, @vercel/node (types)Vercel: https://tests-workers.vercel.appISC
ocarina-holy-bookPublic documentation + AI skills + PDFsTypeScript6.0.xVitePress 2 alpha, @sugarat/theme, vue 3.5, pagefind, vitepress-plugin-image-optimizepnpm 11, Node 24, eslint 9, prettier 3.8, husky, lint-staged, commitlint, sass-embeddedGitHub Pages (/ocarina-holy-book/)MIT

Python early adopter#

Python 3.12+ featureUse in Ocarina
PEP 695 (class Foo[T]:)Generic signatures everywhere (TestSuite[Driver], Watcher[Driver], Test[Driver], Result[T], Ok[T], Thunk[T], etc.)
PEP 695 type aliases (type X = ...)Every alias: type Result[T] = Ok[T] | Fail, type Effect = Callable[[], None], type Thunk[T] = Callable[[], T], type Mode = Literal[...]
TypeGuard (Python 3.10+)is_ok, is_fail, is_test_result_ok, is_test_result_fail, is_test_result_skipped
Self (3.11+)Fluent returns from POMs, loggers, invariants
@final (3.8+)Locks critical classes (Watcher, Test, TestCycle, ChainRunner, Ok, Fail, …)
Unpack (3.11+)HumanizedDriver signature in ocarina-example
Protocol (3.8+)ScreenshotDriver, SupportsWrite[str]
Literal (3.8+)All enums (SeleniumCliStoreKeys, LOGGERS_CHOICES, Mode)
Never (3.11+)_SilentArgumentParser.error signature

Practical consequence: there is a dedicated CI workflow unstable_python_full_build.yml that pushes Python 3.15-dev monthly (cron: "0 3 1 * *"), because Ocarina aims to be ready for the next interpreter as soon as it ships. See ../10-cicd/02-ocarina-workflows.md

00.03 — End-to-end execution flow of an e2e campaign

00.03 — End-to-end execution flow of an e2e campaign#

Run python -u src/main.py … on either suite (ocarina-example or ocarina-with-ai-example) and this chain kicks off:

USER  ────────────────────────────────────────────────────────────────────
       python -u src/main.py --browser firefox --workers 3 [...]
              │
              ▼
       (1) parse CLI
           CliStoreSingleton.push(create_selenium_auto_cli_store())
              │
              ▼
       (2) build pool
           create_selenium_drivers_pool(max_size=N)
              │
              ▼
       (3) warm up external dependencies
           - Redis (ocarina-example)
           - Heroku dyno (ai-example, via curl --retry 6)
              │
              ▼
       (4) bootstrap(
              test_cycle  = create_e2e_test_cycle(drivers_pool),
              run_plugins = lambda results: run_plugins(
                                generate_docx_proof, generate_json_results,
                                exceptions_logger=...),
              post_exec   = pretty_print_results + sys.exit(1) on fail
           )
              │
OCARINA  ─────┼──────────────────────────────────────────────────────────
              │
              ▼
       (5) TestCycle.run_all (saturate_workers=True)
              ├─ smoke_tests_campaigns      [mode: fail-fast | wait-for-all]
              │     └─ TestCampaign.run_all
              │           └─ TestSuite.run (max_workers, saturate_workers)
              │                 └─ ThreadPoolExecutor → TestFlow.run
              │                       └─ pool.acquire() → TestExecutor.execute
              │                             ├─ setup()                  (optional)
              │                             ├─ watchers.start()         (daemon threads)
              │                             ├─ chain_runners            (Railway DSL)
              │                             ├─ watchers.stop()
              │                             └─ teardown()               (always)
              ├─ campaigns (main)
              │  (skipped if a smoke failed)
              │
SUT   ────────┼────────────────────────────────────────────────────────────
              │
              ▼
       Selenium WebDriver ⇄ real browser
       sometimes: OTP HTTP GET + Redis (on the ocarina-example side)
              │
              ▼
       (6) run_plugins(results)
              ├─ generate_docx_proof  (reads the log tree, builds .docx files)
              ├─ generate_json_results (serializes results to .json)
              ├─ others if declared (parallelized via ThreadPoolExecutor)
              │
              ▼
       (6') post_exec(results)
              ├─ pretty_print_results (ANSI, hierarchical)
              └─ has_test_cycle_failed → sys.exit(1) if applicable

Step-by-step#

(1) Parse CLI#

create_selenium_auto_cli_store() detects the OS via platform.system():

00.04 — Relations between the six repositories

00.04 — Relations between the six repositories#

Every edge of the graph is a contract — a secret, a URL, a payload type, or a version. One pair per section below.

ocarinaocarina-example#

DirectionMechanism
ocarinaocarina-examplepip install ocarina from PyPI
ocarina-exampleocarinaNone (the example pushes nothing)

The example writes its own adapters on top of the framework:

  • lib/ext/ocarina/adapters/agnostic/act.py → adds an on_failure hook that turns an HTTP error page (title matched by ERROR_PAGE_REGEX) into HttpErrorPageReachedError.
  • lib/ext/ocarina/adapters/agnostic/match_page.pycreate_match_page(raised_exceptions=transient_errors).
  • lib/ext/ocarina/adapters/agnostic/env_getters.py → typed EnvGetters[_CredsKeys, _ValuesKeys].
  • lib/ext/ocarina/adapters/selenium/test_suite.py → pins max_retries_per_test=8, transient_errors=..., autoscreen_on_fail=True, propagates --only/--exclude.
  • lib/ext/ocarina/adapters/selenium/test_campaign.py → pins max_workers=get_max_workers().

ocarinaocarina-with-ai-example#

  • pip install . ruff mypy mypy-extensions typing-extensions pre-commit — the AI example pins its dep in pyproject.toml: ocarina>=1.0.3.
  • act adapter is minimal here. No on_failure (CURA doesn’t throw deliberately random HTTP error pages). See ../08-ai-example/
  • create_drivers_pool adapter is overridden to build a clean Chrome (password manager off, leak detection off). See ../08-ai-example/06-data-gaps.md

ocarina-exampleigoristan#

DirectionContractDetail
ocarina-exampleigoristanPublic URLsEverything goes through https://mojo-molotov.github.io/igoristan/<route>
igoristanocarina-examplenone (the SUT doesn’t know it’s being tested) — 

src/constants/pages/: