Prufy notes
The domain · 12 min

The lifecycle

A claim is always in exactly one status. Exactly one function can move it. Everything else is built around those two facts.

Rather than a pile of booleans like isVerified and isExpired, which can contradict each other, a claim has one status and a fixed list of moves.

The state machineRuns the real transition function
Send an event
The claim right now
{
  "status": "pending",
  "failedChecks": 0,
  "lastFailure": null
}
What happened
Send an event to see what the function does.
Bright arrows are the legal moves from where you are. Illegal events are worth clicking too: the error you see is the one the real function returns.
Predict it first
A verified owner clicks abandon. What should happen?

Who owns what

VerifiedAt riskare the only statuses that count as owning.

At risk still owns the domain on purpose. Records get removed by accident during migrations, so losing one starts a 7-day clock instead of an immediate loss. Nobody is silently revoked.

The whole table

Every status down the side, every event across the top. A dot means illegal.

All 56 combinationsRead from the code's TRANSITIONS table
FromPassedFailedCode expiredNew codeMissingGrace overSupersededAbandoned
PendingVerifiedPendingExpiredPending···Abandoned
VerifiedVerified···At risk·Transferred·
At riskVerified····LapsedTransferred·
Lapsed···Pending···Abandoned
Expired···Pending···Abandoned
Transferred········
Abandoned········
A test walks every one of these cells, against a table written out by hand from the spec, so a wrong table can't pass its own test.

Not every check changes anything

A finished check only produces an event if it should. The cells that say nothing changes are as important as the ones that do.

From a check result to an eventCalls the real eventForOutcome
StatusVerifiedPropagatingLookup errorNot found
PendingCHECK_PASSEDCHECK_FAILEDCHECK_FAILEDCHECK_FAILED
VerifiedCHECK_PASSEDNothing changesNothing changesRECORD_MISSING
At riskCHECK_PASSEDNothing changesNothing changesNothing changes
The empty cells are the point: a DNS outage can't hurt someone who already owns a domain.

When the worker comes back

How long the worker waitsFrom PENDING_BACKOFF_MS
Failure 1
30 s
Failure 2
1 min
Failure 3
2 min
Failure 4
5 min
Failure 5
15 min
Failure 6
30 min
Verified
24 h
Between re-checks.
At risk
6 h
Between re-checks, looking for it to return.
Grace period
7 days
To restore a missing record before it lapses.
Fast at first, when you've probably just added the record. Then it backs off, so a claim nobody's working on doesn't keep hitting DNS. It holds at 30 minutes until the code expires.