Skip to content

Add Hypervel Doctor - #69

Merged
binaryfire merged 45 commits into
0.4from
feature/doctor
Oct 22, 2026
Merged

binaryfire merged 45 commits into
0.4from
feature/doctor

Conversation

@binaryfire

@binaryfire binaryfire commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

This adds hypervel/doctor, a port of Laravel Doctor for inspecting application configuration and infrastructure from the command line. It includes the doctor command, 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.

  • Database checks use the registered connection factory and driver-neutral connection API, including custom drivers that do not use PDO. Built-in split connections check each selectable read and write record, and explicit role aliases check their selected role. SQLite repairs use the effective endpoint path. Migration checks include registered paths and respect the configured migration connection.
  • Cache checks perform a real write/read/delete round trip. Failover checks distinguish a working service with unavailable backups from a service that cannot retain data. Nested cache and queue configurations are followed without probing every configured connection.
  • PHP and extension checks read the installed dependency requirements, including version constraints and package providers or replacements. The Swoole minimum stays in Composer metadata. Redis checks use shared requirements and fetch server information only when active features need it.
  • File checks honor relocated application paths, the selected environment file, and configured public storage links. Git checks distinguish tracked files from effectively ignored files, including literal filenames and rules inherited from a parent repository.
  • Repairs preserve existing files, conflicting storage links, and healthy directory permissions. Cache-table creation is offered only for layouts the generator can create, and repairs are checked again before reporting success. --fix does not choose between multiple repair options.
  • Environment repairs rebuild an existing configuration cache and verify the written value in a fresh application process. External environment overrides and application configuration that ignores the setting produce a failed repair rather than an in-memory false success. Normal child-process inheritance is unchanged outside these repairs.
  • Configuration checks preserve the original file and serialization error, including when configuration files declare local variables. Machine output preserves literal markup and backslashes. Composer inspection does not run scripts; explicit Composer repairs keep scripts enabled and have no process timeout.
  • Composer audit distinguishes vulnerable dependencies, configured abandoned-package or filter-list policy failures, and execution errors. Active logging stack discovery accepts the same string, array, and enum channel names as the logging manager.

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:

  • Migration connection and output state is isolated by coroutine. Concurrent migration commands no longer overwrite each other's selected connection, while registered migration paths remain available to all runs.
  • Migration and failover state validates its owning instance, so a reused object ID cannot inherit a released instance's connection, output, or failure history. Replacement failover stores and queues report their own first failure event.
  • Cache and queue managers reject recursive built-in wrapper definitions during construction. Valid shared children, custom drivers, and deferred backup failures keep their existing behavior.
  • RedisRequirements owns 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 --json exposes 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.
  • Explicit --env selects 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.
  • Key generation handles exported assignments and trailing dotenv comments while retaining exact-current-key matching. Missing Beanstalkd tubes report an empty queue, and enum connection names remain usable in queue failover events.
  • Route-list and queue JSON output preserves literal values without console styling.

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 ApplicationTimezoneIsValid and 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

  • Adds the new hypervel/doctor package with a Doctor service, fluent run configuration (only, except, bail, fixUsing, beforeRerun), and result models (DiagnosticResult, FixResult, DiagnosticReport, Link, Status) in src/doctor
  • Ships built-in diagnostics for environment files, app key, debug mode, database/cache/queue/Redis/session/storage reachability, Composer audit/autoload/lock freshness, PHP versions and extensions, migrations, scheduled tasks, and bootstrap caching, many with local-only fixes
  • Adds renderers for CLI, JSON, GitHub Actions annotations, and AI-agent output, plus a doctor command with --format, --fix, --fail-on, and selection options, and a make:diagnostic generator with fixable stubs
  • Honors startup --env arguments during bootstrap even when the app is not in console mode, and forwards --env from config:cache and route:cache subprocesses
  • Fixes coroutine state isolation in FailoverStore, FailoverQueue, Migrator, and DatabaseMigrationRepository via weak-owner references, rejects circular cache/queue failover definitions with InvalidArgumentException, and returns 0 for missing Beanstalkd tube counts
  • Behavioral Change: storage:link/storage:unlink no longer fall back to a default public-storage mapping — apps relying on the implicit default need an explicit filesystems.links entry; invalid doctor environment configuration and circular failover definitions now throw

Macroscope summarized cc2cd7f.

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.
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: hypervel/components-backup/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9fcf4546-8fea-4353-bd6a-9b1c22522ef4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add Hypervel Doctor diagnostics and safe repair workflows

✨ Enhancement 🐞 Bug fix 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add optional Doctor commands and APIs to diagnose active application services and configuration.
• Offer explicit, verified repairs and CLI, JSON, GitHub, and agent-readable reports.
• Isolate concurrent migration state and reject recursive cache and queue definitions.
Diagram

graph TD
  Provider["Package discovery"] --> Command["Doctor command"] --> Run["Diagnostic run"] --> Checks["Selected checks"] --> Services["Active services"]
  Checks --> Report["Result report"] --> Renderers["Output renderers"]
  Run --> Repairs["Approved repairs"] --> Report
Loading
High-Level Assessment

The optional, Composer-discovered package preserves a familiar diagnostic API while using Hypervel's existing managers and connection factories. A separate generic probing framework or startup bypass would add complexity without improving the targeted checks; keeping repairs explicit and outside normal application operations is appropriate.

Files changed (147) +16558 / -95

Enhancement (58) +7477 / -0
DiagnosticMakeCommand.phpGenerate custom diagnostic classes +85/-0

Generate custom diagnostic classes

• Adds the command that creates standard or fixable diagnostic skeletons.

src/doctor/src/Console/DiagnosticMakeCommand.php

DoctorCommand.phpRun diagnostics from Artisan +392/-0

Run diagnostics from Artisan

• Adds filtering, bail and failure thresholds, interactive or deterministic repairs, and four output formats.

src/doctor/src/Console/DoctorCommand.php

diagnostic.fixable.stubTemplate fixable diagnostics +49/-0

Template fixable diagnostics

• Provides a generated diagnostic skeleton with an explicit repair method.

src/doctor/src/Console/stubs/diagnostic.fixable.stub

diagnostic.stubTemplate basic diagnostics +36/-0

Template basic diagnostics

• Provides a generated diagnostic skeleton for application checks.

