trelix v3.2.2 to v3.3.8: A GitHub App Already Hardened and Running in Production, and a Connector That Never Touches a Pixel A developer documented thirteen tagged releases of the Trelix project from v3.2.2 through v3.3.8, after discovering that the published v3.2.1 Docker image never contained the trelix-mcp entrypoint and that its console script silently ignored all flags. The response included a real-subprocess E2E suite in CI that installs published artifacts and spawns trelix-mcp over stdio JSON-RPC, plus a 742-line verify_release.py script with five independent check functions. The developer notes that while the code itself held up under source review, the surrounding documentation and changelog repeatedly drifted from what the code actually does. docker run --entrypoint trelix-mcp ghcr.io/sairam0424/trelix:3.2.1 --help returns exit code 127: command not found. Not a typo, not a stale tag — the published 3.2.1 image never contained trelix-mcp at all. The builder stage copied core trelix and nothing else, and .dockerignore 's blanket packages/ exclusion would have blocked the MCP package even if someone had remembered the COPY line. A second, unrelated defect shipped in the same release: the published trelix-mcp console script ignored every flag you gave it — --help , -h , --version , anything — and silently launched the real MCP stdio server instead. Both were found the only way they could have been found: by installing the actual published artifacts and running them, not by reading a source tree that had never been wrong. That's v3.2.2, and it's where this span starts. This article covers the thirteen tagged releases from v3.2.2 through v3.3.8 — 2026-08-26 through 2026-09-25 — picking up the day after the last article in this series ended at v3.2.1. v3.3.8 is the current release: tagged, pushed, marked "Latest," and — I checked this directly rather than trusting the changelog — live on PyPI right now. The prior span's throughline was a green test suite that never touched the bug it claimed to cover — a MagicMock standing in for an embedder, an all-ones attention mask making masked and unmasked math identical, a unit test that asserted a bug as its own specification. That defect class is still present in this span more on it below , but it's no longer the dominant story. Two things sit ahead of it now. The first is that the response to catching defects graduated from "write a regression test" to "build a system that makes this class of defect structurally unable to reach a tag again." The second is quieter and, I think, more interesting: almost everything genuinely new in this span — a diagram connector, an MCP protocol upgrade, a retriever-caching fix, a compression provider, an audit-log pruning mechanism — turned out to be sound at the code level when I went and checked it against source. What kept drifting was the layer just above the code: a renamed class the CHANGELOG never caught up to, a performance number with no artifact behind it, a guarantee that overstates what the code actually does. If the last article's angle was "the code lied to the tests," this one's second angle is closer to "the code is right, and the notes about the code keep being slightly wrong" — which is a more mature failure mode, and one that only shows up once the cruder failure mode has already been closed off. v3.2.2's fixes were correct but ordinary. What matters is what happened next. v3.2.3, two releases later, turned the exact manual "install the real published artifacts and run them" pass that had just caught two live defects into permanent CI: a real-subprocess E2E suite that spawns trelix-mcp as an actual OS process talking real stdio JSON-RPC, fresh-venv installs of all four published packages, a smoke-test-built-artifacts job that release.yml 's publish job is now hard-gated on, a Docker check that trelix-mcp is actually present in the built image, and a Helm-lint check that the rendered image tag matches Chart.yaml . The same release fixed a real, separate bug along the way — a LIKE -wildcard escaping gap in path filter -scoped BM25/grep queries, where unescaped and % in ordinary directory names were being read as SQL wildcards. Not injection the queries were already parameterized , just a distinct semantics gap, closed with a shared escape like pattern helper and an ESCAPE '\' clause. The centerpiece is scripts/verify release.py , a 742-line script with five independent check functions that each return a list of failures and never raise — so one category's bug can't hide another's results. check pypi installs does a fresh venv per package and a real pip install