Download the PHP package geekset/octane-doctor without Composer
On this page you can find all versions of the php package geekset/octane-doctor. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download geekset/octane-doctor
More information about geekset/octane-doctor
Files in geekset/octane-doctor
Package octane-doctor
Short Description Octane readiness scanner for Laravel: detect long-lived worker risks, explain each finding, and gate CI on new ones.
License MIT
Homepage https://github.com/octane-doctor/octane-doctor
Informations about the package octane-doctor
Octane Doctor looks at an existing Laravel application, reports patterns that tend to break under long lived workers, and explains each finding in terms a developer can act on.
It is built for teams who already have a real codebase. The default rules are conservative on purpose. The package favours a small set of high signal checks over a wide net of guesses.
What it can do
- Detect common Octane risk patterns in Laravel code (mutable static state, request scoped objects stored on long lived services, request and auth helpers used in singleton constructors, container instances cached on services, missing Octane configuration).
- Explain why each finding matters under Octane and how to fix it.
- Produce JSON output that fits into CI pipelines.
- Snapshot today's findings into a baseline so a team can adopt the scanner gradually and fail CI only on new findings.
What it does not do
- Guarantee that an application is Octane safe. Readiness is a risk signal, not a certificate.
- Replace load testing, profiling, or production validation.
- Automatically fix issues. The MVP focuses on accurate findings and useful remediation text. Automated rewrites are deliberately out of scope.
- Understand arbitrary domain logic. Custom rules cover patterns the built in rule set cannot know about.
Example output
Two contrived classes:
Run the scanner:
What the developer sees in the terminal:
Severity badges (HIGH red, MEDIUM yellow, LOW blue, INFO grey) are coloured in the actual terminal output.
Installation
The package self registers via Laravel's package discovery. Publish the config when you want to customise it:
Supported versions
- PHP 8.2, 8.3, 8.4, 8.5
- Laravel 10.x, 11.x, 12.x, 13.x
PHP 8.2 is the floor because the package relies on readonly classes throughout the model. Laravel Octane itself requires PHP 8.2 on its current major, so this matrix matches the real ecosystem support window for the framework this package exists to protect.
Quick start
Run a scan against the configured paths (app/ and config/ by default):
You will see one block per finding, including the severity, rule id, file location, summary, why it matters, and a remediation hint. The command exits with a non zero status when any finding meets the configured severity threshold.
JSON output
The JSON document is schema versioned and stable across point releases:
File paths in the JSON output are relative to the application's base path so a baseline produced on a developer machine matches the one CI produces. The warnings array is empty on a healthy run and lists structured {code, message, path} entries when something is off, for example a configured scan path that no longer exists.
Severity threshold
--fail-on overrides the fail_on value in config/octane-doctor.php.
Baseline workflow
Most legacy applications have findings on day one. The baseline command records the current set of findings as already acknowledged so future scans only react to new ones.
The baseline path defaults to storage/app/octane-doctor-baseline.json and can be overridden via octane-doctor.baseline in config or --path on the command. Commit the baseline so CI sees the same view as developers locally.
Pass --no-baseline to ignore the baseline for an audit run:
Inspecting rules
List every registered rule (built in plus anything in custom_rules):
The output is a terse table of id, severity, category, risk class, and title. Pass --format=json for a stable machine-readable shape that fits into a CI annotation step.
When you want the full picture for one rule, look it up by id:
Output covers the title, severity, category, risk class, why it matters, remediation, and concrete examples that show a flagged form versus a safe form of the pattern.
For tight iteration on a single rule, scope a scan to that rule alone:
--rule exits non-zero with a hint to rules:list when the id is unknown, so an out of date CI invocation fails loudly instead of silently scanning nothing.
Configuration
config/octane-doctor.php:
To disable a built in rule, copy the default rules list and remove the entry you do not want.
Suppressing findings
Use octane-doctor.ignore for permanent suppressions that should never be reported again. Each entry is matched against both the rule id and the finding fingerprint:
The baseline workflow above is the right choice when you want to acknowledge today's findings and surface new ones. The ignore list is the right choice when you have already decided a pattern is acceptable for your codebase.
Built in rules
| Rule id | Severity | Category | Risk class | What it flags |
|---|---|---|---|---|
mutable-static-state |
medium | static-state | data-leak | Mutable static class or trait properties. |
risky-helpers-in-constructor |
medium | request-state | data-leak | Calls to request(), auth(), session(), or the matching facades inside a class constructor. |
request-context-as-property |
high | request-state | data-leak | Properties typed as Request, the auth guard, Route, or Session on long lived services. |
container-as-property |
medium | container-lifecycle | request-scope-misuse | The container or Application stored as an instance property. |
request-in-singleton |
high | singleton-safety | data-leak | Singleton bound services whose constructor accepts a request scoped framework object. |
suspicious-singleton-name |
medium | singleton-safety | data-leak | Singleton bindings whose class name implies per-request state (CurrentUser, TenantContext, etc). |
octane-config-check |
info / low | configuration | request-scope-misuse | Octane not installed, or installed but config/octane.php not published. |
category groups rules by the subject area they inspect; risk_class answers "what kind of damage if this rule is violated under a long-lived worker". The two axes are independent: filter by category to triage by code area, group by risk class for ticketing and onboarding briefs.
Each rule contains a per dispatch and per request safe list so events, mailables, notifications, form requests, and controllers are not flagged for patterns that are documented Laravel idioms in those contexts.
Custom rules
Custom rules cover patterns the shipped rule set cannot know about, for example a project-specific tenant context wrapper or a base class your team treats as long-lived. Implement OctaneDoctor\Rules\Rule and register the class in octane-doctor.custom_rules.
The example below flags any singleton binding to App\Tenancy\TenantContext because the team that wrote it decided the class is always per-request. It walks the host application's container bindings, so the rule does not need to parse files.
Register the rule in config:
Custom findings flow through the same fingerprint, baseline, ignore list, sorting, and CLI/JSON output as the built in rules.
For rules that inspect source code instead of container bindings, implement OctaneDoctor\Rules\AstVisitingRule instead. The Scanner walks every configured path once and runs every AST rule's visitor inside a single NodeTraverser pass, so the rule count does not multiply file IO. Build your visitor in buildVisitor() and drain accumulated state into findings inside findingsFor(). The shipped MutableStaticState rule is a worked example.
CI usage
The minimum viable CI step is one command:
For staged rollouts, capture the baseline, commit it to the repo, then have CI run the same octane-doctor:scan command. Anything new becomes a failing build. Anything already baselined stays quiet.
Known limitations
The scanner is conservative by design. A few caveats worth knowing about up front:
- Heuristic, not a proof. Rules detect patterns that tend to break under Octane, not patterns that always do. A passing scan is a useful signal, not a certificate. Pair it with load testing and the official Octane documentation before declaring an application Octane-safe.
- No automated fixes. Every finding ships with a remediation hint. There is no
--fixflag and no plan for one until the scanner has earned more trust on a wider variety of codebases. Getting the findings right is a prerequisite for trusting an automatic rewrite, and an early auto fix would damage that trust on the first false positive. - No deep package compatibility audit. The scanner does not maintain a database of "package X is or is not Octane-safe". It walks bindings from your application's container at scan time and reports patterns, regardless of which package registered them.
- Source paths are filtered, container paths are too. Configured scan paths apply to AST-based rules (the file walkers) and to container-walking rules (
request-in-singleton,suspicious-singleton-name) alike. A binding whose concrete class lives outside every configured path is skipped, so a scope ofapp/will not report on vendor classes. - PHP 8.1 is not supported. The package relies on
readonlyclasses throughout its value objects. See the Supported versions section for the full matrix.
Development
See CONTRIBUTING.md for the full development workflow.
Security
Report security issues privately. See SECURITY.md for the supported versions matrix and reporting instructions.
Contributing
See Code of Conduct.
License
The MIT License (MIT). See LICENSE.md.
All versions of octane-doctor with dependencies
illuminate/contracts Version ^10.0||^11.0||^12.0||^13.0
nikic/php-parser Version ^5.0
nunomaduro/termwind Version ^1.15||^2.0
spatie/laravel-package-tools Version ^1.16
symfony/finder Version ^6.0||^7.0