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: 89 packages on Packagist so far.
- 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
AI / LLM
Quality
π¦ Open Source β packages on Packagist
89 packages β reusable PHP 8.3+ libraries with hardened CI/CD, SemVer, backward-compatibility checks, and tests on Testo with mutation testing (MSI 85β100%).
How one person ships this many: see Workflow below.
Built to be used by AI coding assistants too: every package ships an llms.txt API reference, and 40 of them ship an agent skill (SKILL.md) that projects using the llm/skills Composer plugin pick up on composer install.
Five that show the range:
| Package | What it does |
|---|---|
| yii3-ab-testing Β· docs | 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 |
| context | Deadlines, cancellation and request-scoped values for PHP β Go's context.Context idea, with no dependencies. One budget follows a request through every layer: HTTP client timeouts (-http), database-side statement timeouts on MySQL / MariaDB / PostgreSQL (-db), graceful shutdown of CLI workers on OS signals (-cli), external processes stopped when the deadline passes (-process). The docs say plainly where an in-flight call cannot be aborted |
| yii3-mcp Β· docs | MCP server for Yii3 on the official mcp/sdk: domain operations become LLM tools through attributes, operations from an OpenAPI spec are bridged as tools β and, the part generic MCP servers skip, per-user RBAC, an audit log and telemetry on everything the model touches |
| property-testing-core Β· docs | Framework-agnostic property-based testing engine: generators with integrated shrinking, a structured runner, regression corpus, lifecycle events β plus stateful/model-based testing. No test-framework dependency; Testo and PHPUnit adapters plug it in |
| understudy Β· docs | Test doubles where the stubbed call is a real call: when(fn () => $repo->find(1))->returns($book) β no method names in strings, so a rename or a wrong argument is a type error before the test runs. Testo and PHPUnit adapters, Psalm and PHPStan plugins |
The rest of the ecosystem β resilience, observability, payments, files, testing, Yii3 infrastructure
| Area | Packages |
|---|---|
| Resilience | resilience β retry, circuit breaker and bulkhead composed in the right order Β· retry Β· circuit-breaker Β· bulkhead Β· duration Β· result |
| Context & cancellation | context (+ -cli, -db, -http, -process) β deadlines, cancellation and request-scoped values that follow a request through HTTP calls, DB statement timeouts, CLI worker shutdown and subprocesses |
| Delivery | yii3-outbox (+ -db, -clickhouse) Β· yii3-webhooks (+ -db) Β· yii3-outbox-webhooks-bridge Β· yii3-idempotency (+ -db, -redis) β 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 |
| Payments | payments β provider-neutral payment contracts, PSR-18 transport and webhook pipeline Β· payments-testing β deterministic fake gateways and framework-agnostic contract assertions |
| 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 |
| Files | yii3-filestorage (+ -db, -flysystem, -web, -attachments, -images) β DI-native storage facade over swappable backends, deduplication ledger, signed downloads, tenant-scoped attachments, named-preset image derivatives |
| Media | media-converter β type-safe ffmpeg/ffprobe wrapper: transcode/remux/filter pipeline, retry + bulkhead, progress events, DRM-aware probing |
| HTTP & semantics | pinned-http-client β PSR-18 client for untrusted URLs: resolves the host, checks every address, pins the connection Β· link-preview β SSRF-safe OpenGraph / Twitter Cards extraction Β· json-ld β JSON-LD 1.1 processor: expand, flatten, node API, RDF, N-Quads |
| Query & domain | specification β Specification pattern, composable type-safe query building Β· schema β schema-as-code combinators: one definition drives runtime validation, property-based generation and JSON Schema export |
| ClickHouse | clickhouse-toolkit Β· yii3-clickhouse-toolkit |
| Property-based testing | property-testing-core adapters and extensions: property-testing-testo Β· property-testing-phpunit Β· property-testing-names β realistic person names as inputs Β· property-testing-openapi β requests generated from an OpenAPI document |
| Testing & quality | understudy (+ -testo, -phpunit, -psalm, -phpstan) β test doubles with a call-closure API and static-analysis plugins Β· openapi-contract β framework-neutral OpenAPI contract validation for PSR-7 Β· doc-exec β doctest for PHP: executes fenced code blocks from docs, diffs the output Β· quality-ledger Β· mutation-history β append-only quality ledgers with regression ratchets |
| Tooling | rector-named-literals Β· rector-datetime-immutable Β· ecosystem-sandbox β runnable checkout sandbox for the whole ecosystem (a demo application, not a package) |
Recent releases β updated daily from Packagist:
| Date | Release |
|---|---|
| 2026-10-28 | yii3-filestorage v0.7.0 |
| 2026-10-28 | yii3-filestorage-images v0.4.1 |
| 2026-10-28 | yii3-filestorage-attachments v0.2.0 |
| 2026-10-28 | yii3-filestorage-web v0.4.0 |
| 2026-10-27 | yii3-idempotency v2.3.0 |
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 deadline-propagating context 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 sports fan site (Yii3, PHP 8.5, PostgreSQL / Redis, Temporal, real-time via Centrifugo; built on my own packages) β match calendar with live updates, a long-running archive of player and head-to-head statistics, fan profiles, guestbook and private messages, admin panel.
- ecosystem-sandbox β a runnable Yii3 shop that composes 60+ of my packages into one checkout and payment flow: outbox, idempotency, retries, circuit breaker, webhooks and telemetry working together, not just in isolation.
- 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.
- 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



