Files
jspg/GEMINI.md
2025-09-30 01:10:58 -04:00

3.4 KiB

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 $refs 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.