[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GZ6HHFVTZTYQ2MMZ69ST7N":3,"skill-same:01M6GZ6HHFVTZTYQ2MMZ69ST7N":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":41,"repositoryHtmlUrl":42,"repositoryHomepageUrl":6,"ownerHtmlUrl":43,"ownerBlogUrl":44,"ownerDescription":45,"updatedAt":46,"install":47,"resources":60},"01M6GZ6HHFVTZTYQ2MMZ69ST7N","measure-elapsed-time-with-a-monotonic-clock",null,"Use when timing durations, timeouts or latency — read a monotonic clock that never steps backwards, not wall time, so DST and NTP cannot corrupt the measurement.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",80,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-measure-elapsed-time-with-a-monotonic-clock\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-measure-elapsed-time-with-a-monotonic-clock\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28,29,30,31,32],"time","clock","with","measure elapsed time with a monotonic clock","read","dst","use","never","latency","timing","measurement","wall","when","2026-11-10 10:12:30",false,"---\nname: measure-elapsed-time-with-a-monotonic-clock\ndescription: Use when timing durations, timeouts or latency — read a monotonic clock that never steps backwards, not wall time, so DST and NTP cannot corrupt the measurement.\n---\n\n# Measure elapsed time with a monotonic clock\n\nThe wall clock is a moving target: NTP can step it backwards, DST relabels it, and a VM suspend jumps it. Any duration — a timeout, a latency histogram, a stopwatch — must come from a monotonic source that only ever advances.\n\n## Procedure\n\n1. Pick the monotonic API for the language, not `now()`:\n```\nPython   time.monotonic_ns() \u002F perf_counter()\nGolang   time.Since(start)  (uses monotonic component)\nJava     System.nanoTime()\nNode     process.hrtime.bigint()\nC        clock_gettime(CLOCK_MONOTONIC_RAW, &ts)\n```\n2. Time the interval with monotonic, report the instant with wall time:\n```python\nimport time\nfrom datetime import datetime, timezone\nstart_mono = time.monotonic()\nstart_wall = datetime.now(timezone.utc)\ndo_work()\nelapsed  = time.monotonic() - start_mono\nfinished = datetime.now(timezone.utc)\nprint(f\"elapsed={elapsed:.3f}s started={start_wall.isoformat()} finished={finished.isoformat()}\")\n```\n3. Use the monotonic delta for timeouts and SLO math; use the wall instants for logs and correlation.\n4. On Linux, confirm which clock you are reading — `CLOCK_REALTIME` is wall, `CLOCK_MONOTONIC` excludes suspend time, `CLOCK_BOOTTIME` includes it:\n```\ncat \u002Fproc\u002Fuptime            # monotonic-ish seconds since boot\n```\n5. In Go, keep the monotonic reading rather than stripping it: `t.Round(0)` or a JSON\u002Fserialise round trip drops it, after which `Sub` silently uses wall time.\n6. In a histogram, bucket by the monotonic delta; using wall time makes a step appear as a negative or huge bucket.\n7. Test the property: monkeypatch the wall clock backwards and assert the measured duration stays positive.\n\n## Pitfalls\n\n- `time.time()` differences go negative when NTP steps the clock back; a timeout computed as `now - start > limit` then never fires.\n- `CLOCK_MONOTONIC` excludes suspend, so a laptop or VM that slept shows a shorter interval than reality; use `CLOCK_BOOTTIME` when suspend must count.\n- Serialising a Go `time.Time` through JSON strips the monotonic component; the same value measures differently after a round trip.\n- `process.hrtime()` in Node is monotonic but not epoch-based; adding it to `Date.now()` mixes two clocks.\n- A monotonic clock has an arbitrary epoch — never log it as a timestamp, only as a delta.\n\n## Verification\n\n```\npython3 -c \"import time; a=time.monotonic(); b=time.monotonic(); print('mono delta ok', b>=a)\"\n```\nMonotonic readings never decrease, and a negative-step test on the wall clock leaves the monotonic measurement positive. Report: \"durations measured with `monotonic_ns`; wall clock used only for log instants; timeout test steps wall clock back and still fires.\"\n","# Measure elapsed time with a monotonic clock\n\nThe wall clock is a moving target: NTP can step it backwards, DST relabels it, and a VM suspend jumps it. Any duration — a timeout, a latency histogram, a stopwatch — must come from a monotonic source that only ever advances.\n\n## Procedure\n\n1. Pick the monotonic API for the language, not `now()`:\n```\nPython   time.monotonic_ns() \u002F perf_counter()\nGolang   time.Since(start)  (uses monotonic component)\nJava     System.nanoTime()\nNode     process.hrtime.bigint()\nC        clock_gettime(CLOCK_MONOTONIC_RAW, &ts)\n```\n2. Time the interval with monotonic, report the instant with wall time:\n```python\nimport time\nfrom datetime import datetime, timezone\nstart_mono = time.monotonic()\nstart_wall = datetime.now(timezone.utc)\ndo_work()\nelapsed  = time.monotonic() - start_mono\nfinished = datetime.now(timezone.utc)\nprint(f\"elapsed={elapsed:.3f}s started={start_wall.isoformat()} finished={finished.isoformat()}\")\n```\n3. Use the monotonic delta for timeouts and SLO math; use the wall instants for logs and correlation.\n4. On Linux, confirm which clock you are reading — `CLOCK_REALTIME` is wall, `CLOCK_MONOTONIC` excludes suspend time, `CLOCK_BOOTTIME` includes it:\n```\ncat \u002Fproc\u002Fuptime            # monotonic-ish seconds since boot\n```\n5. In Go, keep the monotonic reading rather than stripping it: `t.Round(0)` or a JSON\u002Fserialise round trip drops it, after which `Sub` silently uses wall time.\n6. In a histogram, bucket by the monotonic delta; using wall time makes a step appear as a negative or huge bucket.\n7. Test the property: monkeypatch the wall clock backwards and assert the measured duration stays positive.\n\n## Pitfalls\n\n- `time.time()` differences go negative when NTP steps the clock back; a timeout computed as `now - start > limit` then never fires.\n- `CLOCK_MONOTONIC` excludes suspend, so a laptop or VM that slept shows a shorter interval than reality; use `CLOCK_BOOTTIME` when suspend must count.\n- Serialising a Go `time.Time` through JSON strips the monotonic component; the same value measures differently after a round trip.\n- `process.hrtime()` in Node is monotonic but not epoch-based; adding it to `Date.now()` mixes two clocks.\n- A monotonic clock has an arbitrary epoch — never log it as a timestamp, only as a delta.\n\n## Verification\n\n```\npython3 -c \"import time; a=time.monotonic(); b=time.monotonic(); print('mono delta ok', b>=a)\"\n```\nMonotonic readings never decrease, and a negative-step test on the wall clock leaves the monotonic measurement positive. Report: \"durations measured with `monotonic_ns`; wall clock used only for log instants; timeout test steps wall clock back and still fires.\"\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-measure-elapsed-time-with-a-monotonic-clock",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-11 08:47:40",{"source":8,"skillName":5,"commands":48,"prompt":58,"zipAvailable":59},[49,52,55],{"tool":50,"command":51},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill measure-elapsed-time-with-a-monotonic-clock",{"tool":53,"command":54},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill measure-elapsed-time-with-a-monotonic-clock",{"tool":56,"command":57},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill measure-elapsed-time-with-a-monotonic-clock","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-measure-elapsed-time-with-a-monotonic-clock\u002FSKILL.md",true,[61,65,71],{"path":62,"resourceType":62,"resourceTypeDesc":63,"sizeBytes":64,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"SOURCE.md","REFERENCE","参考文档",369,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-measure-elapsed-time-with-a-monotonic-clock\u002FSOURCE.md",{"path":72,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":73,"sourceHtmlUrl":74},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-measure-elapsed-time-with-a-monotonic-clock\u002FTRUST.auto.yaml",[76,104,127,145,158,168],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":80,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":33},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":109,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":33},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[113,114,115,116,117,118,119,120,121,122,123,124,125,126],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":131,"sourceHtmlUrl":132,"categories":133,"keywords":134,"publishedAt":33},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[135,114,136,137,138,139,140,124,123,122,141,142,143,118,144,117,116],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":149,"sourceHtmlUrl":150,"categories":151,"keywords":152,"publishedAt":33},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[153,154,115,155,156,125,123,157,121,120,118,117],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":159,"name":160,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":161,"sourceHtmlUrl":162,"categories":163,"keywords":164,"publishedAt":33},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[165,166,167],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":172,"sourceHtmlUrl":173,"categories":174,"keywords":175,"publishedAt":33},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[176,177,178,179,180,181,182,26,183,184,185],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]