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
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.
| **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)) |
124
124
| **Logical** | `AND`, `OR`, `NOT` | `AND`/`OR`: `conditions: [...]`; `NOT`: `value:` (wraps a single operation) |
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.
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
23
23
24
24
| Version | Introduces | RFC |
25
25
|---------|-----------|-----|
26
+
| v0.5.3 |`DATE_DIFF` operation; date operands for the comparison operators |[RFC-020](/rfcs/rfc-020)|
26
27
| v0.5.2 |`annotation-schema.json` for stand-off notes |[RFC-005](/rfcs/rfc-005), [RFC-018](/rfcs/rfc-018)|
27
28
| v0.5.1 | Tag-based immutable schema URLs; refinements within the v0.5.x line |[RFC-013](/rfcs/rfc-013)|
@@ -34,6 +35,8 @@ This table is the single source of truth for which schema version introduced whi
34
35
35
36
Multi-organization execution ([RFC-009](/rfcs/rfc-009)) reuses `competent_authority` (v0.2.0) and adds no schema construct of its own.
36
37
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.
Copy file name to clipboardExpand all lines: docs/src/content/rfcs/rfc-021.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
---
2
-
title: "RFC-016: Date Comparison and Difference Operations"
2
+
title: "RFC-021: Date Comparison and Difference Operations"
3
3
---
4
4
5
5
**Status:** Proposed
@@ -29,7 +29,7 @@ Make the ordered comparison operators dispatch on operand type instead of forcin
29
29
- both operands parse as ISO 8601 dates: chronological comparison
30
30
- anything else (including a number compared against a date): a type error, as before
31
31
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.
33
33
34
34
```yaml
35
35
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
61
61
- The peildatum-versus-date comparison that authors reach for most often now works directly, with no detour through `AGE`.
62
62
- 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.
63
63
- `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.
65
65
- 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.
66
66
67
67
### Tradeoffs
@@ -88,14 +88,14 @@ Add named operators for date ordering. Rejected for comparison because it duplic
88
88
- 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`.
89
89
- 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.
90
90
- 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.
92
92
- 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.
94
94
95
95
## References
96
96
97
97
- [RFC-001: YAML Schema Design Decisions](/rfcs/rfc-001), temporal metadata and `$calculation_date`
0 commit comments