Category: spec-conformance Severity: minor
Location: Sources/ARCP/Runtime/JobManager.swift:796-802
Spec: ARCP v1.1 §14
What
§14 ('Lease expiration clock') states runtimes MUST evaluate expires_at against a monotonic, NTP-disciplined clock and SHOULD allow a small bounded grace. Both this check and LeaseManager.expireDue/refresh use wall-clock Date(), so a backward NTP step or clock skew can cause premature or delayed expiration. No bounded grace is applied.
Evidence
func checkLeaseExpiration() throws {
guard let leaseExpiresAt, Date() >= leaseExpiresAt else { return }
throw ARCPError.leaseExpired(
leaseId: LeaseId("lease_job_\(jobId.rawValue)"),
expiredAt: leaseExpiresAt
)
}
Proposed fix
Inject a clock abstraction backed by a monotonic source for expiry comparisons and apply a small bounded grace (e.g. 1s) per §14; keep Date() only for wire timestamps.
Acceptance criteria
Category: spec-conformance Severity: minor
Location:
Sources/ARCP/Runtime/JobManager.swift:796-802Spec: ARCP v1.1 §14
What
§14 ('Lease expiration clock') states runtimes MUST evaluate expires_at against a monotonic, NTP-disciplined clock and SHOULD allow a small bounded grace. Both this check and LeaseManager.expireDue/refresh use wall-clock
Date(), so a backward NTP step or clock skew can cause premature or delayed expiration. No bounded grace is applied.Evidence
Proposed fix
Inject a clock abstraction backed by a monotonic source for expiry comparisons and apply a small bounded grace (e.g. 1s) per §14; keep Date() only for wire timestamps.
Acceptance criteria