# Gemini Project Overview: `jspg` This document outlines the purpose of the `jspg` project and the specific modifications made to the vendored `boon` JSON schema validator crate. ## What is `jspg`? `jspg` is a PostgreSQL extension written in Rust using the `pgrx` framework. Its primary function is to provide fast, in-database JSON schema validation against the 2020-12 draft of the JSON Schema specification. It works by: 1. Exposing a SQL function, `cache_json_schemas(...)`, which takes arrays of schema objects, compiles them, and caches them in memory. 2. Exposing a SQL validation function, `validate_json_schema(schema_id, instance)`, which validates a JSONB instance against one of the pre-cached schemas. 3. Using a locally modified (vendored) version of the `boon` crate to perform the validation, allowing for custom enhancements to its core logic. ## `boon` Crate Modifications The version of `boon` located in the `validator/` directory has been modified to address specific requirements of the `jspg` project. The key deviations from the upstream `boon` crate are as follows: ### 1. Correct Unevaluated Property Propagation in `$ref` - **Problem:** In the original `boon` implementation, if a schema validation failed inside a `$ref`, the set of properties that had been evaluated by that referenced schema was not correctly propagated back up to the parent validator. This caused the parent to incorrectly flag already-evaluated properties as "unevaluated," leading to spurious `unevaluatedProperties` errors. - **Solution:** The `Uneval::merge` function in `validator/src/validator.rs` was modified. The original logic, which performed an *intersection* of unevaluated properties (`retain`), was replaced with a direct *assignment*. Now, the parent validator's set of unevaluated properties is completely replaced by the final set from the child validator. This ensures that the most current state of evaluated properties is always passed up the chain, regardless of validation success or failure within the `$ref`. ### 2. Runtime Strictness Control - **Problem:** The `jspg` project requires that certain schemas (e.g., those for public `puncs`) enforce a strict "no extra properties" policy, while others do not. This strictness needs to cascade through the entire validation hierarchy, including all `$ref` chains. A compile-time flag was unsuitable because it would incorrectly apply strictness to shared, reusable schemas. - **Solution:** A runtime validation option was implemented. 1. A `ValidationOptions { be_strict: bool }` struct was added and is passed to the core `validate` function in `validator.rs`. 2. The `jspg` code determines whether a validation run should be strict (based on the `punc`'s `public` flag or if we are validating a a global `type`) and passes the appropriate option. 3. The `Validator` struct carries these options through the entire recursive validation process. 4. The `uneval_validate` function was modified to only enforce this strict check if `options.be_strict` is `true` **and** it is at the root of the validation scope (`self.scope.parent.is_none()`). This ensures the check only happens at the very end of a top-level validation, after all `$ref`s and sub-schemas have been processed. 5. When this runtime strictness check fails, it now generates a more descriptive `ADDITIONAL_PROPERTIES_NOT_ALLOWED` error, rather than a generic `FALSE_SCHEMA` error.