Skip to content

Commit abd0770

Browse files
committed
docs(rfc): hernummer naar RFC-020 en maak de claims waar
RFC-016 is al geclaimd door PR #510/#511 (foreach) en RFC-019 door PR #690, dus dit RFC krijgt nummer 020. Daarnaast de tekst in lijn gebracht met de implementatie: de EQUALS-datumfallback is gescoped tot de gemengde vorm (string vs {iso}-object), de canonieke-vorm-afwijzing geldt luid voor de ordeningsoperatoren en datumoperaties maar stil voor EQUALS, en de non-breaking-claim benoemt nu expliciet dat de strikte parsing ook AGE/DATE_ADD/DAY_OF_WEEK bereikt. Status naar Accepted. Versie-register in schema.md aangevuld met v0.5.3 (incl. de onafhankelijke versionering van het annotatieschema) en de operatietabel in law-format.md bijgewerkt naar 22 operaties.
1 parent f84d3b8 commit abd0770

4 files changed

Lines changed: 15 additions & 13 deletions

File tree

conformance/v0.5.0/manifest.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@
5252
"AGE",
5353
"DATE_ADD",
5454
"DATE",
55-
"DAY_OF_WEEK",
56-
"DATE_DIFF"
55+
"DAY_OF_WEEK"
5756
]
5857
},
5958
"advanced": {

docs/src/content/docs/concepts/law-format.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,13 @@ Operations are the building blocks of law logic:
120120
|----------|-----------|--------|
121121
| **Arithmetic** | `ADD`, `SUBTRACT`, `MULTIPLY`, `DIVIDE` | `values: [...]` |
122122
| **Aggregate** | `MIN`, `MAX` | `values: [...]` |
123-
| **Comparison** | `EQUALS`, `GREATER_THAN`, `LESS_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL` | `subject:`, `value:` |
123+
| **Comparison** | `EQUALS`, `GREATER_THAN`, `LESS_THAN`, `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL` | `subject:`, `value:` (operands may be numbers or ISO dates, see [RFC-020](/rfcs/rfc-020)) |
124124
| **Logical** | `AND`, `OR`, `NOT` | `AND`/`OR`: `conditions: [...]`; `NOT`: `value:` (wraps a single operation) |
125125
| **Collection** | `IN`, `LIST` | `IN`: `subject:` + `value:` or `values: [...]`; `LIST`: `items: [...]` |
126126
| **Conditional** | `IF` (alias `SWITCH`) | `cases: [{when:, then:}]`, `default:` |
127-
| **Date** | `AGE`, `DATE_ADD`, `DATE`, `DAY_OF_WEEK` | `AGE`: `date_of_birth:`, `reference_date:`; `DATE_ADD`: `date:` + `years:`/`months:`/`days:`; `DATE`: `year:`, `month:`, `day:`; `DAY_OF_WEEK`: `date:` |
127+
| **Date** | `AGE`, `DATE_ADD`, `DATE`, `DAY_OF_WEEK`, `DATE_DIFF` | `AGE`: `date_of_birth:`, `reference_date:`; `DATE_ADD`: `date:` + `years:`/`months:`/`days:`; `DATE`: `year:`, `month:`, `day:`; `DAY_OF_WEEK`: `date:`; `DATE_DIFF`: `from:`, `to:`, `in:` (days/months/years) |
128128

129-
These 21 operations make up the schema. The engine also accepts the compat aliases `NOT_EQUALS`, `IS_NULL`, `NOT_NULL`, and `NOT_IN` for backward compatibility, but they are outside the schema, so prefer wrapping the positive operation in `NOT`. See [RFC-004: Uniform Operation Syntax](/rfcs/rfc-004) for the full specification.
129+
These 22 operations make up the schema. The engine also accepts the compat aliases `NOT_EQUALS`, `IS_NULL`, `NOT_NULL`, and `NOT_IN` for backward compatibility, but they are outside the schema, so prefer wrapping the positive operation in `NOT`. See [RFC-004: Uniform Operation Syntax](/rfcs/rfc-004) for the full specification.
130130

131131
### Variable References
132132

docs/src/content/docs/reference/schema.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ The law format is defined by a JSON Schema. All law YAML files in the corpus mus
77

88
## Current Version
99

10-
The current schema version is **v0.5.2**.
10+
The current schema version is **v0.5.3**.
1111

1212
Schema URLs use immutable git tags to guarantee reproducibility. The format is:
1313

1414
```
15-
https://raw.githubusercontent.com/MinBZK/regelrecht/refs/tags/schema-v0.5.2/schema/v0.5.2/schema.json
15+
https://raw.githubusercontent.com/MinBZK/regelrecht/refs/tags/schema-v0.5.3/schema/v0.5.3/schema.json
1616
```
1717

1818
The tag `schema-vX.Y.Z` is created when a schema version is released. Using tags instead of `refs/heads/main` ensures that the schema a law file references can never change underneath it. See [RFC-013](/rfcs/rfc-013) for the rationale.
@@ -23,6 +23,7 @@ This table is the single source of truth for which schema version introduced whi
2323

2424
| Version | Introduces | RFC |
2525
|---------|-----------|-----|
26+
| v0.5.3 | `DATE_DIFF` operation; date operands for the comparison operators | [RFC-020](/rfcs/rfc-020) |
2627
| v0.5.2 | `annotation-schema.json` for stand-off notes | [RFC-005](/rfcs/rfc-005), [RFC-018](/rfcs/rfc-018) |
2728
| v0.5.1 | Tag-based immutable schema URLs; refinements within the v0.5.x line | [RFC-013](/rfcs/rfc-013) |
2829
| v0.5.0 | `hooks`, `overrides` (reactive execution); `procedure`, `procedure_id` (Awb lifecycle); Woo support | [RFC-007](/rfcs/rfc-007), [RFC-008](/rfcs/rfc-008) |
@@ -34,6 +35,8 @@ This table is the single source of truth for which schema version introduced whi
3435

3536
Multi-organization execution ([RFC-009](/rfcs/rfc-009)) reuses `competent_authority` (v0.2.0) and adds no schema construct of its own.
3637

38+
The annotation schema (`annotation-schema.json`) versions independently of the law schema: it lives at `schema/v0.5.2/`, where it was introduced, and a new law-schema version does not republish it.
39+
3740
## Validation
3841

3942
Validate law files against the schema:
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "RFC-016: Date Comparison and Difference Operations"
2+
title: "RFC-021: Date Comparison and Difference Operations"
33
---
44

55
**Status:** Proposed
@@ -29,7 +29,7 @@ Make the ordered comparison operators dispatch on operand type instead of forcin
2929
- both operands parse as ISO 8601 dates: chronological comparison
3030
- anything else (including a number compared against a date): a type error, as before
3131

32-
No new operator names. `$peildatum > $grensdatum` simply works, the same way `$bedrag > 1000` does. `EQUALS` is made date-aware too: when both operands denote a date it compares them chronologically, so the string form `"2025-01-01"` equals the reference-date object form `{iso: "2025-01-01", ...}`. Combined with the canonical-form requirement on date strings (see Implementation Notes), `EQUALS` and the ordering operators can never disagree on the same pair of dates.
32+
No new operator names. `$peildatum > $grensdatum` simply works, the same way `$bedrag > 1000` does. `EQUALS` is made date-aware for exactly one pair of forms: a date string against the reference-date object, so `"2025-01-01"` equals `{iso: "2025-01-01", ...}`. Two strings or two objects keep structural equality, which for canonical date strings already coincides with chronological equality. Combined with the canonical-form requirement on date strings (see Implementation Notes), `EQUALS` and the ordering operators can never disagree on the same pair of dates.
3333

3434
```yaml
3535
operation: GREATER_THAN_OR_EQUAL
@@ -61,7 +61,7 @@ The name pairs with the existing `DATE_ADD`: one adds an offset to a date, the o
6161
- The peildatum-versus-date comparison that authors reach for most often now works directly, with no detour through `AGE`.
6262
- Route A introduces no new vocabulary. There is nothing new to learn or document for comparison; the existing operators just accept a wider operand type.
6363
- `DATE_DIFF` removes the unit ambiguity at the call site. The author states whether they mean days, months, or years, so the result is never silently the wrong granularity.
64-
- The change is additive and non-breaking. No value type is added, no existing law changes meaning, and every published schema version keeps validating the laws that reference it.
64+
- The change is additive and non-breaking for every law in the corpus. No value type is added, no existing law changes meaning, and every published schema version keeps validating the laws that reference it. One sharpening does reach the existing date operations: the canonical-form requirement below also makes `AGE`, `DATE_ADD`, and `DAY_OF_WEEK` reject a non-zero-padded literal like `1990-1-1` that the lenient parser used to accept. That failure is loud, and no law in the corpus contains such a literal.
6565
- Both routes reuse arithmetic that the engine already ships and tests for `AGE`, so the calendar edge cases (leap years, end-of-month) are handled consistently.
6666

6767
### Tradeoffs
@@ -88,14 +88,14 @@ Add named operators for date ordering. Rejected for comparison because it duplic
8888
- The sign convention follows the existing difference helpers, which are positive when their first argument is the later date. `DATE_DIFF(from, to)` passes `(to, from)` to those helpers so the result is positive when `to` is on or after `from`.
8989
- Route A only takes the date path when both operands fail numeric coercion and both parse as dates. A number compared against a date stays a type error rather than coercing one side, so mistakes surface loudly.
9090
- Like the other date operations, `DATE_DIFF` must be nested inside a `value` and is not valid directly at the action level.
91-
- `EQUALS` gains the date fallback only when neither operand is already structurally equal and both denote a date. Plain string and numeric equality keep their existing behavior, and membership (`IN`) is untouched.
91+
- `EQUALS` gains the date fallback only when the operands are not structurally equal and form the mixed pair of a date string and an `{iso}` object. Two objects stay structurally compared, so values that merely carry the same `iso` field do not become equal, and plain string and numeric equality keep their existing behavior. Membership (`IN`) is untouched and stays structural: a date string is `EQUALS` to its object form but not `IN` a list that contains only the object form. That asymmetry is deliberate, because making membership date-aware would change list semantics well beyond dates.
9292
- The `in` unit is normally a literal (`days`, `months`, `years`), and the schema enumerates those. It may also be a variable that resolves to one of those strings, so the schema accepts a variable reference alongside the enum.
93-
- Date parsing requires canonical `YYYY-MM-DD` form. The underlying parser is lenient and would accept `2025-1-1`, but such a literal would compare chronologically under `>`/`<` while being inequal under `EQUALS` (which compares strings). To keep the operators consistent, a non-zero-padded date is rejected at parse time across every date operation, not silently accepted. The form the engine produces for `$referencedate.iso` is already canonical.
93+
- Date parsing requires canonical `YYYY-MM-DD` form. The underlying parser is lenient and would accept `2025-1-1`, but such a literal would compare chronologically under `>`/`<` while being inequal under `EQUALS` (which compares strings). To keep the operators consistent, a non-zero-padded date is rejected at parse time by the ordering operators, `DATE_DIFF`, and the existing date operations (`AGE`, `DATE_ADD`, `DAY_OF_WEEK`). `EQUALS` is the one place that stays quiet: its date fallback simply does not fire when a side fails to parse, so a non-canonical literal falls back to plain string equality instead of raising an error. The form the engine produces for `$referencedate.iso` is already canonical.
9494

9595
## References
9696

9797
- [RFC-001: YAML Schema Design Decisions](/rfcs/rfc-001), temporal metadata and `$calculation_date`
9898
- [RFC-004: Uniform Operation Syntax](/rfcs/rfc-004), operation property-name conventions
9999
- Engine: `packages/engine/src/operations.rs` (`execute_ordered_comparison`, `execute_equality`, `execute_date_diff`, `calculate_years_difference`, `calculate_months_difference`)
100-
- Schema: `schema/v0.5.3/schema.json` (`dateDiffOperation`, `comparisonOperation`)
100+
- Schema: `schema/v0.5.4/schema.json` (`dateDiffOperation`, `comparisonOperation`)
101101
- [Glossary of Dutch Legal Terms](/reference/glossary)

0 commit comments

Comments
 (0)