Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
52ec5e7
Issue #89 Fix int32 type validation to reject decimal values like 3.14
simbo1905 Sep 27, 2025
bd738cb
Issue #89 Update CI test count to 461 after adding int32 decimal vali…
simbo1905 Sep 27, 2025
411fef7
Issue #89 Update CI test count to 463 after adding integer validation…
simbo1905 Sep 27, 2025
d4fd468
Issue #89 Update CI test count to 463 after adding integer validation…
simbo1905 Sep 27, 2025
cf16f71
Issue #91 Fix additionalProperties default value in JTD validator
simbo1905 Sep 27, 2025
60735a7
merge
simbo1905 Sep 28, 2025
bc1ae9d
Remove JtdExhaustiveTest from PR to allow merging bug fix
simbo1905 Sep 28, 2025
667fe3e
464
simbo1905 Sep 28, 2025
b1e876a
Merge remote-tracking branch 'origin/main' into feature/jqwik-propert…
simbo1905 Sep 28, 2025
e6877c3
Issue #94 Fix discriminator validation for simple type mappings
simbo1905 Sep 28, 2025
35b0632
Update CI test count and add PR creation instructions
simbo1905 Sep 28, 2025
d607df1
Merge branch 'main' into feature/jqwik-property-testing-88
simbo1905 Sep 28, 2025
16eef74
Issue #96 Add test case for nested elements properties bug
simbo1905 Sep 28, 2025
aa63d83
Update CI test count for new nested elements test
simbo1905 Sep 28, 2025
de41602
Merge branch 'main' into feature/jqwik-property-testing-88
simbo1905 Sep 28, 2025
971684e
pivot to strict rfc
simbo1905 Sep 28, 2025
bab95f9
wip
simbo1905 Sep 28, 2025
219b7a6
wip
simbo1905 Sep 28, 2025
dc41f40
wip
simbo1905 Sep 28, 2025
7c5c522
JtdExhaustiveTest.java
simbo1905 Sep 28, 2025
8cefcb7
ci test count
simbo1905 Sep 28, 2025
3b9f390
tidy up
simbo1905 Sep 28, 2025
4d24932
tidy
simbo1905 Sep 28, 2025
03a9c4e
code review feedback
simbo1905 Sep 28, 2025
35bafd6
bump
simbo1905 Sep 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
for k in totals: totals[k]+=int(r.get(k,'0'))
except Exception:
pass
exp_tests=466
exp_tests=475
exp_skipped=0
if totals['tests']!=exp_tests or totals['skipped']!=exp_skipped:
print(f"Unexpected test totals: {totals} != expected tests={exp_tests}, skipped={exp_skipped}")
Expand Down
42 changes: 41 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@
- Never commit unverified mass changes—compile or test first.
- Do not use Perl or sed for multi-line structural edits; rely on Python 3.2-friendly heredocs.

## Markdown-Driven-Development (MDD)
We practice **Markdown-Driven-Development** where documentation precedes implementation:

