Skip to content

Fix Sanctum cache settlement and restore current parity - #484

Merged
binaryfire merged 14 commits into
0.4from
audit/sanctum-correctness-lifecycle-parity
Aug 7, 2026
Merged

Fix Sanctum cache settlement and restore current parity#484
binaryfire merged 14 commits into
0.4from
audit/sanctum-correctness-lifecycle-parity

Conversation

@binaryfire

@binaryfire binaryfire commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

This change completes the Sanctum correctness audit and updates the package to the current supported Laravel surface while preserving Hypervel's coroutine-safe guard and cache design.

The main change is ownership. Database callbacks now attach to the connection that registered them. Sanctum token cache changes and Auth user cache invalidation now settle only after the owning database transaction commits. Rollbacks leave the previously committed cache state intact.

The package also restores current CSRF route configuration, protected provider extension points, bearer parsing, testing behavior, command validation, package metadata, and public types. Existing Hypervel choices remain intact: explicit per-guard session configuration, header-only credentials, the strict id|token format, and middleware priority owned by the application middleware configurator.

For more details, see: docs/plans/2026-08-07-1302-sanctum-correctness-cache-settlement-and-current-parity.md

Transaction ownership

  • Bind afterCommit and rollback callbacks to the connection that registered them.
  • Preserve the existing ambient behavior for unnamed transaction-manager callbacks.
  • Document that after-commit work follows the selected transaction and its parent stack on one connection; it does not coordinate independent transactions across connections.
  • Cover commit, rollback, nesting, missing-manager, and cross-connection behavior.

Token and user cache correctness

  • Move token cache invalidation to successful model events and defer it until transaction settlement.
  • Clear pre-created negative token entries after creation.
  • Keep last-used timestamp refreshes limited to the token entry.
  • Use late static binding and the configured token model's real primary key for every cache read, write, and invalidation path.
  • Settle Auth's Eloquent user cache invalidation on the mutated model's connection.
  • Preserve event-time cache-key inputs while discovering cache descriptors at commit time.

Relationship revocation

  • Add a token-specific MorphMany relation with a protected construction seam on HasApiTokens.
  • Keep cache-disabled relation deletion on its existing single-query path.
  • When caching is enabled, select the exact token ID set, delete that same set through a cloned scoped builder, and invalidate it after commit.
  • Preserve global scopes, soft deletes, custom token connections, integer keys, string keys, and reusable relation builders.

Sanctum behavior and parity

  • Restore the configurable CSRF cookie route and current provider method structure.
  • Keep Hypervel's direct coroutine-safe guard instead of introducing Laravel's mutable request guard.
  • Use the request bearer parser and centralize strict token-format validation in findToken().
  • Reject empty or overflowing integer token identifiers before cache or database access while preserving custom string-key models and custom lookup overrides.
  • Normalize enum abilities once and compare them strictly without an intermediate allocation.
  • Make actingAs() select the requested guard and preserve the concrete authenticatable type.
  • Validate prune hours before issuing a destructive query.
  • Complete split-package dependencies, provider discovery, static reset behavior, and maximum-level type coverage.

Documentation

  • Document automatic cache invalidation paths and their after-commit timing.
  • Clarify the explicit invalidation required after raw, quiet, eventless, or arbitrary builder mutations.
  • Document bounded-cache guidance for attacker-controlled invalid token inputs.
  • Correct framework documentation that previously implied coordination across every open database connection.
  • Record the public Sanctum differences from Laravel without exposing internal implementation detail.

Compatibility and performance

Supported Laravel method names, signatures, named arguments, guard behavior, token-model customization, and protected provider extension points are preserved or restored.

Bearer authentication removes a duplicate validation pass and model allocation. Ability checks avoid array_flip(). Cache-disabled relation deletion remains one query. Cache-enabled relation deletion adds one scalar ID-selection query only on that write path so the deleted set can be invalidated correctly. Transaction registration adds a local connection-name lookup only when a callback is scheduled. No read path gains a query, cache round trip, lock, retry, yield, or retained worker state.

