A quality-first factory for e-commerce payment plugins: one spec, one shared conformance suite, platform adapters generated under strict gates.
Payment integrations are maintained once per platform (WooCommerce, Sylius, PrestaShop, Magento, Shopify, SFCC...) and the conventions that keep them consistent get copy-pasted by hand — then drift. Teams increasingly let AI agents produce the new plugins, but agents ship business code, not the quality layer around it. PluginForge codifies that layer once and makes the machine enforce it.
spec/*.yaml ──► SpecLoader (fails fast, lists every error)
│
▼
┌── core (Domain / Application / Infrastructure)
│ ProviderClient: eligibility, payment, refund, webhook HMAC
│
▼
adapters/<platform> ◄── generated by the generate-plugin skill
│ (contract: AdapterInterface)
▼
conformance suite ──► the SAME behavioral scenarios on every adapter
│
▼
gates: PHPStan max · PSR12+sniffs · PHPCompatibility · coverage ratchet · semgrep
│
▼
journal/generation-export.json ──► verified in CI (tamper-evident provenance)
composer install
vendor/bin/phpunit # 44 tests, includes the full conformance suite
vendor/bin/phpstan analyse # level max
vendor/bin/phpcs # PSR12 + ForgeStandard architecture sniffs
php bin/forge validate-spec spec/examples/generic-bnpl.yamlOr everything at once with go-task: task check.
spec/— the integration contract (forge: "1.0"): provider, products (pnx / pay_later / pay_now), endpoints, webhook signature, credential config. JSON Schema is the canonical form; the loader enforces the runtime subset and reports all problems at once.src/— the platform-agnostic core. Value objects (Moneyin minor units), neutral snapshots (CartSnapshot,OrderSnapshot,RefundSnapshot), one orchestrator (ProviderClient) speaking one wire contract, HMAC webhook verification on the raw body.adapters/— platform adapters. The Sylius 2 adapter is the reference implementation: pure, tested classes plus the honest boundary of what stays in the host application (see adapters/sylius2/README.md).conformance/—AdapterConformanceTestCase: 12 behavioral scenarios (eligibility mapping, plan normalization and filtering, payment creation, partial and full refunds, webhook signature accept/reject, credential cipher roundtrip and tamper detection). Every adapter inherits them — consistency is proven, not claimed.
| Gate | Level | Note |
|---|---|---|
| PHPStan | max | treatPhpDocTypesAsCertain: false |
| PHPCS | PSR12 + ForgeStandard | architecture sniffs: no *Helper, exceptions named *Exception, no debug output |
| PHPCompatibility | 8.2–8.5 | |
| Tests | 44 / 82 assertions | unit + conformance, all green locally and in CI |
| Coverage ratchet | 68 % lines / 44 % methods floors | measured at v0.1.0; floors only move up (tools/phpunit-threshold.php) |
| Semgrep | taint rule | request superglobals → debug sinks |
| Provenance | NoireBox journal | sealed at generation, verified by slabbdev/noirebox-verify in CI |
CI runs all of it on PHP 8.2, 8.3 and 8.4, with actions pinned by commit SHA.
journal/generation-export.json is a signed, hash-chained export of the
decisions taken while building this repository (what was generated, from
which spec, which gates passed, the SHA-256 of the produced sources). CI
verifies the chain and its Ed25519 attestation on every push — tampering
with the journal fails the build. The sealing used
NoireBox.
The .claude/skills/generate-plugin/SKILL.md procedure is what an agent —
or a human who does not want to guess — follows to produce a new adapter
under the gates. Read conventions/CONVENTIONS.md first; the sniffs will
read it for you afterwards.
- Adapter for a second platform (the first fork of the conformance story).
- A real
RemoteTransporthardening pass (retries, timeouts per environment). - Spec-driven UI config for eligibility widgets.
MIT — see LICENSE.