.__ .___
_______ ____ ____________ |__| ____ ______ __| _/ ____ ___ __
\_ __ \ / _ \ / ___/\____ \ | |_/ __ \ / ___/ / __ | _/ __ \ \ \/ /
| | \/( <_> ) \___ \ | |_> >| |\ ___/ \___ \ / /_/ | \ ___/ \ /
|__| \____/ /____ >| __/ |__| \___ >/____ > /\ \____ | \___ > \_/
\/ |__| \/ \/ \/ \/ \/
root@romancentral~ $ cd /opt/projects && docker compose up -d
Projects
Acheron fills the evident gap in dependency scanning for C++ ecosystems. Born after one too many attempts to bend general-purpose scanners to a C++-shaped world — tools like trivy or grype are formidable in their own domains, but none felt at home with recipe-only remotes and source-built libraries. Acheron keeps the lockfile as the single source of truth: a sober ledger of what enters the build, independent of how artifacts are produced. The Conan 2 path is implemented end to end today; Bazel and vcpkg are architected behind the same plugin layer, scheduled as phases 2 and 3.
- End-to-end Conan 2 pipeline: zero-copy
conan.lockparsing, joined against the local Conan cache database for recipe and source paths - Four-stage provenance waterfall — user overrides → OSV
determineversionsource-file fingerprinting (parallel MD5 hashing of the package's sources) →conandata.ymlURL/tag extraction → an honest “could not assess” surfaced in the report diagnostics instead of a silent gap - Batch vulnerability assessment against OSV.dev over a C++20-coroutine HTTPS client (Boost.Asio/Beast): connection pooling, exponential-backoff retries, and a lock-free three-state circuit breaker
- Persistent RocksDB TTL cache for provenance lookups — zero-copy batched reads, bloom filters, atomic write batches
- In-house CVSS calculator covering v3.0, v3.1 and v4.0 (base, temporal, environmental — spec-accurate rounding included), plus EPSS score enrichment via FIRST.org
- Three report formats: SARIF 2.1.0, GitLab Dependency Scanning 15.2.3, and CycloneDX 1.7 VDR — provider query failures travel into the reports as scan messages
- Architecture built on five C++20 concepts with a type-erased engine core; ecosystems plug in as compile-time traits over a variant — the seam Bazel and vcpkg will slot into
- Uniformly
std::expected-based error handling (no exceptions in the domain layer) and full OpenTelemetry instrumentation: nested spans and metrics from cache hits to circuit-breaker trips
Bencher can post continuous-benchmarking results straight into GitHub pull requests — for GitLab, the docs stop at “call the API yourself”. bencher2gitlab is that missing piece: it takes the JSON report from bencher run and posts it as a Markdown table in the merge request, exactly where people actually look. No statistics of its own — Bencher already decides server-side what counts as a regression; this tool makes the verdict visible.
- Idempotent by design: each comment carries a hidden HTML marker keyed on project/branch/testbed/adapter, so a re-push updates the existing comment instead of stacking new ones — parallel testbed jobs (gcc, clang, …) get their own comments without knowing about each other
- “Post first, fail second”: instead of letting
bencher run --errkill the job before the report exists, bencher2gitlab posts the comment and then exits non-zero on active alerts — the job goes red and the reason is right there in the MR - Clean exit-code contract: 0 no alerts, 1 alerts (comment posted first), 2 operational error — with 2 winning over 1
- Tokens are read exclusively from the environment, never from flags — nothing leaks into
psoutput or shell history; documents the GitLab limitation thatCI_JOB_TOKENcannot write MR notes - Plain Go with zero dependencies — three REST endpoints didn't seem worth an SDK; report structs written against Bencher's Rust types and OpenAPI spec, deliberately lenient parsing so upstream additions don't break anything
- Tests never touch a real GitLab: an
httptestfake of the Notes API including pagination and the job-token 403 behavior, plus golden-file coverage of the Markdown rendering
A self-hosted bridge that syncs bank transactions from Enable Banking (PSD2 / Open Banking) into Actual Budget or Firefly III. Built for anyone who wants automated bank-to-budget synchronisation without handing credentials to a third party. The consent is read-only by construction: it cannot initiate a payment even if asked to.
- Two budget backends behind one interface, selected by a single environment variable — a shared harness runs every scenario where the two could disagree against both of them, so a difference in behaviour surfaces in the test suite rather than in someone's budget
- Pending-to-cleared lifecycle with pre-authorisation matching: a hotel authorised as “Hotel Berlin” at 120.00 and booked as “VISA Hotel Berlin” at 138.50 is one purchase, not two
- Matching is record linkage, not a rule set — the part of this project I got wrong first. The same meal appears authorised as “Da Luigi Roma” and booked as “Visa Da Luigi”, the bank having prefixed a card scheme and cut the tail to fit its field. A similarity score cannot tell that apart from a different branch of the same chain: measured, “Shell Tankstelle”/“VISA Shell” and “Da Luigi Roma”/“Visa Da Luigi Milano” both score 0.667 under Sørensen–Dice, and no weighting against Jaro–Winkler separates them. Truncation removes a word; a different branch contradicts one. So the published model does the work instead — Fellegi–Sunter (1969), the same one behind Splink and national statistics offices: each field yields a discrete comparison level worth log₂(m/u) bits of evidence, and the sum becomes a probability
- The batch is decided together rather than pair by pair — a one-to-one assignment over the whole run, which is Jaro’s (1989) reading of linkage as an assignment problem, solved with the Hungarian method. Weighed one at a time, two bookings can both claim the same authorisation and the tie falls to whichever the loop reached first, so the same statement in a different order produced a different budget. Under the constraint that stops being possible, and two payments nothing can tell apart are matched up instead of both landing in front of a person
- Two thresholds rather than one, which is where the model has always kept its clerical review zone. Anything landing between them is held back for a person to decide rather than guessed at — written to no budget, deferring that account's opening balance (which is written once and never revised), and visible on the dashboard, in
/healthand in its own metrics. Candidates are recomputed when the page is drawn and the probability shown is rechecked when the answer comes back, so a decision made against a stale page is refused rather than applied - The parameters are argued for rather than asserted. A generated table in the repository moves every one of them by a factor of three and counts which decisions change as a result — it is the reason the shipped values are the ones they are, and a change to it fails the build until somebody has read the diff. Cases get settled three ways: a review answered, a pair the bank’s own reference confirms, and — if switched on — one confirmation per sync about a decision the matcher made alone, picked for how much its answer would say about the parameters. That third one exists because the automatic band is where the expensive mistakes are and the only place nothing would otherwise ever contradict the matcher. Where enough have accumulated, the parameters can be refit from them: a Dirichlet posterior over the levels, Platt scaling for the scale. Only half the model needs anybody’s answer, though. Those probabilities describe pairs that are one payment; the other half describes pairs that are not, and at most one candidate in a window can be a transaction’s counterpart — so every other one it was weighed against is a draw from exactly that population, and counting them needs no labels at all. That is what makes a refit reachable on an installation nobody is answering questions on. Nothing fitted takes effect on its own, though. It has to pass a gate — six documented behaviours still decided the same way, a Brier score better on evidence the fit never saw, and a person pressing the button — and before that it runs in shadow beside the real decision, so what it would have changed is a number rather than a hope
- Opening balances and drift detection: the balance that predates the first import is written once and only ever compared thereafter, distinguishing booked from available balance types, and never silently corrected
- Integration tests against a real Firefly III instance, brought up and destroyed per merge request — deliberately in a timezone west of UTC, which is what exposed a date bug the hand-written test fixture had been agreeing with all along
- Full OpenTelemetry instrumentation — metrics, traces and logs — with Pyroscope continuous profiling and structured logs carrying trace context. Including the things that are otherwise invisible: the distribution of match probabilities, without which the two thresholds are numbers an operator has to guess at, and every database operation by statement kind and table
- Embedded dark-mode web UI with sidebar navigation: a review page for the transactions the matcher would not decide on its own, a matching page showing the parameters in force beside the ones your own answers would support, health endpoint, manual sync trigger, sync history, failure email notifications, session expiry warnings, and a Docker Hub update checker
- Single static binary in a non-root Docker image — no runtime dependencies beyond SQLite
- CycloneDX SBOM embedded in every container image with BuildKit attestations on Docker Hub
The backend behind the live music widget on the home page, built to retire Last.fm scrobbling and its third-party widget entirely. The service registers itself as a Spotify Connect device via librespot and observes Connect cluster updates — so it sees what is playing on any device of the account, not just when it is the active player. Visitors get every play pushed over WebSocket the moment it happens.
- Live playback-state replication: pause, resume, seek and stop are mirrored to the website as lightweight state frames, with client-side position extrapolation while playing
- Scrobble semantics done properly — a play only counts after 30 seconds of listening; 30-day top songs and artists served from Postgres
- Crash-safe by construction: replay guard plus idempotent inserts, a
kill -9and restart never double-counts a play - WebSocket origin allowlist and strict CORS; TLS terminated by nginx, the app itself speaks plain HTTP on loopback only
- Full OpenTelemetry instrumentation — traces, metrics and logs via OTLP with strictly bounded metric cardinality, correlated down to individual cluster updates
- The widget on the other end is dependency-free vanilla JS that derives its color scheme live from the album cover
A compliance scanner for Linux host firewalls: it checks an nftables ruleset against a declarative target specification — versionable, diffable, CI-ready. The established firewall-compliance tools (Tufin, FireMon, AlgoSec, Batfish) target network appliances and vendor routers; Linux host firewalls are an afterthought at best. Where Linux tooling exists, it stops at syntax-checking individual rules or hard-wired frameworks (PCI, NIST). Anabasis fills that gap: an engine that validates the effective resulting traffic policy of an nftables config against a user-defined, versioned specification.
- No hand-rolled config parsing — the live ruleset is ingested through the libnftables JSON frontend (
nft -j list ruleset) into a normalized internal rule model - Syntactic layer: predicate matching against the rule AST with assert/require/forbid operators — a rule exists, is missing, or a forbidden pattern is present
- Semantic layer: the packet space is modeled as set algebra over header fields (BDDs / disjoint hyperrectangles), so flow assertions like “traffic X must be blocked/allowed” hold regardless of rule order, shadowing, or phrasing
- On a violation, the engine extracts a concrete counterexample packet
- The target spec is a declarative YAML/JSON artifact living in the repo — the compliance policy itself becomes reviewable, diffable code
- Findings are emitted as SARIF, plugging straight into CI pipelines and code-scanning frontends
The self-hosted observability platform behind everything else on this page. A multi-tenant stack for metrics, logs, traces and continuous profiling — Mimir, Loki, Tempo and Pyroscope on self-hosted S3 (MinIO), fronted by Grafana and HAProxy, alerting through Alertmanager into PagerDuty — provisioned entirely from one Ansible monorepo. The nowplaying traces with their 14-day retention mentioned on the legal page? They land here.
- Cryptographic tenant isolation: step-ca runs in Registration-Authority mode with the signing key on an isolated network segment, never publicly reachable; every connected host holds a 24-hour SPIFFE-style certificate, and HAProxy derives the tenant ID from the certificate CN at the edge — hard-set, not client-assertable
- Certificates renew via systemd template units every 15 minutes and hot-reload into the collector with no process restart and no telemetry gap; a CA rotation propagates to every host automatically
- 44 alert rules in six groups, including a dead-man's switch (a permanently firing watchdog whose absence pages) and paired ratio-plus-absolute 4xx alerts with traffic floors — one catches quiet scans, the other floods where the ratio stays innocent
- Hardened exporter wrappers instead of upstream install scripts: systemd sandboxing, dedicated users,
visudo-validated sudoers whitelists, pinned venvs — plus a bespoke LUKS/TPM encryption-health checker feeding the textfile collector - Tail-based trace sampling on outcome attributes — you cannot head-sample on a value that only exists once the span is finished; noise outcomes are kept at 10%, everything else in full
- Three-playbook lifecycle (provision, idempotent reconfigure, per-host onboarding) with per-file drift-isolated restart handlers; the observability host is onboarded as its own tenant — dogfooded by construction
- Kernel, NVMe and Docker tuning with reasoning in the comments (conntrack timeouts vs. gRPC keepalive races, BBR, absolute
dirty_byteson large-RAM hosts) and a self-test script asserting every value post-reboot - Two-tier secrets — ansible-vault plus GPG-backed
pass, encrypted at rest in git — and restic offsite backups that respect each store's consistency model: stop what is concurrent-read-unsafe, stream a live Postgres dump where downtime is unnecessary