{
  "about": "An entry of UpFork's ledger. Check it by hand as https://upfork.dev/docs/ledger says, or at https://upfork.dev/verify/E-72",
  "entry": {
    "seq": 72,
    "kind": "lesson-version",
    "record": "{\"ai\":{\"apps\":[\"Claude\"],\"models\":[\"Claude Opus 5.5\"]},\"article\":\"telegram-bots-on-postgresql-alone-sponsor-bot-s-queues-forced-join-gate-and\",\"articleRevision\":1,\"assumed\":\"a time-limited data protector, in an app where every clock comes from an injected `TimeProvider`, would expire by that clock.\",\"author\":{\"account\":\"a_9d470b566acab5f65bdc\",\"handle\":\"ramin-valadan\"},\"evidence\":\"phase 11, commit 0c3e538.\",\"fix\":\"the expiry goes inside the protected text and is checked against the app's own clock (the two-step sign-in challenge does this).\",\"happened\":\"it reads the machine's clock: tests on a frozen clock couldn't expire it, and a frozen clock behind real time expired it at once.\",\"kind\":\"not-in-docs\",\"learnedBy\":\"ai\",\"lesson\":\"L-JG9M\",\"packages\":\"\",\"product\":\"telegram-uploader-bot-forced-join\",\"productRevision\":null,\"publishedAt\":\"2026-10-26T08:26:45.701Z\",\"site\":\"https://upfork.dev\",\"title\":\"ASP.NET Core's time-limited data protector checks the machine's clock, not TimeProvider\",\"type\":\"lesson-version\",\"url\":\"https://upfork.dev/lessons/L-JG9M\",\"version\":1,\"why\":\"\"}",
    "recordHash": "aa1d1ba43c5cba587a0737325ef0e0606d35ceb7785abffc2341290685efcee2",
    "prevHash": "dd597ba16f34c6cc059babb935b89dddf34c28a4ed203f4654db0a0187ac6f26",
    "entryHash": "84eef87adf67b381dbdd8cef5338b32c8d1d6fcf121253082bdf9793b9392a12",
    "keyId": "k1",
    "signature": "MtDTPR04HtR1Lrb/Ove33pM2WC0yII/Th8JP3QhAF+degKqVa8C9ggI2FGsRckey4Ng+mT0vrDtc1jZrwMiADQ==",
    "recordedAt": "2026-10-26T08:27:08.889388+00:00",
    "publicKey": "VuHuHXAtO3XAqgnwvMenp0f/3vTV061hnAIizYvwh40=",
    "algorithm": "Ed25519"
  },
  "path": [],
  "checkpoint": null,
  "keys": "https://upfork.dev/ledger/keys.json"
}