Skip to content

Complete Facade Documenter correctness and drift prevention - #475

Merged
binaryfire merged 22 commits into
0.4from
facade-documenter-audit
Aug 6, 2026
Merged

Complete Facade Documenter correctness and drift prevention#475
binaryfire merged 22 commits into
0.4from
facade-documenter-audit

Conversation

@binaryfire

@binaryfire binaryfire commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Facade docblocks are generated API metadata used by editors and static analysis. The previous documenter could emit valid-looking but incorrect types, lose useful PHPDoc information, miss standard import forms, and leave stale metadata outside the Support package unnoticed.

This change makes Facade Documenter a reliable source of truth for every first-party facade. It also corrects the framework contracts that were producing inaccurate metadata and adds repository checks for package metadata that should remain uniform.

Facade Documenter

  • Keep class-level @method tags as parser nodes until final rendering instead of recovering method identity from formatted strings.
  • Preserve PHPStan parameter, return, template, generic, and conditional information when it can be represented truthfully.
  • Render unions, intersections, arrays, nullability, and template bounds with the correct PHPDoc precedence.
  • Resolve self, parent, static, constants, imported aliases, qualified names, and same-namespace classes using PHP lexical rules.
  • Replace the import regex with bounded native tokenization that supports grouped, comma-separated, multiline, aliased, bracketed-namespace, and CRLF imports while excluding closure, trait, function, and constant uses.
  • Render scalar, array, enum, finite-float, and non-finite-float defaults through phpdoc-parser constant-expression nodes.
  • Report unrepresentable object defaults with enough context to identify and exclude the owning method.
  • Support one-line and tab-indented docblock tags and trailing PHPDoc-only parameters.
  • Publish generated source through the existing atomic Filesystem replacement boundary while preserving file permissions.
  • Accumulate lint failures so one run reports all stale facades.

The implementation remains a short-lived procedural CLI. It does not add application, coroutine, worker, cache, registry, or request-time machinery.

Framework contracts and generated facades

The audit exposed several source contracts that did not describe behavior already supported by their implementations:

  • Cache repository contracts now expose the enum and iterable key forms accepted by Hypervel repositories.
  • Filesystem contracts include the separator accepted by every prepend and append implementation, and pooled filesystem metadata reflects the safe shared surface.
  • Bus batch identifiers are consistently typed as strings across the contract, database repository, and test fakes.
  • Data accessors return Hypervel\Support\Stringable while enum coercion continues to accept any PHP Stringable implementation.

All affected Support facades were regenerated. Inertia, Sentry, and Socialite metadata was also refreshed against their current proxy APIs.

Drift prevention

A normal PHPUnit test now discovers concrete first-party facades from the root Composer PSR-4 mappings. It runs one lint process across the complete inventory and parses every generated docblock with phpdoc-parser.

This replaces directory-specific shell discovery and catches both stale output and invalid generated tags without a hardcoded facade list or an additional CI workflow.

Focused regressions cover type precedence, templates, relative ownership, constants, imports, defaults, class-level methods, ignored methods, tag layouts, dynamic parameters, file publication, lint behavior, and deterministic fixture cleanup.

Composer metadata

A repository-wide invariant now checks the structures that should be uniform across split packages:

  • external dependency constraints match the root manifest;
  • Hypervel package dependencies are represented by self.version replacements;
  • declared autoload paths exist;
  • support metadata points to the components repository.

The existing package metadata was aligned with those rules. This includes direct extension and package requirements, valid Boost mappings, current dependency constraints, and missing support metadata. Duplicated root checks were removed from package-specific tests while their package-owned assertions remain.

Documentation and maintenance

  • Document facade generation, mixins, ignored methods, and linting in the package and contribution guides.
  • Keep the Facade Documenter README as a thin package entry point rather than a second documentation source.
  • Record the complete renderer design and verification plan for future maintenance.
  • Clarify repository verification checkpoints so targeted feedback remains fast and the full composer fix pipeline runs once at meaningful boundaries.
  • Remove timing races from Coordinator timer tests by making their intended ordering explicit.

Verification

composer fix passes, including formatting, both PHPStan configurations, the parallel framework suite, Testbench, and package dogfood. The Facade Documenter package suite, all-facade lint and parse checks, Composer metadata checks, and affected package tests also pass after merging the latest 0.4.

Summary by CodeRabbit

  • New Features

    • Added configurable separators for filesystem prepend and append operations.
    • Expanded cache operations and support for enum-based keys.
    • Batch operations now consistently use string identifiers.
    • Improved facade documentation generation with stronger type resolution, validation, linting, and diagnostics.
  • Bug Fixes

    • Improved handling of imports, default values, conditional types, duplicate methods, and file permissions.
    • Corrected generated API annotations across caching, requests, Redis, scheduling, and other services.
  • Documentation

    • Added guidance for generating facade docblocks and documenting filesystem separators.

The documenter treated PHPStan tags like ordinary PHPDoc, flattened useful parameter conditionals, wrapped top-level unions, stopped after the first lint mismatch, and rendered some string defaults incorrectly. This produced less precise facade metadata and made drift checks harder to fix in one pass.

Prefer PHPStan parameter and return tags, preserve conditionals only when their targets can be represented accurately, and flatten unsupported cases to safe unions. Keep native nullability correct, use the parser to escape string defaults, report every lint mismatch, and remove an unreachable constant-array branch.

Add regressions for conditional resolution, magic-method unions, string defaults, and aggregated lint failures. Subprocess tests now use the active PHP binary so they run against the same runtime as the suite.
The cache contract inherited seven PSR methods with string-only keys even though Hypervel repositories accept enums and, where supported, arrays. Static analysis therefore rejected calls that the framework handles correctly, and generated Cache metadata exposed a narrower API than the implementation.

Redeclare the PSR methods with Hypervel's actual key types and precise iterable shapes. Point CacheManager's mixin at the concrete repository, matching the real facade target, and retain the key type on getMultiple's returned iterable.

Regenerate the Cache facade from the corrected declarations so its method signatures now match the runtime API without changing runtime behavior.
Every filesystem implementation accepts an optional separator for prepend and append, but the contract omitted it. Valid calls through the contract failed static analysis even though the implementations handled them.

Add the separator to the contract and shared fixture, describe its newline default, and give FilesystemManager the pooled filesystem mixin and accurate when and unless metadata. The Storage facade now documents methods common to every disk plus safe borrow-scoped pooled accessors while leaving driver-specific raw accessors on the resolved disk.

Regenerate the Storage facade so the documented surface follows those rules and matches the types developers receive at runtime.
Bus batch identifiers are stored and returned as strings, but the repository contract, database implementation, and test fakes still accepted integers on several paths. That mismatch made the fake more permissive than production and exposed an API that the underlying storage does not provide.

Narrow every batch identifier parameter to string across the contract, implementation, and fakes. Correct the PostgreSQL serialization test to use the same string identifier and retain its missing void return type.

Regenerate the Bus facade so its batch methods expose the corrected identifier type consistently.
Many Support facade docblocks had drifted from their current targets. They retained redundant parentheses around unions, flattened conditional return types, or omitted methods added since their last generation.

Regenerate every remaining affected facade with the corrected documenter. The output now keeps supported parameter conditionals, renders top-level unions consistently, preserves precise defaults and generics, and includes the current public methods without changing facade runtime behavior.

Update the Redis metadata regression to assert the canonical unwrapped union emitted from its source declaration.
Facade docblocks can drift when their managers, contracts, or mixed-in implementations change. Individual package tests cover only parts of that generated surface, allowing stale metadata to remain unnoticed.

Discover every concrete Support facade with reflection and run the documenter in lint mode against the complete set. Abstract facade bases are excluded by their actual class shape rather than a hard-coded filename list.

This turns facade regeneration into a checked repository invariant while keeping the test independent of the current facade inventory.
Package facades depend on generated method metadata for editor support and static analysis, but the documentation did not explain how package authors should define, generate, or verify that surface.

Add the canonical workflow to the package guide, including mixins, ignored methods, generation, and linting. Link the contribution guide to that workflow so repository checks are easy to find.

Reduce the Facade Documenter README to package metadata and links, leaving the Hypervel documentation as the single source of user guidance.
Three timer tests used a one-millisecond interval and then asserted caller state immediately after scheduling. Under parallel load, the eagerly started child coroutine could reach its deadline before the caller resumed, so the callback legitimately ran before clear or coordinator resume was attempted.

Use a long interval for the clear and closing cases so those actions determine the result without slowing the tests. Remove the racy pre-deadline assertion from the elapsed-timer case, which still proves the callback fires once and reports that the coordinator is open.

The no-early-fire behavior remains covered by the long-interval closing case and the separate monotonic elapsed-time regression.
Keep fast feedback focused on the files and package being changed. Reserve the complete formatter, analysis, and test pipeline for meaningful checkpoints through composer fix.\n\nDocument how to recover from a failed combined check without rerunning expensive work that has already passed, while requiring agents to inspect the current Composer script instead of relying on remembered steps.\n\nUpdate the framework and porting workflows to use the same verification terminology.
Document the complete design for correcting Facade Documenter output and preventing generated metadata drift.

Record the verified parser, reflection, import, filesystem, and Composer behavior behind the implementation. Define the exact rendering rules, failure contracts, test coverage, regeneration workflow, and deliberate limits so the work can be reviewed and maintained from the final design rather than its discovery history.
Track each test-owned top-level fixture path created beneath the disposable Testbench application.

