fundraisingbox/symfony-precognition
Symfony bundle that brings Precognition-style request validation to Symfony apps, letting frontends preview form errors before submission without running the controller, for faster feedback and fewer failed submissions.
Architecture fit. Unchanged in kind: this is a Symfony bundle, not a Laravel package. It hooks Symfony's HTTP kernel (kernel.controller/short-circuit and kernel.exception listeners), the Symfony Validator/MapRequestPayload/MapQueryString argument resolvers, and the DI container to short-circuit or filter validation failures. None of these extension points map onto Laravel's HTTP kernel, FormRequest lifecycle, or Illuminate\Validation. For a Laravel-first portfolio the architectural fit remains poor-to-none — Laravel's native Precognition (HandlePrecognitiveRequests, Precognition / Precognition-Validate-Only headers) is a first-party feature and replacing it with a third-party bundle is a net negative. Its legitimate fit is the Symfony half of a hybrid estate (Symfony services, admin/back-office, API Platform endpoints), where no equivalent first-party primitive exists.
What v1.0.0 changes. This is the first stable release and it materially closes the "is this a sketch or a package?" question:
PrecognitiveForm attribute, short-circuit listener, validate-only listener, violation path filter, response listener, and bundle service registration. The API surface is now enumerable — which means the fork/vendor scope is finally estimable rather than speculative.require precognitive route opt in). This is the single most valuable safety control in the release: precognition cannot silently apply to an endpoint that has side effects.require symfony components and declare supported versions), and the bug-fix list evidences real Symfony 6.4 ↔ 7.x dual support (new HttpException for 6.4, MapUploadedFile PHPStan ignore on 6.4, MapQueryString status preservation).Architectural nuance worth flagging. The two listeners imply two precognitive paths with different risk profiles:
PrecognitiveForm): controller is skipped, validation runs in the argument resolver. Low side-effect risk, but authorization performed in the controller is skipped too.kernel.exception + violation path filter): the controller executes, throws a validation exception, and the listener filters violations down to the requested fields. If the controller performs work before validation (persistence, dispatch, external calls), a precognitive request can trigger side effects. This should be treated as the primary safety hazard in adoption.Technical risk.
| Risk | Severity | Change vs. prior | Note |
|---|---|---|---|
| Bus factor | High | unchanged | Single org, ~8 stars, no dependents. v1.0.0 and release automation improve quality confidence, not continuity confidence |
| Side effects on validate-only path | High | new/escalated | Controllers execute before kernel.exception filtering; any pre-validation work runs on precognitive requests |
| Authorization bypass | High | refined | Short-circuit path skips in-controller authorization; validate-only path runs it but may run it after side effects. Policies must sit in the validation layer or a security listener |
| Exception-listener coupling | Medium | new | Behavior depends on listener priority relative to Security, API Platform, and your own exception listeners — a fragile, non-obvious integration seam |
| Semantic drift vs. Laravel | Medium | slightly reduced | Header primitives now exist and are inspectable, but parity with Laravel's contract is still unverified |
| Version coupling | Medium | reduced | Supported Symfony versions declared and 6.4/7.x both exercised in fixes |
| False validation confidence | Medium | unchanged | Precognitive rules can drift from execution-time rules absent one source of truth |
| Subrequest edge cases | Low | reduced | ignore validation exceptions from subrequests shipped — indicates the edge existed and was addressed |
Key questions.
Precognition-Validate-Only semantics match Laravel's, or the gateway must translate.PrecognitiveForm attribute vs. Symfony constraints) and can that declaration be exported as a rule manifest shared with the Laravel side?1.x? (Versions are declared; the policy is not.)Stack fit. Unchanged: adopt only where a Symfony runtime is in the request path. Laravel remains the client-facing BFF/API gateway using native Precognition; Symfony services use this bundle. One UX, two implementations — acceptable only if headers and the 422 error envelope are normalized at the gateway.
Migration path. Do not migrate Laravel endpoints onto this package. Instead:
MapRequestPayload/PrecognitiveForm so the short-circuit path applies.FormRequest rules and Symfony constraints derive from one source.Compatibility. PHP 8.1+; Symfony 6.4 LTS and 7.x both exercised. No dependency conflict surface with Laravel packages (no shared deps) — the constraint remains operational (two validation stacks, two rule sources). Verify listener priorities against Security and API Platform in a realistic kernel before piloting.
Sequencing.
Maintenance. 1.0.0 is a semver commitment, which reduces churn risk, but you are still effectively the maintainer. Pin the version; do not float. Budget a quarterly review of Symfony major compatibility and keep the documented fork procedure current — the release automation suggests upstream will keep pace, but continuity is still one person deep.
Support. No vendor, no SLA, GitHub issues only. v1.0.0's hygiene (PHPStan, pre-commit, release-please, MIT) raises the floor on quality but not on availability. If Symfony endpoints are revenue-bearing, the fork remains plan, not insurance.
Scaling. Precognition roughly doubles request volume on opted-in validated endpoints while removing controller/DB work per rejected request — but only on the short-circuit path. Endpoints using the validate-only path still execute the controller, so the cost model is closer to "validate twice" than "skip the expensive part." Net benefit is favorable for write-heavy forms mapped to request DTOs, unfavorable for cheap endpoints or controllers with pre-validation work. Exclude precognitive requests from rate-limit accounting or give them a separate budget.
Failure modes.
Ramp-up. For a Symfony developer: half a day for the happy path; add a day to understand the two-listener split, opt-in semantics, and listener priorities. For a Laravel developer: near-zero conceptual ramp-up (it mirrors native Precognition), real ramp-up on Symfony kernel events and exception listeners if they must debug or fork. Document the two-stack split explicitly — and the short-circuit vs. validate-only distinction — or engineers will assume the native middleware covers Symfony routes and that the controller never runs.
How can I help you explore Laravel packages today?