Skip to content

Milestone: 4.0.0-beta.1 #1214

Description

@jsenko

4.0.0-beta.1

The first published artifact of the 4.0 line. Almost everything it ships has already landed on
main: the JSON Schema compatibility checker covering drafts 4/6/7 and 2019-09/2020-12, upfront
dereferencing, cross-version comparison through a compound schema, the generator work underneath
it, and — most recently — the JSON Schema packages transpiling to TypeScript for the first time.

What remains is making it consumable: a migration guide, documentation that matches the code, and
a verified build. Registry integration also needs the checker to be at least as good as the one it
replaces, which pulled in boolean roots, nested-difference reporting and a set of wrong-verdict
fixes (items 4–16). The release itself is a workflow run.

Why a beta rather than 4.0.0. The breaking changes hit the shared core runtime that every
consumer depends on, not only JSON Schema, so semver requires a major. But the library API surface
has not been reshaped yet, and that reshaping is deliberately deferred until Registry integration
shows what a real consumer needs. The beta line exists to publish something usable now without
freezing an API that is still expected to change.

Goals

  • Registry can depend on a published artifact rather than a local snapshot.
  • A consumer upgrading from 3.x can find out what broke and what to do about it.
  • The published documentation describes the API that actually exists.
  • The checker never calls a change compatible that Registry's existing checker correctly rejects.

