license: 180-day post-expiry check-in window; reason-aware 403 (#308) #309
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/lic-expiry-sync"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #308. Nikola bumped the window from the issue's 60 days to 180 days (6 months).
Before this, two behaviors killed late-renewal self-healing: check-ins stopped the moment the local key expired, and every 403 was treated as revocation (the server 403s for expired too — so a two-day payment hiccup could permanently mark an instance revoked).
expiredRetryWindow = 180d: an expired, unrevoked license keeps checking in (existing daily-retry cadence) for six months past expiry; a renewal re-signs the same license id server-side and the next 200 installs it with zero admin action. After the window, an abandoned instance goes quiet for good.checkin()parses the newreasonfield (license-server#24): onlyrevoked/unknownsetst.Revoked. Legacy servers without the field: a bare 403 while the local key is itself expired falls back to the expired outcome.ForceCheckin(#86) gains the same outcome +ErrExpired("no renewal found yet; the instance keeps checking") instead of a misleading unreachable/revoked error.StatusexposesrenewalWatchUntilwhile the watch is live. Enforcement is untouched — an expired license never counts toward the cap; the watch only enables self-healing.Tests: expired→renew→auto-resync end to end; 403-expired ≠ revoked; 403-revoked still stops; legacy bare-403 fallback; window end goes quiet (both loop and Status).
Follow-up (small, non-blocking): surface
renewalWatchUntilin the#admin/licensingpanel — the scout shows the panel renders via thelicStatusFailed-adjacent status block (~line 3682 web/static/index.html); fits the #302 admin polish pass.