src/doctor/src/Console/stubs/diagnostic.stub

Fixable.phpDefine the repair contract +19/-0

Define the repair contract

• Specifies how a diagnostic applies a selected fix to an outcome.

src/doctor/src/Contracts/Fixable.php

Diagnostic.phpProvide the diagnostic base API +244/-0

Provide the diagnostic base API

• Defines check contracts, named messages, status helpers and machine-readable result codes.

src/doctor/src/Diagnostic.php

DiagnosticSelection.phpSelect diagnostics by scope +169/-0

Select diagnostics by scope

• Matches class, group and package selectors while combining inclusion and exclusion rules.

src/doctor/src/DiagnosticSelection.php

DiagnosticSource.phpAttribute diagnostic sources +233/-0

Attribute diagnostic sources

• Resolves package and file metadata by class and caches only that stable attribution.

src/doctor/src/DiagnosticSource.php

ApplicationKeyIsSet.phpCheck application encryption keys +94/-0

Check application encryption keys

• Detects missing application keys and offers an eligible key-generation repair.

src/doctor/src/Diagnostics/ApplicationKeyIsSet.php

BootstrapCacheMatchesEnvironment.phpAssess bootstrap cache usage +112/-0

Assess bootstrap cache usage

• Reports configuration, route and event cache state against local or production expectations.

src/doctor/src/Diagnostics/BootstrapCacheMatchesEnvironment.php

CacheStoreIsReachable.phpProbe active cache storage +339/-0

Probe active cache storage

• Tests a real cache round trip, distinguishes degraded failover and offers viable local store alternatives.

src/doctor/src/Diagnostics/CacheStoreIsReachable.php

ComposerAuditPasses.phpCheck Composer security audit +109/-0

Check Composer security audit

• Runs an audit and reports dependency advisories or audit failures.

src/doctor/src/Diagnostics/ComposerAuditPasses.php

ComposerAutoloadIsValid.phpValidate Composer autoloading +96/-0

Validate Composer autoloading

• Checks whether the application's Composer autoload metadata is usable.

src/doctor/src/Diagnostics/ComposerAutoloadIsValid.php

ComposerLockIsFresh.phpCheck lockfile freshness +189/-0

Check lockfile freshness

• Compares Composer manifests and lock information to flag stale dependency resolution.

src/doctor/src/Diagnostics/ComposerLockIsFresh.php

ConfigurationCanBeCached.phpCheck configuration cacheability +82/-0

Check configuration cacheability

• Detects configuration that cannot safely be compiled into a cache.

src/doctor/src/Diagnostics/ConfigurationCanBeCached.php

ConfigurationFilesCanBeLoaded.phpCheck configuration loading +64/-0

Check configuration loading

• Reports failures when application configuration files are loaded.

src/doctor/src/Diagnostics/ConfigurationFilesCanBeLoaded.php

DatabaseConnectionIsReachable.phpProbe configured database transport +145/-0

Probe configured database transport

• Uses the registered connection factory and driver-neutral API to check database reachability, including custom drivers.

src/doctor/src/Diagnostics/DatabaseConnectionIsReachable.php

DebugModeMatchesEnvironment.phpCheck production debug settings +84/-0

Check production debug settings

• Flags production debug mode and offers an explicit correction.

src/doctor/src/Diagnostics/DebugModeMatchesEnvironment.php

EnvironmentFileExists.phpCheck the selected environment file +106/-0

Check the selected environment file

• Checks the application's actual environment-file path and offers safe local creation when missing.

src/doctor/src/Diagnostics/EnvironmentFileExists.php

EnvironmentFileIsGitIgnored.phpCheck environment-file Git protection +172/-0

Check environment-file Git protection

• Distinguishes tracked from effectively ignored files and verifies any newly added ignore rule.

src/doctor/src/Diagnostics/EnvironmentFileIsGitIgnored.php

FilesystemDisksAreReachable.phpProbe configured filesystem disks +115/-0

Probe configured filesystem disks

• Checks filesystem disk availability and reports inaccessible backing storage.

src/doctor/src/Diagnostics/FilesystemDisksAreReachable.php

MigrationsAreUpToDate.phpCheck pending migrations +119/-0

Check pending migrations

• Uses registered migration paths and the selected migration connection to report unapplied migrations.

src/doctor/src/Diagnostics/MigrationsAreUpToDate.php

PhpVersionSatisfiesComposerRequirement.phpCheck installed PHP constraints +73/-0

Check installed PHP constraints

• Tests the running PHP version against installed packages' Composer requirements.

src/doctor/src/Diagnostics/PhpVersionSatisfiesComposerRequirement.php

PublicStorageLinkExists.phpCheck configured public storage links +213/-0

Check configured public storage links

• Inspects links targeting the public disk and repairs only missing links, leaving conflicts untouched.

src/doctor/src/Diagnostics/PublicStorageLinkExists.php

QueueConnectionIsAsynchronous.phpAssess active queue execution +86/-0

Assess active queue execution

• Reports whether the effective queue connection is suitable for production asynchronous work.

src/doctor/src/Diagnostics/QueueConnectionIsAsynchronous.php

QueueConnectionIsReachable.phpProbe active queue backends +171/-0

Probe active queue backends

• Checks concrete queue connections and distinguishes total failure from reduced failover capacity.

src/doctor/src/Diagnostics/QueueConnectionIsReachable.php

RecommendedPhpExtensionsAreLoaded.phpReport recommended PHP extensions +93/-0

Report recommended PHP extensions

• Identifies missing optional extensions separately from required platform dependencies.

src/doctor/src/Diagnostics/RecommendedPhpExtensionsAreLoaded.php

RedisConnectionsAreReachable.phpProbe active Redis connections +70/-0

Probe active Redis connections

• Checks Redis connections required by active cache, queue and session drivers.

src/doctor/src/Diagnostics/RedisConnectionsAreReachable.php

RedisSupportsConfiguredFeatures.phpCheck Redis feature compatibility +128/-0

Check Redis feature compatibility

• Tests client and server versions only for features used by active services.

src/doctor/src/Diagnostics/RedisSupportsConfiguredFeatures.php

RequiredConfigurationValuesAreSet.phpValidate active-driver settings +298/-0

Validate active-driver settings

• Finds missing settings for the application's selected broadcast, filesystem, logging, mail and queue drivers.

src/doctor/src/Diagnostics/RequiredConfigurationValuesAreSet.php

RequiredPhpExtensionsAreLoaded.phpCheck installed extension requirements +130/-0

Check installed extension requirements

• Evaluates required extensions and version constraints from installed Composer metadata and providers.

src/doctor/src/Diagnostics/RequiredPhpExtensionsAreLoaded.php

ScheduledTasksRequireScheduler.phpCheck scheduled-task execution +46/-0

Check scheduled-task execution

• Advises when configured scheduled tasks need Hypervel's long-running scheduler.

src/doctor/src/Diagnostics/ScheduledTasksRequireScheduler.php

SessionDriverIsReachable.phpProbe active session storage +135/-0

Probe active session storage

• Checks the selected session backend and its required database or Redis resources.

src/doctor/src/Diagnostics/SessionDriverIsReachable.php

SqliteDatabaseExists.phpCheck SQLite database files +118/-0

Check SQLite database files

• Detects missing configured SQLite databases and offers an eligible file-creation repair.

src/doctor/src/Diagnostics/SqliteDatabaseExists.php

StorageIsWritable.phpCheck application storage permissions +177/-0

Check application storage permissions

• Checks relocated storage paths and repairs missing or unwritable directories without disturbing healthy permissions.

src/doctor/src/Diagnostics/StorageIsWritable.php

Doctor.phpCoordinate Doctor diagnostics and fixes +268/-0

Coordinate Doctor diagnostics and fixes

• Registers diagnostic classes, resolves fresh instances, catches ordinary errors and preserves coroutine cancellation.

src/doctor/src/Doctor.php

DoctorServiceProvider.phpRegister Doctor services and checks +98/-0

Register Doctor services and checks

• Installs built-in diagnostics, merges configuration, registers commands and exposes config publishing.

src/doctor/src/DoctorServiceProvider.php

EnvironmentMode.phpResolve Hypervel environment modes +79/-0

Resolve Hypervel environment modes

• Maps configured application environments to local or production diagnostic expectations.

src/doctor/src/EnvironmentMode.php

Doctor.phpExpose the Doctor facade +38/-0

Expose the Doctor facade

• Provides facade access to the registered Doctor service.

src/doctor/src/Facades/Doctor.php

PendingRun.phpManage one diagnostic run +272/-0

Manage one diagnostic run

• Applies selection, bail, observation and fix decisions, then rechecks after approved repairs.

src/doctor/src/PendingRun.php

AgentRenderer.phpRender agent-readable reports +95/-0

Render agent-readable reports

• Formats diagnostic and repair outcomes for agent-oriented command output.

src/doctor/src/Renderers/AgentRenderer.php

CliRenderer.phpRender interactive console results +411/-0

Render interactive console results

• Displays grouped outcomes, remediation and repair confirmations for human users.

src/doctor/src/Renderers/CliRenderer.php

GithubRenderer.phpRender GitHub annotations +103/-0

Render GitHub annotations

• Converts report findings into GitHub Actions annotation output.

src/doctor/src/Renderers/GithubRenderer.php

DiagnosticFixOutcome.phpRepresent a repair outcome +69/-0

Represent a repair outcome

• Associates a diagnostic with its fix result for reporting.

src/doctor/src/Results/DiagnosticFixOutcome.php

DiagnosticOutcome.phpRepresent a diagnostic outcome +107/-0

Represent a diagnostic outcome

• Associates a check with its result and exposes repair eligibility.

src/doctor/src/Results/DiagnosticOutcome.php

DiagnosticReport.phpAggregate versioned diagnostic reports +135/-0

Aggregate versioned diagnostic reports

• Collects check and repair outcomes, computes failure thresholds and supports JSON serialization.

src/doctor/src/Results/DiagnosticReport.php

DiagnosticResult.phpModel diagnostic findings +213/-0

Model diagnostic findings

• Stores status, remediation, details, context and declared fix choices.

src/doctor/src/Results/DiagnosticResult.php

FixResult.phpModel repair results +102/-0

Model repair results

• Stores the status and details of an attempted repair.

src/doctor/src/Results/FixResult.php

Link.phpDefine result documentation links +53/-0

Define result documentation links

• Builds links used in findings and report renderers.

src/doctor/src/Results/Link.php

Message.phpDefine named diagnostic messages +46/-0

Define named diagnostic messages

• Encapsulates summaries, remediation, confirmations and links for reusable result messages.

src/doctor/src/Results/Message.php

Status.phpDefine diagnostic statuses +23/-0

Define diagnostic statuses

• Provides the pass, notice, warning, failure, skip and error states.

src/doctor/src/Results/Status.php

ActiveDrivers.phpTrace active service backends +171/-0

Trace active service backends

• Follows configured cache, queue, logging and mail wrappers to identify resources actually used.

src/doctor/src/Support/ActiveDrivers.php

Composer.phpSupport Composer checks +23/-0

Support Composer checks

• Provides shared Composer-related operations for diagnostics.

src/doctor/src/Support/Composer.php

ComposerJson.phpRead application Composer metadata +125/-0

Read application Composer metadata

• Provides access to the root Composer manifest for dependency diagnostics.

src/doctor/src/Support/ComposerJson.php

Configured.phpNormalize configuration inspection +40/-0

Normalize configuration inspection

• Provides helpers for retrieving configured values and identifying missing keys.

src/doctor/src/Support/Configured.php

Details.phpFormat diagnostic details +42/-0

Format diagnostic details

• Provides shared formatting for missing settings and process output.

src/doctor/src/Support/Details.php

InstalledPackages.phpSnapshot installed platform requirements +108/-0

Snapshot installed platform requirements

• Reads installed Composer requirements and providers per check without retaining worker-lived dependency snapshots.

src/doctor/src/Support/InstalledPackages.php

RedisRequirements.phpCentralize Redis feature minimums +65/-0

Centralize Redis feature minimums

• Owns phpredis, Redis and Valkey requirements shared by diagnostics and test helpers.

src/redis/src/RedisRequirements.php

Bug fix (5) +180 / -11
CacheManager.phpReject recursive cache wrappers +43/-1

Reject recursive cache wrappers

