You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Note on compatibility change**: The compatibility percentage decreased from 65.9% to 54.4% because format validation is now implemented but follows the JSON Schema specification correctly - format validation is annotation-only by default and only asserts when explicitly enabled via format assertion controls. Many tests in the suite expect format validation to fail in lenient mode, but our implementation correctly treats format as annotation-only unless format assertion is enabled.
108
-
109
-
The metrics distinguish between:
110
-
-**unsupportedSchemaGroup**: Whole groups skipped due to unsupported features (e.g., $ref, anchors)
111
-
-**testException**: Individual tests that threw exceptions during validation
112
-
-**lenientMismatch**: Expected≠actual results in lenient mode (counted as failures in strict mode)
-**Contains validation**: `contains` with `minContains`/`maxContains` constraints
126
-
-**Unique items**: Structural equality using canonicalization for objects/arrays
127
-
-**Prefix items**: Tuple validation with `prefixItems` + trailing `items` validation
128
-
-**Combined features**: Complex schemas using all array constraints together
129
-
130
-
#### Format Validation Tests (`JsonSchemaFormatTest.java`) - Pack 5
131
-
-**Format validators**: 11 built-in format validators (uuid, email, ipv4, ipv6, uri, uri-reference, hostname, date, time, date-time, regex)
132
-
-**Opt-in assertion**: Format validation only asserts when explicitly enabled via Options, system property, or root schema flag
133
-
-**Unknown format handling**: Graceful handling of unknown formats (logged warnings, no validation errors)
134
-
-**Constraint integration**: Format validation works with other string constraints (minLength, maxLength, pattern)
135
-
-**Specification compliance**: Follows JSON Schema 2020-12 format annotation/assertion behavior correctly
136
-
137
84
### Development Workflow
138
85
139
86
1.**TDD Approach**: All tests must pass before claiming completion
@@ -143,34 +90,229 @@ The metrics distinguish between:
143
90
144
91
### Key Design Points
145
92
146
-
-**Single public interface**: `JsonSchema` contains all inner record types
147
-
-**Lazy $ref resolution**: Root references resolved at validation time
148
-
-**Conditional validation**: if/then/else supported via `ConditionalSchema`
149
-
-**Composition**: allOf, anyOf, not patterns implemented
150
-
-**Error paths**: JSON Pointer style paths in validation errors
151
-
-**Array validation**: Draft 2020-12 array features (contains, uniqueItems, prefixItems)
152
-
-**Format validation**: 11 built-in format validators with opt-in assertion mode
153
-
-**Structural equality**: Canonical JSON serialization for uniqueItems validation
93
+
MVF — Compile-time “stack of sources; dedup; multi-root” (legacy-free)
94
+
95
+
Design you approved (verbatim high-level concept):
96
+
97
+
New compile-time architecture (stack of sources; dedup; multi-root)
98
+
99
+
We move from “compile one document → single root tree” to “compile many documents (possibly just one) into an immutable set of roots using a work stack.” For this refactor, the stack will usually hold only the initial document, but the skeleton for pushing remote URIs is implemented and deduped. At runtime we still validate from the first root exactly as today; local $ref works the same.
100
+
101
+
Key invariants for this refactor:
102
+
- If a schema contains no remote $ref, the work stack never grows beyond the initial item; compiler returns a single-root as today.
103
+
- All existing behavior of string/number/array/object/pattern/enum/local $ref remains byte-for-byte identical from the public API
repeat until Work Stack is empty (dedup by normalized docUri) --+
129
+
```
130
+
131
+
Perfect — let's lock this down to exactly what you asked for:
132
+
1. Restate the whiteboard sketch (your vision).
133
+
2. Document the Minimum Viable Future (MVF) of the architecture — the bare essence, no bells and whistles, no speculative "extras."
134
+
3. Call out explicitly where my earlier refinements added details beyond your MVF (and why).
135
+
136
+
⸻
137
+
138
+
MVF Design Doc (README-driven; legacy-free)
139
+
140
+
This document is the minimal architecture to refactor compile-time. It is intentionally spare. No coding prompt. No production code. Any small additions beyond your sketch are explicitly annotated as [Note: required context] and kept to an absolute minimum.
141
+
142
+
References for current repo practices (logging, tests, single public surface) are from the project docs and reports.   
143
+
144
+
⸻
145
+
146
+
1) Restatement of your whiteboard (concise)
147
+
- Compile-time: Use a LIFO work stack of schema sources (URIs). Start with the initial source. For each popped source: parse → build root → discover $ref tokens. Tag each $ref as LOCAL (same document) or REMOTE (different document). REMOTE targets are pushed if unseen (dedup by normalized doc URI). The Roots Registry maps docUri → Root.
148
+
- Runtime: Unchanged for MVF. Validate only against the first root (the initial document). Local $ref behaves exactly as today.
149
+
- If no remote $ref: The work stack never grows; the result is exactly one root; public behavior is byte-for-byte identical.
C -->|empty| Z[freeze Roots (immutable) → return primary root facade]
161
+
C --> D[fetch/parse JSON for docUri]
162
+
D --> E[build Root AST]
163
+
E --> F[scan $ref strings]
164
+
F -->|LOCAL| G[tag Local(pointer)]
165
+
F -->|REMOTE| H{normalize target docUri; seen?}
166
+
H -->|yes| G
167
+
H -->|no| I[push target docUri] --> G
168
+
G --> J[register/replace Root(docUri)]
169
+
J --> C
170
+
```
171
+
• Dedup rule: A given normalized docUri is compiled at most once.
172
+
• Immutability: Roots registry is frozen before returning the schema facade.
173
+
• Public API: unchanged; runtime uses the existing explicit validation stack. 
174
+
175
+
[Note: required context] “normalize” means standard URI resolution against base; this is necessary to make dedup unambiguous (e.g., ./a.json vs a.json → same doc).
176
+
177
+
2.2 Runtime vs compile-time (Mermaid)
178
+
```mermaid
179
+
sequenceDiagram
180
+
participant U as User
181
+
participant C as compile()
182
+
participant R as Roots (immutable)
183
+
participant V as validate()
184
+
185
+
U->>C: compile(initialJson, initialUri)
186
+
C->>R: build via work stack (+dedup)
187
+
C-->>U: facade bound to R.primary
188
+
U->>V: validate(json)
189
+
V->>V: explicit stack evaluation (existing)
190
+
V->>R: resolve local refs within primary root only (MVF)
191
+
V-->>U: result (unchanged behavior)
192
+
```
193
+
194
+
⸻
195
+
196
+
3) Conceptual model (approximate TypeScript; non-compiling by design)
197
+
198
+
This is approximate TypeScript to explain the conceptual model.
199
+
It is not valid project code, not a spec, and should not compile.
- Local $ref → tag Local; no change to the work stack.
283
+
- Remote $ref → normalize; push if unseen.
284
+
- Dedup ensures each remote is compiled at most once.
285
+
286
+
4.2 Object/runtime (MVF)
287
+
- Exactly as today: Runtime follows only Local references inside the primary root.
288
+
- Remote roots are compiled and parked in the registry but not traversed (until future work/tests enable it).
289
+
- This preserves byte-for-byte API behavior and test outcomes.
290
+
291
+
⸻
154
292
155
-
### Testing Best Practices
293
+
5) Your words (short summary, in your own terms)
294
+
- "Don't add a new phase; make compile naturally handle multiple sources using a stack that starts with the initial schema."
295
+
- "Collect local vs remote $ref while compiling; rewrite/tag them; push unseen remotes; deduplicate; compile each into its own root; when the stack is empty, we have an immutable list of roots."
296
+
- "Runtime stays the same now (single root, local refs only), so all existing tests pass unmodified."
297
+
- "Use sealed interfaces / data-oriented tags so future remote traversal becomes a simple exhaustive match without touching today's behavior."
298
+
- "Cycle at compile-time should throw a named JDK exception (no new type)."
299
+
- "No legacy; no recursion; single path; stack-based eval and compile."
300
+
- "No new tests in this refactor; this is the refactor step of red→green→refactor."
156
301
157
-
-**Test data**: Use JSON string literals with `"""` for readability
158
-
-**Assertions**: Use AssertJ for fluent assertions
159
-
-**Error messages**: Include context in validation error messages
160
-
-**Edge cases**: Always test empty collections, null values, boundary conditions
302
+
⸻
161
303
162
-
### Performance Notes
304
+
6) What (little) I added & why
305
+
- URI normalization mention — [Note: required context]: Without it, dedup can mis-treat different spellings of the same document as distinct; normalization is the minimal assumption needed for a correct work-stack/dedup design.
306
+
- Immutable freeze call-out — [Note: required context]: The registry must be read-only after compile to preserve the project's immutability/thread-safety guarantees.
307
+
- Cycle detection language — [Note: required context]: To match your requirement "throw a specific JDK exception at compile-time," the doc names the behavior plainly (message content is illustrative, not prescriptive).
163
308
164
-
-**Compile once**: Schemas are immutable and reusable
165
-
-**Stack validation**: O(n) time complexity for n validations
166
-
-**Memory efficient**: Records with minimal object allocation
167
-
-**Thread safe**: No shared mutable state
309
+
No other embellishments, flags, prompts, or extra phases have been introduced.
168
310
169
-
### Debugging Tips
311
+
⸻
170
312
171
-
-**Enable logging**: Use `-Djava.util.logging.ConsoleHandler.level=FINE`
172
-
-**Test isolation**: Run individual test methods for focused debugging
173
-
-**Schema visualization**: Use `Json.toDisplayString()` to inspect schemas
174
-
-**Error analysis**: Check validation error paths for debugging
313
+
7) Repo-fit (why this plugs in cleanly)
314
+
-Readme-driven dev + logging/test discipline remain unchanged; this refactor is internal and keeps current usage stable.
-Legacy path is purged; this doc does not reference or rely on it. The single compilation path is consistent with the purge mandate.
175
317
176
-
Repo-level validation: Before pushing, run `mvn verify` at the repository root to validate unit and integration tests across all modules.
318
+
This is the MVF architecture doc only. It is purposefully minimal, legacy-free, and aligned to your whiteboard. No prompts, no code to compile, no behavior change to the public API today.
Copy file name to clipboardExpand all lines: json-java21-schema/README.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,7 @@ Stack-based JSON Schema validator using sealed interface pattern with inner reco
4
4
5
5
- Draft 2020-12 subset: object/array/string/number/boolean/null, allOf/anyOf/not, if/then/else, const, format (11 validators), $defs and local $ref (including root "#")
6
6
- Thread-safe compiled schemas; immutable results with error paths/messages
7
+
-**Novel Architecture**: This module uses an innovative immutable "compile many documents (possibly just one) into an immutable set of roots using a work stack" compile-time architecture for high-performance schema compilation and validation. See `AGENTS.md` for detailed design documentation.
0 commit comments