You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
EnforceAuditSnapshotOnRetryRule — flags App\Actions\* classes whose constructor injects an entity audit logger and whose $connection->transaction(...) calls do not begin with an in-memory state reset ($model->refresh(), fresh fetch via ->newQuery()->findOrFail(...) / ->fresh(), or fresh instantiation via new ... / ->newInstance()). Doctrine: ADR-0001 §Snapshot-on-Retry Safety. Identifier: enforceAuditSnapshotOnRetry.firstStatementMustResetState. Promoted from cross-territory Pest arch tests (emmie PR #187, entreezuil PR #139, ublgenie PR #166, kendo PR #1029). Receiver detection is type-based (Illuminate\Database\ConnectionInterface subtype) — replaces territory-specific property-name matching ($this->db vs $this->connection). Escape hatch: // @audit-snapshot-retry-safety: <rationale> marker preceding the transaction call.
Changed
PHP constraint: bumped composer.jsonphp from ^8.3 to ^8.4. The package's Pint config (mb_str_functions: true) normalizes ltrim/trim calls to mb_ltrim/mb_trim, which are PHP 8.4+ functions. The new rule introduced the first mb_ltrim/mb_trim callsites; aligning the constraint with the formatter's actual output. All consuming territories already run PHP 8.4 — no real-world impact.
LogRule (BREAKING): extended FORBIDDEN_METHODS from ['delete', 'update'] to ['delete', 'forceDelete', 'forceDeleteQuietly', 'update']. On a SoftDeletes-bearing model ->delete() is a no-op against the underlying row and ->forceDelete() is the only call that actually purges; the rule's compliance teeth previously rested on the migration-time convention that audit-log models never adopt SoftDeletes. Static-call shapes (Model::destroy(), Model::forceDestroy(), DB::table('logs')->truncate()) remain out of scope — getNodeType() returns MethodCall::class, and static-call coverage is tracked as issue #4. Origin: issue #1, surfaced by ally review on Back-to-code/ublgenie-app#163. Pre-cascade audit across emmie, kendo, entreezuil, ublgenie surfaced one new violation: ublgenie/app/Actions/DeleteBranch.php:56 (InvoiceLog::query()->whereIn(...)->forceDelete()) — operational/processing log, not an audit log; migrates to consumer-side phpstan.neonignoreErrors per package convention. Versioning: per ADR-0021 §Versioning, this is a Major bump (new errors in code that previously passed); within 0.x this ships as v0.2.0.