TEST-VECTORS.md
Canonical algorithms for vectors
These test vectors are defined against a fixed, fully specified core algorithm set.
Machine-readable vectors
The executable golden vectors used by kron-core tests live in:
core/testdata/vectors/v1.jsoncore/testdata/vectors/v2.jsoncore/testdata/vectors/v3.jsoncore/testdata/vectors/v4.jsoncore/testdata/vectors/v5.jsoncore/testdata/vectors/v6.jsoncore/testdata/vectors/v7.json
Current implementation coverage in that file focuses on implemented MVP behavior:
uniform,skewEarly, andskewLatedistributions (including skew shape parameter coverage)after,before, andaround/centerwindow behaviorzero-duration window behavior
seed strategies (
stable,daily,weekly)constraint handling (
hours,dow,between,dom,months,date/dates) and unschedulable outcomesedge cases: timezone period-key boundaries and odd
arounddurations
Seed hash
HASH = SHA-256SeedInput = Identity + "\n" + PeriodKey + "\n" + SaltSeedHash = hex(lowercase(SHA-256(SeedInput)))
PRNG
PRNG = SplitMix64seed_u64 = uint64_be(SHA-256(SeedInput)[0:8])SplitMix64 step:
x = x + 0x9E3779B97F4A7C15
z = x
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9
z = (z ^ (z >> 27)) * 0x94D049BB133111EB
z = z ^ (z >> 31)
return z
NextFloat64():
u = next_uint64()
f = (u >> 11) / 2^53
So 0 ≤ f < 1.
Window mapping
Let W = window_end - window_start in whole seconds, where W ≥ 0.
If
W == 0:chosen_time = window_start.Else, for a unit value
xin[0,1):
offset_seconds = floor(x * (W + 1))
chosen_time = window_start + offset_seconds seconds
This mapping permits selecting window_end when offset_seconds == W.
Distributions
Let u = NextFloat64().
uniform:x = u
skewEarly(shape=s)wheres > 0:x = u^s
skewLate(shape=s)wheres > 0:x = 1 - (1 - u)^s
Constraints are evaluated after mapping to a candidate time, using deterministic resampling with the same PRNG stream.
Constraint sampling budget
MaxAttempts = 64Attempts consume one
NextFloat64()per attempt.
If no candidate satisfies constraints after MaxAttempts, the period is unschedulable.
Notation
Times are RFC3339 UTC.
PeriodID = NominalTime.UTC().Format(RFC3339).For
SeedStrategy=stable,PeriodKey = PeriodID.For
SeedStrategy=daily,PeriodKey = YYYY-MM-DD in Timezone corresponding to NominalTime.For
SeedStrategy=weekly,PeriodKey = ISO week YYYY-Www in Timezone corresponding to NominalTime.
Core decision vectors
V1 — uniform, after-window, stable seed
Request
Identity:prod/db-backupNominalTime:2026-03-01T00:00:00ZTimezone:UTCWindowMode:afterWindowDuration:3h(W=10800)Distribution:uniformSeedStrategy:stableSalt:backupConstraints: none
Expected
PeriodID:2026-03-01T00:00:00ZWindowStart:2026-03-01T00:00:00ZWindowEnd:2026-03-01T03:00:00ZSeedHash:9c85657760a63b4d925af6088cceb2bb4448380b2e6856b203915a0a51ab5101First u:0.8462881248863515offset_seconds:9140ChosenTime:2026-03-01T02:32:20ZUnschedulable:false
V2 — skewLate, around-window, stable seed
Request
Identity:msgs/parisNominalTime:2026-03-02T09:00:00ZTimezone:Europe/ParisWindowMode:aroundWindowDuration:90m(W=5400)Distribution:skewLate(shape=2.5)SeedStrategy:stableSalt:msgsConstraints: none
Expected
PeriodID:2026-03-02T09:00:00ZWindowStart:2026-03-02T08:15:00ZWindowEnd:2026-03-02T09:45:00ZSeedHash:8b95acf566414238f55eb4541a1bc726b80d02fe86a0cd2ad52988a74860b2f5First u:0.4757178150383121x = 1 - (1-u)^2.5:0.800972654023368offset_seconds:4326ChosenTime:2026-03-02T09:27:06ZUnschedulable:false
V3 — daily seed strategy
Request
Identity:daily/testNominalTime:2026-03-01T00:00:00ZTimezone:UTCWindowMode:afterWindowDuration:1h(W=3600)Distribution:uniformSeedStrategy:dailySalt: emptyConstraints: none
Expected
PeriodID:2026-03-01T00:00:00ZPeriodKey:2026-03-01WindowStart:2026-03-01T00:00:00ZWindowEnd:2026-03-01T01:00:00ZSeedHash:3a1cbafc74e05e46dc6a4eff53a9d71da286eda9585a70c5c19bd43c52763161First u:0.3528233669308106offset_seconds:1270ChosenTime:2026-03-01T00:21:10ZUnschedulable:false
V4 — zero window duration (no sampling)
Request
Identity:exact/nojitterNominalTime:2026-01-01T00:00:00ZTimezone:UTCWindowMode:afterWindowDuration:0s(W=0)Distribution:uniformSeedStrategy:stableSalt: emptyConstraints: none
Expected
PeriodID:2026-01-01T00:00:00ZWindowStart:2026-01-01T00:00:00ZWindowEnd:2026-01-01T00:00:00ZSeedHash:8b0e1ef5c9c9886e07842b8f00c04697f5257c68188a33de362a414012b4eb84ChosenTime:2026-01-01T00:00:00ZUnschedulable:false
V5 — constraints cause unschedulable (sampling budget exceeded)
Constraint model
Only:between=18:58-19:00inUTC(inclusive bounds)Equivalent allowed offset range (relative to window start):
3500..3600seconds inclusiveMaxAttempts = 64
Request
Identity:home/lightsNominalTime:2026-03-01T18:00:00ZTimezone:UTCWindowMode:afterWindowDuration:1h(W=3600)Distribution:uniformSeedStrategy:stableSalt:lightsConstraints:Only(between=18:58-19:00)
Expected
PeriodID:2026-03-01T18:00:00ZWindowStart:2026-03-01T18:00:00ZWindowEnd:2026-03-01T19:00:00ZSeedHash:d61bedd4e238549ebdb9d45993ea58904aa8042c4691967c720b0f2006416345ChosenTime: emptyUnschedulable:trueReason:no candidate accepted within MaxAttempts
V6 — calendar constraints (dom, months, date/dates) in zero-window cases
v6.json adds deterministic zero-window vectors to validate day/month/date-range constraint behavior.
Coverage in this vector set:
schedulable candidate with combined
Only(dom, months, dates)unschedulable candidate with
Avoid(dom)unschedulable candidate with
Avoid(months)unschedulable candidate with
Avoid(dates range)
V7 — skew-shape parameter determinism
v7.json adds deterministic vectors for skewLate with explicit shape values.
Coverage in this vector set:
explicit
shape=1.5explicit
shape=2.5stable output differences from shape changes under fixed period/window/seed strategy
Adapter outcome vectors
These vectors combine a core decision with policy evaluation at a specific now.
A1 — missed with deadline=0s
Decision
Use V1 decision.
ChosenTime:2026-03-01T02:32:20Z
Policy
deadline = 0sconcurrency = forbidsuspend = false
Input
now = 2026-03-01T02:32:21Zactive_execution = falsestate: period not handled yet
Expected outcome
Terminal outcome:
missedNo execution started
Period marked handled as
missed
A2 — executed within deadline
Decision
Use V1 decision.
ChosenTime:2026-03-01T02:32:20Z
Policy
deadline = 10mconcurrency = forbidsuspend = false
Input
now = 2026-03-01T02:40:00Zactive_execution = falsestate: period not handled yet
Expected outcome
Terminal outcome:
executedExecution started once
Period marked handled as
executed
A3 — skipped due to forbid concurrency
Decision
Use V3 decision.
ChosenTime:2026-03-01T00:21:10Z
Policy
deadline = 30mconcurrency = forbidsuspend = false
Input
now = 2026-03-01T00:25:00Zactive_execution = true
Expected outcome
Terminal outcome:
skippedNo new execution started
Period marked handled as
skipped
A4 — idempotency prevents duplicate execution
Decision
Use V1 decision.
Policy
deadline = 10mconcurrency = allowsuspend = false
Input
now = 2026-03-01T02:35:00Zactive_execution = falsestate: LastHandledPeriodID == 2026-03-01T00:00:00Z with outcome=executed
Expected outcome
No execution started
Period remains handled
Adapter reports
job_exists/already handledbehavior