Time is an explicit, recorded input — never an ambient read (v2.27.0 scheduling ·…
A scheduler that reads the wall clock inside its decision is
unauditable: you cannot replay "why didn't the 8am job run on the
24th?" because the inputs to that decision — the current time, the
operative timezone, the holiday set, the timezone database in
effect — were ambient, not recorded. v2.27.0 makes the opposite
true by construction for AXON's temporal guard, the window.
The law. Every decision about WHEN something runs is a pure, total function of explicit, recorded inputs: the instant
now(UTC), the declaredwindow(timezone + allowed day/hour spans + literal holiday dates), and the IANA tz-database version. The decision reads nothing ambiently; it is replayable from those inputs alone.
The four inputs — all explicit
nowis passed in, not read. The pure decisionis_in_window(now, window)takes the instant as an argument. The supervisor reads the clock once, at the top of a tick, and threads that value through — so the logic is unit-testable with a fixed clock and identical across replicas evaluating the same minute.- The timezone is a literal.
timezone: "America/Bogota"is part of the program, format-checked at compile time and resolved against the IANA database at runtime. A DST transition is not a special case the adopter handles — the tz database carries the offset history, so9..18local means wall-clock 9am–6pm on both sides of the shift. - The spans and holidays are literals.
allow:day/hour ranges andexclude:dates ("2026-12-25") are verified program text — type-checked for real calendar validity (axon-T826: no Feb 30). They are not fetched, not inferred, not political. A named holiday calendar ("US federal holidays") is deliberately out of scope precisely because it would be a non-deterministic, ambient input — the antithesis of this law. - The tz-db version is recorded. A window verdict depends on
the IANA timezone database (offsets and DST rules change between
releases). The run's audit records the
tz_db_versionthe decision used, so the verdict is replayable even across a tz-database upgrade — you can reconstruct exactly which rules were in force.
Why it is pure and total
The decision is a finite fold: convert now to the window's
timezone, test the local date against the holiday set, test the
local weekday/hour against the spans. No loop is unbounded, no
branch calls a model, nothing is persisted or mutated. An
unresolvable timezone fails closed (the tick does not fire)
rather than guessing. Given the same (now, window, tz-db version), the verdict is identical bit-for-bit — the precondition
for replay, audit, and cross-replica agreement.
What this forbids
- No ambient clock read inside the decision. The logic never
calls "what time is it?" itself; the instant is an argument. A
decision you cannot re-run with a supplied
nowis not a decision under this law. - No hidden timezone. "Local time" with no declared zone is ambient and machine-dependent. The zone is always explicit.
- No unrecorded dynamic input. Should a future extension source the holiday set dynamically (e.g. from a store), it MUST record the resolved set into the decision's audit — otherwise the verdict stops being replayable and leaves this law. The explicit input may be computed; it may never be a silent side-read.
- No political calendar baked in. Built-in national holiday tables are non-deterministic across jurisdictions and years; they are not an explicit input and are excluded by design.
v2.46.0 — the cognitive completion
v2.27.0 made the scheduler time-honest and left the model blind: a
window-gated daemon fires at exactly 9am Bogotá and then prompts a
model that does not know it is Monday. Every production agent that
schedules, greets, reasons about "this week" or "before 6pm" needs
the current date-time — and the folk fix (string-interpolating a
server timestamp into the ask:) is precisely the ambient,
unrecorded, timezone-naïve clock read this law forbids.
v2.46.0 applies the same four-input discipline to cognition:
- Declared, never ambient. A step that carries time says so in
source:
now: "America/Bogota"on the step, or on the boundcontextframe (every step within inherits it; a step's ownnow:overrides). The zone is format-checked (axon-T892) — you state WHOSE time the cognition runs in. - One instant per run. The runtime captures the clock ONCE per run and renders THAT instant in each declared zone — two steps in one run can never disagree about "now". A daemon tick is a new run with a fresh capture, which is exactly right.
- Deterministic rendering. The injected line —
Current datetime: 2026-07-07T14:33:05-05:00 (America/Bogota; tzdb 2025b; captured at run start).— is a pure function of(capture, zone, tz-db version). DST-correct via the same chrono-tz machinery aswindow. - Recorded for replay. The flow envelope carries
temporal_context: {captured_utc, tzdb_version, zones}(both transports, v2.7.0 parity), so the exact prompt the model saw is reconstructible byte-for-byte.
Fail-closed at every layer: a malformed zone is a compile error
(axon-T892); a shape-valid zone unknown to the tz database is
refuted by the TemporalContextSoundness proof at verify/deploy and
fails the step loudly at runtime — never a silent omission of the
time a step declared it needs.
Relation to the other laws
- The time-domain instance of
total_expressions: a temporal predicate is a total, pure, statically-checked computation, not a delegated guess. - Shares the spirit of
no_unwitnessed_advantage: a claim (there, an advantage; here, a schedule decision) is only trustworthy when it is backed by recorded, checkable inputs.
The honest test: if you cannot replay a scheduling decision from
values you wrote down, your scheduler is guessing. AXON writes them
down — now, the zone, the spans, the holidays, the tz-db version
— and computes.