• Detects cycles in built-in stack and failover stores during construction and uses the shared lock-table default.

src/cache/src/CacheManager.php

DatabaseMigrationRepository.phpIsolate migration repository connections +18/-1

Isolate migration repository connections

• Stores the selected migration-table connection per coroutine while retaining non-coroutine behavior.

src/database/src/Migrations/DatabaseMigrationRepository.php

Migrator.phpIsolate migrator invocation state +51/-5

Isolate migrator invocation state

• Moves selected connection and output into per-coroutine state without changing shared registered migration paths.

src/database/src/Migrations/Migrator.php

MigratorState.phpRepresent migrator invocation state +23/-0

Represent migrator invocation state

• Holds the connection and console output associated with a migration invocation.

src/database/src/Migrations/MigratorState.php

QueueManager.phpReject recursive failover queues +45/-4

Reject recursive failover queues

• Checks built-in failover connection graphs during construction without eagerly probing backup availability.

src/queue/src/QueueManager.php

Refactor (7) +34 / -70
CacheTableCommand.phpShare generated cache table defaults +6/-3

Share generated cache table defaults

• Exposes and uses the migration generator's default cache table names.

src/cache/src/Console/CacheTableCommand.php

DatabaseStore.phpOwn the default cache lock table +3/-1

Own the default cache lock table

• Defines the database store's default lock-table name for reuse by the manager and diagnostics.

src/cache/src/DatabaseStore.php

HashFieldExpirationCheck.phpReuse Redis feature requirements +4/-1

Reuse Redis feature requirements

• Reads hash-field expiration minimums from the shared Redis requirements definition.

src/cache/src/Redis/Console/Doctor/Checks/HashFieldExpirationCheck.php

PhpRedisCheck.phpReuse the phpredis minimum +3/-6

Reuse the phpredis minimum

• Replaces a duplicated client-version requirement with RedisRequirements.

src/cache/src/Redis/Console/Doctor/Checks/PhpRedisCheck.php

RedisVersionCheck.phpReuse Redis server requirements +9/-13

Reuse Redis server requirements

• Delegates Redis and Valkey feature-version decisions to RedisRequirements.

src/cache/src/Redis/Console/Doctor/Checks/RedisVersionCheck.php

RequiresHashFieldExpiration.phpShare hash-expiration test requirements +6/-45

Share hash-expiration test requirements

• Replaces duplicated client and server version rules with RedisRequirements.

src/foundation/src/Testing/Concerns/RequiresHashFieldExpiration.php

SessionManager.phpShare the Redis session default +3/-1

Share the Redis session default

• Defines the default Redis connection name for session handling and diagnostics.

src/session/src/SessionManager.php

Tests (65) +7840 / -12
CacheManagerTest.phpTest cache wrapper cycle handling +101/-0

Test cache wrapper cycle handling

• Covers recursive stores, valid shared children and unaffected custom or deferred behavior.

tests/Cache/CacheManagerTest.php

DoctorCommandTest.phpTest shared Redis requirements in cache Doctor +35/-2

Test shared Redis requirements in cache Doctor

• Updates client and server version expectations for the existing Redis checks.

tests/Cache/Redis/Console/DoctorCommandTest.php

DatabaseMigratorIntegrationTest.phpAlign migration integration setup +4/-3

Align migration integration setup

• Moves invocation-owned migration setup into the appropriate coroutine context.

tests/Database/DatabaseMigratorIntegrationTest.php

MigratorCoroutineIsolationTest.phpTest concurrent migrator isolation +179/-0

Test concurrent migrator isolation

• Covers overlapping connections, output, child inheritance, instance independence and failure restoration.

tests/Database/MigratorCoroutineIsolationTest.php

MigratorTest.phpAdapt migrator state tests +2/-4

Adapt migrator state tests

• Adjusts existing assertions to coroutine-local migration invocation state.

tests/Database/MigratorTest.php

ArchTest.phpCheck Doctor package architecture +75/-0

Check Doctor package architecture

• Adds architectural assertions for the new package and its boundaries.

tests/Doctor/ArchTest.php

DiagnosticMakeCommandTest.phpTest diagnostic generation +116/-0

Test diagnostic generation

• Verifies generated standard and fixable diagnostic classes.

tests/Doctor/Feature/Console/DiagnosticMakeCommandTest.php

ApplicationKeyIsSetTest.phpTest application-key checks +149/-0

Test application-key checks

• Covers missing keys, environment handling and repair behavior.

tests/Doctor/Feature/Diagnostics/ApplicationKeyIsSetTest.php

BootstrapCacheMatchesEnvironmentTest.phpTest bootstrap-cache expectations +135/-0

Test bootstrap-cache expectations

• Covers local and production cache combinations.

tests/Doctor/Feature/Diagnostics/BootstrapCacheMatchesEnvironmentTest.php

CacheStoreIsReachableTest.phpTest cache probes and repairs +549/-0

Test cache probes and repairs

• Covers nested failover, degraded capacity, round trips and eligible cache-table repairs.

tests/Doctor/Feature/Diagnostics/CacheStoreIsReachableTest.php

ComposerAuditPassesTest.phpTest Composer audit findings +61/-0

Test Composer audit findings

• Covers security-audit results and execution failures.

tests/Doctor/Feature/Diagnostics/ComposerAuditPassesTest.php

ComposerAutoloadIsValidTest.phpTest Composer autoload checks +112/-0

Test Composer autoload checks

• Covers valid and invalid autoload metadata.

tests/Doctor/Feature/Diagnostics/ComposerAutoloadIsValidTest.php

ComposerLockIsFreshTest.phpTest lockfile freshness checks +210/-0

Test lockfile freshness checks

• Covers Composer manifest and lockfile comparison cases.

tests/Doctor/Feature/Diagnostics/ComposerLockIsFreshTest.php

ConfigurationCanBeCachedTest.phpTest configuration cacheability +77/-0

Test configuration cacheability

• Covers cacheable and unsupported configuration values.

tests/Doctor/Feature/Diagnostics/ConfigurationCanBeCachedTest.php

ConfigurationFilesCanBeLoadedTest.phpTest configuration file loading +70/-0

Test configuration file loading

• Covers successful loading and configuration errors.

tests/Doctor/Feature/Diagnostics/ConfigurationFilesCanBeLoadedTest.php