Items

  1. Write the 3.x to 4.0 migration guide #1215 — a 3.x → 4.0 guide exists only as a working draft
    outside the repository, so it is invisible to everyone it is written for. It needs to become a
    real document in docs/, covering the core-runtime changes that affect every consumer
    (RootNode removed and Node.root() moving to RootCapable, Node.attach() removed,
    traversal entry points taking Any, the ModelType JSON Schema constant renames, and the
    removal of the JsonUtil typed-accessor family), the JSON Schema model renames, and the
    compatibility checker's move from static methods to builders. Each change wants a before/after,
    not just a name.

  2. Refresh the user guide for the 4.0 API #1216 — docs/user-guide/schema-compatibility.md
    currently documents JsonSchemaCompatibilityChecker.isBackwardCompatible(...) and its
    siblings, which no longer exist — the entry points are builder-based. Both the Java and the
    TypeScript examples are affected, so the published documentation's primary example does not
    compile against the artifact being released. reading-and-writing.md uses the deprecated
    Document-typed methods throughout; those still work, so it is a lesser problem but the same
    one. The guide should also say that JSON Schema is now available in the TypeScript package,
    which it was not before.

  3. Verify the full build and generated output before the beta #1217 — a green mvn clean install -Ptranspilation
    on both CI JDKs, plus a diff of the generated OpenAPI and AsyncAPI sources against the
    3.1.x maintenance branch to confirm no unintended accessor-signature changes reached specs that were not the
    target of this work. The JSON Schema spec was deliberately rewritten; OpenAPI and AsyncAPI were
    not, and that distinction has not been verified since.

  4. Report the leaf difference for a nested change, not only the containing property #1224 — a change nested inside properties is reported only as a change to the containing
    property: maxLength going from 10 to 5 on property a yields
    OBJECT_TYPE_PROPERTY_SCHEMAS_CHANGED at /a, while the same edit at the root of a schema
    reports STRING_TYPE_MAX_LENGTH_DECREASED. The leaf differences are already computed on every
    nested comparison and discarded by an isolated scope, so the work is in deciding which to keep
    and how to attach them. Included in the beta because
    JSON Schema: modern draft support via Apitomy Data Models Apicurio/apicurio-registry#10219 makes replacing its
    existing checker conditional on the new one being at least as good as the one it replaces, and
    that checker reports "String type max length decreased" at /properties/a/maxLength.

  5. Support boolean schema roots through Library #1225 — a JSON Schema may be the literal true or false. Nested booleans already work, but
    Library.readRootFromJSONString("true") fails with a ClassCastException: the facade narrows
    to ObjectNode and casts, while the generated ModelReader.readRoot(JsonNode) underneath
    already accepts any node. The write side has the matching gap — there is no
    Library.writeRoot, and writeNode(Node) cannot take a boolean root because a boolean schema
    is a RootCapable but not a Node. Promoted into the beta by
    Compare the legacy and Apitomy JSON Schema checkers across the ported test corpus Apicurio/apicurio-registry#10221: the difference table came back clean apart from this one
    case. It was believed to be the only thing between Registry and deleting the checker it is
    replacing, until items 6–16 turned up.

  6. Check compatibility verdicts against a JSON Schema validator #1230 — the catalogue passes in full, yet targeted probing found the four defects below, three
    of them false "compatible"s and three of them regressions against Registry's existing checker.
    Hand-picked cases do not enumerate edit × location, and the Registry difference table ran
    over the same catalogue. This item checks verdicts against a JSON Schema validator over
    generated schema pairs and documents, on every draft. It comes first so that items 7–16 are
    fixed test-first, and anything else it finds joins this milestone.

  7. Nested traversal into definitions, $defs and prefixItems corrupts the checker's cross-field state #1226 — recursion into definitions, $defs and prefixItems reuses the diff visitor and
    overwrites the schemas its cross-field logic reads. Any schema with definitions can get the
    wrong verdict, in either direction. Regression.

  8. An incompatible change inside dependentSchemas is reported as compatible #1227 — an incompatible change inside dependentSchemas is reported under a constant that is
    flagged backward-compatible, so the check passes. Regression.

  9. Boolean subschema changes in items, unevaluatedItems and unevaluatedProperties are not compared #1228 — items, unevaluatedItems and unevaluatedProperties skip the comparison when either
    side is a boolean schema. Regression for items.

  10. Tuple validation is not normalised for 2019-09 and 2020-12 #1229 — 2019-09 tuples are never compared, and 2020-12 items next to prefixItems is
    ignored. Not a regression, since the existing checker cannot read these drafts, but wrong on
    the drafts this release exists to support.

  11. Adding type to an untyped schema is reported as compatible #1231 — adding type to an untyped schema that has other keywords is not reported. False
    "compatible", not a regression (the existing checker misses it too).

  12. Relaxing or adding a oneOf branch is reported as compatible #1232 — oneOf is compared as if it were anyOf, so relaxing or adding a branch passes even
    when a document can then match two branches. Not a regression. Two catalogue cases encode the
    wrong answer.

  13. Narrowing number to integer in a type list is reported as compatible #1233 — number → integer inside a type list is normalised away. Regression.

  14. Boolean schemas in a tuple cannot be read in drafts 4 to 2019-09 #1234 — a boolean tuple element (items: [true]) cannot be read in drafts 4 to 2019-09: the
    spec types tuple elements as full schemas. Regression, and a breaking change to the generated
    API, which is why it belongs in the beta.

  15. unevaluatedProperties and unevaluatedItems are ignored when properties or tuple positions change #1235 — unevaluatedProperties and unevaluatedItems are ignored when properties or tuple
    positions are added or removed, so the decision falls back to additionalProperties /
    additionalItems alone. Not a regression (modern drafts only), but a false "compatible".

  16. Replacing an anyOf alternative so that another is lost is reported as compatible #1245 — anyOf coverage is checked in the wrong direction: replacing an alternative so that
    another is lost (anyOf[string, integer] → anyOf[string, string]) passes. Regression. Fixed
    together with Relaxing or adding a oneOf branch is reported as compatible #1232, which changes the same function.

  17. Release 4.0.0-beta.1 #1218 — trigger release.yaml on main. The POM is already at
    4.0.0-beta.1-SNAPSHOT, and the workflow now understands pre-release versions: it will publish
    4.0.0-beta.1, mark the GitHub release as a prerelease, publish to npm under the beta
    dist-tag so latest stays on GA, and set the branch to 4.0.0-beta.2-SNAPSHOT afterwards.

Deferred

Recorded so the scope question is not re-opened. The backlog lives in #1042 and #1041.

  • The library API surface — capability accessors on Library, retiring the global reference
    resolver registry, generalising clone/transform off Document, and the read/write naming
    scheme. All breaking, all cheaper before GA than after, and all deliberately deferred so the
    shape can be decided with Registry as a real consumer rather than speculatively. To be resolved
    before 4.0.0, not before this beta.
  • Removing the deprecated *Document methods — they exist to give consumers a migration
    window across the beta line.
  • Dynamic reference resolution and configurable strictness — neither blocks a first published
    artifact. Note that the reporting half of the checker API is no longer deferred: item 4 pulls
    nested-difference reporting into the beta, because Registry's replacement decision turns on
    diagnostic quality and not only on verdicts.

Open questions

  • Should the migration guide cover the generator's own API, or only the library's? Generator users
    are a different and much smaller audience.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions