[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GZS3HSDRD3GX0PBFPPQYF1":3,"skill-same:01M6GZS3HSDRD3GX0PBFPPQYF1":71},{"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":29,"linkOnly":30,"markdownContent":31,"markdownBody":32,"frontMatter":33,"refName":34,"commitSha":35,"skillDirectory":36,"forksCount":37,"repositoryHtmlUrl":38,"repositoryHomepageUrl":6,"ownerHtmlUrl":39,"ownerBlogUrl":40,"ownerDescription":41,"updatedAt":42,"install":43,"resources":56},"01M6GZS3HSDRD3GX0PBFPPQYF1","recover-from-a-stale-state-lock",null,"Use when terraform refuses to run because the state lock is held by a crashed or killed run. Verifies the holder is dead before force-unlocking, never disabling locking.","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-recover-from-a-stale-state-lock\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-recover-from-a-stale-state-lock\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28],"state","stale","lock","recover from a stale state lock","run","terraform","use","never","when","2026-11-10 10:12:30",false,"---\nname: recover-from-a-stale-state-lock\ndescription: Use when terraform refuses to run because the state lock is held by a crashed or killed run. Verifies the holder is dead before force-unlocking, never disabling locking.\n---\n\n# Recover from a stale state lock\n\nA crash or killed CI job leaves a lock with no process behind it. Force-unlocking a lock that is still held corrupts state; confirm the holder is gone first.\n\n## Procedure\n\n1. Read who holds the lock; the error names the ID, path, and operation:\n       Error: Error acquiring the state lock\n       ID: 8f3c...  Operation: OperationTypeApply  Who: ci-runner@...\n2. For S3+DynamoDB, inspect the lock row:\n       aws dynamodb get-item --table-name tf-locks \\\n         --key '{\"LockID\":{\"S\":\"acme-tfstate\u002Fprod\u002Fterraform.tfstate\"}}'\n3. Confirm no live process holds it: the CI job that owns the ID is finished or failed, and no `terraform apply` runs on that runner.\n       ps aux | grep '[t]erraform apply'\n4. Only then force-unlock with the exact ID from the error:\n       terraform force-unlock 8f3c-...\n5. If a run genuinely is in progress, wait for it; `-lock-timeout=5m` makes waiting automatic.\n6. After force-unlock, immediately `terraform plan` to confirm state is intact and consistent.\n7. Do not delete the DynamoDB row by hand instead of force-unlock; the CLI also notifies the backend and keeps lock metadata consistent.\n8. Fix the root cause: set `-lock-timeout`, add CI concurrency limits, and ensure killed jobs do not orphan locks.\n\n## Pitfalls\n\n- Force-unlocking a lock held by a live apply, so two writers interleave and corrupt state.\n- Deleting the lock table row manually, leaving the backend's lock metadata inconsistent.\n- `-lock=false` as a \"fix\", removing locking for every future run.\n- Force-unlocking with a guessed ID; the CLI requires the real one, and people work around it by deleting the row.\n- Not running a plan after unlock, so pre-existing corruption surfaces at the next apply.\n\n## Verification\n\n    aws dynamodb get-item --table-name tf-locks \\\n      --key '{\"LockID\":{\"S\":\"acme-tfstate\u002Fprod\u002Fterraform.tfstate\"}}'   # Item: null after unlock\n    terraform plan                                                    # acquires lock, no errors\n\nReport: the stale lock ID, the evidence the holder was dead, the force-unlock result, and the clean plan afterward.\n","# Recover from a stale state lock\n\nA crash or killed CI job leaves a lock with no process behind it. Force-unlocking a lock that is still held corrupts state; confirm the holder is gone first.\n\n## Procedure\n\n1. Read who holds the lock; the error names the ID, path, and operation:\n       Error: Error acquiring the state lock\n       ID: 8f3c...  Operation: OperationTypeApply  Who: ci-runner@...\n2. For S3+DynamoDB, inspect the lock row:\n       aws dynamodb get-item --table-name tf-locks \\\n         --key '{\"LockID\":{\"S\":\"acme-tfstate\u002Fprod\u002Fterraform.tfstate\"}}'\n3. Confirm no live process holds it: the CI job that owns the ID is finished or failed, and no `terraform apply` runs on that runner.\n       ps aux | grep '[t]erraform apply'\n4. Only then force-unlock with the exact ID from the error:\n       terraform force-unlock 8f3c-...\n5. If a run genuinely is in progress, wait for it; `-lock-timeout=5m` makes waiting automatic.\n6. After force-unlock, immediately `terraform plan` to confirm state is intact and consistent.\n7. Do not delete the DynamoDB row by hand instead of force-unlock; the CLI also notifies the backend and keeps lock metadata consistent.\n8. Fix the root cause: set `-lock-timeout`, add CI concurrency limits, and ensure killed jobs do not orphan locks.\n\n## Pitfalls\n\n- Force-unlocking a lock held by a live apply, so two writers interleave and corrupt state.\n- Deleting the lock table row manually, leaving the backend's lock metadata inconsistent.\n- `-lock=false` as a \"fix\", removing locking for every future run.\n- Force-unlocking with a guessed ID; the CLI requires the real one, and people work around it by deleting the row.\n- Not running a plan after unlock, so pre-existing corruption surfaces at the next apply.\n\n## Verification\n\n    aws dynamodb get-item --table-name tf-locks \\\n      --key '{\"LockID\":{\"S\":\"acme-tfstate\u002Fprod\u002Fterraform.tfstate\"}}'   # Item: null after unlock\n    terraform plan                                                    # acquires lock, no errors\n\nReport: the stale lock ID, the evidence the holder was dead, the force-unlock result, and the clean plan afterward.\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-recover-from-a-stale-state-lock",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-14 02:27:51",{"source":8,"skillName":5,"commands":44,"prompt":54,"zipAvailable":55},[45,48,51],{"tool":46,"command":47},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill recover-from-a-stale-state-lock",{"tool":49,"command":50},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill recover-from-a-stale-state-lock",{"tool":52,"command":53},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill recover-from-a-stale-state-lock","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-recover-from-a-stale-state-lock\u002FSKILL.md",true,[57,61,67],{"path":58,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":62,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":65,"sourceHtmlUrl":66},"SOURCE.md","REFERENCE","参考文档",357,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-recover-from-a-stale-state-lock\u002FSOURCE.md",{"path":68,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":69,"sourceHtmlUrl":70},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-recover-from-a-stale-state-lock\u002FTRUST.auto.yaml",[72,100,123,141,154,164],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":76,"sourceHtmlUrl":77,"categories":78,"keywords":79,"publishedAt":29},"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",[],[80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":101,"name":102,"nameZh":6,"description":103,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":105,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":29},"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",[],[109,110,111,112,113,114,115,116,117,118,119,120,121,122],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":124,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":127,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":29},"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",[],[131,110,132,133,134,135,136,120,119,118,137,138,139,114,140,113,112],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":142,"name":143,"nameZh":6,"description":144,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":145,"sourceHtmlUrl":146,"categories":147,"keywords":148,"publishedAt":29},"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",[],[149,150,111,151,152,121,119,153,117,116,114,113],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":155,"name":156,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":157,"sourceHtmlUrl":158,"categories":159,"keywords":160,"publishedAt":29},"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",[],[161,162,163],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":165,"name":166,"nameZh":6,"description":167,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":168,"sourceHtmlUrl":169,"categories":170,"keywords":171,"publishedAt":29},"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",[],[172,173,174,175,176,177,178,26,179,180,181],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]