Validation

  • Focused Sanctum, Auth, and Database regression coverage passes.
  • Static analysis covers configurable token models, relation construction, enum abilities, concrete acting-as returns, and current-token generics.
  • The complete formatting, static-analysis, parallel test, Testbench, and dogfood gates pass.

Summary by CodeRabbit

  • New Features
    • Added configurable Sanctum CSRF-cookie routing, including custom prefixes and route disabling.
    • Added support for custom personal access-token relations and token models.
    • Added enum-based token abilities and improved guard configuration.
  • Bug Fixes
    • Token and user cache invalidation now respects transaction commits and rollbacks.
    • Authentication now consistently uses bearer tokens and rejects query or body tokens.
    • Improved validation for expired-token pruning options.
  • Documentation
    • Clarified transaction-aware dispatching, Sanctum caching, middleware, and CSRF configuration.

Pass the registering connection name through after-commit and rollback callback registration so work cannot attach to a newer transaction on another connection.

Preserve the existing ambient behavior for direct unnamed manager callbacks and document that boundary precisely. Add unit and integration regressions covering independent connections, nested transactions, rollback, immediate execution, and missing-manager failures.
Replace claims that queued work waits for every open database transaction with the actual contract: it follows the latest applicable transaction and its enclosing stack on that connection.

Carry the corrected wording through Bus, Foundation, Queue, Events, Mail, Notifications, Broadcasting, Scout, and Eloquent event surfaces. Document how applications should schedule work that depends on commits across multiple connections without implying cross-connection atomic coordination.
Schedule cached Eloquent user invalidation on the mutated model's own database connection instead of clearing entries before persistence or transaction settlement.

Snapshot request-sensitive cache-key inputs at model-event time while discovering provider descriptors at commit time. Cover saves, deletes, nested transactions, rollback, cross-connection ownership, immediate execution, fail-closed missing-manager behavior, and descriptors registered while a transaction remains open.
Invalidate token and tokenable cache entries only after successful persistence and transaction settlement, including creation, updates, soft deletes, restores, force deletes, and last-used writes.

Add a dedicated token relation whose cache-enabled bulk delete selects and removes one exact scoped ID set without mutating reusable builders. Honor custom token primary keys, connections, string IDs, and late-static cache namespaces throughout.

Make token lookup reject malformed or overflowing identifiers before cache or SQL, and compare abilities strictly without allocating a flipped map. Add counterfactual coverage for transaction outcomes, custom models, relation deletion, cache-disabled query count, lookup boundaries, and stored ability coercion.
Delegate Authorization parsing to the framework request parser and make the configured token model's findToken method the single authority for token format and lookup behavior.

Remove the guard's duplicate model allocation, identifier checks, and query/body credential fallback. Preserve configured retrieval callbacks and provider matching, with regressions for standard bearer parsing, header-only defaults, custom lookup models, invalid credentials, and last-used behavior.
Make actingAs preserve the concrete authenticatable, normalize enum abilities strictly, and select the requested guard as the coroutine-local default as well as setting its user.

Replace misleading token-model generics with the actual configurable model contract and restore the current-host placeholder from a canonical default during test cleanup. Add focused coverage for custom guard selection, enum abilities, concrete returns, and static placeholder reset.
Move CSRF route registration into the provider so route caching, disablement, and custom prefixes are honored, and restore the protected guard/provider construction seams from current Sanctum.

Retain Hypervel's direct coroutine-safe guard and Middleware::statefulApi priority owner. Validate each Sanctum guard's explicit session_guards contract, keep middleware filtering strict, and derive cache-safe provider models from configured auth guards.

Cover real CSRF behavior, route names and middleware, cached and malformed configuration, factory overrides, provider validation, and exact middleware filtering.
Resolve the configured personal-access-token model and reject negative, decimal, or nonnumeric --hours values before constructing or executing a destructive query.

