Backend engineer with 15+ years of commercial PHP. I design and build high-load services and APIs β and I publish the reusable parts as open source.
- 10 years in ad-tech: advertising networks with RTB (Real-Time Bidding) integrations, buying and selling traffic β MySQL for operational data, ClickHouse for impression analytics, Redis/Memcached for caching.
- Now: product development on Yii3 / PHP 8.5 with Clean Architecture (Domain / Application / Infrastructure / Endpoint, boundaries enforced statically by Deptrac), plus support and refactoring of large Yii2 legacy systems.
- LLM in production: the application acts as an MCP server β assistants connect over Model Context Protocol and call domain tools via tool-calling, guarded by per-user RBAC and an audit log.
- I care about the things that are invisible until they break: retries, idempotency, exactly-once delivery, backpressure, mutation-tested code.
Languages
Frameworks
Data
Infrastructure & Real-time
Quality
π¦ Open Source β packages on Packagist
Reusable PHP 8.3+ libraries with hardened CI/CD, SemVer, backward-compatibility checks, and tests on Testo with mutation testing (MSI 85β100%).
How does one person ship this many? Not by cutting corners β the volume is a side effect of a repeatable process, not the goal. The process is public in php-package-toolkit and explained in Workflow below.
Five that show the range:
| Package | What it does |
|---|---|
| yii3-ab-testing | Deterministic A/B testing for Yii3 β stateless hash-based assignment (same subject, same variant, every time, no session state), weighted variants, forced variant for QA, explicit exposure/conversion tracking. A full family: -db, -clickhouse, -web, -outbox |
| yii3-outbox | Transactional outbox β events committed in the same transaction as the data, then relayed. No lost messages on crash, no dual-write. Yii3 had no such thing |
| yii3-mcp | MCP server for Yii3: expose CQRS handlers as LLM tools, auto-bridge OpenAPI β MCP, and β the part generic MCP servers skip β per-user RBAC and an audit log on everything the model touches |
| property-testing | Property-based testing with integrated shrinking (Hedgehog model) and stateful / model-based testing β the two things PHP's PBT libraries don't do. Generates inputs, finds a counterexample, shrinks it to the minimal one. A Testo plugin |
| clickhouse-toolkit | Framework-agnostic ClickHouse toolkit: parameterized query builder, data reader, batch writer, DDL builder, partition manager, migration runner β the pieces ORM query builders don't cover for an analytics store |
The rest of the ecosystem β resilience, observability, Yii3 infrastructure
| Area | Packages |
|---|---|
| Resilience | retry Β· circuit-breaker Β· bulkhead Β· duration Β· result |
| Delivery | yii3-outbox (+ -db, -clickhouse) Β· yii3-webhooks (+ -db) Β· yii3-outbox-webhooks-bridge Β· yii3-idempotency (+ -db) β safe request retries via Idempotency-Key |
| Experiments | yii3-feature-flags (+ -db, -ui) Β· yii3-ab-testing (+ -db, -clickhouse, -web, -outbox) |
| Attribution | yii3-utm (+ -db) β UTM/click-id capture, touchpoint history in one cookie, consent-gated middleware, append-only attribution journal |
| Observability | yii3-telemetry (+ -otel) Β· yii3-metrics (+ -prometheus) Β· yii3-correlation-id Β· yii3-health-check Β· yii3-audit-log (+ -db) Β· domain-monitor |
| AI / LLM | yii3-mcp Β· yii3-mcp-rbac-bridge Β· yii3-mcp-audit-log-bridge Β· yii3-mcp-telemetry-bridge |
| Yii3 infrastructure | yii3-tenancy (+ -db) Β· yii3-settings (+ -db, -ui) Β· yii3-workflow (+ -db) Β· yii3-api-problem Β· yii3-maintenance-mode Β· yii3-seo Β· yii3-centrifugo Β· yii3-respect-validation Β· yii3-recaptcha Β· yii3-turnstile |
| Media | media-converter β type-safe ffmpeg/ffprobe wrapper: transcode/remux/filter pipeline, retry + bulkhead, progress events, DRM-aware probing |
| Query & domain | specification β Specification pattern, composable type-safe query building |
| ClickHouse | clickhouse-toolkit Β· yii3-clickhouse-toolkit |
| Tooling | rector-named-literals Β· rector-datetime-immutable |
The honest answer to "how does one person publish this many packages?" is that the agent does the mechanical work inside a rulebook a human wrote β and that rulebook is php-package-toolkit, open source, so the claim is auditable rather than asserted.
The loop
- Scaffold from contract, not from scratch. An agent generates each package from versioned templates plus a machine-checked rulebook (
AGENTS.md). File layout, code style, CI pipeline, doc structure, and security rules are a fixed contract, never a per-project decision. - Write, then gate. The agent writes the code, tests, and docs, then runs the same gate every package must pass: Psalm level 1 with zero suppressions, mutation testing (MSI 85β100% β line coverage is not enough; the toolkit's
ER-003writeup covers the difference), backward-compatibility checks before every major, SHA-pinned hardened CI, and Testo tests with property-based coverage where invariants exist. - Human owns the judgment. I design the API, decide the abstractions and layer boundaries, review every change, and own release decisions. The agent never merges, tags, or publishes on its own β those are explicit human gates encoded in the skill workflows that drive each step.
What the agent makes cheap is execution, not judgment. Deciding what the right abstraction for a transactional outbox or a deterministic A/B engine looks like is the part I bring; the toolkit makes shipping it a matter of hours instead of weeks, without lowering the bar.
- A fitness / training platform backend (Yii3, PHP 8.5, PostgreSQL) β activity tracking with
.fitfile parsing, duels and leagues, JWT auth, S3 storage, real-time via Centrifugo, transactional outbox for event delivery. Strict Clean Architecture layering enforced by Deptrac; built on my own packages. - A Yii3 product backend (PHP 8.5, MySQL / ClickHouse / Memcached) β admin panel, REST API with OpenAPI, RBAC, multi-language, media pipeline, and an MCP server that lets LLM assistants operate the product safely.
- Low-latency, high-load services where milliseconds and correctness both matter
- Distributed patterns done properly: outbox, idempotency, retries with backoff, bulkheads
- Libraries other people can depend on β documented, versioned, mutation-tested
- Making LLMs a first-class, permission-aware part of a backend rather than a bolt-on


