Build1 distinct publisher3 min readUpdated
Six new feature areas landed in v3.0.0, every one off by default, and a verify command that refuses to call an unreadable database clean.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
trelix closed a six-release run with v3.1.1, dated 2026-08-15: 68 commits, 137 files changed, +19,829/-1,211 lines since v2.11.0 [1][2]. The write-up on dev.to leads with a hash-chained audit trail, but the more transferable decision is smaller than any feature in the release: `trelix audit verify` exits 2 when it cannot open the database, rather than 0 [3].
The demonstration is short. Seed three events, reach past the application with `sqlite3 audit.db "UPDATE audit_log SET principal='attacker' WHERE id=2"`, and verify reports the chain as tampered, names id 2 as the first divergent entry, and exits 1 [4]. Delete the newest row instead and it names id 3, even though the surviving rows form a valid chain [5]. Point it at a file SQLite cannot open and it exits 2 [3]. That is three outcomes where most check commands ship two, and the third is the one that keeps a broken check from being reported as a passing one [6].
The truncation catch needs its own machinery. Each row's `entry_hash` is `sha256(prev_hash || canonical_json(content))`, canonicalised with `sort_keys=True` and `separators=(",", ":")` [7]. Exactly eleven columns are hashed, in a fixed `_CONTENT_COLUMNS` tuple, and the DB-assigned `id` is deliberately excluded because a writer cannot hash a value it does not have until after the INSERT [8]. A hash chain is therefore structurally blind to a deleted tail [9], so an `audit_meta` table carries a running `count` and `head_hash`, upserted inside the same transaction as the insert, and `verify_chain` checks both against the chain it just walked [10]. `audit_log.id` is `INTEGER PRIMARY KEY AUTOINCREMENT` rather than a rowid alias, so a delete-then-refill cannot close the gap it made [11].
The trail is a separate SQLite file, defaulting to `<cwd>/.trelix/audit.db` and never the index database, on the grounds that the index is disposable and a trail that vanishes on reindex is not a trail [12]. It is stdlib `sqlite3`, 54 tests, and fail-open by default via `AuditConfig.fail_closed: bool = False` so a full disk is not an outage [13]. `trelix audit export --format ndjson` writes one JSON object per line for SIEM ingestion [14].
The discipline that costs more is the defaults. v3.0.0 carries six new feature areas plus an opt-in FTS5 declaration boost [15], and all of them ship off: `TRELIX_AUDIT_ENABLED`, `TRELIX_OIDC_ENABLED`, `TRELIX_LLM_THINKING_ENABLED` and `TRELIX_RETRIEVAL_COMPRESSION` all false, `declaration_boost_enabled` false, and `context_token_budget` still the same `12_000` integer as v2.12.0 [16]. A default v3.0.0 install assembles context byte-identically to a default v2.12.0 install, and there is a test asserting it rather than a release note claiming it [17]. The major bump is scope, not breakage [18].
The SSO half is scoped the same way: trelix is a resource server, not an OIDC client, with no `/login`, no `/callback`, no code exchange and no refresh [19]. Algorithms are asymmetric-only, defaulting to RS256 and ES256, and the check runs in `OidcVerifier.__init__`, again against the unverified JWS header in `authenticate`, and a third time in `jwt.decode` [20]. The test worth reading skips trelix's own header gate and signs a token with HS256 using a real 2048-bit public key's PEM as the HMAC secret, then asserts `jwt.decode` alone refuses it [21]. `Principal.principal_id` is subject plus issuer, never email, because email-keyed identity is an account-takeover primitive [22].
Two things to watch. Fail-open is the seam: because a dropped write never reaches the insert transaction that increments `audit_meta.count`, an event lost to a full disk leaves the chain and the count mutually consistent, so verify will call it clean [23]. And defaults tend to drift after the release that announces them, so the number worth rechecking at v3.2 is whether `context_token_budget` is still 12,000 and whether the four false flags are still false [16].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The span from trelix v2.11.0 to v3.1.1 is six releases (v2.11.1, v2.12.0, v3.0.0, v3.0.1, v3.1.0, v3.1.1), the last dated 2026-08-15.
That span comprises 68 commits, 137 files changed, +19,829/-1,211 lines.
Pointed at something SQLite cannot open, trelix audit verify exits 2 rather than 0, because 'I could not check' and 'I checked and it is clean' must never collapse into the same green build.
After seeding three events and running sqlite3 audit.db "UPDATE audit_log SET principal='attacker' WHERE id=2", trelix audit verify --db audit.db reports the audit chain as TAMPERED with first divergent entry id 2, and exits with code 1.
Deleting the newest row instead is still caught, naming id 3, even though the surviving rows form a perfectly valid chain.
Each row's entry_hash is sha256(prev_hash || canonical_json(content)), canonicalised in ten lines of src/trelix/audit/store.py with sort_keys=True and separators=(",", ":").
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Specific and reproducible, but single-source and unverified
Every claim traces to one maintainer-style dev.to post. Its internal specificity is high — command transcripts with exit codes, file paths, the exact hash construction, named config variables, a test count and an explicit limits section — which makes the claims falsifiable by any reader who installs the tool. But nothing in the cluster is independently corroborated: no second publisher, no repository audit, no third-party reproduction of the tamper transcripts or the byte-identical-context test.
Releases shipped; no external uptake evidence
The only adoption-grade facts are the project's own releases and their aggregate diff statistics, plus a self-run command transcript. There are no downloads, installs, deployments, named users, security reports or third-party integrations in the supplied material, and the marquee features are shipped off by default, so even installed versions need not exercise them.
Slightly understated relative to its own detail
The framing is conservative for a release post: the headline promotes an exit code rather than a feature list, the major version bump is explicitly attributed to scope rather than breakage, and a limits paragraph concedes the trail is tamper-evident rather than tamper-proof, that only the HTTP surface is audited, that retention is declarative only, and that authorization is absent. Pushing the score back toward zero is the absence of any independent verification and one unflagged consequence of the design — fail-open writes plus in-transaction count increments mean a dropped event still verifies clean.
Project-authored release promotion on a developer platform
The single source is a first-person release write-up on dev.to describing the author's own project, including install commands and configuration guidance — a promotional posture with an interest in the release reading as disciplined and enterprise-ready. Mitigating factors are the falsifiable specifics and the self-disclosed limitations; the supplied material discloses no sponsorship, funding or commercial relationship, so those are not scored.
Moderate-low: verifiable detail, one interested publisher
Confidence is limited by structure rather than vagueness. The technical claims are stated precisely enough to trust provisionally and to falsify cheaply, but there is one publisher, one author, an evident promotional incentive, and no adoption evidence at all, so conclusions about real-world integrity guarantees or uptake should stay tentative.
build
Once the question needs a cube, you own the parser1 distinct publisher
build
One event per token: the fix went in the proxy, because that was the only box he owned1 distinct publisher
build
Four REST calls became one query: the sidecar pattern, minus the marketing1 distinct publisher
science
OX Security says MCP command execution is a design choice, so server owners own the risk1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 15, 2026