Preserve zero and positive values, return standard command status codes, and add regressions proving invalid input performs no deletion while configured models and expiration rules remain honored.
Declare the split package's direct runtime dependencies and mirror Sanctum provider discovery in the monorepo metadata.

Add executable metadata checks and maximum-level static-analysis coverage for actingAs enum abilities and concrete returns, configurable token models, current-token generics, and trait-only token relationship construction. Keep the public contracts aligned with the runtime without adding wrappers or broad suppressions.
Describe per-guard session trust, provider matching, token-only guards, explicit middleware-priority ownership, and the supported protected relation extension point.

Correct cache invalidation and transaction timing guidance, document deliberate eventless and raw-query escape hatches, explain bounded negative-cache and pruning behavior, and state exact route configuration types. Keep the package README limited to public Laravel differences while the Boost guide owns operational detail.
Mark Sanctum complete in the audit routing index and checklist, close carried revalidation items, and route the new Sanctum, Database, and Auth findings to every affected package.

Add the final completion ledger entry with ownership, transaction semantics, compatibility, performance, rejected complexity, regression coverage, and validation results. Remove stale references to a future Sanctum audit and record Bus and Foundation as consumers of the corrected after-commit documentation.
Record the evidence, final architecture, accepted findings, implementation boundaries, counterfactual test coverage, performance budget, compatibility decisions, and rejected alternatives for the completed Sanctum work.

Keep the core anti-overengineering rules intact and document the final Database and Auth ownership decisions, including connection-local callback settlement and the absence of speculative cache, locking, retry, or cross-connection coordination machinery.
# Conflicts:
#	docs/plans/2026-07-12-0900-framework-coroutine-state-lifecycle-audit.md
#	docs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.md
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@binaryfire, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a4edbf9-7de9-4a85-acaf-9c372be7f150

📥 Commits

Reviewing files that changed from the base of the PR and between aa332fb and f978924.

📒 Files selected for processing (10)
  • docs/plans/2026-07-12-0900-framework-coroutine-state-lifecycle-audit.md
  • docs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.md
  • docs/plans/2026-08-02-1321-http-correctness-json-api-and-current-laravel-parity.md
  • docs/plans/2026-08-03-1909-mail-correctness-current-parity-and-package-boundaries.md
  • docs/plans/2026-08-06-0916-view-correctness-lifecycle-and-current-parity.md
  • docs/plans/2026-08-06-0925-translation-correctness-current-parity-and-worker-lifecycles.md
  • docs/plans/2026-08-07-1302-sanctum-correctness-cache-settlement-and-current-parity.md
  • src/database/src/Connection.php
  • src/sanctum/src/Sanctum.php
  • tests/Sanctum/PersonalAccessTokenCacheTest.php
📝 Walkthrough

Walkthrough

Sanctum now supports transaction-aware token and user-cache invalidation, configurable CSRF routes and guards, stricter token handling, custom token relations, command validation, package metadata, documentation, and expanded tests.

Changes

Sanctum correctness and parity

