Licensing: "Remove licence" button — clean downgrade to the free tier (after #437's state cards) #438

Closed
opened 2026-09-06 02:04:24 +00:00 by Cordy · 1 comment
Owner

Nikola, 2026-09-06, while approving the #437 inactive-state cards: an operator who deliberately downgrades to the free tier should be able to remove the key — today a key can only be replaced, never removed; it lingers until expiry or revocation.

Behaviour (all falls out of existing design once the key is cleared):

  • Clears the stored key and licence state (revoked / failing-since / last check-in reset with it).
  • Cap returns to 50 immediately; seat records themselves are untouched.
  • Check-ins stop entirely — "no licence installed never phones home" applies again. The clean sovereignty downgrade.
  • No #437 card is shown (it only exists when a key is installed but not counting); the page returns to its unlicensed look with the install form.
  • Loud log line + admin bell entry on removal, mirroring the #437 transitions. Consider an audit event (license-remove) for symmetry with seat-release.

Sequencing: after the #437 cards land (the button belongs on/near that surface). UI change → confirm-dialog mockup first, house rule — the dialog should state the three consequences above in one honest sentence each, seat-release style. Reinstalling later is just pasting the key again; nothing is lost server-side.

Nikola, 2026-09-06, while approving the #437 inactive-state cards: an operator who deliberately downgrades to the free tier should be able to remove the key — today a key can only be replaced, never removed; it lingers until expiry or revocation. Behaviour (all falls out of existing design once the key is cleared): - Clears the stored key and licence state (revoked / failing-since / last check-in reset with it). - Cap returns to 50 immediately; seat records themselves are untouched. - **Check-ins stop entirely** — "no licence installed never phones home" applies again. The clean sovereignty downgrade. - No #437 card is shown (it only exists when a key is installed but not counting); the page returns to its unlicensed look with the install form. - Loud log line + admin bell entry on removal, mirroring the #437 transitions. Consider an audit event (`license-remove`) for symmetry with `seat-release`. Sequencing: **after** the #437 cards land (the button belongs on/near that surface). UI change → confirm-dialog mockup first, house rule — the dialog should state the three consequences above in one honest sentence each, seat-release style. Reinstalling later is just pasting the key again; nothing is lost server-side.
Cordy closed this issue 2026-09-06 04:10:51 +00:00
Author
Owner

Shipped in v0.6.134 (PR #440, merged; dogfoods live, build_info v0.6.134, enc licence untouched).

Decision record (per the approved license-remove mockup):

  • Placement: the Licence facts card gains a footer — audit note left, quiet "Remove licence…" right. Rendered only while a key is installed; on the free tier there is no trace of it, which also answers the original question: after removal, no card, no warning, clean free tier.
  • Confirm: one honest paragraph, no typing ritual (reversible by nature — the key stays valid in the customer account). The seat line is computed live: fits-the-free-tier, or amber over-50 stating the enforcement rule in the #437 dropcard's calm wording.
  • Manager.RemoveKey: clears key, label and every licence flag including a pending revoked watch; persists; keeps seat history and the drop/restore trail (removing a key is not amnesia). Keyless = no phone-home, ever. A config/CAIRN_LICENSE_KEY key re-installs at the next boot — the FAQ documents removing it from config to make the downgrade stick.
  • DELETE /api/v1/license: admin-gated, 409 when nothing is installed, audited as license-remove.
  • Docs: CHANGELOG v0.6.134, licensing-faq "How do I downgrade to the free tier?", ARCHITECTURE admin-surface row, audit verb inventory. Wiki Home working-log entry added.

TDD: TestRemoveKeyReturnsToFreeTier witnessed compile-red on the runner; full suite green after the splice (covers revoked-state cleanup, persistence across reload, trail survival, double-removal, and the no-phone-home guarantee).

Shipped in **v0.6.134** (PR #440, merged; dogfoods live, `build_info v0.6.134`, enc licence untouched). **Decision record (per the approved license-remove mockup):** - **Placement**: the Licence facts card gains a footer — audit note left, quiet "Remove licence…" right. Rendered only while a key is installed; on the free tier there is no trace of it, which also answers the original question: after removal, no card, no warning, clean free tier. - **Confirm**: one honest paragraph, no typing ritual (reversible by nature — the key stays valid in the customer account). The seat line is computed live: fits-the-free-tier, or amber over-50 stating the enforcement rule in the #437 dropcard's calm wording. - **`Manager.RemoveKey`**: clears key, label and every licence flag including a pending revoked watch; persists; keeps seat history and the drop/restore trail (removing a key is not amnesia). Keyless = no phone-home, ever. A config/`CAIRN_LICENSE_KEY` key re-installs at the next boot — the FAQ documents removing it from config to make the downgrade stick. - **`DELETE /api/v1/license`**: admin-gated, 409 when nothing is installed, audited as `license-remove`. - Docs: CHANGELOG v0.6.134, licensing-faq "How do I downgrade to the free tier?", ARCHITECTURE admin-surface row, audit verb inventory. Wiki Home working-log entry added. **TDD:** `TestRemoveKeyReturnsToFreeTier` witnessed compile-red on the runner; full suite green after the splice (covers revoked-state cleanup, persistence across reload, trail survival, double-removal, and the no-phone-home guarantee).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#438
No description provided.