CORE-SPEC.md
Scope
This document defines the formal contract of kron-core.
kron-core is a pure, deterministic scheduling engine.
It contains no side effects, no I/O, no persistence, and no adapter-specific logic.
All adapters (krond, kron-operator, future integrations) must treat this specification as authoritative for scheduling behavior.
Design Constraints
kron-core must be:
Pure: no external state access.
Deterministic: identical inputs produce identical outputs.
Stateless: all required state is provided as input.
Time-explicit: no internal clock access.
Side-effect free.
Versioning
kron-core exposes a semantic version.
A change that alters:
window calculation
seed derivation
distribution math
constraint evaluation
determinism guarantees
requires a major version increment.
Core Concepts
Identity
A stable string identifying the job:
Identity string
Must be UTF-8 and non-empty.
Period
A period is defined solely by:
NominalTime (UTC instant)
Timezone (IANA)
kron-core does not compute cron schedules unless explicitly provided a schedule resolver.
Primary Interfaces
DecisionRequest
The engine consumes a single request object:
DecisionRequest {
Identity string
NominalTime time.Time (UTC)
Timezone string
WindowMode enum {After, Around}
WindowDuration time.Duration
Distribution DistributionSpec
SeedStrategy SeedSpec
Salt string
Constraints ConstraintSpec
}
All times are interpreted in UTC except where constraints require timezone interpretation.
DecisionResult
The engine produces:
DecisionResult {
PeriodID string
NominalTime time.Time (UTC)
WindowStart time.Time (UTC)
WindowEnd time.Time (UTC)
ChosenTime time.Time (UTC)
SeedHash string
Distribution DistributionSpec
ConstraintMeta ConstraintMeta
}
If unschedulable:
DecisionResult {
...
ChosenTime nil
Unschedulable true
Reason string
}
Determinism Requirements
For identical DecisionRequest values:
DecisionResultmust be byte-for-byte identical in:ChosenTimeSeedHashWindowStartWindowEnd
Determinism must hold across:
Process restarts
Different machines
Different architectures
Supported Go versions within compatibility window
Floating point calculations must not introduce nondeterministic rounding across architectures.
If floating math is used internally, results must be quantized deterministically before producing ChosenTime.
PeriodID
PeriodID = NominalTime.UTC().Format(RFC3339)
Must not depend on timezone formatting differences.
Window Computation
Given:
N = NominalTime
D = WindowDuration
If WindowMode=After:
WindowStart = N
WindowEnd = N + D
If WindowMode=Around:
Half = D / 2
WindowStart = N - Half
WindowEnd = N + Half
If D=0:
WindowStart = N
WindowEnd = N
ChosenTime = N
No distribution sampling occurs when WindowStart == WindowEnd.
Seed Derivation
Seed input string is constructed as:
SeedInput =
Identity + "\n" +
PeriodKey + "\n" +
Salt
PeriodKey depends on seed strategy.
Seed Strategies
Stable
PeriodKey = PeriodID
Daily
PeriodKey = YYYY-MM-DD in Timezone corresponding to NominalTime
Weekly
PeriodKey = ISOWeek(YYYY-Www) in Timezone corresponding to NominalTime
Seed Hash
A cryptographic hash function must be used.
The hash function must:
Be fixed for a major version.
Produce identical results across platforms.
Be documented in implementation.
Output encoding:
SeedHash = lowercase hexadecimal string
The full hash output must be used for PRNG seeding.
PRNG Requirements
The pseudorandom generator:
Must be deterministic for a given SeedHash.
Must produce reproducible sequences.
Must not depend on runtime-global randomness.
Initialization:
PRNG(seed = SeedHash bytes)
Sequence generation order must be stable and documented.
Distribution Specification
DistributionSpec {
Name string
Params map[string]string
}
Parameter parsing must be deterministic.
Unknown parameters must cause error.
Distribution Contract
Given:
U = PRNG.NextFloat64()
U must satisfy:
0 ≤ U < 1
Distributions must transform U into an offset within:
[0, WindowDuration]
or symmetrically around nominal in Around mode.
The final offset must be clamped to window bounds.
Constraint Specification
ConstraintSpec {
OnlyClauses []Clause
AvoidClauses []Clause
}
Constraint evaluation must:
Interpret time in specified Timezone.
Be pure.
Not modify state.
Candidate Selection Algorithm
Initialize PRNG with SeedHash.
For attempt in
0..MaxAttempts-1:Generate
U.Compute candidate offset via distribution.
Compute candidate time.
If candidate satisfies constraints:
Return candidate.
If no candidate accepted:
Return Unschedulable.
MaxAttempts must be fixed and documented.
MaxAttempts must be deterministic and independent of runtime conditions.
Constraint Evaluation Rules
Given candidate time T:
Convert
Tto schedule timezone.Evaluate
OnlyClauses:If present,
Tmust satisfy at least one clause set.
Evaluate
AvoidClauses:If any clause matches, candidate rejected.
Clause types and evaluation logic are defined in SYNTAX.md.
Constraint evaluation must not modify T.
Error Handling
The engine must return explicit errors for:
Invalid timezone
Invalid distribution name
Invalid distribution parameters
Invalid seed strategy
Invalid constraint definitions
Negative window duration
Errors must not panic.
Timezone Handling
Timezone must be resolved via IANA database.
If timezone is invalid:
Return error.
All conversions must be deterministic given identical timezone database.
Implementations must document supported timezone database source.
Precision Rules
Internal calculations may use nanoseconds.
Final
ChosenTimemust be truncated or rounded in a deterministic manner.Rounding policy must be stable and documented.
ChosenTime must never fall outside window bounds due to rounding.
Unschedulable Semantics
If no valid candidate found:
DecisionResult.Unschedulable = true
DecisionResult.ChosenTime = zero value
SeedHash, WindowStart, WindowEnd, and PeriodID must still be populated.
Stability Guarantees
For a fixed major version:
Seed derivation format must not change.
Hash algorithm must not change.
PRNG algorithm must not change.
Distribution math must not change.
Window computation must not change.
Any change affecting output for identical inputs requires major version increment.
Performance Requirements
Decision() must:
Execute in bounded time.
Be O(1) relative to window duration.
Not allocate unbounded memory.
Not depend on external services.
Prohibited Behaviors
kron-core must not:
Access system clock.
Perform I/O.
Access filesystem.
Access network.
Read environment variables.
Use global mutable state.
Use non-deterministic randomness.
Conformance
A conforming implementation must:
Pass all golden test vectors defined in TEST-VECTORS.md.
Produce identical outputs across supported architectures.
Preserve determinism guarantees.
Adapters must not alter or reinterpret DecisionResult fields.
kron-core is the authoritative source of scheduling truth.