Remove only those paths during teardown and always continue through the parent lifecycle. Use the Filesystem boundary for fixture reads, writes, directory creation, and cleanup so repeated and parallel runs cannot inherit files from earlier tests.
Add explicit void return types to the remaining Facade Documenter test methods that needed no behavioral changes.

This completes the package typing convention independently from the renderer corrections and keeps the behavioral commits focused on the contracts they protect.
Keep class-level method tags structured until output and render unions, intersections, arrays, nullability, templates, conditionals, relative names, constants, imports, dynamic parameters, and defaults without changing their PHPDoc meaning.

Use bounded PHP tokenization for imports, canonical lexical class resolution, parser constant-expression nodes for defaults, and atomic mode-preserving filesystem replacement for generated source. Fail clearly when reflection cannot represent a truthful default or an ignore hook is declared incorrectly.

Correct the Support data-accessor Stringable contract while preserving coercion of arbitrary PHP Stringable values. Regenerate the affected Support facades and add focused regressions for every corrected boundary, including line-layout-independent tags, precedence, ownership, import forms, publication, filtering, error behavior, and package dependencies.
Regenerate the Inertia facade against the corrected documenter.

Preserve the current proxy union types, include the public state reset hook, and normalize callable and object ordering so the committed facade metadata matches the package source exactly.
Regenerate the Sentry facade from its current proxy signatures.

Collapse the redundant mixed and void union on withScope while retaining the precise template-derived integration metadata produced by the corrected renderer.
Regenerate the Socialite facade from the current manager API.

Use the existing global Closure import in the generated method signature so the facade remains stable under the repository formatter and accurately reflects its source.
Move facade metadata validation to the package that owns generation and discover production facades from Composer PSR-4 mappings.

Filter candidates safely before autoloading, then use reflection to identify concrete facades. Run one lint pass across the complete inventory and parse every generated docblock so stale or syntactically invalid first-party metadata fails the normal test suite without a hardcoded list or separate workflow.
Bring root and split package requirements onto the same supported constraints and declare the external packages and extensions used by component packages.

Require sockets where Engine uses socket constants, remove Boost autoload mappings for source directories that do not exist, and normalize repository support metadata for packages that were missing it. Add deterministic package sorting for Prompts and remove the completed Boost documentation porting ledger.
Add one repository-wide invariant for Composer metadata that can be checked uniformly across every split package.

Require external dependency constraints to match the root manifest, Hypervel dependencies to be represented by self.version replacements, declared autoload paths to exist, and support metadata to match the repository. Remove duplicated root checks from package-specific tests while retaining their package-owned dependency, provider, extension, and discovery assertions.
@coderabbitai

coderabbitai Bot commented Aug 6, 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: 15 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: f26466bb-3de2-45e3-b6d1-d0ae9b023973

📥 Commits

Reviewing files that changed from the base of the PR and between 1c97921 and 585e7c6.

📒 Files selected for processing (2)
  • docs/plans/2026-08-05-2103-facade-documenter-complete-correctness-and-drift-prevention.md
  • src/facade-documenter/facade.php
📝 Walkthrough

Walkthrough

The PR improves Facade Documenter parsing, type resolution, default rendering, filesystem publication, linting, and validation. It also updates generated facade annotations, API contracts, Composer manifests, package metadata, documentation, tests, and verification guidance.

Changes

Facade Documenter correctness

Layer / File(s) Summary
Documenter implementation and publication
src/facade-documenter/facade.php
Preserves structured method tags, resolves complex types and imports, renders defaults through AST nodes, preserves permissions, and aggregates lint failures.
Documenter regression coverage
tests/FacadeDocumenter/*
Adds coverage for parsing, type precedence, imports, constants, defaults, dynamic parameters, publication, linting, metadata, and facade-wide validation.
Package guidance
src/facade-documenter/*, src/boost/docs/*
Updates package links, adds the Filesystem dependency, and documents facade generation and linting.

API contracts and facade annotations

Layer / File(s) Summary
Core contract updates
src/bus/*, src/contracts/*, src/cache/*, src/support/src/Testing/*, src/support/src/Traits/*
Narrows batch IDs to strings, declares cache operations, adds filesystem separators, and distinguishes Hypervel and native Stringable types.
Generated facade annotations
src/support/src/Facades/*, src/filesystem/src/FilesystemManager.php, src/inertia/src/Inertia.php, src/sentry/src/Facade.php, src/socialite/src/Socialite.php, src/redis/src/RedisConnection.php
Adds current facade methods and refines documented parameters, returns, unions, conditional types, Redis command metadata, and mixins.

Repository metadata and verification

Layer / File(s) Summary
Composer and package metadata
composer.json, src/*/composer.json, tests/Composer/*, tests/*/PackageMetadataTest.php
Updates extensions, dependency versions, support metadata, package sorting, and manifest consistency checks.
Verification and supporting tests
AGENTS.md, tests/Bus/*, tests/Coordinator/*, tests/Redis/*
Consolidates verification guidance and updates affected test inputs, timing, and expectations.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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 main changes: improving Facade Documenter correctness and preventing generated facade metadata drift.
Docstring Coverage ✅ Passed Docstring coverage is 90.32% which is sufficient. The required threshold is 80.00%.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch facade-documenter-audit

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.

@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown

Greptile Summary

The PR substantially strengthens facade metadata generation and adds repository-wide drift checks.

  • Preserves richer PHPDoc type, import, method, and default-value information during generation.
  • Atomically republishes generated facades while retaining source permissions.
  • Aligns framework contracts, generated facades, package metadata, documentation, and regression coverage.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/facade-documenter/facade.php Reworks facade discovery, PHPDoc resolution, import tokenization, default rendering, lint accumulation, and atomic publication; no follow-up-eligible blocking defect was established.
tests/FacadeDocumenter/FacadeDocblocksTest.php Adds complete first-party facade discovery plus lint and generated-docblock parsing checks.
tests/Composer/PackageManifestConsistencyTest.php Adds repository-wide assertions for package dependency, replacement, autoload-path, and support-metadata consistency.
src/contracts/src/Cache/Repository.php Broadens documented cache key forms to match supported enum and iterable inputs.
src/contracts/src/Filesystem/Filesystem.php Aligns filesystem append and prepend contracts with the separator argument supported by implementations.
src/bus/src/BatchRepository.php Standardizes batch identifiers as strings across the public repository contract.
src/support/src/Traits/InteractsWithData.php Corrects Stringable return metadata while retaining broad native Stringable coercion inputs.
composer.json Aligns root dependency and package metadata used by the new consistency checks.

Reviews (3): Last reviewed commit: "facade-documenter: type rendered string ..." | Re-trigger Greptile

@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: 2

🧹 Nitpick comments (7)
tests/FacadeDocumenter/LintExitCodeTest.php (1)

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

Add the documenter output to the exit-code assertion.

The other exit-code assertions in this file pass a diagnostic message. Lines 50, 54, 103, and 112 all do. This assertion does not. If the documenter fails for an unexpected reason, the failure report shows only the exit codes and hides the cause.

♻️ Proposed change
-        $this->assertSame(1, $lint->getExitCode());
+        $this->assertSame(1, $lint->getExitCode(), $lint->getErrorOutput() . $lint->getOutput());
🤖 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/FacadeDocumenter/LintExitCodeTest.php` at line 204, Update the
exit-code assertion in the relevant test method to pass the documenter output as
its diagnostic message, matching the existing assertions in this file and
preserving the expected exit code of 1.
tests/FacadeDocumenter/PhpstanTagResolutionTest.php (1)

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

Decide whether generated unions must normalize object|mixed to mixed.

The renderer currently produces object|mixed from broadened object : mixed branches and existing generated App facade annotations. If this output is intentional, the current tests and metadata are consistent. If the style should collapse to mixed, update the renderer and the related expectations.

🤖 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/FacadeDocumenter/PhpstanTagResolutionTest.php` around lines 233 - 234,
Decide the intended normalization for generated union types containing mixed,
then apply it consistently in the renderer responsible for facade annotations
and update the related PhpstanTagResolutionTest expectations and metadata.
Preserve object|mixed if that output is intentional; otherwise collapse it to
mixed wherever these broadened branches are rendered.
tests/FacadeDocumenter/ConstFetchResolutionTest.php (1)

234-235: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add a title docblock to the new test method.

The neighbouring test at Line 312 has a title docblock. This test does not. Add one for consistency with the repository docblock convention.

♻️ Proposed docblock
+    /**
+     * Prefer lexical constant owners and keep explicit global class names.
+     */
     public function testConstantOwnersPreferLexicalClassesAndPreserveExplicitGlobalNames(): void

As per coding guidelines: "Add method title docblocks in imperative Laravel style; add class docblocks only when unusual complexity needs explanation."

🤖 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/FacadeDocumenter/ConstFetchResolutionTest.php` around lines 234 - 235,
Add an imperative Laravel-style title docblock immediately above
testConstantOwnersPreferLexicalClassesAndPreserveExplicitGlobalNames(), matching
the neighboring test’s repository convention.

Source: Coding guidelines

tests/FacadeDocumenter/TypePrecedenceTest.php (1)

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

Report every mismatch instead of failing on the first.

This loop asserts 18 rendering rules. If the renderer regresses on several rules, only the first mismatch appears. Collect the missing methods and assert once, so one run shows every regression.

♻️ Proposed change
-        foreach ($expectedMethods as $expectedMethod) {
-            $this->assertStringContainsString($expectedMethod, $contents);
-        }
+        $missingMethods = array_values(array_filter(
+            $expectedMethods,
+            fn (string $expectedMethod): bool => ! str_contains($contents, $expectedMethod),
+        ));
+
+        $this->assertSame([], $missingMethods, 'Generated facade is missing expected `@method` lines.');
🤖 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/FacadeDocumenter/TypePrecedenceTest.php` around lines 222 - 224, Update
the assertion loop in the TypePrecedence test to collect every expected method
absent from contents, then perform one aggregate assertion after the loop.
Preserve the existing 18 rendering-rule checks while reporting all mismatches
instead of stopping at the first failure.
tests/FacadeDocumenter/PackageMetadataTest.php (1)

19-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use the same repository-root helper as the sibling test.

tests/FacadeDocumenter/FacadeDocblocksTest.php resolves the repository root with dirname(__DIR__, 2). This test uses a /../../ relative path. Use one form in both files.

♻️ Proposed change
         $composer = json_decode(
-            file_get_contents(__DIR__ . '/../../src/facade-documenter/composer.json'),
+            file_get_contents(dirname(__DIR__, 2) . '/src/facade-documenter/composer.json'),
             true,
             512,
             JSON_THROW_ON_ERROR,
         );
🤖 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/FacadeDocumenter/PackageMetadataTest.php` around lines 19 - 24, Update
the composer.json path in the test’s JSON-loading setup to resolve the
repository root with the same dirname(__DIR__, 2) helper used by
FacadeDocblocksTest.php, keeping the existing file_get_contents and json_decode
behavior unchanged.
tests/FacadeDocumenter/DefaultValueTest.php (2)

247-247: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

assertSame(1, preg_match(...)) does not assert a single docblock. Both tests use preg_match to capture the generated docblock and compare the result to 1. preg_match stops after the first match and returns 1, so the assertion proves only that a docblock exists. If the intent is to prove the generator emits exactly one docblock, use preg_match_all.

  • tests/FacadeDocumenter/DefaultValueTest.php#L247-L247: replace preg_match with preg_match_all and read the first set from the match array before parsing.
  • tests/FacadeDocumenter/TypePrecedenceTest.php#L226-L226: apply the same replacement, then assign $docComment from the first match set.
🤖 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/FacadeDocumenter/DefaultValueTest.php` at line 247, Update the docblock
extraction assertions in tests/FacadeDocumenter/DefaultValueTest.php at lines
247-247 and tests/FacadeDocumenter/TypePrecedenceTest.php at lines 226-226 to
use preg_match_all, assert that exactly one match is found, and assign the
docComment from the first match set before parsing; preserve the existing
parsing and validation behavior.

235-237: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Render -INF with the matching PHPDoc-style constant form.

INF and NAN render as named constants, but -INF renders as -1.0E+999 because the renderer intentionally chooses an equivalent float literal. This produces the same value, but keeps the default expression form inconsistent with the other infinite constants. Update the renderer to emit the matching negative infinite form.

🤖 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/FacadeDocumenter/DefaultValueTest.php` around lines 235 - 237, Update
the default-value renderer used by DefaultValueTest so negative infinity is
emitted as the PHPDoc-style expression -INF instead of the equivalent -1.0E+999
literal. Preserve the existing named-constant rendering for INF and NAN.
🤖 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 `@src/support/src/Facades/Redis.php`:
- Line 53: Update the Redis facade annotations for lrem(), keys(), and lInsert()
to match phpredis: order lrem() parameters as key, value, count with count
optional; declare keys() as returning matched keys; and declare lInsert() as
returning the insertion result/list size or failure value instead of void.

In `@tests/FacadeDocumenter/FacadeDocumenterTestCase.php`:
- Around line 31-58: Update writeAppFile() to place fixtures under a
worker-unique root beneath APP_PATH, using the platform-appropriate process ID,
and record that root for cleanup instead of the first relative-path segment.
Adjust tearDown() to delete only each test’s recorded unique fixture directory
while preserving parent::tearDown().

---

Nitpick comments:
In `@tests/FacadeDocumenter/ConstFetchResolutionTest.php`:
- Around line 234-235: Add an imperative Laravel-style title docblock
immediately above
testConstantOwnersPreferLexicalClassesAndPreserveExplicitGlobalNames(), matching
the neighboring test’s repository convention.

In `@tests/FacadeDocumenter/DefaultValueTest.php`:
- Line 247: Update the docblock extraction assertions in
tests/FacadeDocumenter/DefaultValueTest.php at lines 247-247 and
tests/FacadeDocumenter/TypePrecedenceTest.php at lines 226-226 to use
preg_match_all, assert that exactly one match is found, and assign the
docComment from the first match set before parsing; preserve the existing
parsing and validation behavior.
- Around line 235-237: Update the default-value renderer used by
DefaultValueTest so negative infinity is emitted as the PHPDoc-style expression
-INF instead of the equivalent -1.0E+999 literal. Preserve the existing
named-constant rendering for INF and NAN.

In `@tests/FacadeDocumenter/LintExitCodeTest.php`:
- Line 204: Update the exit-code assertion in the relevant test method to pass
the documenter output as its diagnostic message, matching the existing
assertions in this file and preserving the expected exit code of 1.

In `@tests/FacadeDocumenter/PackageMetadataTest.php`:
- Around line 19-24: Update the composer.json path in the test’s JSON-loading
setup to resolve the repository root with the same dirname(__DIR__, 2) helper
used by FacadeDocblocksTest.php, keeping the existing file_get_contents and
json_decode behavior unchanged.

In `@tests/FacadeDocumenter/PhpstanTagResolutionTest.php`:
- Around line 233-234: Decide the intended normalization for generated union
types containing mixed, then apply it consistently in the renderer responsible
for facade annotations and update the related PhpstanTagResolutionTest
expectations and metadata. Preserve object|mixed if that output is intentional;
otherwise collapse it to mixed wherever these broadened branches are rendered.

In `@tests/FacadeDocumenter/TypePrecedenceTest.php`:
- Around line 222-224: Update the assertion loop in the TypePrecedence test to
collect every expected method absent from contents, then perform one aggregate
assertion after the loop. Preserve the existing 18 rendering-rule checks while
reporting all mismatches instead of stopping at the first failure.
🪄 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: c6b4bd37-e220-41a4-bc8f-ecf0be67c864

📥 Commits

Reviewing files that changed from the base of the PR and between 8e83f84 and 48aa9f1.

📒 Files selected for processing (97)
  • AGENTS.md
  • composer.json
  • docs/plans/2026-08-05-2103-facade-documenter-complete-correctness-and-drift-prevention.md
  • src/boost/composer.json
  • src/boost/docs-ported.md
  • src/boost/docs/contributions.md
  • src/boost/docs/filesystem.md
  • src/boost/docs/packages.md
  • src/bus/src/BatchRepository.php
  • src/bus/src/DatabaseBatchRepository.php
  • src/cache/src/CacheManager.php
  • src/cache/src/Repository.php
  • src/console/composer.json
  • src/contracts/src/Cache/Repository.php
  • src/contracts/src/Filesystem/Filesystem.php
  • src/database/composer.json
  • src/engine/composer.json
  • src/facade-documenter/README.md
  • src/facade-documenter/composer.json
  • src/facade-documenter/facade.php
  • src/filesystem/src/FilesystemManager.php
  • src/fortify/composer.json
  • src/inertia/src/Inertia.php
  • src/passkeys/composer.json
  • src/prompts/composer.json
  • src/sentry/src/Facade.php
  • src/socialite/src/Socialite.php
  • src/support/src/Facades/App.php
  • src/support/src/Facades/Artisan.php
  • src/support/src/Facades/Bus.php
  • src/support/src/Facades/Cache.php
  • src/support/src/Facades/Config.php
  • src/support/src/Facades/Context.php
  • src/support/src/Facades/Cookie.php
  • src/support/src/Facades/DB.php
  • src/support/src/Facades/Date.php
  • src/support/src/Facades/Event.php
  • src/support/src/Facades/Exceptions.php
  • src/support/src/Facades/File.php
  • src/support/src/Facades/Gate.php
  • src/support/src/Facades/Grpc.php
  • src/support/src/Facades/Http.php
  • src/support/src/Facades/Lang.php
  • src/support/src/Facades/Log.php
  • src/support/src/Facades/Pipeline.php
  • src/support/src/Facades/Process.php
  • src/support/src/Facades/Redis.php
  • src/support/src/Facades/Request.php
  • src/support/src/Facades/Response.php
  • src/support/src/Facades/Route.php
  • src/support/src/Facades/Schedule.php
  • src/support/src/Facades/Session.php
  • src/support/src/Facades/Storage.php
  • src/support/src/Facades/View.php
  • src/support/src/Facades/Vite.php
  • src/support/src/Testing/Fakes/BatchRepositoryFake.php
  • src/support/src/Testing/Fakes/BusFake.php
  • src/support/src/Traits/InteractsWithData.php
  • src/validation/composer.json
  • tests/Auth/PackageMetadataTest.php
  • tests/Broadcasting/PackageMetadataTest.php
  • tests/Bus/BusBatchTest.php
  • tests/Cache/Fixtures/ArrayFilesystem.php
  • tests/Composer/PackageManifestConsistencyTest.php
  • tests/Coordinator/TimerTest.php
  • tests/FacadeDocumenter/CaseInsensitiveDedupeTest.php
  • tests/FacadeDocumenter/ClassDocblockMethodFilteringTest.php
  • tests/FacadeDocumenter/ClassDocblockResolutionTest.php
  • tests/FacadeDocumenter/ConditionalDedupeTest.php
  • tests/FacadeDocumenter/ConstFetchResolutionTest.php
  • tests/FacadeDocumenter/DefaultValueTest.php
  • tests/FacadeDocumenter/DocTagParsingTest.php
  • tests/FacadeDocumenter/DocblockNativeNullabilityMergeTest.php
  • tests/FacadeDocumenter/DynamicParameterTest.php
  • tests/FacadeDocumenter/FacadeDocblocksTest.php
  • tests/FacadeDocumenter/FacadeDocumenterTestCase.php
  • tests/FacadeDocumenter/FilePublicationTest.php
  • tests/FacadeDocumenter/GenericPreservationTest.php
  • tests/FacadeDocumenter/GracefulDegradationTest.php
  • tests/FacadeDocumenter/IdempotenceTest.php
  • tests/FacadeDocumenter/IgnoredMethodsTest.php
  • tests/FacadeDocumenter/ImportResolutionTest.php
  • tests/FacadeDocumenter/LintExitCodeTest.php
  • tests/FacadeDocumenter/MixedNativeNullableTest.php
  • tests/FacadeDocumenter/NullableSelfStaticTest.php
  • tests/FacadeDocumenter/PackageMetadataTest.php
  • tests/FacadeDocumenter/PhpstanTagResolutionTest.php
  • tests/FacadeDocumenter/RelativeTypeResolutionTest.php
  • tests/FacadeDocumenter/StaticPrefixGuardTest.php
  • tests/FacadeDocumenter/TraitImportSourceTest.php
  • tests/FacadeDocumenter/TypePrecedenceTest.php
  • tests/FacadeDocumenter/WrapperCollapseTest.php
  • tests/Http/PackageMetadataTest.php
  • tests/Mail/PackageMetadataTest.php
  • tests/Notifications/PackageMetadataTest.php
  • tests/Redis/PackageMetadataTest.php
  • tests/Support/Traits/InteractsWithDataTest.php
💤 Files with no reviewable changes (8)
  • tests/Broadcasting/PackageMetadataTest.php
  • tests/Http/PackageMetadataTest.php
  • src/boost/docs-ported.md
  • tests/Mail/PackageMetadataTest.php
  • tests/Auth/PackageMetadataTest.php
  • tests/FacadeDocumenter/CaseInsensitiveDedupeTest.php
  • tests/Notifications/PackageMetadataTest.php
  • tests/FacadeDocumenter/NullableSelfStaticTest.php

Comment thread src/support/src/Facades/Redis.php
Comment thread tests/FacadeDocumenter/FacadeDocumenterTestCase.php
Collapse flattened conditional branches when an exact mixed member makes the remaining union redundant. Regenerate the App facade so its conditional container methods advertise the canonical mixed result.

Correct RedisConnection metadata for keys and lInsert, remove pooled subscription commands that always throw, and regenerate the Redis facade from the owning annotations. Keep the working manager-level subscription API unchanged.

Add focused source and generated metadata regressions, improve subprocess failure diagnostics, document the lexical constant regression, and keep the implementation plan aligned with the final contracts and generated output.
@binaryfire

Copy link
Copy Markdown
Collaborator Author

@coderabbitai Follow-up is pushed in 1c97921.

Implemented:

  • Conditional branches now collapse to mixed when an exact branch member is mixed. Generic and array uses of mixed remain intact. The App facade was regenerated from the corrected renderer.
  • RedisConnection now owns truthful keys() and lInsert() return metadata, and the Redis facade was regenerated. The adjacent stale subscribe and psubscribe annotations were also removed because pooled connections reject those calls.
  • Multi-facade lint failures now include subprocess output, and the lexical constant-owner regression has its missing method title.
  • Focused regressions cover the renderer, source-owned Redis metadata, generated output, and the complete set of guarded pooled commands.

Kept unchanged after verification:

  • lrem($key, $count, $value) remains in Laravel-compatible order; Hypervel reorders it only at the phpredis boundary.
  • Testbench already isolates BASE_PATH by worker token and PID. Adding another PID directory below APP_PATH would duplicate that isolation and break fixture PSR-4 paths.
  • -1.0E+999 remains the negative-infinity representation because phpdoc-parser rejects -INF.
  • The docblock test intentionally extracts one class docblock, so preg_match() is the correct contract.
  • The existing repository-root expression is correct and consistent with the package tests.
  • The small fixed assertion set remains direct; an aggregate assertion helper would add machinery without improving coverage.

The focused Facade Documenter and Redis suites pass, all generated facades lint cleanly, and the final diff is whitespace-clean.

@coderabbitai

coderabbitai Bot commented Aug 6, 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 1c9792157
printf '\n--- changed paths ---\n'
git diff-tree --no-commit-id --name-only -r 1c9792157

printf '\n--- relevant diff excerpts ---\n'
git show --format= --no-ext-diff --unified=40 1c9792157 -- \
  src/facade-documenter/facade.php \
  src/database/src/RedisConnection.php \
  src/support/src/Facades/App.php \
  src/support/src/Facades/Redis.php \
  tests/FacadeDocumenter \
  tests/Redis \
  | sed -n '1,1800p'

Length of output: 32975


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- RedisConnection follow-up diff ---'
git show --format= --no-ext-diff --unified=30 1c9792157 -- src/redis/src/RedisConnection.php

printf '%s\n' '--- Redis facade guard hook and related generated metadata ---'
rg -n -C 8 \
  'ignoredFacadeDocumenterMethods|`@method` static .* (keys|lInsert|subscribe|psubscribe|ssubscribe)\(' \
  src/support/src/Facades/Redis.php src/redis/src/RedisConnection.php

printf '%s\n' '--- exact conditional regression context ---'
rg -n -C 12 \
  'BroadenedGenericConditional|BroadenedBareConditional|array<.*mixed|mixed>' \
  tests/FacadeDocumenter/PhpstanTagResolutionTest.php

Length of output: 17744


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '317,375p' src/support/src/Facades/Redis.php

Length of output: 1156


@binaryfire Verified the follow-up in 1c9792157.

  • flattenConditionalBranches() now collapses only a top-level exact mixed branch. Nested generic and array types remain unchanged.
  • App now documents the affected methods as mixed.
  • RedisConnection owns the corrected keys() and lInsert() metadata.
  • Generated Redis metadata matches the source metadata.
  • subscribe() and psubscribe() are removed from the pooled RedisConnection surface. The facade-level methods remain part of the separate manager API.
  • The new regression checks cover the corrected metadata and guarded pooled commands.
  • The lint failure assertion now includes subprocess output.
  • The lexical constant-owner test has its missing method description.

The retained decisions are consistent with the stated contracts. I did not execute the test suites in this inspection environment.


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

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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

🤖 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 `@src/facade-documenter/facade.php`:
- Around line 896-909: Update flattenConditionalBranches to declare both $if and
$else as string parameters and declare its return type as string, preserving the
existing implementation and PHPDoc contract.
🪄 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: ba9eee2c-649d-4b89-a38b-5d5d911eced6

📥 Commits

Reviewing files that changed from the base of the PR and between 48aa9f1 and 1c97921.

📒 Files selected for processing (9)
  • docs/plans/2026-08-05-2103-facade-documenter-complete-correctness-and-drift-prevention.md
  • src/facade-documenter/facade.php
  • src/redis/src/RedisConnection.php
  • src/support/src/Facades/App.php
  • src/support/src/Facades/Redis.php
  • tests/FacadeDocumenter/ConstFetchResolutionTest.php
  • tests/FacadeDocumenter/LintExitCodeTest.php
  • tests/FacadeDocumenter/PhpstanTagResolutionTest.php
  • tests/Redis/PackageMetadataTest.php
🚧 Files skipped from review as they are similar to previous changes (6)
  • tests/FacadeDocumenter/ConstFetchResolutionTest.php
  • tests/FacadeDocumenter/PhpstanTagResolutionTest.php
  • tests/FacadeDocumenter/LintExitCodeTest.php
  • src/support/src/Facades/App.php
  • src/support/src/Facades/Redis.php
  • docs/plans/2026-08-05-2103-facade-documenter-complete-correctness-and-drift-prevention.md

Comment thread src/facade-documenter/facade.php
Declare the exact native contracts for conditional branch flattening and docblock/native nullability merging. Both helpers operate only on rendered type strings, while nested resolution either returns a string or propagates its failure.

Remove redundant PHPDoc type annotations while retaining the nullability merge explanation that cannot be expressed by the signature. Keep AST and reflection helpers outside this bounded typing change.

Record the complete rendered-string helper boundary in the implementation plan so the source and design remain aligned.
@binaryfire
binaryfire merged commit 4ed476c into 0.4 Aug 6, 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