PHPackages                             zidbih/laravel-deadlock - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. zidbih/laravel-deadlock

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

zidbih/laravel-deadlock
=======================

Make temporary Laravel workarounds expire and fail CI when ignored.

v0.6.1(1mo ago)985.4k—7.6%2MITPHPPHP ^8.2CI passing

Since Dec 30Pushed 2w agoCompare

[ Source](https://github.com/medmahmoudhdaya/laravel-deadlock)[ Packagist](https://packagist.org/packages/zidbih/laravel-deadlock)[ RSS](/packages/zidbih-laravel-deadlock/feed)WikiDiscussions main Synced 3d ago

READMEChangelogDependencies (28)Versions (15)Used By (0)

Laravel Deadlock
================

[](#laravel-deadlock)

[![Packagist Version](https://camo.githubusercontent.com/6cf14a2951b45c45dfc7b1cc270190479f23de84eacd560df1be18e35da43bb1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7a69646269682f6c61726176656c2d646561646c6f636b)](https://camo.githubusercontent.com/6cf14a2951b45c45dfc7b1cc270190479f23de84eacd560df1be18e35da43bb1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7a69646269682f6c61726176656c2d646561646c6f636b)[![Packagist Downloads](https://camo.githubusercontent.com/ca1b1bd58ce19558e5823fd794c3758f94f7c7967a49c242268d3c24a6de2627/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7a69646269682f6c61726176656c2d646561646c6f636b)](https://camo.githubusercontent.com/ca1b1bd58ce19558e5823fd794c3758f94f7c7967a49c242268d3c24a6de2627/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7a69646269682f6c61726176656c2d646561646c6f636b)[![Packagist License](https://camo.githubusercontent.com/95603b28f726016c869b93e7cf00b999b1082c32ed5671745a3a65e16e1d8610/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7a69646269682f6c61726176656c2d646561646c6f636b)](https://camo.githubusercontent.com/95603b28f726016c869b93e7cf00b999b1082c32ed5671745a3a65e16e1d8610/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7a69646269682f6c61726176656c2d646561646c6f636b)[![codecov](https://camo.githubusercontent.com/75ca6a4a83f774841a8459ea368eba9666972aa974439ddcd5c10c748fdfee44/68747470733a2f2f636f6465636f762e696f2f67682f6d65646d61686d6f756468646179612f6c61726176656c2d646561646c6f636b2f67726170682f62616467652e737667)](https://codecov.io/gh/medmahmoudhdaya/laravel-deadlock)

Laravel Deadlock helps you track temporary workarounds before they turn into permanent debt.

Annotate classes or methods with an expiration date, then enforce those deadlines in local development and CI without affecting production.

What It Does
------------

[](#what-it-does)

- Scans the codebase for `#[Workaround]` attributes
- Lists workarounds and their status
- Fails CI when a workaround has expired
- Blocks local execution of expired code
- Never enforces in production

---

Installation
------------

[](#installation)

```
composer require zidbih/laravel-deadlock
```

### Compatibility

[](#compatibility)

- Laravel **10, 11, 12** with PHP **8.2+**
- Laravel **13** with PHP **8.3+**

---

Quick Start
-----------

[](#quick-start)

Add `#[Workaround]` to a class or method with a clear description and expiration date.

```
use Zidbih\Deadlock\Attributes\Workaround;

#[Workaround(
    description: 'Temporary bypass for legacy payment gateway',
    expires: '2025-03-01'
)]
class PaymentService
{
    // ...
}
```

`#[Workaround]` supports **classes** and **methods**. Other scopes are ignored.

### When It Expires

[](#when-it-expires)

- **Local Development**: Execution is blocked with an exception
- **CI/CD**: Pipelines fail when running the check command
- **Production**: No effect

---

Runtime Enforcement
-------------------

[](#runtime-enforcement)

### Automatic Enforcement for Controllers

[](#automatic-enforcement-for-controllers)

Controllers are discovered automatically and enforced at runtime.
Add the attribute; no additional calls are required.

```
namespace App\Http\Controllers;

use Zidbih\Deadlock\Attributes\Workaround;

#[Workaround(description: 'Legacy controller awaiting refactor', expires: '2025-06-01')]
final class UserController extends Controller
{
    #[Workaround(description: 'Temporary validation bypass', expires: '2025-02-01')]
    public function store()
    {
        // ...
    }
}
```

### Explicit Enforcement for Services, Jobs, and Commands

[](#explicit-enforcement-for-services-jobs-and-commands)

For non-controller classes, enforcement is explicit by design to avoid hidden runtime behavior.

#### Class-Level

[](#class-level)

```
namespace App\Services;

use Zidbih\Deadlock\Attributes\Workaround;
use Zidbih\Deadlock\Support\DeadlockGuard;

#[Workaround(description: 'Temporary legacy pricing service', expires: '2025-01-01')]
final class PricingService
{
    public function __construct()
    {
        DeadlockGuard::check($this);
    }
}
```

#### Method-Level

[](#method-level)

```
namespace App\Services;

use Zidbih\Deadlock\Attributes\Workaround;
use Zidbih\Deadlock\Support\DeadlockGuard;

final class PricingService
{
    #[Workaround(description: 'Temporary calculation logic', expires: '2025-02-01')]
    public function calculate()
    {
        DeadlockGuard::check($this, __FUNCTION__);

        return 42;
    }
}
```

---

Artisan Commands
----------------

[](#artisan-commands)

### `deadlock:list`

[](#deadlocklist)

List all detected workarounds and their current status.

```
php artisan deadlock:list
```

Example output:

[![List command output](docs/images/list-command-output.png)](docs/images/list-command-output.png)

#### Filters

[](#filters)

- Show only expired workarounds:

```
php artisan deadlock:list --expired
```

- Show only active workarounds:

```
php artisan deadlock:list --active
```

- Show workarounds expiring in **7 days or less**:

```
php artisan deadlock:list --critical
```

#### Summary

[](#summary)

The command includes a summary line by default so totals are visible at a glance.

### `deadlock:check`

[](#deadlockcheck)

Fail CI when one or more workarounds have expired.

```
php artisan deadlock:check
```

If an expired workaround is found, the command exits with **code 1**.

To fail before a workaround expires, use `--fail-within`:

```
php artisan deadlock:check --fail-within=7
```

This fails when a workaround is already expired or expires within the next **7 days**.

For machine-readable output, use JSON mode:

```
php artisan deadlock:check --json
```

Example JSON output:

```
{
  "success": false,
  "expired_count": 1,
  "expired": [
    {
      "description": "Temporary payment gateway workaround",
      "expires": "2025-02-10",
      "location": "PaymentService::process",
      "file": "/app/Services/PaymentService.php",
      "line": 18,
      "class": "PaymentService",
      "method": "process"
    }
  ]
}
```

Example failure output:

```
Expired workarounds detected:

- Temporary payment gateway workaround | expires: 2025-02-10 | PaymentService::process
- Legacy admin controller | expires: 2025-01-31 | AdminController

```

### `deadlock:doctor`

[](#deadlockdoctor)

Diagnose workaround usage that may look valid but will not behave as expected.

```
php artisan deadlock:doctor
```

The doctor command reports unsupported `#[Workaround]` targets, invalid attribute arguments, and missing or incorrect `DeadlockGuard::check(...)` calls for explicit runtime enforcement.

Example output:

[![Doctor command output](docs/images/doctor-command-output.png)](docs/images/doctor-command-output.png)

### `deadlock:extend`

[](#deadlockextend)

Update the `expires` date of an existing `#[Workaround]` attribute in your source code.

It supports three target modes:

- Extend the workaround on a class
- Extend the workaround on one method
- Extend every workaround declared on a class

#### Targeting

[](#targeting)

Use exactly one of these target options:

- `--class=App\Services\PricingService`
- `--controller=TestController`

`--controller` is a shortcut for classes under `App\Http\Controllers`.

Examples:

```
php artisan deadlock:extend --controller=TestController --days=7
php artisan deadlock:extend --controller=Admin\TestController --method=index --months=1
php artisan deadlock:extend --class=App\Services\PricingService --days=7
```

#### How Targeting Works

[](#how-targeting-works)

`--class` only:

- Targets the class-level `#[Workaround]` on that class

`--class` or `--controller` with `--method=...`:

- Targets only the workaround on that method

`--class` or `--controller` with `--all`:

- Targets the class-level workaround
- Targets every method-level workaround declared on that class

#### Date Options

[](#date-options)

You must provide either:

- `--days=N`
- `--months=N`
- `--date=YYYY-MM-DD`

You may combine `--days` and `--months` in the same command.

```
php artisan deadlock:extend --class=App\Services\PricingService --months=1 --days=7
```

`--date` is absolute and replaces the current expiry date directly.

```
php artisan deadlock:extend --class=App\Services\PricingService --date=2026-06-01
```

`--date` cannot be combined with `--days` or `--months`.

#### Examples

[](#examples)

Extend a class-level workaround:

```
php artisan deadlock:extend --class=App\Services\PricingService --days=7
```

Extend a method-level workaround:

```
php artisan deadlock:extend --class=App\Services\PricingService --method=calculate --days=7
```

Extend every workaround on a class:

```
php artisan deadlock:extend --class=App\Services\PricingService --all --months=1 --days=7
```

Extend a controller workaround:

```
php artisan deadlock:extend --controller=TestController --days=7
```

Extend a nested controller method workaround:

```
php artisan deadlock:extend --controller=Admin\TestController --method=index --date=2026-06-01
```

#### Validation

[](#validation)

- Use exactly one of `--class` or `--controller`
- `--method` and `--all` cannot be used together
- Without `--method` or `--all`, the command updates only the class-level workaround
- `--days` and `--months` must be positive integers
- `--date` must use `YYYY-MM-DD`
- The target class must resolve to a real PHP file
- The targeted class or method must already have a `#[Workaround]`

---

CI/CD Integration
-----------------

[](#cicd-integration)

Run the check command in your pipeline:

```
php artisan deadlock:check
```

CI example:

```
- name: Deadlock check
  run: php artisan deadlock:check
```

---

Runtime Exceptions
------------------

[](#runtime-exceptions)

When expired code is accessed locally, a `WorkaroundExpiredException` is thrown with:

- Description
- Expiration date
- Exact code location

Example exception output:

[![Expired workaround exception](docs/images/workaround-exception.png)](docs/images/workaround-exception.png)

---

Production Safety
-----------------

[](#production-safety)

Laravel Deadlock never enforces workaround deadlines in production.

- Runtime exceptions only occur in **local** environments
- CI blocks merges before debt reaches production
- Live users are never affected

---

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md)

---

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance95

Actively maintained with recent releases

Popularity38

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~11 days

Recently: every ~18 days

Total

14

Last Release

34d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b8435c1650e36d1af5d86c9955e343d4ce94ad62949a09e43c4f5cc1a47dba79?d=identicon)[medmahmoudhdaya](/maintainers/medmahmoudhdaya)

---

Top Contributors

[![medmahmoudhdaya](https://avatars.githubusercontent.com/u/192469611?v=4)](https://github.com/medmahmoudhdaya "medmahmoudhdaya (89 commits)")

---

Tags

laraveltodoworkaroundmaintainabilitytechnical debttemporary fixci enforcementcode expiration

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/zidbih-laravel-deadlock/health.svg)

```
[![Health](https://phpackages.com/badges/zidbih-laravel-deadlock/health.svg)](https://phpackages.com/packages/zidbih-laravel-deadlock)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77022.3M151](/packages/laravel-mcp)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k91.9k1](/packages/mike-bronner-laravel-model-caching)[laravel/surveyor

Static analysis tool for Laravel applications.

86121.4k13](/packages/laravel-surveyor)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