DatabaseConnectionIsReachableTest.phpTest database transport probes +179/-0

Test database transport probes

• Covers reachable databases, custom transports and connection failures.

tests/Doctor/Feature/Diagnostics/DatabaseConnectionIsReachableTest.php

DebugModeMatchesEnvironmentTest.phpTest debug-mode safeguards +122/-0

Test debug-mode safeguards

• Covers environment-specific findings and correction behavior.

tests/Doctor/Feature/Diagnostics/DebugModeMatchesEnvironmentTest.php

EnvironmentFileExistsTest.phpTest selected environment-file handling +190/-0

Test selected environment-file handling

• Covers relocated files, production behavior and safe creation.

tests/Doctor/Feature/Diagnostics/EnvironmentFileExistsTest.php

EnvironmentFileIsGitIgnoredTest.phpTest effective Git protection +249/-0

Test effective Git protection

• Covers literal filenames, tracked files, inherited ignore rules and verified repairs.

tests/Doctor/Feature/Diagnostics/EnvironmentFileIsGitIgnoredTest.php

FilesystemDisksAreReachableTest.phpTest filesystem disk probes +99/-0

Test filesystem disk probes

• Covers reachable and failing configured disks.

tests/Doctor/Feature/Diagnostics/FilesystemDisksAreReachableTest.php

MigrationsAreUpToDateTest.phpTest migration findings +207/-0

Test migration findings

• Covers registered paths, selected connections and pending migrations.

tests/Doctor/Feature/Diagnostics/MigrationsAreUpToDateTest.php

PhpVersionSatisfiesComposerRequirementTest.phpTest installed PHP constraints +105/-0

Test installed PHP constraints

• Covers PHP requirement matching against Composer metadata.

tests/Doctor/Feature/Diagnostics/PhpVersionSatisfiesComposerRequirementTest.php

PublicStorageLinkExistsTest.phpTest public storage link safety +242/-0

Test public storage link safety

• Covers configured links, conflicts, wrong targets and verified creation.

tests/Doctor/Feature/Diagnostics/PublicStorageLinkExistsTest.php

QueueConnectionIsAsynchronousTest.phpTest queue execution expectations +171/-0

Test queue execution expectations

• Covers synchronous, deferred, null and failover queue behavior across environments.

tests/Doctor/Feature/Diagnostics/QueueConnectionIsAsynchronousTest.php

QueueConnectionIsReachableTest.phpTest queue reachability findings +100/-0

Test queue reachability findings

• Covers configured backends and degraded failover.

tests/Doctor/Feature/Diagnostics/QueueConnectionIsReachableTest.php

RecommendedPhpExtensionsAreLoadedTest.phpTest recommended extensions +51/-0

Test recommended extensions

• Verifies reporting for optional PHP extensions.

tests/Doctor/Feature/Diagnostics/RecommendedPhpExtensionsAreLoadedTest.php

RedisConnectionsAreReachableTest.phpTest active Redis probes +163/-0

Test active Redis probes

• Covers connections used by cache, queues and sessions.

tests/Doctor/Feature/Diagnostics/RedisConnectionsAreReachableTest.php

RedisSupportsConfiguredFeaturesTest.phpTest conditional Redis capabilities +158/-0

Test conditional Redis capabilities

• Covers client and server minimums and avoids unnecessary feature probes.

tests/Doctor/Feature/Diagnostics/RedisSupportsConfiguredFeaturesTest.php

RequiredConfigurationValuesAreSetTest.phpTest active configuration requirements +372/-0

Test active configuration requirements

• Covers nested drivers and required settings, including Mercure credentials.

tests/Doctor/Feature/Diagnostics/RequiredConfigurationValuesAreSetTest.php

RequiredPhpExtensionsAreLoadedTest.phpTest platform-extension resolution +146/-0

Test platform-extension resolution

• Covers installed requirements, version constraints, providers and replacements.

tests/Doctor/Feature/Diagnostics/RequiredPhpExtensionsAreLoadedTest.php

ScheduledTasksRequireSchedulerTest.phpTest scheduler advice +38/-0

Test scheduler advice

• Covers scheduled-task detection and Hypervel scheduler guidance.

tests/Doctor/Feature/Diagnostics/ScheduledTasksRequireSchedulerTest.php

SessionDriverIsReachableTest.phpTest session backend reachability +128/-0

Test session backend reachability

• Covers configured session drivers and failing backing stores.

tests/Doctor/Feature/Diagnostics/SessionDriverIsReachableTest.php

SqliteDatabaseExistsTest.phpTest SQLite file checks +153/-0

Test SQLite file checks

• Covers file detection, configured paths and safe creation.

tests/Doctor/Feature/Diagnostics/SqliteDatabaseExistsTest.php

StorageIsWritableTest.phpTest storage permission repairs +161/-0

Test storage permission repairs

• Covers relocated paths, missing directories and preservation of healthy permissions.

tests/Doctor/Feature/Diagnostics/StorageIsWritableTest.php

DoctorServiceProviderTest.phpTest Doctor command integration +1043/-0

Test Doctor command integration

• Exercises provider registration, command formats, filtering, fixes and exit behavior.

tests/Doctor/Feature/DoctorServiceProviderTest.php

LinkTest.phpTest diagnostic documentation links +64/-0

Test diagnostic documentation links

• Checks link construction for reported findings.

tests/Doctor/Feature/Results/LinkTest.php

ConfiguredTest.phpTest configuration helpers +68/-0

Test configuration helpers

• Covers configured-value normalization and missing-value detection.

tests/Doctor/Feature/Support/ConfiguredTest.php

DiagnosticSelectionTest.phpTest diagnostic selectors +96/-0

Test diagnostic selectors

• Covers matching and composition of class, group and package filters.

tests/Doctor/Feature/Support/DiagnosticSelectionTest.php

DoctorTest.phpTest programmatic Doctor runs +665/-0

Test programmatic Doctor runs

• Covers fresh instances, results, fixes, selection, reruns and cancellation propagation.

tests/Doctor/Feature/Support/DoctorTest.php

EnvironmentModeTest.phpTest environment mapping +58/-0

Test environment mapping

• Covers configured modes, strict unknown environments and invalid mappings.

tests/Doctor/Feature/Support/EnvironmentModeTest.php

