Effective dating: which rate is in force on a date
Area: Bitemporal time Teaches: the valid-time axis —
insert iof(…) at #date#writes a fact whose effectivity begins on a civil date, andas_of <#date#>reads which facts were in force on a given day. This is distinct from (and composable with) the transaction-timeas_of <int>of temporal_as_of_surface. Prerequisites:as_oftime-travel, and first-class relations. Run:ox build examples/effective_dated_tax_v0 && ox run-scenario examples/effective_dated_tax_v0
“What was the standard tax rate on 2024-04-15?” is a valid-time question: it asks what was true in the world on that day, not what the system happened to know at some processing instant. Hand-rolling an effectiveFrom: Date field forces every query to re-implement interval logic. Argon puts effectivity on the substrate: an enactment is written at its effective date, and a date-stamped as_of read projects the rates in force.
What to read in tax.ar
StandardRate is “the standard rate in force”; each enactment is one individual, and its value rides on a rate relation tuple. The enactment writes both at the effective date, so before that date neither holds:
pub type StandardRate;
pub rel rate(r: StandardRate, pct: Decimal);
pub mutate enact(r: StandardRate, pct: Decimal, effective: Date) {
insert iof(r, StandardRate) at effective;
insert rate(r, pct) at effective;
}
The queries read the valid-time axis with a date-literal as_of:
pub query rate_on_2023_06_01() -> StandardRate as_of #2023-06-01#;
pub query rate_on_2024_04_15() -> StandardRate as_of #2024-04-15#;
pub query rate_on_2025_06_01() -> StandardRate as_of #2025-06-01#;
pub query rate_now() -> StandardRate;
Running it
The demo.toml enacts three rates — 20% effective 2020-01-01, 22% effective 2024-01-01, 19% effective 2025-01-01 — passing the Date and Decimal arguments in their exact table forms ({ date = "…" }, { decimal = "…" }). Each date-stamped query then projects the rates whose valid-time has begun by that day:
query tax::rate_on_2023_06_01: 1 row(s) — only the 2020 rate has begun
query tax::rate_on_2024_04_15: 2 row(s) — 2020 + 2024 are both in force by a 2024 filing
query tax::rate_on_2025_06_01: 3 row(s) — 2020 + 2024 + 2025
query tax::rate_now: 3 row(s) — every begun rate (valid = now)
The decisive contrast is rate_on_2023_06_01 vs rate_on_2024_04_15: the same query shape, two civil dates, and the row count rises from 1 to 2 because the 2024 enactment’s valid-time interval opens between them. A rate enacted at #2024-01-01# is invisible to a 2023 read and visible to a 2024 read — the effectivity is enforced by the substrate, not by a where clause in the query.
Honest caveats (what runs today)
- The rate table is append-only in this v0: each enactment opens a valid-time interval but does not close the prior one, so a later date sees all begun rates accumulated (hence 3 rows in 2025), not only the single rate that superseded. Closing the prior interval (so a date sees exactly one rate) is the
during/ bitemporal-retraction follow-on. Datearguments use the{ date = "…" }table form (a bare string parses as an individual);Decimalarguments use{ decimal = "…" }, parsed exactly rather than through a float.- This is the valid-time axis (true-in-the-world). It composes with — and is distinct from — the transaction-time axis of temporal_as_of_surface (when the system learned a fact).
This example is compiled and run in CI; its valid-time as_of <#date#> round-trip is pinned by a corpus test (oxc-runtime/tests/examples_corpus.rs), so the effective-dating surface can’t drift from the language.
Source
The package’s real Argon source, transcluded from the files this corpus compiles — what you read here is exactly what CI builds.
root.ar
//! Effective-dated tax rates — the temporal substrate end-to-end (arc5).
//!
//! A tax model cannot ask "what rate was in effect on 2024-04-15" without
//! valid-time. This package is the living proof that it now can:
//!
//! * each rate is enacted `at #date#` — a bitemporal VALID-time assertion
//! (RP-004 §7.5), not a hand-rolled `effectiveFrom: Date` field;
//! * `as_of <#date#>` queries read the VALID-time axis — "what was valid
//! at VT = t" — distinct from and composable with the transaction-time
//! `as_of <int>` axis (RP-004 §6/§15).
//!
//! The `mod` indirection (rather than a flat `root.ar`) keeps the qualified
//! mutation/query paths stable (`tax::…`) instead of the `<anonymous>::…`
//! single-file trap.
mod tax;
tax.ar
//! The effective-dated rate table.
//!
//! `StandardRate` is the concept of "the standard income-tax rate in force".
//! Each enactment introduces a fresh `StandardRate` individual whose VALID
//! time begins on the day the statute took effect — `insert iof(r, StandardRate)
//! at #date#`. The runtime threads that `at <date>` onto the event's bitemporal
//! valid-time extent (RP-004 §7.5), so an `as_of <#date#>` query projects the
//! rate(s) in force on that civil day.
//!
//! The rate's numeric value rides on a `rate(StandardRate, Decimal)` relation
//! tuple set in the same mutation, so each enactment is one atomic step.
pub type StandardRate;
pub rel rate(r: StandardRate, pct: Decimal);
// ANCHOR: enact
/// Enact a new standard rate, effective from `effective` (a `#date#`).
/// The membership AND the rate value both take the valid-time of the
/// enactment: before `effective` the rate did not hold.
pub mutate enact(r: StandardRate, pct: Decimal, effective: Date) {
insert iof(r, StandardRate) at effective;
insert rate(r, pct) at effective;
}
// ANCHOR_END: enact
// ── Valid-time time-travel queries (the effective-dating wall) ──
//
// "Which standard rate(s) were in force on <date>?" Each reads the VALID-time
// axis via `as_of <#date#>`. A rate enacted `at #2024-01-01#` is invisible to
// an `as_of #2023-…#` read and visible to an `as_of #2024-…#` read.
// ANCHOR: valid_time_queries
/// The rate(s) in force in mid-2023 — before the 2024 enactment.
pub query rate_on_2023_06_01() -> StandardRate as_of #2023-06-01#;
/// The rate(s) in force on a 2024 filing day — after the 2024 enactment.
pub query rate_on_2024_04_15() -> StandardRate as_of #2024-04-15#;
// ANCHOR_END: valid_time_queries
/// The rate(s) in force in 2025 — after the 2025 enactment supersedes.
pub query rate_on_2025_06_01() -> StandardRate as_of #2025-06-01#;
/// The latest believed snapshot (VALID = now): every enacted rate whose
/// valid-time has begun is visible (the table is append-only here).
pub query rate_now() -> StandardRate;