[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6H083ASYNX8ABH3TMNGEHJB":3,"skill-same:01M6H083ASYNX8ABH3TMNGEHJB":81},{"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":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":50,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M6H083ASYNX8ABH3TMNGEHJB","scrub-pii-from-structured-logs",null,"Use when application logs, request lines, or debug output may carry emails, ids, or tokens. Redact at the emit site and verify with a canary through the real sink.","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-scrub-pii-from-structured-logs\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-scrub-pii-from-structured-logs\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"logs","scrub","scrub pii from structured logs","structured","pii","canary","verify","site","use","application","tokens","emails","output","with","at","ids","debug","request","when","2026-11-10 10:12:30",false,"---\nname: scrub-pii-from-structured-logs\ndescription: Use when application logs, request lines, or debug output may carry emails, ids, or tokens. Redact at the emit site and verify with a canary through the real sink.\n---\n\n# Scrub PII from structured logs\n\nLogs are the most common uncontrolled copy of personal data. This skill keeps them useful while removing identifiers at the emit site, before anything is stored.\n\n## Procedure\n\n1. Enumerate every sink: stdout, files, syslog, the aggregator (Loki\u002FElastic), and any error forwarder. Each sink is an independent copy.\n\n2. Define an allowlist of loggable fields per event, not a denylist. Unknown fields are dropped, never passed through.\n\n3. Redact at emit, not in the pipeline: once the line reaches a transport it is already stored and replicated.\n\n4. Mask rather than drop where operators need to correlate: `u***@domain.com`, card as `************4242`, keeping only the last four.\n\n5. Use a keyed hash as a join key: `user_ref = sha256(user_id + pepper)[:16]` so the same user correlates across lines without the raw id appearing.\n\n6. Install the filter at the logger:\n   ```python\n   class PIIFilter(logging.Filter):\n       PAT = re.compile(r\"[\\w.+-]+@[\\w-]+\\.[\\w.-]+\")\n       def filter(self, record):\n           record.msg = self.PAT.sub(\"[email]\", str(record.msg)); return True\n   ```\n\n7. Scrub exception args and traceback locals, not just the message; request bodies appear inside tracebacks.\n\n8. Set and enforce a retention window on the log store, 30 days typical, and confirm the store actually expires lines.\n\n9. Ship a canary: log a synthetic email in a test environment and grep the index to confirm it is absent.\n\n## Pitfalls\n\n- URLs carry PII in query strings (`?email=`); scrub the request line and query before logging it.\n- `repr()` of a dataclass dumps every field; log selected fields explicitly one at a time.\n- Debug logging left on in production bypasses the filter; assert the effective level at startup.\n- Multi-line stack traces evade single-line regexes; scrub each rendered line individually.\n- Third-party log shippers with auto-capture may attach the request body; disable auto-capture explicitly.\n\n## Verification\n\n    grep -cE \"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\" \u002Fvar\u002Flog\u002Fapp\u002F*.log   # expect 0\n\nReport the sinks covered, the retention set, and the canary scan result through the real aggregator.\n","# Scrub PII from structured logs\n\nLogs are the most common uncontrolled copy of personal data. This skill keeps them useful while removing identifiers at the emit site, before anything is stored.\n\n## Procedure\n\n1. Enumerate every sink: stdout, files, syslog, the aggregator (Loki\u002FElastic), and any error forwarder. Each sink is an independent copy.\n\n2. Define an allowlist of loggable fields per event, not a denylist. Unknown fields are dropped, never passed through.\n\n3. Redact at emit, not in the pipeline: once the line reaches a transport it is already stored and replicated.\n\n4. Mask rather than drop where operators need to correlate: `u***@domain.com`, card as `************4242`, keeping only the last four.\n\n5. Use a keyed hash as a join key: `user_ref = sha256(user_id + pepper)[:16]` so the same user correlates across lines without the raw id appearing.\n\n6. Install the filter at the logger:\n   ```python\n   class PIIFilter(logging.Filter):\n       PAT = re.compile(r\"[\\w.+-]+@[\\w-]+\\.[\\w.-]+\")\n       def filter(self, record):\n           record.msg = self.PAT.sub(\"[email]\", str(record.msg)); return True\n   ```\n\n7. Scrub exception args and traceback locals, not just the message; request bodies appear inside tracebacks.\n\n8. Set and enforce a retention window on the log store, 30 days typical, and confirm the store actually expires lines.\n\n9. Ship a canary: log a synthetic email in a test environment and grep the index to confirm it is absent.\n\n## Pitfalls\n\n- URLs carry PII in query strings (`?email=`); scrub the request line and query before logging it.\n- `repr()` of a dataclass dumps every field; log selected fields explicitly one at a time.\n- Debug logging left on in production bypasses the filter; assert the effective level at startup.\n- Multi-line stack traces evade single-line regexes; scrub each rendered line individually.\n- Third-party log shippers with auto-capture may attach the request body; disable auto-capture explicitly.\n\n## Verification\n\n    grep -cE \"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\" \u002Fvar\u002Flog\u002Fapp\u002F*.log   # expect 0\n\nReport the sinks covered, the retention set, and the canary scan result through the real aggregator.\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-scrub-pii-from-structured-logs",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-15 02:28:10",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill scrub-pii-from-structured-logs",{"tool":59,"command":60},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill scrub-pii-from-structured-logs",{"tool":62,"command":63},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill scrub-pii-from-structured-logs","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-scrub-pii-from-structured-logs\u002FSKILL.md",true,[67,71,77],{"path":68,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":70,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":72,"resourceType":73,"resourceTypeDesc":74,"sizeBytes":75,"sourceHtmlUrl":76},"SOURCE.md","REFERENCE","参考文档",356,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-scrub-pii-from-structured-logs\u002FSOURCE.md",{"path":78,"resourceType":73,"resourceTypeDesc":74,"sizeBytes":79,"sourceHtmlUrl":80},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-scrub-pii-from-structured-logs\u002FTRUST.auto.yaml",[82,110,133,151,164,174],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":86,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":39},"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",[],[90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":114,"licenseFileUrl":115,"sourceHtmlUrl":116,"categories":117,"keywords":118,"publishedAt":39},"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",[],[119,120,121,122,123,124,125,126,127,128,129,130,131,132],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":114,"licenseFileUrl":137,"sourceHtmlUrl":138,"categories":139,"keywords":140,"publishedAt":39},"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",[],[141,120,142,143,144,145,146,130,129,128,147,148,149,124,150,123,122],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":152,"name":153,"nameZh":6,"description":154,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":114,"licenseFileUrl":155,"sourceHtmlUrl":156,"categories":157,"keywords":158,"publishedAt":39},"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",[],[159,160,121,161,162,131,129,163,127,126,124,123],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":165,"name":166,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":167,"sourceHtmlUrl":168,"categories":169,"keywords":170,"publishedAt":39},"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",[],[171,172,173],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":175,"name":176,"nameZh":6,"description":177,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":178,"sourceHtmlUrl":179,"categories":180,"keywords":181,"publishedAt":39},"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",[],[182,183,184,26,185,186,187,28,188,189,190],"tests","cover","verify tests cover changed lines","coverage","pr","exercise","patch","code","share"]