Repository navigation
Add Hypervel Doctor - #69
Conversation
Keep the shared migrator and migration repository safe when concurrent commands select different database connections. Store invocation state in coroutine context while preserving protected properties, registered migration paths, and normal non-coroutine use. Replicate migrator state for child coroutines and restore the selected connection independently of the ambient database default. Cover overlapping runs, output isolation, child inheritance, independent instances, and failure restoration. Move migration test setup that owns invocation state into the test coroutine.
Validate built-in stack and failover definitions when constructing their repositories, before recursive configuration can exhaust memory. Walk each branch independently so shared children remain valid, custom creators retain control, and unavailable backup stores still fail only when used. Give the database cache and migration generator owning constants for their default table names. Use the same defaults in the manager and verify agreement with shipped configuration, allowing diagnostics to offer table creation only for layouts the generator actually creates.
Check failover connection chains inside the existing connector construction callback. A recursive lazy failover definition now raises an actionable configuration error instead of recursing during queue operations. Inspect only children using the confirmed failover driver. Preserve custom connectors, deferred backup failures, pooled construction, and valid shared children without adding work to queue operations. Add regression coverage for each supported path.
Add RedisRequirements as the shared owner of the baseline phpredis version and hash field expiration requirements. Its pure checks keep version policy consistent across the Redis doctor command, feature diagnostics, and integration test support without performing network requests. Preserve Valkey version precedence and require a known supported server version. Reject unsupported clients before fetching server information, retain existing command presentation and functional probes, and declare the direct Foundation dependency on the Redis package.
Define the Redis session connection fallback on SessionManager and use it when constructing the handler. Diagnostics can now use the same value without duplicating the session connection name or changing database session fallback behavior. Verify that the shipped database configuration provides the canonical Redis session connection.
Port Laravel Doctor with selectable diagnostics, programmatic runs, fix callbacks, diagnostic generation, and human and machine-readable output. Register the optional package through Composer discovery and preserve its extension model while adapting command input, service resolution, and cancellation to Hypervel. Probe actual configured database, cache, queue, session, filesystem, and Redis resources. Honor custom database transports, registered migration paths, nested cache and queue wrappers, configured storage links, and relocated application paths. Keep repairs explicit, preserve conflicting files and healthy directory permissions, and verify repaired resources before reporting success. Check installed dependency PHP and extension constraints, including providers and replacements, without duplicating framework version requirements. Inspect effective Git protection for the selected environment file and apply Redis feature requirements only to active services that need them. Keep startup timezone validation authoritative. Port applicable upstream tests and add regressions for coroutine lifetimes, cancellation, degraded failover, platform metadata, Git filenames, storage repairs, and nondefault configuration. Align Testbench semver metadata with the shared runtime dependency and register optional diagnostic metadata cleanup.
Add the Doctor guide with command usage, result formats, diagnostics, repairs, configuration, and extension examples. Explain maintenance-only repair usage and the scope of Hypervel-specific infrastructure checks. Link the guide from the documentation index and record the environment-mode method name and startup timezone behavior for applications porting Laravel Doctor.
Describe the package architecture, supported upstream surface, runtime adaptations, and framework corrections needed by the diagnostics. Record the reasoning behind migration isolation, shared Redis requirements, platform metadata checks, and repair behavior. Include the verification requirements and approved compatibility differences as a reference for future maintenance.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
PR Summary by QodoAdd Hypervel Doctor diagnostics and safe repair workflows
AI Description
Diagram
High-Level Assessment
Files changed (147)
|
Code Review by Qodo
1.
|
| return array_filter( | ||
| config()->array('filesystems.links'), | ||
| fn (string $target): bool => $this->normalize($target) === $root, |
There was a problem hiding this comment.
4. Valid storage links trigger a check error 🐞 Bug ≡ Correctness
PublicStorageLinkExists::expectedLinks() requires filesystems.links to exist, although the storage:link command supplies a default when that key is absent. An application using that command's default link configuration therefore gets a diagnostic error instead of an inspection of its public storage link.
Agent Prompt
## Issue description
The storage-link diagnostic throws when the links config key is absent, while the corresponding framework command accepts it and uses a default link.
## Fix Focus Areas
- src/doctor/src/Diagnostics/PublicStorageLinkExists.php[129-136]
## Recommended Fix
Read the link configuration with the same default mapping as StorageLinkCommand, then filter the resulting links by the public disk root.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
There was a problem hiding this comment.
filesystems.links is supplied and shallow-merged by Foundation, so normal applications already receive this required configuration. The owning storage commands now use that same required key instead of maintaining a separate fallback. Doctor and storage:link therefore inspect the same configured mapping without duplicating defaults.
[High impact] The PR appears safe to merge; no new actionable defect remains from this review. SummaryAdds optional
Reviews (3) · Last reviewed commit: "Document Doctor endpoint checks and audi..." · Reviewed by Greptile |
Add a read-only accessor for the variable names already tracked by DotenvManager. Preserve entries whose loaded value is null so callers can distinguish file-owned values from genuinely external environment variables. This lets maintenance operations exclude stale inherited dotenv values without changing normal process inheritance or mutating the parent environment. Cover loaded, external, and null-valued keys.
Document that console execution can propagate bootstrap and command exceptions, and that facade dispatch can propagate exceptions from the resolved service. Retain the existing specific exception annotations. These forwarding methods do not limit failures to missing commands or unresolved facades. Accurate annotations let static analysis recognize legitimate cancellation handling without suppressions or runtime changes.
Add an opt-in --json option for configuration sections and individual keys. Emit raw JSON with preserved value types and fail on encoding errors, while keeping normal display and missing-key behavior unchanged. Cover scalar and structured values, console markup, and the public command signature. Fresh application diagnostics can inspect effective configuration without parsing presentation output.
Read explicit --env arguments even when serve or watch boots with HTTP semantics. Keep runningInConsole false so provider and server behavior remains correct. Select the environment filename before the cached-configuration early return, without loading dotenv in cached mode. Environment-file consumers now target the selected file consistently. Cover console and server startup plus cached file selection, and record the deliberate environment-detection difference.
Pass the startup --env argument to the isolated configuration and route cache builders. Preserve ordinary environment inheritance and the existing resolved cache-path and autoloader overrides. Exercise real child processes so a selected environment controls both configuration values and environment-dependent routes, including rebuilding an existing configuration cache.
Skip dotenv reload when the configuration cache file currently exists, and load dotenv when that file has been removed. Keep configuration rebuild and replay behavior intact. Consult the current file rather than the memoized application boot state so cache changes between worker generations take effect. Preserve inherited environment values and cover cache creation and removal after bootstrap.
Set the framework-owned HTTP bootstrap flag only in SERVER state. Forked workers inherit it, while separately executed Artisan processes determine their own console mode instead of inheriting a false flag through the environment. Align Testbench entrypoints and server fixtures, and exercise actual process-driver context propagation from both console and HTTP-mode parents. Preserve normal application environment inheritance.
Recognize an optional export prefix when replacing APP_KEY in the environment file. Continue matching the current key and preserve the protected replacement-pattern hook. Cover plain and exported assignments through the real key-generation command so successful generation persists the new key in either supported dotenv form.
Share tube-stat retrieval across total, pending, delayed, and reserved queue counts. Treat only the protocol response for a nonexistent tube as an empty queue; preserve connection and other server failures. This allows monitoring and read-only reachability checks before a tube has received jobs. Cover all count methods and ensure connection errors remain visible without adding a preliminary network request.
Convert enum connection identifiers to their string values before constructing QueueFailedOver. Preserve null as the default-connection selector. Exercise named, enum, and default connections through a real failover operation while retaining cancellation behavior and the existing event contract.
Expose getPendingMigrations through the existing protected filtering method so exclusions and subclass behavior remain authoritative. Doctor now reports the same pending migrations as the migrator. Run migration repairs through Artisan against the inspected application, retaining registered paths and migration-connection routing. Preserve no-force behavior, command failure details, and cancellation. Replace mocked successful subprocess coverage with a real SQLite migration on the configured schema connection.
Run storage:link through Artisan so repair uses the inspected application configuration. Recheck every expected link after execution, report command failures and exceptions, and preserve cancellation and explicit force requirements. Use the required shipped filesystems.links configuration in both link commands instead of repeating a literal default. Exercise real configured links and retain coverage for conflicts, failed commands, and successful exits that did not create the expected link.
After changing a deployment setting, rebuild an existing configuration cache and verify the effective value in clean child processes. Exclude inherited dotenv-owned variables, preserve external overrides and explicit environment selection, and share the resolved cache path. Keep failures free of secret values and leave normal subprocess inheritance unchanged. Avoid rotating an application key from a stale result. Offer cache-table creation only for the complete conventional missing schema, then verify both tables and cache operations before switching stores. Exercise cached and uncached repairs, sequential cache creation, external overrides, ignored environment settings, partial schemas, and real SQLite migrations.
Normalize mail connection URLs and apply the actual credential precedence for Postmark, Resend, Cloudflare, and Mailgun. Respect merged Syslog handler arguments, default SQS overflow storage, and enum or default wrapper names. Keep missing mailer records from hiding other missing configuration values. Probe lazy SQS and Beanstalkd connections with read-only queue counts, and handle the native session alias as file-backed storage. Cover factory-specific defaults and overrides, missing credentials, wrapper discovery, and connection failures.
Check both console input and Prompts interactivity before offering repairs. Preserve explicit deterministic --fix behavior without allowing piped input to accept a repair implicitly. Keep numeric option keys intact when adding the decline choice. Cover real piped command input, interactive selection, and explicit fixes, using the shared test autoloader path for independently booted processes.
Attribute cache serialization failures by evaluating exported values rather than rejecting objects categorically. Valid stdClass values remain cacheable, and failures identify the actual configuration entry. Pass cancellation through both configuration-file evaluation and export attribution instead of turning it into an ordinary diagnostic failure. Cover valid objects, failing export hooks, and cancellation at the nested execution boundaries.
Pass --no-scripts to the dry-run autoload check because Composer can execute autoload scripts even during a dry run. Keep scripts enabled for the explicit repair. Update the command assertion to preserve strict autoload validation while making inspection free of Composer script side effects.
Use exclusive file creation for the missing-database repair. A database created between inspection and repair is left intact instead of being opened in a truncating mode. Cover an existing file with content and preserve the normal new-file repair behavior.
Add owner access to failing directories without removing existing group, other, or special permission bits. Leave healthy paths unchanged. Include the effective file-cache lock directory alongside its data path and deduplicate shared paths. Cover relocated lock storage and preserved permissions during repair.
Explain worker reloads after deployment changes, the narrow full-restart case for inherited runtime environment values, explicit server --env selection, and JSON configuration output. Document read-only queue probe permissions and the built-in driver semantics assumed by diagnostics. Use a complete directory-check-and-repair example to demonstrate Fixable without duplicating application-key persistence logic or exposing internal repair helpers.
Describe fresh-application verification, factory-aligned diagnostics, in-process migration and storage repairs, and approved startup environment handling. Keep ordinary launcher inheritance and existing reload behavior explicit. Record the remaining full-package audit and publication checks without retaining superseded approaches or review history.
Write JSON, agent JSON, and GitHub annotations without console formatting so literal tags and backslashes survive serialization. Human output keeps its existing styles. Exercise all three formats through the command with decorated and undecorated output, checking both the original diagnostic text and exit status.
Use raw output for route-list JSON while preserving normal CLI formatting. Route names containing markup or escaped angle brackets now remain intact in the serialized result. Cover actual registered routes under terminal and redirected output modes.
Write failed-job lists, monitor results, and worker pause/resume events as raw JSON. Console styles must not alter queue names or introduce terminal escape sequences into these records. Extend existing command tests with literal markup and backslashes, retaining busy-event dispatch, current-command routing, and human-output coverage.
Evaluate each configuration file in a closure, matching the framework loader. Local variables declared by an application configuration file can no longer overwrite the diagnostic iterator and hide the original exception. Retain flat and nested filename attribution, documentation links, and cancellation propagation in the regression coverage.
Remove the default process timeout from lock-file and autoload repairs, matching the framework Composer helper. Dependency resolution, downloads, and repair scripts may legitimately take longer than a minute. Keep inspection timeouts unchanged and verify the repair timeout through the existing recorded-process assertions.
Follow Composer platform normalization before comparing PHP requirements. Strip distribution suffixes only when the original version cannot be parsed, preserving valid development releases and reporting the original version on failure. Cover Ubuntu and Sury version strings, incompatible upper bounds, and development versions that must not be treated as stable releases.
Accept trailing whitespace and comments that dotenv ignores when matching the current APP_KEY assignment. Preserve those bytes during atomic publication while retaining exact-current-key protection. Extend the existing cases for quoted, exported, empty, and CRLF assignments. Different keys, longer prefixed keys, and mismatched quotes remain rejected.
Update the agent-output example to use selected environment paths, its actual documentation link, and consistent outcome counts. Record raw machine output, isolated config evaluation, Composer repair timeouts, PHP distribution normalization, and dotenv suffix preservation in the implementation plan.
Validate coroutine state against a weak reference to its owner before reading a selected connection or console output. PHP can reuse an object ID while its old context entry survives, which allowed a replacement migrator or repository to inherit another instance's connection. Keep non-coroutine state on the instance and preserve independent state when copying coroutine context. Add replacement-instance regressions alongside the existing concurrency, restoration, and output-isolation coverage.
Associate failover history with a weak owner so a new store cannot inherit the failure episode of a released store with the same object ID. This restores the first CacheFailedOver event for each independent instance. Share the history reader and writer between normal failover and operations that visit every store. Preserve recovery, cancellation, listener interruption, and coroutine isolation. Cover releasing and replacing a real failover store.
Store a weak owner with coroutine-local queue failure history and ignore entries belonging to released or different instances. A replacement queue now emits its own first QueueFailedOver event even when PHP reuses an earlier object's ID. Preserve the existing failure-episode and transaction dispatch behavior. Add a regression using independent queue instances, a failing primary, and a working fallback.
Recognize completed Composer JSON reports and distinguish vulnerable dependencies, configured policy failures, and failures to run the audit. Use Composer's exit status rather than reconstructing its abandoned-package or filter-list policy. Show abandoned replacements and filter matches as diagnostic details. Preserve successful report-only audits and cover policy failures, unavailable reports, and missing lock files.
Resolve configured read and write aliases and probe every selectable record of a built-in split connection. Keep base read probes on the normal factory path while preserving explicit read aliases' custom-extension resolution. Report failing roles and record indexes without dumping configuration. Apply bounded PDO timeouts to effective record options without overriding explicit timeouts, masking invalid options, or changing custom transport configuration. Inspect and repair SQLite's effective selected path instead of the base path that read/write configuration can override. Exercise the real factory with healthy and unavailable replicas, role aliases, custom transports, record-owned options, and SQLite file repairs.
Accept comma-separated channel lists, trim channel names, and normalize enum names as LogManager does. Doctor now checks required values for those active channels instead of silently overlooking them. Extend the existing Slack webhook diagnostic coverage with the supported stack forms. Keep inline logger objects outside named configuration discovery.
Remove autoloader environment values that the environment helper does not pass to child processes. The independently booted test application already supplies its autoloader. Keep the explicit autoloader setting on the piped-input subprocess that actually consumes it. Remove redundant base and environment path resets already performed by fixture setup. Preserve real external overrides and cached, uncached, explicit-environment, and piped-input repair coverage.
Describe read/write database coverage and Composer policy findings in the diagnostic overview. Update the implementation plan with the final endpoint selection, driver handling, and instance ownership rules. Keep correctness fixes out of the package's public API differences list and retain the existing custom diagnostic extension model.
This adds
hypervel/doctor, a port of Laravel Doctor for inspecting application configuration and infrastructure from the command line. It includes thedoctorcommand, diagnostic generation, programmatic checks, explicit repairs, and text, JSON, GitHub, and agent output.The package is optional and uses normal Composer discovery. Applications can register their own diagnostics and select checks by class, group, or package.
Behavior
Doctor checks the resources the application actually uses: database connections and migrations, cache stores, queues, sessions, Redis, filesystem disks, storage paths, environment files, and Composer requirements. The port retains the upstream diagnostic and repair APIs while accounting for Hypervel's long-lived workers and configuration.
--fixdoes not choose between multiple repair options.Programmatic runs resolve fresh diagnostic instances and preserve coroutine cancellation. Stable source metadata is cached by diagnostic class; health results and installed dependency snapshots are not retained across runs. Repairs that change deployment files or shared configuration are documented as maintenance operations.
Framework changes
The port also fixes shared behavior used by these checks:
RedisRequirementsowns the client and hash field expiration version requirements used by diagnostics and integration test support. Cache-table and Redis-session defaults also have a single owning definition.config:show --jsonexposes individual configuration values or sections without changing the existing text output.Migrator::getPendingMigrations()exposes the existing pending-migration policy, including exclusions. Dotenv exposes the names it loaded so a caller can distinguish file values from external overrides.--envselects the environment for server-mode commands as well as ordinary console commands. Cache builders forward that selection to their children. Workers skip dotenv reload when a configuration cache exists; the documentation explains when a full server restart is needed for inherited runtime environment values.Network probes stay in the diagnostic commands. Instance ownership checks use weak references without retaining released objects or adding shared registries.
Compatibility
Invalid application timezones already stop Hypervel during startup, before commands run. The port therefore omits
ApplicationTimezoneIsValidand its command workaround. There is no bootstrap bypass.The framework-specific environment helper is named
EnvironmentMode::fromHypervelEnvironment(). The documentation covers this difference, installation, diagnostics, repairs, and custom checks.Verification
Formatting and both PHPStan configurations passed. The full components suite, Testbench package suite, and consumer suites passed, followed by targeted regression checks for the final corrections.
Coverage includes coroutine isolation and cancellation, custom database transports, nested and degraded failover, installed platform metadata and distribution PHP versions, literal Git filenames, relocated paths, storage-link conflicts, factory configuration precedence, and persistent repair verification through fresh application boots. Command regressions exercise machine output with and without terminal colors.
Note
Add Hypervel Doctor package with built-in diagnostics, fixes, and output renderers
hypervel/doctorpackage with aDoctorservice, fluent run configuration (only,except,bail,fixUsing,beforeRerun), and result models (DiagnosticResult,FixResult,DiagnosticReport,Link,Status) in src/doctordoctorcommand with--format,--fix,--fail-on, and selection options, and amake:diagnosticgenerator with fixable stubs--envarguments during bootstrap even when the app is not in console mode, and forwards--envfromconfig:cacheandroute:cachesubprocessesFailoverStore,FailoverQueue,Migrator, andDatabaseMigrationRepositoryvia weak-owner references, rejects circular cache/queue failover definitions withInvalidArgumentException, and returns 0 for missing Beanstalkd tube countsstorage:link/storage:unlinkno longer fall back to a defaultpublic-storagemapping — apps relying on the implicit default need an explicitfilesystems.linksentry; invalid doctor environment configuration and circular failover definitions now throwMacroscope summarized cc2cd7f.