Harden framework contracts and request-scoped state#431
Conversation
Establish a reusable package-by-package process for auditing coroutine safety, worker-lifetime state, resource ownership, liveness, native boundaries, test isolation, and hot-path performance across every framework package. Track the 71-package run through a compact operating plan and a separate findings ledger so post-compaction context restoration remains bounded as completed-package history grows. Include lower-level-first ordering, cross-package revalidation, evidence and anti-overengineering gates, owner approval boundaries, validation and review workflows, and mandatory pre-commit summaries. Remove the superseded package coroutine-safety guide after carrying its durable taxonomy and remediation lessons into the new source of truth.
Define upstream deprecation relative to the framework or package being ported, not one of its transitive dependencies. This prevents dependency-level deprecations from being mistaken for Laravel API deprecations when Laravel intentionally retains and supports a wrapper.
Declare the external interfaces inherited by the standalone contracts package and document its upstream sources. Add metadata coverage that loads every external parent interface through the split package dependencies, preventing a subtree release from relying accidentally on the monorepo root.
Replace incomplete console, container, and foundation signatures with evidence-backed native types and update every concrete implementation. Normalize the supported resolveCommands input shapes at their shared boundary, retain Laravel's live add wrapper, and cover scalar, array, and variadic command registration without accepting misleading nested arrays.
Express the real model, value, and caster return types in the Eloquent casting contracts and align every implementation and fixture. The narrower contracts make invalid caster implementations visible to static analysis while preserving the full set of values accepted and returned by the runtime casting pipeline.
Add the missing native return types to the JSON schema, once-hash, and validation contracts and update their concrete test surfaces. These signatures now describe the behavior already required by callers, removing mixed and implicit returns without narrowing supported application behavior.
Describe the native error and lifecycle behavior of Engine channels, sockets, HTTP clients, servers, signals, and WebSocket primitives with accurate contract documentation. Correct coroutine creation diagnostics at the shared boundary and add deterministic coverage both inside and outside coroutine context so failures remain actionable in either execution mode.
Port Laravel's current ShouldBeDiscovered contract and filter listeners that explicitly opt out of automatic discovery. Include representative listener fixtures, discovery regressions, and public documentation so applications can keep selected listeners available for manual registration without changing the discovery policy for their directory.
Rename the inherited handshake and process symbols to standard English spellings across contracts, implementations, event names, consumers, exceptions, and tests. Hypervel 0.4 has no compatibility burden, so the incorrect public names are removed outright instead of retaining aliases that would permanently duplicate the API.
Remove Request::get(), which combines route attributes and request input and is no longer part of Laravel's recommended request API. Migrate framework callers and tests to the explicit input source, document the intentional omission, and leave no throwing compatibility tombstone so static analysis catches future accidental use.
Remove UrlGenerator::forceRootUrl() in favor of Laravel's supported useOrigin() API. Update the focused coverage and record the intentional omission so future upstream ports preserve the modern surface instead of restoring a compatibility alias.
Remove Middleware::validateCsrfTokens() and keep preventRequestForgery() as the single supported configuration API. Update the matching upstream test location and package differences note so future ports recognize that the alias was omitted deliberately rather than missed.
Remove the deprecated database-inspection forwarding methods and the migration generator's obsolete fullpath option. Delete the now-unused Composer dependency from MigrateMakeCommand, update its tests, and document the supported schema and migration APIs so no dead compatibility wiring remains.
Mark Gate policy, ability, callback, and class-resolution mutators as boot-time configuration surfaces. The warnings make their worker-wide lifetime explicit for long-running Swoole applications without changing runtime behavior or adding checks to authorization hot paths.
Treat configured Email, File, and Password defaults as worker-lifetime prototypes and return an isolated clone for each resolution. Clone nested executable rules, reject callbacks that return the wrong rule family, and reset Email's static callback with the rest of its state. Regression coverage exercises mutation, nested rules, callable defaults, concurrent requests, invalid results, and reset behavior.
Move session validation errors out of the worker-singleton view factory and into a minimal coroutine-local request overlay. Compose global, request, and per-view data once at render time with explicit precedence, restore nested scopes in finally blocks, and remove the singleton mutation that allowed concurrent requests to observe each other's errors.
Type the filesystem factory and manager construction path as Filesystem and accept the enum disk names already supported by the implementation. Validate custom creator results once before caching or publication, turning an eventual unrelated method failure into an immediate boundary error without adding work to resolved-disk operations.
Create Eloquent model identifiers only for objects the restoration path can actually reconstruct, leaving custom queue-contract objects to normal PHP serialization. Resolve morph-map aliases before every collection restoration use so morph-mapped Eloquent collections follow the same correct path as single models. Add regressions for custom entities, custom collections, relation stripping, and morph-mapped collections.
Capture the verified contracts work unit, its shared validation, view, filesystem, and queue findings, regression coverage, performance assessment, and completed review state. Mark contracts complete in the framework audit and adopt one branch and pull request per work unit. Keep the ledger decision-focused by matching each work-unit heading to its pull-request title without duplicating repository links or commit history.
|
Warning Review limit reached
Next review available in: 30 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe change set adds a coroutine-state audit plan and ledger, tightens public contracts, removes deprecated APIs, corrects event and process naming, hardens filesystem, queue, and validation behavior, and introduces request-scoped view data with supporting tests. ChangesFramework audit and contract alignment
Estimated code review effort: 4 (Complex) | ~60 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR addresses three categories of shared-state hazards in Hypervel's long-lived Swoole worker model and cleans up deprecated upstream APIs for the 0.4 release. The key architectural fixes are correct, well-tested with concurrent-coroutine regression coverage, and add no new per-request locks or clones beyond what the stated goals require.
Confidence Score: 5/5Safe to merge. All three architectural changes are correctly bounded to their owning surfaces with no new shared state introduced. The concurrent-coroutine tests for both view isolation and validation-default isolation prove the fixed behaviors under real interleaving. The morph-map collection fix is covered by a new integration test. Spelling corrections and deprecated API removals are atomic across contracts, implementations, and callers. No incorrect logic, missing cleanup, or unsafe state mutation was found in any changed path. No files require special attention. The RequestSharedData + ShareErrorsFromSession pair and the three validation-rule default() methods are the highest-impact changes and are covered by parallel-coroutine regression tests. Important Files Changed
Reviews (2): Last reviewed commit: "Remove a stale migration autoload commen..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/Validation/ValidationDefaultRuleIsolationTest.php (1)
1-141: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winAdd cleanup for
PasswordandtestInvalidCallableResultIsRejected()can leavePassword::$defaultCallbackpointing at the wrong type and pollute later tests. AddtearDown()to callPassword::flushState()andEmail::flushState().♻️ Suggested cleanup
class ValidationDefaultRuleIsolationTest extends TestCase { + protected function tearDown(): void + { + parent::tearDown(); + + Password::flushState(); + Email::flushState(); + } + public function testConfiguredDefaultsAreClonedBeforeMutation(): void🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/Validation/ValidationDefaultRuleIsolationTest.php` around lines 1 - 141, Add a tearDown() method to ValidationDefaultRuleIsolationTest that calls Password::flushState() and Email::flushState(), ensuring configured defaults and callbacks are reset after every test.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/contracts/composer.json`:
- Line 33: Remove the "monolog/monolog" dependency from the contracts package
requirements in composer.json, leaving the existing psr/log dependency and all
other package requirements unchanged.
In `@src/contracts/src/JsonSchema/JsonSchema.php`:
- Around line 8-47: Add hypervel/json-schema as a direct dependency in
src/contracts/composer.json so the JsonSchema contract’s imported and returned
Hypervel\JsonSchema\Types classes are available when the contracts package is
installed independently.
In `@src/database/src/Console/Migrations/MigrateMakeCommand.php`:
- Around line 36-46: Update the stale comment near writeMigration() to remove
the obsolete claim that the framework dumps autoload or registers migrations
through class loaders. Keep the comment aligned with writeMigration()’s actual
behavior: creating the migration file and reporting the result.
---
Outside diff comments:
In `@tests/Validation/ValidationDefaultRuleIsolationTest.php`:
- Around line 1-141: Add a tearDown() method to
ValidationDefaultRuleIsolationTest that calls Password::flushState() and
Email::flushState(), ensuring configured defaults and callbacks are reset after
every test.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7884f398-2519-4ce1-a260-ac2f6f3c3dab
📒 Files selected for processing (106)
AGENTS.mddocs/ai/package-coroutine-safety-review.mddocs/plans/2026-07-12-framework-coroutine-state-lifecycle-audit-ledger.mddocs/plans/2026-07-12-framework-coroutine-state-lifecycle-audit.mdsrc/auth/src/Access/Gate.phpsrc/boost/docs/events.mdsrc/console/src/Application.phpsrc/container/src/Container.phpsrc/contracts/README.mdsrc/contracts/composer.jsonsrc/contracts/src/Console/Application.phpsrc/contracts/src/Console/Kernel.phpsrc/contracts/src/Container/Container.phpsrc/contracts/src/Database/Eloquent/Castable.phpsrc/contracts/src/Database/Eloquent/CastsAttributes.phpsrc/contracts/src/Database/Eloquent/CastsInboundAttributes.phpsrc/contracts/src/Database/Eloquent/SupportsPartialRelations.phpsrc/contracts/src/Database/ModelIdentifier.phpsrc/contracts/src/Engine/ChannelInterface.phpsrc/contracts/src/Engine/CoroutineInterface.phpsrc/contracts/src/Engine/Http/ClientInterface.phpsrc/contracts/src/Engine/Http/Http.phpsrc/contracts/src/Engine/Http/RawResponseInterface.phpsrc/contracts/src/Engine/Http/ServerFactoryInterface.phpsrc/contracts/src/Engine/Http/ServerInterface.phpsrc/contracts/src/Engine/Http/V2/ClientFactoryInterface.phpsrc/contracts/src/Engine/Http/V2/ClientInterface.phpsrc/contracts/src/Engine/Http/V2/RequestInterface.phpsrc/contracts/src/Engine/Http/V2/ResponseInterface.phpsrc/contracts/src/Engine/Http/Writable.phpsrc/contracts/src/Engine/SignalInterface.phpsrc/contracts/src/Engine/Socket/SocketFactoryInterface.phpsrc/contracts/src/Engine/Socket/SocketOptionInterface.phpsrc/contracts/src/Engine/SocketInterface.phpsrc/contracts/src/Engine/WebSocket/FrameInterface.phpsrc/contracts/src/Engine/WebSocket/ResponseInterface.phpsrc/contracts/src/Engine/WebSocket/WebSocketInterface.phpsrc/contracts/src/Events/ShouldBeDiscovered.phpsrc/contracts/src/Filesystem/Factory.phpsrc/contracts/src/Foundation/Application.phpsrc/contracts/src/JsonSchema/JsonSchema.phpsrc/contracts/src/Server/OnHandshakeInterface.phpsrc/contracts/src/ServerProcess/ProcessInterface.phpsrc/contracts/src/Support/HasOnceHash.phpsrc/contracts/src/Validation/ValidatesWhenResolved.phpsrc/database/README.mdsrc/database/src/Console/DatabaseInspectionCommand.phpsrc/database/src/Console/Migrations/MigrateMakeCommand.phpsrc/engine/src/Coroutine.phpsrc/filesystem/src/FilesystemManager.phpsrc/foundation/README.mdsrc/foundation/src/Application.phpsrc/foundation/src/Configuration/Middleware.phpsrc/foundation/src/Console/Kernel.phpsrc/foundation/src/Events/DiscoverEvents.phpsrc/http/README.mdsrc/http/src/Request.phpsrc/queue/src/SerializesAndRestoresModelIdentifiers.phpsrc/reverb/src/ReverbServiceProvider.phpsrc/routing/README.mdsrc/routing/src/UrlGenerator.phpsrc/server-process/src/AbstractProcess.phpsrc/server-process/src/Listeners/BootProcessListener.phpsrc/server/src/Event.phpsrc/validation/src/Rules/Concerns/ClonesCustomRules.phpsrc/validation/src/Rules/Email.phpsrc/validation/src/Rules/File.phpsrc/validation/src/Rules/Password.phpsrc/view/src/Concerns/ManagesEvents.phpsrc/view/src/Factory.phpsrc/view/src/Middleware/ShareErrorsFromSession.phpsrc/view/src/RequestSharedData.phpsrc/view/src/View.phpsrc/websocket-server/src/Exceptions/WebSocketHandshakeException.phpsrc/websocket-server/src/HandshakeHandler.phpsrc/websocket-server/src/Server.phptests/Console/ConsoleApplicationResolveTest.phptests/Contracts/Database/ModelIdentifierTest.phptests/Contracts/PackageMetadataTest.phptests/Contracts/Telescope/TelescopeTagTest.phptests/Database/DatabaseEloquentModelTest.phptests/Database/DatabaseMigrationMakeCommandTest.phptests/Database/EloquentModelCustomCastingTest.phptests/Database/Fixtures/TestCast.phptests/Engine/CoroutineNonCoroutineTest.phptests/Engine/CoroutineTest.phptests/Filesystem/FilesystemManagerTest.phptests/Foundation/Configuration/MiddlewareTest.phptests/Foundation/Http/Middleware/ConvertEmptyStringsToNullTest.phptests/Foundation/Http/Middleware/TransformsRequestTest.phptests/Foundation/Http/Middleware/TrimStringsTest.phptests/Http/HttpRequestTest.phptests/Integration/Database/MariaDb/EloquentCastTest.phptests/Integration/Database/MySql/EloquentCastTest.phptests/Integration/Foundation/DiscoverEventsTest.phptests/Integration/Foundation/Fixtures/EventDiscovery/ShouldBeDiscoveredListeners/RegisteredListener.phptests/Integration/Foundation/Fixtures/EventDiscovery/ShouldBeDiscoveredListeners/SkippedListener.phptests/Integration/Queue/ModelSerializationTest.phptests/Queue/SerializesModelsTest.phptests/Routing/RoutingUrlGeneratorTest.phptests/ServerProcess/AbstractProcessTest.phptests/ServerProcess/BootProcessListenerTest.phptests/Validation/ValidationDefaultRuleIsolationTest.phptests/Validation/ValidationPasswordRuleTest.phptests/View/RequestSharedDataTest.phptests/View/ViewTest.php
💤 Files with no reviewable changes (1)
- docs/ai/package-coroutine-safety-review.md
Migration creation no longer invokes Composer or dumps autoload files, but the surrounding comment still described that removed behavior. Delete the obsolete comment instead of replacing it with narration of the self-explanatory writeMigration call.
|
@coderabbitai Thanks for the review. I traced all four findings through the split-package graph and the test lifecycle. One change was required: f7818f2 removes the stale migration comment that still claimed The other three findings are intentionally unchanged:
The focused migration command test passes, the diff check is clean, and the follow-up has completed review. |
|
Tip For best results, initiate chat on the files or code changes. |
Summary
This PR establishes a trustworthy contracts boundary for Hypervel 0.4 and fixes the shared-state problems exposed while tracing those contracts through their concrete implementations.
The previous architecture had three related weaknesses. Several public contracts did not describe their actual runtime values. The standalone contracts package depended implicitly on packages available only through the monorepo root. And a few Laravel-derived configuration patterns stored request-mutated objects or request data in worker-lifetime state, which is unsafe when sibling requests share a Swoole worker.
This change corrects those problems at their owning boundaries:
For more details, see:
docs/plans/2026-07-12-framework-coroutine-state-lifecycle-audit.mdContract integrity
The contracts subtree is released independently, so it must not rely on root-only dependency declarations. Its package metadata now declares every external parent interface it extends, and focused metadata coverage verifies that those dependencies remain present.
Native signatures now follow the values accepted and returned by the full caller/implementer graph. This is intentionally narrower than a mechanical typing pass: each changed signature was carried through concrete implementations and fixtures, while optional packages that appear only in lazy type positions remain optional.
The Engine contracts also document the native false/error and cleanup behavior that callers must handle. Coroutine creation failures now produce clear diagnostics both inside and outside coroutine context.
Long-lived worker state
Laravel normally gets a fresh object graph for each request. Hypervel does not. A singleton view factory and static validation defaults therefore need explicit ownership rules.
Session errors now live in a small coroutine-local request overlay. The render path composes worker-global shared data, request data, and per-view data once, preserving the expected precedence without cloning the factory or adding locks. Nested and exceptional middleware scopes restore the previous overlay in
finally.Configured validation defaults remain boot-time configuration, but the configured object is now a prototype. Each resolution clones the rule and its nested executable rules before validation can inject data, attach a validator, collect failures, or apply fluent mutations. This keeps configuration cheap and worker-global while making each validation independent.
Construction and serialization boundaries
The filesystem factory now accepts the disk-name forms already supported by the manager and returns
Filesystemthroughout. Custom creators are checked once at construction, before an invalid value can enter the manager cache. Resolved disk operations pay no additional cost.Queue model identifiers are now created only for Eloquent models and Eloquent collections, because those are the values the restoration path knows how to rebuild. Other queue-contract objects use normal PHP serialization. Collection restoration resolves morph aliases before model construction and pivot checks, matching the existing single-model behavior.
API cleanup
Hypervel 0.4 has no compatibility burden, so deprecated aliases and misspelled low-level APIs are removed rather than preserved indefinitely. The removals are limited to APIs deprecated by the direct upstream framework, not methods merely backed by a deprecated dependency API that Laravel still supports.
This removes the request input mixer, forced-root URL alias, CSRF configuration alias, deprecated database inspection forwarders, the obsolete migration
--fullpathpath, and its dead Composer dependency. Handshake and process spellings are corrected across contracts, implementations, consumers, events, exceptions, and tests. Laravel's live consoleadd()wrapper remains intact.Performance
The hot-path changes are deliberately bounded:
No request-path locks, new registries, manager clones, recursive object-graph machinery, or compatibility shims are introduced.
Testing
Regression coverage exercises standalone contracts metadata, all changed contract implementations, listener discovery opt-outs, Engine diagnostics, configured-rule isolation and concurrent use, request-shared view-data interleaving and restoration, filesystem creator validation, non-Eloquent queue object round trips, morph-mapped Eloquent collection restoration, and supported command registration forms.
The complete formatting, static-analysis, and parallel test gate passes.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Breaking Changes