InstalledPackagesTest.phpTest installed package snapshots +136/-0

Test installed package snapshots

• Covers Composer requirements, provider metadata and per-check freshness.

tests/Doctor/Feature/Support/InstalledPackagesTest.php

DatabaseDiagnostic.phpProvide database test diagnostic +23/-0

Provide database test diagnostic

• Supplies a database-group fixture for selection and run tests.

tests/Doctor/Fixtures/Diagnostics/DatabaseDiagnostic.php

DefaultMetadataDiagnostic.phpProvide default-metadata fixture +19/-0

Provide default-metadata fixture

• Supplies a diagnostic using inferred name and group metadata.

tests/Doctor/Fixtures/Diagnostics/DefaultMetadataDiagnostic.php

FixableDiagnostic.phpProvide repairable test diagnostic +36/-0

Provide repairable test diagnostic

• Supplies a deterministic fix fixture for Doctor workflow tests.

tests/Doctor/Fixtures/Diagnostics/FixableDiagnostic.php

FixesSharedStateDiagnostic.phpProvide shared-state repair fixture +42/-0

Provide shared-state repair fixture

• Changes shared test state to exercise post-fix reruns.

tests/Doctor/Fixtures/Diagnostics/FixesSharedStateDiagnostic.php

HypervelPackageDiagnostic.phpProvide Hypervel package fixture +31/-0

Provide Hypervel package fixture

• Exercises package attribution and selection.

tests/Doctor/Fixtures/Diagnostics/HypervelPackageDiagnostic.php

LinkedDiagnostic.phpProvide linked finding fixture +43/-0

Provide linked finding fixture

• Supplies results with documentation links for rendering tests.

tests/Doctor/Fixtures/Diagnostics/LinkedDiagnostic.php

LocalOnlyFixableDiagnostic.phpProvide local-only repair fixture +37/-0

Provide local-only repair fixture

• Exercises environment-restricted fix eligibility.

tests/Doctor/Fixtures/Diagnostics/LocalOnlyFixableDiagnostic.php

NoticeDiagnostic.phpProvide notice-status fixture +24/-0

Provide notice-status fixture

• Supplies informational outcomes for reporting tests.

tests/Doctor/Fixtures/Diagnostics/NoticeDiagnostic.php

OptionFixableDiagnostic.phpProvide choice-based repair fixture +43/-0

Provide choice-based repair fixture

• Exercises explicit repair-option selection and refusal.

tests/Doctor/Fixtures/Diagnostics/OptionFixableDiagnostic.php

PackagedDiagnostic.phpProvide packaged diagnostic fixture +31/-0

Provide packaged diagnostic fixture

• Exercises package-scoped selection and attribution.

tests/Doctor/Fixtures/Diagnostics/PackagedDiagnostic.php

PackagedNoticeDiagnostic.phpProvide packaged notice fixture +32/-0

Provide packaged notice fixture

• Combines package attribution with informational results.

tests/Doctor/Fixtures/Diagnostics/PackagedNoticeDiagnostic.php

PassingDiagnostic.phpProvide passing diagnostic fixture +23/-0

Provide passing diagnostic fixture

• Supplies successful outcomes for run and rendering tests.

tests/Doctor/Fixtures/Diagnostics/PassingDiagnostic.php

SharedStateWasFixedDiagnostic.phpProvide post-repair state fixture +27/-0

Provide post-repair state fixture

• Checks state changed by another diagnostic's repair during reruns.

tests/Doctor/Fixtures/Diagnostics/SharedStateWasFixedDiagnostic.php

ThrowingDiagnostic.phpProvide failing-check fixture +24/-0

Provide failing-check fixture

• Exercises conversion of ordinary diagnostic exceptions into error results.

tests/Doctor/Fixtures/Diagnostics/ThrowingDiagnostic.php

ThrowingFixDiagnostic.phpProvide failing-repair fixture +37/-0

Provide failing-repair fixture

• Exercises reporting of repair exceptions.

tests/Doctor/Fixtures/Diagnostics/ThrowingFixDiagnostic.php

ThrowingFixableDiagnostic.phpProvide throwable fixable fixture +34/-0

Provide throwable fixable fixture

• Exercises error handling around a repairable diagnostic.

tests/Doctor/Fixtures/Diagnostics/ThrowingFixableDiagnostic.php

WarningDiagnostic.phpProvide warning-status fixture +25/-0

Provide warning-status fixture

• Supplies warnings for renderer and exit-threshold tests.

tests/Doctor/Fixtures/Diagnostics/WarningDiagnostic.php

TestCase.phpBootstrap Doctor feature tests +66/-0

Bootstrap Doctor feature tests

• Provides shared setup and fixture support for the Doctor suite.

tests/Doctor/TestCase.php

FoundationConfigTest.phpCheck framework defaults +13/-0

Check framework defaults

• Asserts cache-related defaults agree with their owning definitions.

tests/Foundation/FoundationConfigTest.php

RequiresHashFieldExpirationTest.phpTest shared Redis test requirements +20/-1

Test shared Redis test requirements

• Checks the test helper against centralized client and server minimums.

tests/Foundation/Testing/Concerns/RequiresHashFieldExpirationTest.php

QueueManagerTest.phpTest failover queue cycle rejection +96/-0

Test failover queue cycle rejection

• Covers circular definitions, valid shared children and deferred backup failures.

tests/Queue/QueueManagerTest.php

RedisRequirementsTest.phpTest centralized Redis minimums +67/-0

Test centralized Redis minimums

• Covers phpredis, Redis and Valkey hash-field expiration requirements.

tests/Redis/RedisRequirementsTest.php

SessionConfigTest.phpCheck Redis session defaults +4/-0

Check Redis session defaults

• Asserts session configuration agrees with the manager's default connection.

tests/Session/SessionConfigTest.php

PackageMetadataTest.phpCheck Doctor package metadata +4/-2<...

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. SQS outages pass the queue health check ✓ Resolved
Description
QueueConnectionIsReachable::probe() treats constructing an SQS queue connection as a successful
reachability probe. When the default queue uses SQS, that path makes no request to the service, so
an unavailable endpoint or unusable credentials can still produce a passing result.
Code

src/doctor/src/Diagnostics/QueueConnectionIsReachable.php[106]