1. **Create GitHub issue** with clear problem statement and goals
2. **Update user documentation** (README.md) with new behavior/semantics
3. **Update agentic documentation** (AGENTS.md) with implementation guidance
4. **Update specialist documentation** (**/*.md, e.g., ARCHITECTURE.md) as needed
5. **Create implementation plan** (PLAN_${issue_id}.md) documenting exact changes
6. **Implement code changes** to match documented behavior
7. **Update tests** to validate the documented behavior
8. **Verify all documentation** remains accurate after implementation

This ensures:
- Users understand behavior changes before code is written
- Developers have clear implementation guidance
- Documentation stays synchronized with code
- Breaking changes are clearly communicated

When making changes, always update documentation files before modifying code.


## Testing & Logging Discipline

Expand Down Expand Up @@ -222,11 +242,21 @@ The property test logs at FINEST level:
### Issue Management
- Use the native tooling for the remote (for example `gh` for GitHub).
- Create issues in the repository tied to the `origin` remote unless instructed otherwise; if another remote is required, ask for its name.
- Tickets and issues must state only what and why, leaving how for later discussion.
- Tickets and issues must state only "what" and "why," leaving "how" for later discussion.
- Comments may discuss implementation details.
- Label tickets as `Ready` once actionable; if a ticket lacks that label, request confirmation before proceeding.
- Limit tidy-up issues to an absolute minimum (no more than two per PR).

### Creating GitHub Issues
- **Title requirements**: No issue numbers, no special characters, no quotes, no shell metacharacters
- **Body requirements**: Write issue body to a file first, then use --body-file flag
- **Example workflow**:
```bash
echo "Issue description here" > /tmp/issue_body.md
gh issue create --title "Brief description of bug" --body-file /tmp/issue_body.md
```
- **Never use --body flag** with complex content - always use --body-file to avoid shell escaping issues

### Commit Requirements
- Commit messages start with `Issue #<issue number> <short description>`.
- Include a link to the referenced issue when possible.
Expand Down Expand Up @@ -488,6 +518,16 @@ IMPORTANT: Never disable tests written for logic that we are yet to write we do
* Virtual threads for concurrent processing
* **Use try-with-resources for all AutoCloseable resources** (HttpClient, streams, etc.)

## RFC 8927 Compliance Guidelines

* **{} must compile to the Empty form and accept any JSON value** (RFC 8927 §2.2)
* **Do not introduce compatibility modes that reinterpret {} with object semantics**
* **Specs from json-typedef-spec are authoritative for behavior and tests**
* **If a test, doc, or code disagrees with RFC 8927 about {}, the test/doc/code is wrong**
* **We log at INFO when {} is compiled to help users who come from non-JTD validators**

Per RFC 8927 §3.3.1: "If a schema is of the 'empty' form, then it accepts all instances. A schema of the 'empty' form will never produce any error indicators."

## Package Structure

* Use default (package-private) access as the standard. Do not use 'private' or 'public' by default.
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,19 @@ This repo contains an incubating JTD validator that has the core JSON API as its

A complete JSON Type Definition validator is included (module: json-java21-jtd).

### Empty Schema `{}` Semantics (RFC 8927)

Per **RFC 8927 (JSON Typedef)**, the empty schema `{}` is the **empty form** and
**accepts all JSON instances** (null, boolean, numbers, strings, arrays, objects).

> RFC 8927 §2.2 "Forms":
> `schema = empty / ref / type / enum / elements / properties / values / discriminator / definitions`
> `empty = {}`
> **Empty form:** A schema in the empty form accepts all JSON values and produces no errors.

⚠️ Note: Some tools or in-house validators mistakenly interpret `{}` as "object with no
properties allowed." **That is not JTD.** This implementation follows RFC 8927 strictly.

```java
import json.java21.jtd.Jtd;
import jdk.sandbox.java.util.json.*;
Expand Down
8 changes: 8 additions & 0 deletions json-java21-jtd/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,14 @@ $(command -v mvnd || command -v mvn || command -v ./mvnw) test -pl json-java21-j
- **Definitions**: Validate all definitions exist at compile time
- **Type Checking**: Strict RFC 8927 compliance for all primitive types

## Empty Schema `{}`

- **Form**: `empty = {}`
- **Behavior**: **accepts all instances**; produces no validation errors.
- **RFC 8927 §3.3.1**: "If a schema is of the 'empty' form, then it accepts all instances. A schema of the 'empty' form will never produce any error indicators."
- **Common pitfall**: confusing JTD with non-JTD validators that treat `{}` as an empty-object schema.
- **Implementation**: compile `{}` to `EmptySchema` and validate everything as OK.

## RFC 8927 Compliance

This implementation strictly follows RFC 8927:
Expand Down
16 changes: 16 additions & 0 deletions json-java21-jtd/src/main/java/json/java21/jtd/Crumbs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package json.java21.jtd;

/// Lightweight breadcrumb trail for human-readable error paths
record Crumbs(String value) {
static Crumbs root() {
return new Crumbs("#");
}

Crumbs withObjectField(String name) {
return new Crumbs(value + "→field:" + name);
}

Crumbs withArrayIndex(int idx) {
return new Crumbs(value + "→item:" + idx);
}
}
19 changes: 19 additions & 0 deletions json-java21-jtd/src/main/java/json/java21/jtd/Frame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package json.java21.jtd;

import jdk.sandbox.java.util.json.JsonValue;

/// Stack frame for iterative validation with path and offset tracking
record Frame(JtdSchema schema, JsonValue instance, String ptr, Crumbs crumbs, String discriminatorKey) {
/// Constructor for normal validation without discriminator context
Frame(JtdSchema schema, JsonValue instance, String ptr, Crumbs crumbs) {
this(schema, instance, ptr, crumbs, null);
}

@Override
public String toString() {
final var kind = schema.getClass().getSimpleName();
final var tag = (schema instanceof JtdSchema.RefSchema r) ? "(ref=" + r.ref() + ")" : "";
return "Frame[schema=" + kind + tag + ", instance=" + instance + ", ptr=" + ptr +
", crumbs=" + crumbs + ", discriminatorKey=" + discriminatorKey + "]";
}
}
Loading