Correct Telescope storage, watcher, and lifecycle behavior - #4
Correct Telescope storage, watcher, and lifecycle behavior#4binaryfire wants to merge 22 commits into
Conversation
Persist every monitored tag through the existing bulk insert, encode updates with invalid UTF-8 substitution, and aggregate exception families before writing updates. Preserve nullable custom repository results while keeping the built-in repository concrete. Apply explicit UUID, tag, and sequence filters without dropping valid falsey identifiers. Order chunked deletes by indexed columns and add counterfactual coverage for empty UUID sets, tag and sequence zero, deterministic aggregation, ordered deletion, invalid UTF-8, and custom repository behavior.
Release the coroutine-local recursion guard in a finally block so failures from tag, filter, or after-recording callbacks propagate without suppressing later entries. Remove obsolete request-domain helpers now that route metadata owns host matching. Restore the Laravel CSP nonce API with coroutine-local ownership and render the nonce on dashboard style and module-script tags. Add failure-path and concurrent-isolation regressions for both behaviors.
Redact configured request and client-response paths by presence so falsey secrets are never exposed. Enforce request limits in exact bytes and truncate Reverb payloads without splitting multibyte characters. Restore the protected client-host extension point with strict matching and cover nested falsey values, exact byte limits, multibyte overage, valid UTF-8 truncation, and subclass overrides.
Extract event properties from the real payload object, match Hypervel framework prefixes directly, and remove obsolete reflection accessibility handling. Record view composer and creator metadata through the existing passive rendering observer without adding per-view container resolution. Fix vendor stack filtering to honor the configured package policy and retain custom ignored paths. Add focused event, view, query, and gate coverage for every corrected branch.
Keep native file-read suppression at the exact checked boundary and return an empty source context when the exception file cannot be read. This prevents telemetry collection from replacing the application exception without installing global warning handling. Add regression coverage for unreadable and missing exception source files while preserving the normal context window.
Clear stale exception content and failed tags when a job later processes successfully. Suppress Telescope only around its batch lookup, keep unrelated failures visible, and treat a concurrently removed batch as absent. Load complete queue and batch detail relations without unbounding index endpoints, restore current BatchWatcher documentation, and cover processed-after-failure, missing-batch, recursive-recording, and full-detail behavior.
Preserve Console's established Finished-then-Failed ordering while reconciling one execution into one final queued Telescope entry. Track only entries that were actually queued, match task identity strictly, and mutate the pending object without an extra database round trip. Cover success, direct failure, nonzero exit, overlap, filtering, throwing after-recording hooks, distinct tasks, finite persistence, and real background child storage behavior.
Install one worker-owned Symfony dump wrapper that records active dumps and delegates inactive or failed-cache paths to the prior handler with labels intact. Refuse installation without a prior owner and avoid wrapper stacking. Reset handler ownership through Telescope's optional test-state cleanup instead of retaining closures from destroyed applications. Type the dump controller to the cache repository and cover every installation, delegation, failure, reset, and re-registration branch.
Apply the configured dashboard domain directly to route metadata, gate Redis, cache, and Guzzle instrumentation behind Telescope's master switch, and keep storage and console registration available through the existing package lifecycle. Add Composer pre-uninstall cleanup, type the recording cache boundary and published gate stub, simplify configuration defaults, and cover domain dispatch, disabled instrumentation, installation output, and provider removal from the disposable application skeleton.
Add source-proven native types to command handlers, entry tags, and mailable tag registration without widening runtime behavior. Make queued-mail detection strict and remove the obsolete hostname-tag comment. These changes keep the public surface Laravel-compatible while making static analysis truthful and removing stale implementation residue.
Declare every direct extension, library, and Hypervel runtime requirement used by the standalone Telescope package, and remove the unused server dependency. Preserve package discovery through the Telescope service provider. Add one executable manifest contract that pins root-aligned external constraints, Hypervel replacement coverage, provider discovery, PHP support, and the removed dependency without duplicating import-scanner machinery.
Set the repository, Horizon, and Foundation renderer release-age policy to seven days and require an npm version that actually enforces it. Keep package-local policy where subtree splits need to remain independently reproducible. Remove misleading Horizon-local pnpm workspace configuration while retaining its npm lock contract, and align the root pnpm release-age value without introducing a monorepo catalog or hoisting machinery that would break split packages.
Move Telescope to the enforced seven-day npm policy, require npm 11.10 or newer, remove the unused local pnpm workspace, and refresh the complete dependency tree with the current safe Axios range. Display schedule status, exit code, and exception details from the corrected telemetry payload, then rebuild and review every tracked dashboard asset from source. Preserve Hypervel branding, Reverb and Context adaptations, and the generated Highlight.js whitespace required by its regex grammar.
Add the canonical Telescope documentation and upstream provenance links while keeping the package README intentionally thin. Correct watcher filtering, deferred recording, Reverb size units, and duplicated model-event guidance in the public guide. The documentation describes supported developer-facing behavior only and avoids duplicating internal worker, watcher, or storage implementation details.
Replace Horizon's temporary unsupported-feature note with one central follow-up for the approved Hypervel Sentinel port. Record the direct Horizon and Telescope dependencies, middleware insertion, source cleanup, and dashboard security coverage required when that package lands. This keeps the future work visible without adding temporary middleware, package stubs, or duplicate TODO comments to either dashboard package.
Reconcile the shared audit records with current 0.4, preserve Permission's active routing and existing telescope-04 ownership, and mark Telescope complete. Close Telescope revalidation for the routed DI, Support, Redis, Queue, and earlier Telescope findings without changing unrelated package dispositions. Record telescope-05 through telescope-40, the final architecture and rejected designs, Laravel API and performance effects, regression coverage, frontend advisory decisions, and the intentional generated Highlight.js diff-check exception.
Record the final evidence-backed design for Telescope storage, queries, recording, watcher ownership, schedule reconciliation, dump handling, routing, package lifecycle, frontend maintenance, public APIs, and documentation. Include the retained core anti-overengineering rules, complete file and counterfactual test inventory, performance and compatibility assessment, rejected alternatives, current 0.4 finding-ID reconciliation, and final audit-record requirements. The plan reflects the reviewed implementation rather than retaining superseded proposals or decision history.
Bring the completed Permission, JSON Schema, JWT, and shared metadata work into the Telescope branch. No incoming change overlaps Telescope runtime behavior or requires an implementation adjustment. Resolve the known Telescope metadata overlap with the reviewed superset manifest and single comprehensive metadata test, and retain the completed Telescope revalidation dispositions and ledger entry.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
🚧 Files skipped from review as they are similar to previous changes (5)
📝 WalkthroughWalkthroughTelescope receives storage, watcher, scheduling, routing, CSP, package lifecycle, documentation, and test updates. Package release-age policies and package metadata also change. ChangesTelescope correctness and lifecycle
Estimated code review effort: 5 (Critical) | ~90+ minutes Sequence Diagram(s)sequenceDiagram
participant Scheduler
participant ScheduleWatcher
participant EntriesRepository
participant TelescopeDashboard
Scheduler->>ScheduleWatcher: emit Finished or Failed event
ScheduleWatcher->>EntriesRepository: create or reconcile scheduled entry
EntriesRepository-->>TelescopeDashboard: return status, exit code, and exception data
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryThis PR comprehensively corrects Telescope storage, query, watcher, dashboard, and worker-lifecycle behavior while updating package metadata, frontend assets, tests, and documentation.
Confidence Score: 5/5The PR appears safe to merge because no blocking failure remains in the reviewed follow-up scope. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| src/telescope/src/Telescope.php | Strengthens coroutine-local recording settlement, queue behavior, and CSP nonce handling without an identified blocking regression. |
| src/telescope/src/Storage/DatabaseEntriesRepository.php | Corrects monitored-tag persistence, falsey filtering, deterministic deletion, update serialization, and exception-family aggregation. |
| src/telescope/src/Watchers/ScheduleWatcher.php | Reconciles Finished→Failed event ordering into one queued entry, with coroutine and deferred-storage behavior preserving the intended identity invariant. |
| src/telescope/src/Watchers/DumpWatcher.php | Introduces worker-owned dump-handler delegation and reset behavior; no eligible concrete failure was established. |
| src/telescope/src/TelescopeServiceProvider.php | Gates disabled-mode instrumentation and applies configured dashboard routing and watcher registration behavior. |
| src/telescope/src/Watchers/RequestWatcher.php | Preserves configured falsey secrets during redaction and enforces exact byte-size limits. |
| src/telescope/src/Watchers/JobWatcher.php | Clears stale job failure state and safely scopes batch lookup recording suppression. |
| src/telescope/src/Watchers/EventWatcher.php | Corrects event-prefix, payload, and listener metadata extraction while reducing repeated dispatcher resolution. |
| src/telescope/src/Watchers/ViewWatcher.php | Adds composer and creator metadata through the existing passive rendering observer. |
| src/telescope/composer.json | Declares direct package dependencies and registers uninstall cleanup. |
| src/telescope/package.json | Updates the standalone frontend toolchain and enforces the npm version required for release-age policy support. |
| src/telescope/resources/js/screens/schedule/preview.vue | Displays the newly recorded schedule status, exit code, and exception details. |
Reviews (2): Last reviewed commit: "Finalize Telescope review records" | Re-trigger Greptile
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (2)
src/telescope/src/Watchers/ScheduleWatcher.php (1)
79-115: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winClear the reconciliation context after it is used.
taskIdentity()returnsspl_object_id(). PHP reuses object ids after an object is destroyed. The context key is never cleared, so it survives for the whole coroutine. If a task object is freed and a laterEventreceives the same id,recordFailedCommandcan merge the failure outcome into the earlier task's queued entry. Thein_arrayqueue check does not prevent this, because the earlier entry stays queued until the coroutine stores its batch.In the current
schedule:runpath theScheduleholds everyEventfor the whole run, so id reuse is unlikely. Clearing the key still removes the hazard at near-zero cost and bounds the reconciliation window to one finished/failed pair.♻️ Proposed hardening
protected function recordFinishedCommand(Events\ScheduledTaskFinished $event): void { $task = $event->task; $exitCode = $task->exitCode(); + + CoroutineContext::forget(static::LAST_RECORDED_TASK_CONTEXT_KEY);if ($recorded !== null && $recorded['task'] === $this->taskIdentity($event->task) && in_array($recorded['entry'], Telescope::getEntriesQueue(), true) ) { $recorded['entry']->content = array_merge($recorded['entry']->content, $outcome); + CoroutineContext::forget(static::LAST_RECORDED_TASK_CONTEXT_KEY); return; }🤖 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/telescope/src/Watchers/ScheduleWatcher.php` around lines 79 - 115, Clear LAST_RECORDED_TASK_CONTEXT_KEY immediately after retrieving the reconciliation context in recordFailedCommand, before processing the recorded entry. Preserve the existing matching and merge behavior for the current finished/failed task pair, while ensuring subsequent events cannot reuse stale context.tests/Telescope/Watchers/DumpWatcherTest.php (1)
23-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSet the recording cache key in each dump recording test.
telescope:dump-watcheris currently written byFeatureTestCase::setUpBeforeClass()instead of being set per test. Explicitly put or foregettelescope:dump-watcherintestActiveDumpWatcherRecordsEntryAndLabelandtestWatcherDoesNotStackHandlersso the tests do not depend on shared test-state or order.🤖 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/Telescope/Watchers/DumpWatcherTest.php` around lines 23 - 41, Update testActiveDumpWatcherRecordsEntryAndLabel and testWatcherDoesNotStackHandlers to explicitly set or forget the telescope:dump-watcher recording cache key within each test, rather than relying on FeatureTestCase::setUpBeforeClass(). Ensure both tests establish their own cache state and remain independent of shared state or execution order.
🤖 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-08-08-1443-telescope-correctness-current-parity-and-watcher-lifecycles.md`:
- Line 228: Correct both occurrences of the “tor retrieve” typo in the audit
plan text to “to retrieve,” leaving the surrounding content unchanged.
- Line 566: Remove the leading space inside the Markdown code span containing
the nonce attribute in the dashboard style documentation, so it renders as
`nonce="..."` without preceding whitespace and satisfies Markdownlint MD038.
In `@src/telescope/config/telescope.php`:
- Around line 85-93: Update the queue configuration comment above the 'queue'
settings to reference the exact deferred-storage job class name,
ProcessPendingUpdates, using the plural form so users can locate the correct
queued job.
In `@src/telescope/src/Storage/EntryQueryOptions.php`:
- Around line 29-34: Validate raw request parameters for uuids and before at the
HTTP boundary before constructing EntryQueryOptions, rejecting scalar uuids and
array before values with the existing validation-error response rather than
invoking typed setters. Preserve valid array uuids and integer/string/null
before values, and add regression coverage for both malformed scalar and array
forms.
In `@src/telescope/src/Telescope.php`:
- Around line 842-846: Update cspNonceAttribute() to HTML-escape the retrieved
nonce with htmlspecialchars using ENT_QUOTES | ENT_SUBSTITUTE and UTF-8 before
interpolating it into the nonce attribute, while preserving the empty-string
behavior when no nonce exists.
In `@src/telescope/src/Watchers/ViewWatcher.php`:
- Around line 104-137: Guard listener static-variable access in
getComposersForEvent() and isWildcardViewComposer() so missing listener,
wildcard, or callback keys do not raise undefined-key errors. Use safe defaults
(including treating absent wildcard as false), and ensure class-based or
otherwise unsupported listeners are rejected or skipped while valid closure
composers retain their current behavior.
---
Nitpick comments:
In `@src/telescope/src/Watchers/ScheduleWatcher.php`:
- Around line 79-115: Clear LAST_RECORDED_TASK_CONTEXT_KEY immediately after
retrieving the reconciliation context in recordFailedCommand, before processing
the recorded entry. Preserve the existing matching and merge behavior for the
current finished/failed task pair, while ensuring subsequent events cannot reuse
stale context.
In `@tests/Telescope/Watchers/DumpWatcherTest.php`:
- Around line 23-41: Update testActiveDumpWatcherRecordsEntryAndLabel and
testWatcherDoesNotStackHandlers to explicitly set or forget the
telescope:dump-watcher recording cache key within each test, rather than relying
on FeatureTestCase::setUpBeforeClass(). Ensure both tests establish their own
cache state and remain independent of shared state or execution order.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4ec807a9-f288-4098-95cd-72d6341f9af2
⛔ Files ignored due to path filters (4)
src/telescope/dist/app.jsis excluded by!**/dist/**src/telescope/dist/styles-dark.cssis excluded by!**/dist/**src/telescope/dist/styles.cssis excluded by!**/dist/**src/telescope/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (77)
.npmrcdocs/plans/2026-07-12-0900-framework-coroutine-state-lifecycle-audit.mddocs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.mddocs/plans/2026-08-08-1443-telescope-correctness-current-parity-and-watcher-lifecycles.mddocs/todo.mdpnpm-workspace.yamlsrc/boost/docs/telescope.mdsrc/foundation/resources/exceptions/renderer/.npmrcsrc/foundation/resources/exceptions/renderer/package.jsonsrc/horizon/.npmrcsrc/horizon/README.mdsrc/horizon/package.jsonsrc/horizon/pnpm-workspace.yamlsrc/telescope/.npmrcsrc/telescope/README.mdsrc/telescope/composer.jsonsrc/telescope/config/telescope.phpsrc/telescope/package.jsonsrc/telescope/pnpm-workspace.yamlsrc/telescope/resources/js/screens/schedule/index.vuesrc/telescope/resources/js/screens/schedule/preview.vuesrc/telescope/src/Actions/UninstallAction.phpsrc/telescope/src/Console/ClearCommand.phpsrc/telescope/src/Console/PauseCommand.phpsrc/telescope/src/Console/PruneCommand.phpsrc/telescope/src/Console/PublishCommand.phpsrc/telescope/src/Console/ResumeCommand.phpsrc/telescope/src/EntryResult.phpsrc/telescope/src/ExceptionContext.phpsrc/telescope/src/ExtractProperties.phpsrc/telescope/src/ExtractTags.phpsrc/telescope/src/ExtractsMailableTags.phpsrc/telescope/src/Http/Controllers/DumpController.phpsrc/telescope/src/Http/Controllers/QueueBatchesController.phpsrc/telescope/src/Http/Controllers/QueueController.phpsrc/telescope/src/Http/Controllers/RecordingController.phpsrc/telescope/src/IncomingEntry.phpsrc/telescope/src/Jobs/ProcessPendingUpdates.phpsrc/telescope/src/Storage/DatabaseEntriesRepository.phpsrc/telescope/src/Storage/EntryModel.phpsrc/telescope/src/Storage/EntryQueryOptions.phpsrc/telescope/src/Telescope.phpsrc/telescope/src/TelescopeServiceProvider.phpsrc/telescope/src/Watchers/BatchWatcher.phpsrc/telescope/src/Watchers/ClientRequestWatcher.phpsrc/telescope/src/Watchers/DumpWatcher.phpsrc/telescope/src/Watchers/EventWatcher.phpsrc/telescope/src/Watchers/FetchesStackTrace.phpsrc/telescope/src/Watchers/JobWatcher.phpsrc/telescope/src/Watchers/RequestWatcher.phpsrc/telescope/src/Watchers/ReverbWatcher.phpsrc/telescope/src/Watchers/ScheduleWatcher.phpsrc/telescope/src/Watchers/ViewWatcher.phpsrc/telescope/stubs/TelescopeServiceProvider.stubsrc/testing/src/PHPUnit/AfterEachTestSubscriber.phptests/Telescope/Actions/UninstallActionTest.phptests/Telescope/Console/InstallCommandTest.phptests/Telescope/Http/CspTest.phptests/Telescope/Http/QueueBatchesControllerTest.phptests/Telescope/Http/RouteTest.phptests/Telescope/Jobs/ProcessPendingUpdatesTest.phptests/Telescope/PackageMetadataTest.phptests/Telescope/Storage/DatabaseEntriesRepositoryTest.phptests/Telescope/Telescope/TelescopeTest.phptests/Telescope/Watchers/ClientRequestWatcherTest.phptests/Telescope/Watchers/DisabledWatcherTest.phptests/Telescope/Watchers/DumpWatcherTest.phptests/Telescope/Watchers/EventWatcherTest.phptests/Telescope/Watchers/ExceptionWatcherTest.phptests/Telescope/Watchers/GateWatcherTest.phptests/Telescope/Watchers/JobWatcherTest.phptests/Telescope/Watchers/QueryWatcherTest.phptests/Telescope/Watchers/RequestWatchersTest.phptests/Telescope/Watchers/ReverbWatcherTest.phptests/Telescope/Watchers/ScheduleWatcherTest.phptests/Telescope/Watchers/ViewWatcherTest.phptests/Testing/PHPUnit/AfterEachTestSubscriberTest.php
💤 Files with no reviewable changes (5)
- src/telescope/pnpm-workspace.yaml
- src/telescope/src/IncomingEntry.php
- src/horizon/pnpm-workspace.yaml
- src/horizon/README.md
- src/telescope/src/ExtractTags.php
Escape coroutine-local CSP nonce values at the HTML attribute sink before rendering dashboard style and module-script tags. Add a quote-bearing nonce regression that verifies both attributes contain encoded output and never expose raw attacker-controlled markup. Preserve the existing Laravel-facing CSP API and coroutine-local ownership.
Capture the concrete event dispatcher once when EventWatcher registers, removing the per-recorded-event container lookup and its static-analysis suppression. Require a real class before inspecting queued listener interfaces so closure source paths containing an at sign cannot be mistaken for Class@method listeners. Restrict passive view metadata reflection to dispatcher wrappers that captured closures, removing dead array branches and their reachable class-string TypeError. Add counterfactual coverage for at-sign closure paths and direct class-array view listeners, including positive controls proving the listeners still execute.
Update the Telescope configuration guidance to reference ProcessPendingUpdates, matching the actual Hypervel and Laravel job class. This keeps the operational documentation accurate for deployments that schedule the pending-update worker.
Amend the completed Telescope design and audit ledger with the final CSP output boundary, passive view-listener invariant, EventWatcher dispatcher ownership, and closure-path safety behavior. Record the counterfactual coverage and performance effects in the existing telescope-12 finding group. Preserve rejected partial query validation and redundant schedule-context cleanup as explicit non-designs without adding decision-history noise.
|
@coderabbitai Follow-up complete. Applied:
No change was needed for the remaining items:
The full project gate was green before review. The affected watcher and CSP tests, formatter, default targeted PHPStan, specialized types gate, and diff validation are green after these corrections. |
|
The remaining items do not require changes under the stated contracts. I have recorded the relevant lifecycle and test-setup constraints for future reviews. ✏️ Learnings added
If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! ✅ Action performedComments resolved. Approval is disabled; enable |
|
@coderabbitai review |
✅ Action performedReview finished.
|
Summary
This PR completes the Telescope correctness, current-parity, and lifecycle work.
It corrects storage and query behavior, including monitored-tag inserts, invalid UTF-8 updates, falsey filters, ordered deletion, exception-family aggregation, and nullable custom repository results.
It also fixes watcher and recording lifecycles: recording guards always settle, schedule outcomes remain one row across the established Console event order, processed jobs clear stale failure state, request redaction preserves falsey secrets, byte limits are exact, and dump handling has one worker-owned wrapper with safe delegation and cleanup.
Dashboard routing now honors the configured domain, globally disabled Telescope installs less instrumentation, CSP nonces are coroutine-local, queue details are complete, Composer uninstall removes the published provider, and the split package declares its direct dependencies.
The dashboard frontend is rebuilt from the updated source and dependency tree. Schedule status and failures are visible, standalone npm release policy is consistent across split packages, public documentation is current, and future Sentinel integration is recorded in one place.
For more details, see
docs/plans/2026-08-08-1443-telescope-correctness-current-parity-and-watcher-lifecycles.md.Compatibility and performance
Laravel-facing APIs, named arguments, callbacks, configuration, repository contracts, and protected extension points are preserved or restored. Hypervel coroutine-local recording, passive view observation, lazy monitored tags, Reverb and Context telemetry, and stateless Guzzle AOP remain intact.
Disabled Telescope performs less boot-time work. Enabled paths remain bounded: monitored tags use one bulk insert, exception updates are aggregated, ordered deletes use indexed columns, schedule reconciliation avoids another database query, and view reflection runs only for recorded views. No request middleware, polling loop, lock, retry layer, or unbounded worker state is introduced.
Testing
composer fix.src/telescope/dist/app.js; normalizing it changes the bundled regex.Summary by CodeRabbit
New Features
Bug Fixes
Documentation