Layer / File(s) Summary
Connection-scoped transaction settlement
src/database/..., src/auth/..., tests/Database/..., tests/Integration/...
Transaction callbacks now use the originating connection. Auth cache invalidation waits for commit when required.
Token cache and relation settlement
src/sanctum/src/PersonalAccessToken.php, src/sanctum/src/PersonalAccessTokenRelation.php, src/sanctum/src/HasApiTokens.php, tests/Sanctum/PersonalAccessTokenCacheTest.php
Token mutations and relation deletes now settle cache invalidation after commit. Custom token models, keys, timestamps, soft deletes, and rollback cases are covered.
Provider, guard, and authentication flow
src/sanctum/src/SanctumServiceProvider.php, src/sanctum/src/SanctumGuard.php, src/sanctum/src/Sanctum.php, tests/Sanctum/*
Sanctum defines configurable CSRF routes, constructs guards through protected hooks, reads bearer tokens from the request, normalizes enum abilities, and resets request state.
Package contracts and validation
composer.json, src/sanctum/composer.json, src/sanctum/src/Console/Commands/PruneExpired.php, types/Sanctum/Sanctum.php, tests/Sanctum/PackageMetadataTest.php
Package dependencies and provider discovery are registered. Pruning validates non-negative integer input and uses the configured token model. Static typing and metadata tests were added.
Audit and documentation records
docs/plans/*, src/sanctum/README.md, src/boost/docs/*, src/queue/src/Queue.php, src/bus/src/Queueable.php
Audit records and package documentation describe Sanctum behavior and connection-scoped after-commit semantics across framework components.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary changes: Sanctum cache settlement fixes and restoration of current framework parity.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch audit/sanctum-correctness-lifecycle-parity

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/sanctum/src/Sanctum.php (1)

91-91: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Import HasAbilities for the PHPDoc type.

Add a use Hypervel\Sanctum\Contracts\HasAbilities; import and use HasAbilities&MockInterface in this annotation. This keeps the file consistent with the required import style.

As per coding guidelines, import classes with use statements instead of using fully qualified class names.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/sanctum/src/Sanctum.php` at line 91, Update the PHPDoc annotation for
$token in Sanctum to reference HasAbilities&MockInterface without its fully
qualified namespace, and add the corresponding use
Hypervel\Sanctum\Contracts\HasAbilities; import alongside the existing imports.

Source: Coding guidelines

tests/Sanctum/PersonalAccessTokenCacheTest.php (1)

1370-1414: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Namespace the new inline fixture models.

These six fixture classes are declared in the global namespace with generic names, for example SoftDeletingPersonalAccessToken and EventPersonalAccessToken. Another Sanctum test file that declares the same name causes a fatal redeclaration error. Move them into a capitalized Fixtures/ directory, or give them a test-specific namespace whose final segment is PersonalAccessTokenCacheTest.

As per coding guidelines: "Put standalone test support files under a capitalized Fixtures/ directory" and "Use test-specific namespaces for collision-prone generic helper classes, with the test class name as the final namespace segment."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Sanctum/PersonalAccessTokenCacheTest.php` around lines 1370 - 1414,
Namespace all six inline fixture models—NamespacedPersonalAccessToken,
SoftDeletingPersonalAccessToken, TimestampDisabledPersonalAccessToken,
CustomTimestampPersonalAccessToken, SecondaryConnectionPersonalAccessToken, and
EventPersonalAccessToken—under a test-specific namespace whose final segment is
PersonalAccessTokenCacheTest, and update any references in the test accordingly
to prevent global-name collisions.

Source: Coding guidelines

src/sanctum/src/PersonalAccessTokenRelation.php (1)

47-65: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

One settlement rule is implemented twice. Both files decide when a cache mutation runs by checking getTransactionManager() === null && transactionLevel() === 0 and otherwise calling afterCommit(). If the rule changes, one copy can be missed.

  • src/sanctum/src/PersonalAccessTokenRelation.php#L47-L65: call the shared helper instead of repeating the branch, and keep only the ID-loop callback here.
  • src/sanctum/src/PersonalAccessToken.php#L310-L321: promote settleCacheMutation() to a shared static helper, or a small trait, that accepts the connection and the callback.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/sanctum/src/PersonalAccessTokenRelation.php` around lines 47 - 65, The
cache-settlement rule is duplicated across both sites. In
src/sanctum/src/PersonalAccessToken.php lines 310-321, promote
settleCacheMutation() to a shared static helper accepting the connection and
callback; in src/sanctum/src/PersonalAccessTokenRelation.php lines 47-65, remove
the transaction branch and call that helper while retaining only the ID-loop
callback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@docs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.md`:
- Line 1891: Update the table cell describing findToken() to escape the literal
pipe in “id|token” or replace it with equivalent wording, preserving the full
malformed- and overflow-identifier rejection requirement within the same table
column.

---

Nitpick comments:
In `@src/sanctum/src/PersonalAccessTokenRelation.php`:
- Around line 47-65: The cache-settlement rule is duplicated across both sites.
In src/sanctum/src/PersonalAccessToken.php lines 310-321, promote
settleCacheMutation() to a shared static helper accepting the connection and
callback; in src/sanctum/src/PersonalAccessTokenRelation.php lines 47-65, remove
the transaction branch and call that helper while retaining only the ID-loop
callback.

In `@src/sanctum/src/Sanctum.php`:
- Line 91: Update the PHPDoc annotation for $token in Sanctum to reference
HasAbilities&MockInterface without its fully qualified namespace, and add the
corresponding use Hypervel\Sanctum\Contracts\HasAbilities; import alongside the
existing imports.

In `@tests/Sanctum/PersonalAccessTokenCacheTest.php`:
- Around line 1370-1414: Namespace all six inline fixture
models—NamespacedPersonalAccessToken, SoftDeletingPersonalAccessToken,
TimestampDisabledPersonalAccessToken, CustomTimestampPersonalAccessToken,
SecondaryConnectionPersonalAccessToken, and EventPersonalAccessToken—under a
test-specific namespace whose final segment is PersonalAccessTokenCacheTest, and
update any references in the test accordingly to prevent global-name collisions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 636aa963-8ab8-4823-bba3-dec69e08a9c4

📥 Commits

Reviewing files that changed from the base of the PR and between 2b614ae and aa332fb.

📒 Files selected for processing (48)
  • composer.json
  • docs/plans/2026-07-12-0900-framework-coroutine-state-lifecycle-audit.md
  • docs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.md
  • docs/plans/2026-08-07-1302-sanctum-correctness-cache-settlement-and-current-parity.md
  • src/auth/src/EloquentUserProvider.php
  • src/boost/docs/broadcasting.md
  • src/boost/docs/events.md
  • src/boost/docs/mail.md
  • src/boost/docs/notifications.md
  • src/boost/docs/queues.md
  • src/boost/docs/sanctum.md
  • src/bus/src/Queueable.php
  • src/database/src/Concerns/ManagesTransactions.php
  • src/database/src/DatabaseTransactionsManager.php
  • src/database/src/Eloquent/BroadcastableModelEventOccurred.php
  • src/database/src/Eloquent/BroadcastsEvents.php
  • src/database/src/Eloquent/BroadcastsEventsAfterCommit.php
  • src/events/src/Dispatcher.php
  • src/foundation/src/Bus/PendingDispatch.php
  • src/queue/src/Queue.php
  • src/sanctum/README.md
  • src/sanctum/composer.json
  • src/sanctum/routes/web.php
  • src/sanctum/src/Console/Commands/PruneExpired.php
  • src/sanctum/src/HasApiTokens.php
  • src/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php
  • src/sanctum/src/PersonalAccessToken.php
  • src/sanctum/src/PersonalAccessTokenRelation.php
  • src/sanctum/src/Sanctum.php
  • src/sanctum/src/SanctumGuard.php
  • src/sanctum/src/SanctumServiceProvider.php
  • src/scout/config/scout.php
  • src/scout/src/ModelObserver.php
  • tests/Database/DatabaseTransactionsTest.php
  • tests/Integration/Auth/EloquentUserProviderCacheTest.php
  • tests/Integration/Database/DatabaseTransactionsTest.php
  • tests/Sanctum/ActingAsTest.php
  • tests/Sanctum/CurrentApplicationUrlWithPortTest.php
  • tests/Sanctum/EnsureFrontendRequestsAreStatefulTest.php
  • tests/Sanctum/GuardTest.php
  • tests/Sanctum/HasApiTokensTest.php
  • tests/Sanctum/PackageMetadataTest.php
  • tests/Sanctum/PersonalAccessTokenCacheTest.php
  • tests/Sanctum/PersonalAccessTokenTest.php
  • tests/Sanctum/PruneExpiredTest.php
  • tests/Sanctum/SanctumRoutesTest.php
  • tests/Sanctum/SanctumServiceProviderTest.php
  • types/Sanctum/Sanctum.php
💤 Files with no reviewable changes (1)
  • src/sanctum/routes/web.php

Comment thread docs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.md Outdated
@greptile-apps

greptile-apps Bot commented Aug 7, 2026

Copy link
Copy Markdown

Greptile Summary

The PR completes Sanctum cache-settlement correctness and current API parity while binding deferred callbacks to their owning database connections.

  • Defers token and Auth user cache invalidation until the owning transaction commits.
  • Adds transaction-aware relationship token revocation and managerless fail-closed regression coverage.
  • Restores Sanctum routing, guard, provider, command, metadata, documentation, and public-type parity.
  • Updates database callback ownership and affected queue, event, broadcast, and Scout integrations.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/database/src/DatabaseTransactionsManager.php Associates transaction callbacks with their owning connection while preserving ambient unnamed-callback behavior.
src/database/src/Concerns/ManagesTransactions.php Routes transaction lifecycle and after-commit registration through connection-aware manager APIs.
src/database/src/Connection.php Exposes connection transaction-manager state and documents manager removal as a tests-only operation that must not survive pooled reuse.
src/sanctum/src/PersonalAccessToken.php Makes token cache reads and invalidation model-aware and settles successful mutations after the owning transaction commits.
src/sanctum/src/PersonalAccessTokenRelation.php Deletes an exact scoped token set and invalidates that same set only after successful transaction settlement.
src/auth/src/EloquentUserProvider.php Defers cached-user invalidation on the mutated model’s database connection.
src/sanctum/src/SanctumGuard.php Restores bearer parsing and token validation parity while retaining coroutine-scoped authentication state.
src/sanctum/src/SanctumServiceProvider.php Restores provider extension points, configurable CSRF routing, and package integration behavior.
composer.json Mirrors split-package Sanctum discovery in aggregate package metadata without adding Sanctum to the default startup-provider boundary.
tests/Sanctum/PersonalAccessTokenCacheTest.php Covers commit, rollback, relationship deletion, and intentional managerless fail-closed cache behavior.

Reviews (2): Last reviewed commit: "sanctum: pin managerless relation settle..." | Re-trigger Greptile

Comment thread src/sanctum/src/PersonalAccessToken.php
Comment thread composer.json
Add a counterfactual regression for cache-enabled token relation deletion when its owning database connection has an open transaction but no transaction manager. The test proves the operation fails closed, restores the exact connection state, and leaves committed cache entries intact after rollback.

Document transaction-manager removal as a tests-only connection seam because the null manager survives pooled release. Import the Sanctum ability contract for the existing intersection annotation without changing runtime behavior.

Repair malformed Markdown table cells found during review and record database-28 across the audit dependency index, completion ledger, ownership maps, and Sanctum implementation plan. No production path, Laravel API, query count, cache operation, or coroutine state changes.
@binaryfire

Copy link
Copy Markdown
Collaborator Author

@coderabbitai @greptile-apps — review follow-up is pushed in f978924.

Accepted changes:

  • Escaped the malformed id\|token table cell and corrected the same verified inline-code issue in the completed HTTP, Mail, View, and Translation plan tables.
  • Imported HasAbilities and shortened the existing intersection annotation.
  • Added a managerless, open-transaction relation-delete regression. It proves the operation fails closed, restores the exact secondary connection state, and preserves both committed cache entries after rollback.
  • Marked Connection::unsetTransactionManager() tests-only because a pooled connection retains a null manager after release.
  • Updated the audit index, ledger, ownership maps, and Sanctum plan with database-28.

No production change was made for managerless transactions. Immediate invalidation before commit can repopulate stale credentials from another connection, and a managerless connection has no safe after-commit hook. The existing exception is intentional fail-closed behavior; all three settlement sites now have counterfactual coverage.

The root provider entry also remains. Root Composer metadata mirrors split-package discovery in this aggregate repository. Sanctum remains absent from DefaultProviders, which is the actual optional startup boundary.

I did not add a test-fixture namespace, a shared settlement helper, or a Markdown lint subsystem. Those changes would add structure without fixing a supported failure.

The authoritative formatting, static-analysis, parallel-test, Testbench, and dogfood checks are green.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git show --stat --oneline --decorate --no-renames f97892426
printf '\n--- changed files ---\n'
git diff-tree --no-commit-id --name-only -r f97892426

printf '\n--- focused diff ---\n'
git show --format=fuller --find-renames --find-copies -- \
  f97892426 -- \
  src/sanctum/src/PersonalAccessTokenRelation.php \
  tests/Sanctum/PersonalAccessTokenCacheTest.php \
  src/database/src/Connection.php \
  composer.json \
  docs/plans/2026-08-07-1302-sanctum-correctness-cache-settlement-and-current-parity.md \
  docs/plans/2026-07-12-0900-framework-coroutine-state-lifecycle-audit.md \
  docs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.md

Length of output: 38851


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Sanctum typing diff ---'
git show --format= -- f97892426 -- src/sanctum/src/Sanctum.php

printf '%s\n' '--- corrected plan-table diffs ---'
git show --format= -- f97892426 -- \
  docs/plans/2026-08-02-1321-http-correctness-json-api-and-current-laravel-parity.md \
  docs/plans/2026-08-03-1909-mail-correctness-current-parity-and-package-boundaries.md \
  docs/plans/2026-08-06-0916-view-correctness-lifecycle-and-current-parity.md \
  docs/plans/2026-08-06-0925-translation-correctness-current-parity-and-worker-lifecycles.md

printf '%s\n' '--- relevant relation settlement implementation ---'
ast-grep outline src/sanctum/src/PersonalAccessTokenRelation.php --items all
rg -n -C 8 'function (delete|settleInvalidation)|afterCommit|transactionLevel|getTransactionManager' \
  src/sanctum/src/PersonalAccessTokenRelation.php \
  src/sanctum/src/PersonalAccessToken.php \
  src/auth/src/EloquentUserProvider.php

Length of output: 15841


@binaryfire Verified f97892426.

The Markdown table fixes are correct. The HasAbilities import and annotation are correct.

The new relation-delete regression verifies the intended managerless transaction behavior. It asserts the fail-closed exception, rolls back the secondary connection, restores its transaction manager, and preserves both committed cache entries.

The Connection::unsetTransactionManager() tests-only warning correctly documents the pooled-connection risk. The retained root provider entry and the absence of a production fallback are consistent with the stated package and settlement boundaries.

No further findings from this follow-up.


✏️ Learnings added
Learnt from: binaryfire
URL: https://github.com/hypervel/components/pull/484

Timestamp: 2026-08-07T17:22:56.286Z
Learning: In Hypervel Database, `Connection::unsetTransactionManager()` is a tests-only seam. A pooled connection retains a null transaction manager after release, so runtime use can make later borrowers fail when they schedule after-commit callbacks.

Learnt from: binaryfire
URL: https://github.com/hypervel/components/pull/484

Timestamp: 2026-08-07T17:22:56.287Z
Learning: For Sanctum token cache invalidation, `PersonalAccessToken`, `PersonalAccessTokenRelation`, and `EloquentUserProvider` intentionally fail closed when their connection has an open transaction but no transaction manager. They must not invalidate immediately because another connection can repopulate stale credentials before commit, and there is no safe after-commit hook.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

You are interacting with an AI system.

@binaryfire
binaryfire merged commit b896af6 into 0.4 Aug 7, 2026
38 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