[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GXR64JRY8RGB0PESXAV3GH":3,"skill-same:01M6GXR64JRY8RGB0PESXAV3GH":76},{"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":34,"linkOnly":35,"markdownContent":36,"markdownBody":37,"frontMatter":38,"refName":39,"commitSha":40,"skillDirectory":41,"forksCount":42,"repositoryHtmlUrl":43,"repositoryHomepageUrl":6,"ownerHtmlUrl":44,"ownerBlogUrl":45,"ownerDescription":46,"updatedAt":47,"install":48,"resources":61},"01M6GXR64JRY8RGB0PESXAV3GH","build-an-incident-timeline-from-timestamps",null,"Use when reconstructing an incident — merges deploy, alert, log and chat timestamps into one UTC-ordered, source-tagged timeline before any narrative is written.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",81,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-build-an-incident-timeline-from-timestamps\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-build-an-incident-timeline-from-timestamps\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28,29,30,31,32,33],"timeline","build","incident","timestamps","build an incident timeline from timestamps","deploy","use","alert","log","chat","narrative","source","when","tagged","2026-11-10 10:12:30",false,"---\nname: build-an-incident-timeline-from-timestamps\ndescription: Use when reconstructing an incident — merges deploy, alert, log and chat timestamps into one UTC-ordered, source-tagged timeline before any narrative is written.\n---\n\n# Build an incident timeline from timestamps\n\nPostmortems go wrong when the story is written before the facts are ordered. Build the timeline first: every event with its source and a UTC timestamp, sorted. The narrative then falls out of the gaps.\n\n## Procedure\n\n1. Fix the timezone first. Convert everything to UTC and record the source clock for each line. A timeline mixing local pod time with UTC chat time is worse than no timeline.\n\n2. Pull machine events into one tab-separated file, one event per line, `ts\u003CTAB>source\u003CTAB>event`:\n       kubectl get events --sort-by=.lastTimestamp \\\n         -o custom-columns=TIME:.lastTimestamp,REASON:.reason,MSG:.message > k8s-events.tsv\n       git log --since=\"6 hours ago\" --pretty='%cI%x09git%x09%h %s' >> timeline.tsv\n\n3. Add human events from chat and ticket exports with their own timestamps:\n       jq -r '.[] | \"\\(.ts)\\tslack\\t\\(.user): \\(.text)\"' incident-export.json >> timeline.tsv\n\n4. Include observability markers: the first alert fired and the metric-deviation onset. The onset usually precedes the alert by minutes, and that gap is itself a finding:\n       curl -s 'localhost:9090\u002Fapi\u002Fv1\u002Fquery?query=rate(err[1m])>0.02&time=\u003CT0-1h>'\n\n5. Sort, dedupe, and clamp to the incident window ± 30 min:\n       sort -k1,1 timeline.tsv | awk '!seen[$0]++' > timeline-sorted.tsv\n\n6. Mark two anchors explicitly: `T0` is the first customer impact (not the first alert); `Tresolved` is when impact ended (metric back under threshold, not \"we stopped looking\"). Derive MTTD = T0→alert, MTTM = alert→mitigation, MTTR = T0→Tresolved.\n\n7. Leave gaps visible. \"07:14 deploy, 07:31 alert\" is a 17-minute blind spot worth naming; filling it with prose hides a missing detection.\n\n## Pitfalls\n\n- Pulling timestamps from unsynchronised clocks without noting skew — 30 s of node skew reorders events and invents causality.\n- Using the deploy time as the cause without evidence. Mark causal claims as hypotheses on separate lines from the fact lines.\n- Taking T0 as the alert time, which understates customer impact and flatters the SLO.\n- Mixing local browser or chat display time with UTC server time in a single column.\n\n## Verification\n\n    wc -l timeline-sorted.tsv                             # sum of sources minus dupes\n    awk -F'\\t' '{print $1}' timeline-sorted.tsv | sort -c  # sorted ascending\n    grep -c 'T0\\|Tresolved' timeline-sorted.tsv           # both anchors present\n\nReport: event count by source, the two anchors with MTTD\u002FMTTM\u002FMTTR, and the single largest unexplained gap named as a detection finding.\n","# Build an incident timeline from timestamps\n\nPostmortems go wrong when the story is written before the facts are ordered. Build the timeline first: every event with its source and a UTC timestamp, sorted. The narrative then falls out of the gaps.\n\n## Procedure\n\n1. Fix the timezone first. Convert everything to UTC and record the source clock for each line. A timeline mixing local pod time with UTC chat time is worse than no timeline.\n\n2. Pull machine events into one tab-separated file, one event per line, `ts\u003CTAB>source\u003CTAB>event`:\n       kubectl get events --sort-by=.lastTimestamp \\\n         -o custom-columns=TIME:.lastTimestamp,REASON:.reason,MSG:.message > k8s-events.tsv\n       git log --since=\"6 hours ago\" --pretty='%cI%x09git%x09%h %s' >> timeline.tsv\n\n3. Add human events from chat and ticket exports with their own timestamps:\n       jq -r '.[] | \"\\(.ts)\\tslack\\t\\(.user): \\(.text)\"' incident-export.json >> timeline.tsv\n\n4. Include observability markers: the first alert fired and the metric-deviation onset. The onset usually precedes the alert by minutes, and that gap is itself a finding:\n       curl -s 'localhost:9090\u002Fapi\u002Fv1\u002Fquery?query=rate(err[1m])>0.02&time=\u003CT0-1h>'\n\n5. Sort, dedupe, and clamp to the incident window ± 30 min:\n       sort -k1,1 timeline.tsv | awk '!seen[$0]++' > timeline-sorted.tsv\n\n6. Mark two anchors explicitly: `T0` is the first customer impact (not the first alert); `Tresolved` is when impact ended (metric back under threshold, not \"we stopped looking\"). Derive MTTD = T0→alert, MTTM = alert→mitigation, MTTR = T0→Tresolved.\n\n7. Leave gaps visible. \"07:14 deploy, 07:31 alert\" is a 17-minute blind spot worth naming; filling it with prose hides a missing detection.\n\n## Pitfalls\n\n- Pulling timestamps from unsynchronised clocks without noting skew — 30 s of node skew reorders events and invents causality.\n- Using the deploy time as the cause without evidence. Mark causal claims as hypotheses on separate lines from the fact lines.\n- Taking T0 as the alert time, which understates customer impact and flatters the SLO.\n- Mixing local browser or chat display time with UTC server time in a single column.\n\n## Verification\n\n    wc -l timeline-sorted.tsv                             # sum of sources minus dupes\n    awk -F'\\t' '{print $1}' timeline-sorted.tsv | sort -c  # sorted ascending\n    grep -c 'T0\\|Tresolved' timeline-sorted.tsv           # both anchors present\n\nReport: event count by source, the two anchors with MTTD\u002FMTTM\u002FMTTR, and the single largest unexplained gap named as a detection finding.\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-build-an-incident-timeline-from-timestamps",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-12 02:28:42",{"source":8,"skillName":5,"commands":49,"prompt":59,"zipAvailable":60},[50,53,56],{"tool":51,"command":52},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill build-an-incident-timeline-from-timestamps",{"tool":54,"command":55},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill build-an-incident-timeline-from-timestamps",{"tool":57,"command":58},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill build-an-incident-timeline-from-timestamps","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-build-an-incident-timeline-from-timestamps\u002FSKILL.md",true,[62,66,72],{"path":63,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":65,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":67,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":70,"sourceHtmlUrl":71},"SOURCE.md","REFERENCE","参考文档",368,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-build-an-incident-timeline-from-timestamps\u002FSOURCE.md",{"path":73,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":74,"sourceHtmlUrl":75},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-build-an-incident-timeline-from-timestamps\u002FTRUST.auto.yaml",[77,105,128,146,159,169],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":81,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":34},"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",[],[85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":109,"licenseFileUrl":110,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":34},"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",[],[114,115,116,117,118,119,120,121,122,123,124,125,126,127],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":129,"name":130,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":109,"licenseFileUrl":132,"sourceHtmlUrl":133,"categories":134,"keywords":135,"publishedAt":34},"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",[],[136,115,137,138,139,140,141,125,124,123,142,143,144,119,145,118,117],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":109,"licenseFileUrl":150,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":34},"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",[],[154,155,116,156,157,126,124,158,122,121,119,118],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":160,"name":161,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":162,"sourceHtmlUrl":163,"categories":164,"keywords":165,"publishedAt":34},"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",[],[166,167,168],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":173,"sourceHtmlUrl":174,"categories":175,"keywords":176,"publishedAt":34},"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",[],[177,178,179,180,181,182,183,26,184,185,186],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]