+            default => Queue::connection($connection),
Evidence
The default probe only resolves a queue object. The SQS connector constructs a client and queue
object without making a request, while the diagnostic returns a passing result if no exception
occurs.

src/doctor/src/Diagnostics/QueueConnectionIsReachable.php[84-107]
src/queue/src/Connectors/SqsConnector.php[22-46]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Constructing an SQS connection does not establish that the service is reachable, but the queue diagnostic reports success after construction.
## Fix Focus Areas
- src/doctor/src/Diagnostics/QueueConnectionIsReachable.php[100-107]
## Recommended Fix
Add an SQS-specific, read-only service request using the configured queue and treat request failures as unreachable. Preserve the existing cancellation handling.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. A race can erase a restored SQLite database ✓ Resolved
Description
SqliteDatabaseExists::fix() checks whether the database is a file, then uses `File::put($database,
'')`, which truncates an existing file. If another process restores or creates the database between
those operations, the repair replaces its contents with an empty file.
Code

src/doctor/src/Diagnostics/SqliteDatabaseExists.php[R100-102]

+        File::ensureDirectoryExists(dirname($database));
+
+        if (File::put($database, '') === false) {
Evidence
The repair's existence check and write are separate operations. The filesystem implementation
delegates put to file_put_contents without exclusive-creation semantics.

src/doctor/src/Diagnostics/SqliteDatabaseExists.php[91-106]
src/filesystem/src/Filesystem.php[209-217]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The SQLite repair uses a truncating write after a separate existence check, leaving a window in which it can erase a newly created database.
## Fix Focus Areas
- src/doctor/src/Diagnostics/SqliteDatabaseExists.php[91-106]
## Recommended Fix
Create the file exclusively rather than calling File::put. If it already exists at creation time, leave it untouched and return the existing-file outcome.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Repair can expose storage directories ✓ Resolved
Description
StorageIsWritable::fix() changes an unwritable existing directory to mode 0775, rather than
adding only the access needed for the application process. Because this repair is eligible in every
environment, doctor --fix can broaden read and traversal permissions on a restricted production
directory.
Code

src/doctor/src/Diagnostics/StorageIsWritable.php[R73-74]

+            if (! $this->canWriteToDirectory($path) && ! @chmod($path, 0775)) {
+                throw new RuntimeException(sprintf('Unable to change permissions for [%s].', $path));
Evidence
The diagnostic marks the failure fixable without an environment restriction, and the repair calls
chmod with a fixed mode. The command automatically approves optionless fixes under --fix.

src/doctor/src/Diagnostics/StorageIsWritable.php[44-54]
src/doctor/src/Diagnostics/StorageIsWritable.php[60-75]
src/doctor/src/Results/DiagnosticResult.php[177-191]
src/doctor/src/Console/DoctorCommand.php[294-297]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The storage repair replaces the mode of an existing directory with 0775, potentially granting access beyond what it previously allowed.
## Fix Focus Areas
- src/doctor/src/Diagnostics/StorageIsWritable.php[64-75]
## Recommended Fix
Do not apply a blanket mode to existing directories. Preserve unrelated permission bits and require an explicit, documented choice for any access-widening repair.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Valid storage links trigger a check error 🐞 Bug ≡ Correctness
Description
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.
Code

src/doctor/src/Diagnostics/PublicStorageLinkExists.php[R133-135]

+        return array_filter(
+            config()->array('filesystems.links'),
+            fn (string $target): bool => $this->normalize($target) === $root,
Evidence
The diagnostic's typed array lookup throws for a missing key. The framework command explicitly
provides a default mapping for that same key.

src/doctor/src/Diagnostics/PublicStorageLinkExists.php[58-65]
src/doctor/src/Diagnostics/PublicStorageLinkExists.php[129-136]
src/foundation/src/Console/StorageLinkCommand.php[55-64]
src/config/src/Repository.php[152-160]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## 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


5. Debug mode returns after a reported repair ✓ Resolved
Description
DebugModeMatchesEnvironment::fix() writes APP_DEBUG=false only to the environment file and
changes the current process's configuration before reporting success. If production supplies
APP_DEBUG=true through its process environment, that value remains in place and takes precedence
when the next process starts.
Code

src/doctor/src/Diagnostics/DebugModeMatchesEnvironment.php[R65-70]

+        if (! is_file($path) || ! is_writable($path)) {
+            return $this->fixFailed('disable-failed')
+                ->withDetails(sprintf('The application environment file [%s] could not be updated.', $path));
+        }
+
+        Env::writeVariable('APP_DEBUG', 'false', $path, overwrite: true);
Evidence
The repair edits a file and the in-memory config but not the process environment. Hypervel builds an
immutable environment repository and loads the environment file at startup; the application config
reads APP_DEBUG from that repository.

src/doctor/src/Diagnostics/DebugModeMatchesEnvironment.php[43-75]
src/support/src/Env.php[134-150]
src/support/src/Env.php[258-278]
src/support/src/DotenvManager.php[20-52]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The debug repair reports success after editing .env even when a process-level APP_DEBUG value will keep debug mode enabled on restart.
## Fix Focus Areas
- src/doctor/src/Diagnostics/DebugModeMatchesEnvironment.php[57-75]
## Recommended Fix
Detect a process-level override before offering or reporting the file repair. When present, return a failure explaining that the deployment environment must be changed instead.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View medium (1)
6. Picking a numeric repair option aborts the run ✓ Resolved
Description
DoctorCommand::chooseFix() spreads fixOptions into a new array, renumbering keys that PHP
coerced from numeric-string option values; casting the selected key back to a string cannot restore
the declared value. When a custom diagnostic uses values such as '1' or '2', the selection can
pass an undeclared option to Doctor::fix(), which throws a LogicException outside its try
block and stops the interactive run.
Code

src/doctor/src/Console/DoctorCommand.php[R333-336]

+            options: [
+                ...$outcome->result->fixOptions,
+                self::SKIP_FIX => $outcome->result->fixDeclineLabel ?? 'Skip — leave unfixed',
+            ],
Evidence
The spread at line 334 renumbers integer keys, while the comment at lines 338–340 accounts for
key-type coercion but not renumbering. The select prompt returns an option’s array key, so casting
that key to a string does not recover the original value; Doctor::fix() rejects values absent from
the diagnostic’s declared options, and its try/catch wraps only the diagnostic’s fix() call.

src/doctor/src/Console/DoctorCommand.php[321-342]
src/doctor/src/Doctor.php[210-235]
src/doctor/src/Console/DoctorCommand.php[331-341]
src/prompts/src/SelectPrompt.php[82-91]
src/doctor/src/Doctor.php[209-221]
src/doctor/src/PendingRun.php[249-268]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`chooseFix()` spreads fix options and renumbers keys coerced from numeric-string values. An interactive selection can therefore pass an undeclared repair option to `Doctor::fix()`.
## Fix Focus Areas
- src/doctor/src/Console/DoctorCommand.php[331-341]
## Recommended Fix
Build the select options with `$outcome->result->fixOptions + [self::SKIP_FIX => ...]` to preserve existing keys. Alternatively, map the selected key back to the original key list before returning it. Add an interactive test using a numeric-string option value.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

7. A missing queue connection shows a raw error 🐞 Bug ☼ Reliability
Description
QueueConnectionIsAsynchronous::check() reads
config()->string("queue.connections.{$connections[0]}.driver"), and that call throws
InvalidArgumentException when queue.default names a connection that is not defined.
Doctor::check turns the exception into a generic error result with the raw exception message, so
the diagnostic's own invalid message and remediation never appear. The sibling
QueueConnectionIsReachable reports the same misconfiguration as unreachable.
Code

src/doctor/src/Diagnostics/QueueConnectionIsAsynchronous.php[62]

+        $driver = $connections[0] === 'null' ? 'null' : config()->string("queue.connections.{$connections[0]}.driver");
Evidence
Repository::string throws when the value is not a string. The PR adds a Configured helper whose
docblock says diagnostics should not throw on misconfiguration, and this line does not use it.

src/doctor/src/Diagnostics/QueueConnectionIsAsynchronous.php[48-66]
src/doctor/src/Support/Configured.php[1-40]
src/config/src/Repository.php[75-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A missing queue connection definition makes `config()->string()` throw. The user then sees a generic error instead of the diagnostic's `invalid` message.
## Fix Focus Areas
- src/doctor/src/Diagnostics/QueueConnectionIsAsynchronous.php[62-62]
## Recommended Fix
Read the driver with `Configured::string(...)`. If the result is null, return `$this->fail('invalid')`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Slow composer audit shows a generic error 🐞 Bug ☼ Reliability
Description
ComposerAuditPasses::check() runs composer audit with ->timeout(10), and when the timeout is
hit, PendingProcess::run() throws ProcessTimedOutException instead of returning a result.
Nothing in the diagnostic catches it, so the audit-failed branch and its remediation never apply.
A slow advisory API therefore shows a raw exception error instead of the audit-specific message.
Code

src/doctor/src/Diagnostics/ComposerAuditPasses.php[R51-56]

+        $process = Process::path(base_path())->timeout(10)->run([
+            ...Composer::command(),
+            'audit',
+            '--format=json',
+            '--no-interaction',
+        ]);
Evidence
The timeout throws from PendingProcess::run, and Doctor::check catches any Throwable and turns it
into an error result. composer audit calls the network, so a 10-second limit can plausibly be hit.

src/doctor/src/Diagnostics/ComposerAuditPasses.php[45-79]
src/process/src/PendingProcess.php[225-236]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
When `composer audit` times out, an exception is thrown and the run reports a generic error instead of `audit-failed`.
## Fix Focus Areas
- src/doctor/src/Diagnostics/ComposerAuditPasses.php[51-56]
## Recommended Fix
Wrap the run in a try/catch for `ProcessTimedOutException` and return `$this->fail('audit-failed')->withDetails('Composer audit timed out.')`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can ask Qodo to dismiss a finding you disagree with, with your reason on record

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/doctor/src/Diagnostics/QueueConnectionIsReachable.php
Comment thread src/doctor/src/Diagnostics/SqliteDatabaseExists.php Outdated
Comment thread src/doctor/src/Diagnostics/StorageIsWritable.php Outdated
Comment on lines +133 to +135
return array_filter(
config()->array('filesystems.links'),
fn (string $target): bool => $this->normalize($target) === $root,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/doctor/src/Diagnostics/DebugModeMatchesEnvironment.php
Comment thread src/doctor/src/Console/DoctorCommand.php Outdated
Comment thread src/doctor/src/Diagnostics/QueueConnectionIsAsynchronous.php
Comment thread src/doctor/src/Diagnostics/ComposerAuditPasses.php
@greptile-apps

greptile-apps Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5 Tier: plus

[High impact] The PR appears safe to merge; no new actionable defect remains from this review.

Summary

Adds optional hypervel/doctor, with selectable diagnostics, explicit repairs, and CLI, JSON, GitHub, and agent output.

  • Hypervel Doctor checks app resources and reports what it finds.
  • Concurrent migration runs keep their own connection and output state.
  • Recursive cache and queue wrappers are rejected during construction.
  • Server commands use the selected environment and keep cached settings in step.
  • JSON commands show selected config values and keep literal output intact.
  • Redis feature version rules now have one shared owner.
  • Queue and storage commands better reflect their configured resources.
  • Test and package metadata changes support the new package and framework behavior.

Reviews (3) · Last reviewed commit: "Document Doctor endpoint checks and audi..." · Reviewed by Greptile

Comment thread src/doctor/src/Diagnostics/DebugModeMatchesEnvironment.php
Comment thread src/doctor/src/Diagnostics/QueueConnectionIsReachable.php
Comment thread src/doctor/src/Diagnostics/RequiredConfigurationValuesAreSet.php Outdated
Comment thread src/doctor/src/Diagnostics/RequiredConfigurationValuesAreSet.php Outdated
Comment thread src/doctor/src/Support/ActiveDrivers.php
Comment thread src/doctor/src/Diagnostics/CacheStoreIsReachable.php Outdated
Comment thread src/doctor/src/Diagnostics/ConfigurationCanBeCached.php
Comment thread src/doctor/src/Diagnostics/StorageIsWritable.php
Comment thread src/doctor/src/Diagnostics/SessionDriverIsReachable.php Outdated
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.
@binaryfire
binaryfire merged commit 85f74c7 into 0.4 Oct 22, 2026
51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant