Skip to content

Fix JSON correctness and package metadata discovery - #13

Closed
binaryfire wants to merge 43 commits into
0.4from
fix/json-correctness
Closed

Fix JSON correctness and package metadata discovery#13
binaryfire wants to merge 43 commits into
0.4from
fix/json-correctness

Conversation

@binaryfire

Copy link
Copy Markdown
Collaborator

Overview

This PR makes JSON nesting and failure behavior consistent across framework-owned storage, transport, validation, diagnostics, and package discovery.

The main rule is simple: a value accepted at Hypervel's public maximum of 512 nested containers must remain readable by the matching framework boundary. PHP uses different depth units for encoding and decoding, so a value encoded with depth 512 requires native decode depth 513. Several framework paths used 512 for both and could turn valid data into null, false, an empty result, or an unrelated type error.

This change defines that contract once in Support Json and applies it only where Hypervel owns both sides of the round trip. External input and protocol-specific readers keep their existing contracts.

What changed

Shared JSON behavior

  • Support Json now treats depth as a nested-container limit and translates it for native decode and validation calls.
  • Caller flags are preserved for encode and decode.
  • Jsonable values receive caller flags plus throwing behavior while retaining ownership of their own depth.
  • Str JSON predicates and framework test-response readers use the same validation and decode contract.
  • Collections, Filesystem, Composer files, maintenance data, HTTP JSON responses, outgoing client requests, JSON sessions, XML normalization, and Inertia test data now preserve framework-owned maximum-depth round trips.

Concurrency transport

  • Serialized closure command ownership moves from Foundation to Concurrency.
  • SerializedClosureResult owns envelope validation, remote exception reconstruction, binary result decoding, gzip-marker handling, and unserialization failures.
  • ProcessDriver and Testbench delegate to the same decoder.
  • Package dependencies and tests move with the implementation.

Request validation

  • Request JSON casts and both validator execution paths use the shared JSON contract.
  • Malformed, empty, and over-depth JSON fail consistently before array, collection, object, or JSON casting.
  • The unused request JSON encoder and obsolete validation fallback are removed.
  • The validation documentation now demonstrates JSON-string input for JSON-backed casts.

Eloquent and database boundaries

  • Eloquent JSON encoding and decoding use matching depth limits while preserving model and attribute context on write failures.
  • First-party JSON class casts reject failed encodes before storage or encryption and validate decoded shapes before construction.
  • JSON path assignment uses the existing attribute encoder instead of duplicating its failure handling.
  • A valid assignment can repair malformed readable JSON, while decryption failures remain fail-loud and cannot authorize overwrite.
  • Query grammars for MySQL, MariaDB, PostgreSQL, and SQLite reject invalid JSON bindings before query execution.
  • Database console commands report native JSON errors instead of passing false into output rendering.

Telescope

  • Stored entries use one readable codec.
  • A depth-overflowing top-level field is replaced with Telescope's existing purge marker while unrelated fields remain available.
  • Non-depth encoding failures remain fail-loud.
  • Exception visibility updates and replacement inserts run atomically in deterministic family order.
  • Structured request and response payloads are masked before size checks.
  • JSON and URL-encoded request bodies cannot fall through to raw storage with configured secrets.
  • Opaque bodies and explicit plain text keep their existing representation.
  • Application responses are decoded once, and deep structured responses are purged without making the entry itself unreadable.

Package discovery

  • Missing Composer metadata remains a supported empty state.
  • Malformed syntax and invalid consumed structures now fail package discovery instead of silently publishing an incomplete cache.
  • Root wildcard and package-specific ignore behavior is preserved and runs before metadata that the application chose not to consume.
  • Package names, versions, and extra.hypervel containers produce path-specific errors.
  • Framework and Testbench discovery share the same focused metadata checks without adding a general parser layer.

Compatibility and cost

Public and protected Laravel-style surfaces are preserved. Explicit native depth arguments on APIs that already expose native PHP semantics remain native. Eloquent custom codecs, stored empty-string handling, filesystem flags, session recovery, raw process output, and opaque Telescope payload behavior remain intact.

Normal JSON reads add one branch and integer increment. Telescope storage still encodes once on success; field-by-field recovery runs only after a depth error. Structured payloads still mask and encode once. The exception transaction is limited to exception chunks. The change adds no cache, registry, retry loop, container lookup, worker state, or general successful-path preflight.

Malformed package metadata now fails loudly by design. Missing metadata remains supported.

Testing

The branch includes focused regressions for every changed boundary, including depth limits, native flags and errors, Eloquent custom and encrypted casts, repair behavior, query grammars, Telescope storage and redaction, serialized closure envelopes, and package discovery.

Verification includes the full Components fix pipeline, Testbench and dogfood suites, focused package suites, and the SQLite, PostgreSQL, MySQL, and MariaDB integration matrices.

Define the implementation-ready plan for Testbench runtime clone ownership, application teardown, configuration loading, SQLite handling, filesystem publication, migration rollback, and split-package metadata.\n\nPreserve the existing worker and parallel-testing model while making partial setup transactional, cleanup exhaustive, and failures truthful. Record the approved Pest cleanup, current upstream parity decisions, anti-overengineering constraints, counterfactual tests, verification cadence, and final audit-record updates.
Rewrite the Testbench remediation plan around Hypervel's long-lived worker and parallel-test ownership model. Restore eager WithConfig timing, distinguish Foundation and Testbench teardown gates, and specify terminate-then-flush ownership for partial applications without changing the established worker clone or service-isolation architecture.

Document the complete filesystem, SQLite, migration, route-cache, metadata, and failure-path designs with counterfactual tests and explicit anti-overengineering constraints. Pin the current Orchestra Testbench 11.4.0 reference and record the two deliberate PHPStan differences that must survive future parity work.

This commit contains only the corrected implementation-ready plan; the existing source and test changes remain uncommitted for implementation review.
Create each worker runtime root with owner-only permissions and verify every required copy before publishing it as active. Preserve active overlays, roll back only paths created by the failed attempt, and keep stale foreign cleanup serialized and best-effort.\n\nRestrict the monorepo configuration fallback to the components root package and expand the runtime tests to cover permissions, copy failures, overlay preservation, partial rollback, and stale worker ownership.
Treat empty YAML documents as defaults, normalize nullable mapping sections, and reject malformed roots or mapping values with clear configuration errors. Preserve associative default keys when combining applicable configuration and describe untrusted seeder values accurately at the runtime boundary.\n\nAdd focused coverage for empty documents, invalid shapes, private monorepo fallback behavior, and top-level configuration key preservation.
Keep WithConfig on Hypervel's worker-startup boundary so providers observe finalized process-global configuration during both registration and boot. Record why Orchestra's deferred mode is intentionally omitted and document explicit test-body mutation as the post-boot alternative.\n\nRemove exception-swallowing around attribute parsing so constructor, target, reflection, and resolver failures reach the test author. Remove invalid Fortify method attributes and add counterfactual coverage for provider timing and wrong-target failures.
Terminate and flush every partially constructed or replaced Testbench application without allowing cleanup failures to hide the original bootstrap error. Restore process-global timezone and environment state at the test-lifetime boundary, run destruction callbacks after failed reloads, and avoid invoking application-bound attributes against stale containers.\n\nUse full reloads at Sentry replacement sites while retaining the intentional raw cached-state refresh. Add lifecycle regressions for null applications, failed replacements, cleanup ordering, callback replay, exact global restoration, and the PHPStan capability guard required by the open CreatesApplication trait.
Classify SQLite memory and URI identifiers before applying local-file fallback behavior. Check every backup, copy, and restore operation, assign backup ownership only after success, and purge the active connection around each swap.\n\nRestore the exact worker-global database configuration even when either purge fails, preserve the primary callback failure, and add focused failure-injection coverage for every filesystem and connection boundary.
Detach terminating callbacks before execution, run every independent cleanup action, clear reentrant registrations, and preserve the first failure without replay. Render cleanup failures through the normal command boundary while retaining established signal exit codes.\n\nClarify temporary application ownership around vendor-link actions: failing wrappers dispose locally, successful returns transfer ownership to Commander, and actions never flush caller-owned applications. Verify link publication and discovery rollback, and cover normal, exceptional, and signal-driven teardown paths.
Unlink a top-level directory symlink before recursive deletion so deleting the link never removes content from its target. Preserve the established clean-directory behavior when callers explicitly request contents-only cleanup.\n\nMake Testbench directory actions admit live and broken links through this shared boundary, exhaust all requested deletions, and report checked failures. Add direct filesystem and action regressions for ordinary directories, linked children, broken links, and target preservation.
Require every owned copy, delete, and restore operation to succeed before reporting a synchronized skeleton state. Register restoration only after a backup is established, preserve user files when publication fails, and continue independent cleanup while retaining the first failure.\n\nKeep file and directory ownership distinct, skip real directories passed to file deletion, and add exact false-return regressions with positive controls for each filesystem operation.
Run every independent purge step while returning a standard failure status when any child command or cleanup action fails. Stop installation immediately when SQLite database creation fails so autoload generation and success output cannot describe an incomplete install.\n\nCover heterogeneous child failures, exhaustive purge behavior, and the install short-circuit without introducing a new status abstraction.
Stage and verify each Workbench symlink before replacing an existing destination, preserve displaced content in a backup until publication succeeds, and remove only links owned by the current run. Keep a valid published link and recoverable backup when backup cleanup itself fails.\n\nRemove redundant Workbench seeder assignment and add failure-injection coverage for staging, publication, rollback, cleanup, broken links, and the retained safe state.
Publish generated routes atomically, capture the exact worker cache path before reloads, and register cleanup that does not depend on a live replacement application. Preserve loader closure scope required by dynamic route files and remove every owned route artifact after a failed reload without masking its error.\n\nMake published-file cleanup exhaustive and failure-reporting while retaining existing snapshots and exclusions. Add counterfactual coverage for failed publication, failed reloads, cache cleanup, closure-stash routes, and surviving published files.
Track only batches created by each Testbench setup, keep repository reads and commands on the selected connection, and roll owned batches back in descending order with repository postcondition checks. Preserve the setup failure while compensating partial migrations and continue all independent cleanup after rollback failures.\n\nRegister paths directly when a later database-refresh concern owns migration execution, honor child command status, and reject invalid or failing configured seeders. Cover existing batches, step migrations, partial failure, secondary connections, refresh ownership, retained batches, and no-replay cleanup.
Delegate path joining to the shared Filesystem helper while preserving Testbench's relative-path contracts, consumer-selected Workbench roots, zero-argument calls, and external absolute paths. Correct variadic PHPDocs and forward path segments without losing their positional shape.\n\nSerialize environment values through one quoting boundary, preserve the valid string zero, and prove semantic dotenv round trips. Extend dogfood coverage so split-package Workbench paths exercise both ordinary and explicit-relative forms.
Terminate and flush every parent-process application created by the parallel runner after clearing its worker-token resolver. Preserve callback failures over cleanup failures, continue flush after a failed termination, and keep attempted-token ownership unchanged.\n\nJoin every test-binary path segment before calling the single-path application API so PHPUnit, ParaTest, and Pest resolve executable files rather than their vendor directory. Add regressions for cleanup order, resolver visibility, first-failure precedence, and every binary mode.
Delete the bundled Pest hook implementation that was never loaded and remove its remaining database callbacks. Keep the upstream detector used by the separate plugin while avoiding a package dependency or a second incomplete integration path.\n\nRemove dead internal annotation plumbing and obsolete coverage metadata, then complete native void typing across the remaining touched Testbench tests without changing their behavior.
Declare composer/semver and hypervel/di directly in the Testbench package metadata because split installations use both at runtime and cannot rely on the monorepo root's development graph or replace entries.\n\nAdd metadata coverage that verifies direct split requirements alongside the root development provisions so subtree releases remain independently installable.
Prefer Telescope values already installed in a child coroutine before reading the live parent. Coroutine forks install their captured snapshot before after-created callbacks run, so overwriting a present value can replace capture-time state after an earlier callback yields.\n\nRetain ordinary-create and omitted-key inheritance, document the cross-package ordering invariant, and add real-provider regressions that prove both the forced interleaving and captured false-value preservation.
Record the completed Testbench, Testing, Filesystem, and Telescope findings with their owning packages, counterfactual coverage, compatibility impact, and bounded performance costs. Reconcile prior Coroutine and Sentry carry-forward records with the verified Telescope consumer fix.\n\nUpdate the routing index, dependency map, active work units, and package checklist without duplicating findings or overstating validation. The records now reflect the final green gates and independent review signoff.
Capture the final design for runtime clone ownership, eager configuration, application teardown, SQLite restoration, console and filesystem cleanup, migration batches, route publication, helper contracts, split metadata, and Telescope fork propagation.\n\nDocument the retained Hypervel architecture, rejected complexity, Laravel and Orchestra compatibility decisions, performance bounds, exact counterfactual coverage, verification cadence, and completed status so future work preserves the reasons behind each boundary.
Assert that Testbench's external and internal dependency keys exist before comparing their constraints with the monorepo root.

Missing split metadata now produces an exact PHPUnit assertion instead of an undefined-array-key error, matching the repository-wide package metadata convention added on 0.4.
# Conflicts:
#	docs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.md
Exercise the named vendor-symlink deletion exception against a protected procfs link that cannot be removed even when CI runs as root. This replaces the parent-permission setup that root can bypass inside the Swoole job container.\n\nUse PHPUnit's exception expectation instead of catching RuntimeException around an explicit failure assertion, preventing the test from mistaking its own AssertionFailedError for the production exception.
Cache trait metadata by the consuming test class so sibling Testbench subclasses cannot inherit stale concern discovery from one shared static value. Move bootstrap-file selection onto each owning object so standalone applications with different base paths cannot reuse another instance's path.

Preserve kernels bound by standalone custom bootstrap files and explicitly close Hypervel's manual Testbench bootstrap sequence before invoking the retained console kernel. This prevents configuration and providers from replaying while keeping command loading intact.

Split Foundation lifecycle coverage from Testbench concern coverage and add counterfactual regressions for class-scoped trait maps, instance-scoped bootstrap files, custom kernel retention, and framework-bootstrap replay.
Document the class-keyed trait cache, instance-owned bootstrap-file selection, and standalone custom-kernel lifecycle. Record why Hypervel closes its manual bootstrap sequence before invoking retained kernels and which Testbench HTTP-stack replacements intentionally remain.

Update the audit ledger and Foundation test inventory with the completed regressions, performance assessment, compatibility boundary, and final review status for testbench-30 and testbench-31.
…ity-lifecycles

Fix Testbench lifecycle, ownership, and parity
Treat the public depth argument as a maximum number of nested containers and translate it to PHP's distinct decode and validation depth unit.

Preserve caller flags, forward throwing behavior to Jsonable values, use json_validate for predicates, and align framework response test readers with the shared contract. Add boundary, native-error, and flag-forwarding coverage.
Raise native decode depths where Collections consumes JSON produced at the framework's 512-container limit. Keep the dependency direction intact rather than coupling Collections back to Support.

Cover collection decoding, Jsonable item serialization, and Arr conversion at the supported boundary and one level beyond it.
Use PHP's native 513 decode depth in both filesystem JSON readers so documents written with 512 nested containers remain readable.

Retain the existing flags-controlled error behavior and missing-file contract, with regressions for maximum depth, overflow, malformed input, and throwing mode.
Route Composer file reads and writes through the shared JSON contract so maximum-depth metadata can be read after it is written.

Encode before inspecting file mode or replacing bytes, ensuring over-depth or otherwise invalid callback results fail without changing the original file. Cover the supported boundary and byte-for-byte failure preservation.
Align maintenance data, HTTP request and response payloads, JSON sessions, XML normalization, and Inertia test data with the shared nesting contract.

Values encoded at 512 nested containers now decode through their owning boundary, while one-level-over values fail at encoding or validation instead of becoming null or unrelated type errors. Existing output shapes and non-throwing session recovery remain unchanged.
Move the serialized-closure command to Concurrency and centralize response-envelope decoding, remote exception reconstruction, binary result handling, and malformed transport errors in SerializedClosureResult.

Delegate ProcessDriver and Testbench process results to the shared decoder, declare their direct package dependencies, and move the command, fixture, and process tests to the owning package. Preserve raw non-closure output and transport-specific encoding behavior.
Route request JSON casts and both validator execution paths through the shared JSON contract, removing the unused request encoder and the dead PHP-version fallback.

Malformed, empty, and over-depth JSON strings now fail consistently in interpreted and compiled validation before array, collection, object, or JSON casting. Correct the public example and cover the normal validated form-request path.
Give Eloquent's codec matching write and read depth limits, keep contextual model errors for failed encodes, and validate decoded shapes before constructing first-party JSON class casts.

Use the existing JSON attribute encoder for path assignments and let valid values replace malformed readable originals without swallowing decryption failures. Cover primitive, encrypted, enum, collection, fluent, data-object, custom codec, and cross-engine repair behavior.
Enable native throwing JSON encoding in base, MySQL, MariaDB, PostgreSQL, and SQLite binding preparation so recursion, non-finite values, and depth failures cannot reach query execution as false.

Keep each grammar's existing encoding flags and binding shapes, tighten an adjacent PostgreSQL comparison, and exercise the protected preparation methods directly across all supported grammar families.
Make database show and table commands raise the native JSON error at serialization time instead of passing false into Symfony output.

Add focused probes for valid output and non-finite metadata so command rendering preserves its existing format while failures retain their real cause.
Store entries through one readable codec, purge only top-level fields that exceed the entry envelope, and keep exception visibility updates and replacement inserts atomic in deterministic family order.

Normalize diagnostic objects with fail-loud encoding, parse application responses once, and unify client request and response masking before size checks. Structured JSON and form bodies can no longer fall through to raw storage with configured secrets, while opaque and explicit text payload behavior remains unchanged.

Cover maximum-depth storage, field recovery, failure ordering, exception family state, updates, structured and raw redaction, response parsing, and watcher normalization.
Distinguish missing Composer metadata from malformed or structurally invalid metadata during framework and Testbench package discovery. Validate package names, versions, and extra.hypervel containers only when they are consumed, preserving wildcard and package-specific ignore semantics.

Share focused package-name and Hypervel-extra readers without adding a parser abstraction, keep protected formatting parity, and fail before publishing a replacement manifest. Cover root and installed metadata, ignored packages, cache preservation, test-state registration, and subprocess startup diagnostics.
Record the final depth, storage, redaction, Eloquent repair, serialized transport, and package metadata contracts implemented by this branch.

Include the verified native JSON behavior, ownership boundaries, anti-overengineering constraints, file map, testing matrix, performance expectations, compatibility notes, and primary references needed to maintain the changes.
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1dbf2bab-166d-48cd-a125-8c2bd46149e8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@binaryfire binaryfire closed this Aug 11, 2026
@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown

Greptile Summary

This PR standardizes framework-owned JSON round trips, hardens package metadata discovery, centralizes concurrency result decoding, and completes broad Testbench lifecycle corrections.

  • Defines shared JSON nesting, validation, flag-preservation, and failure semantics across framework boundaries.
  • Validates Eloquent casts, database JSON bindings, Telescope payloads, and request/response JSON handling.
  • Moves serialized closure response decoding into Concurrency and shares it with Testbench.
  • Makes malformed consumed Composer metadata fail with path-specific diagnostics while preserving ignored and missing metadata behavior.
  • Expands Testbench lifecycle, cleanup, migration, route, filesystem, and parallel-worker coverage.

Confidence Score: 5/5

The PR appears safe to merge because no concrete changed-code failure remained after tracing the principal JSON, concurrency, package-discovery, Telescope, database, and Testbench paths.

The shared depth conversion is consistently applied to framework-owned boundaries, strict metadata failures are intentional, concurrency envelopes are validated before reconstruction, and no reachable lifecycle or cleanup regression was established.

Important Files Changed

Filename Overview
src/support/src/Json.php Defines the shared 512-container contract, converts it to PHP’s native decoding depth, preserves caller flags, and consistently throws on encoding or decoding failures.
src/concurrency/src/SerializedClosureResult.php Centralizes response-envelope validation, remote exception reconstruction, strict base64 decoding, and serialized-result validation.
src/foundation/src/PackageManifest.php Replaces permissive Composer metadata parsing with focused structural validation while retaining missing metadata and ignore behavior.
src/database/src/Eloquent/Concerns/HasAttributes.php Routes JSON-path writes through contextual encoding and permits valid assignments to compare against malformed original JSON without hiding current-value failures.
src/telescope/src/Storage/DatabaseEntriesRepository.php Uses the shared JSON codec, purges only depth-overflowing fields, and atomically updates exception-family visibility with inserts.
src/telescope/src/Watchers/ClientRequestWatcher.php Reworks structured request masking and representation so configured secrets cannot fall through to raw body storage.
src/testbench/src/Concerns/CreatesApplication.php Revises application bootstrap ownership and teardown behavior to avoid replaying bootstrappers and leaking state between tests.
src/testbench/src/Concerns/Database/InteractsWithSqliteDatabaseFile.php Strengthens SQLite test-database path selection, creation, cleanup, and worker ownership.
src/testbench/src/Database/MigrateProcessor.php Adds explicit migration execution and rollback ownership used by Testbench lifecycle cleanup.
src/testbench/src/Console/Commander.php Hardens command execution, environment handling, cleanup, and failure propagation across Testbench subprocess workflows.

Reviews (1): Last reviewed commit: "docs: add JSON correctness implementatio..." | Re-trigger Greptile

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