[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M70FWAJ338SMMXF4QDSRWZ5R":3,"skill-same:01M70FWAJ338SMMXF4QDSRWZ5R":56},{"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":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":29,"linkOnly":30,"markdownContent":31,"markdownBody":32,"frontMatter":33,"refName":35,"commitSha":36,"skillDirectory":37,"forksCount":38,"repositoryHtmlUrl":39,"repositoryHomepageUrl":6,"ownerHtmlUrl":40,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":41,"install":42,"resources":55},"01M70FWAJ338SMMXF4QDSRWZ5R","single-source-of-truth",null,"真相源单一律——意图 \u002F 逻辑 \u002F 状态三层都禁止「真相源数量 > 1」，否则必 drift。Use when 设计新模块\u002F新流程时面对一个概念有多处可能维护其状态、值或定义；或排查 drift 类 bug（A 处和 B 处不一致）；或重构时合并散点逻辑\u002F共享 worker 创建\u002F状态机生命周期对齐时。","KarryViber\u002FOrb","KarryViber","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F223777671?v=4","01M70FTGZ485AP97T3CJCYW1Z2","Karryz","01M70FTGZRWF3FEQBYZ3JWTSPR",66,"MIT","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fsingle-source-of-truth\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28],"single source of truth","single","source","bug","worker","design","use","when","drift","user","2026-11-10 10:12:30",false,"---\nname: single-source-of-truth\ndescription: 真相源单一律——意图 \u002F 逻辑 \u002F 状态三层都禁止「真相源数量 > 1」，否则必 drift。Use when 设计新模块\u002F新流程时面对一个概念有多处可能维护其状态、值或定义；或排查 drift 类 bug（A 处和 B 处不一致）；或重构时合并散点逻辑\u002F共享 worker 创建\u002F状态机生命周期对齐时。\nprovenance: user-authored\n---\n\n# Single Source of Truth — 真相源单一律\n\n## When to Use\n\n- 设计新模块 \u002F 新流程时一个概念有多处可能维护其值\n- 排查 drift 类 bug（A 处和 B 处不一致 \u002F 状态错乱 \u002F 定义冲突）\n- 重构时考虑合并散点逻辑、共享 worker 创建路径、状态机 touchpoint 对齐\n- 用户问「这个值在哪定义的？」「为什么 A 和 B 不一样？」\n\n## 核心定律\n\n**对任何一个概念，其 source of truth 的数量 = 1**。\n\n数量 > 1 → 维护人会 drift，时间会 drift，bug 必至。\n\n## 三个维度（同模式不同表现）\n\n| 维度 | 反模式 | 来源 fact |\n|------|--------|----------|\n| **用户意图** | 单歧义词不澄清，在多 turn 里各自假设 | fact_53 |\n| **代码逻辑** | worker 创建散点，每处自己 spawn，不抽共享 | fact_34 |\n| **运行时状态** | stream lifecycle 6 个 touchpoint 各管各的 arm\u002Fclear | fact_96 |\n\n## Workflow\n\n1. **定位 SoT**：面对一个概念先问「它的 source of truth 在哪？」\n2. **数 SoT 数量**：若 > 1 → 必须处置\n3. **二选一处置**：\n   - **集中**：合并到单一 owner（一个文件 \u002F 一个函数 \u002F 一个 anchor 文件）\n   - **派生**：保留一个 SoT，其余从它**只读派生**（不允许独立写）\n4. **禁止各自维护**：每个分支自己写自己的 = drift 已发生\n\n## 典型反例\n\n- ❌ 用户问 `可以` 你假设是 A 意图执行；下一个 turn 又来个 `可以` 假设是 B → 两次假设独立 drift\n- ❌ scheduler 一处 fork worker，cron 又自己 fork，调试时谁也不知道用哪个\n- ❌ stream start 在 A，append 在 B，stop 在 C，error path 在 D 各自 setState → lifecycle 必断\n- ❌ Anchor ts 一处写文件、一处 in-memory 缓存、一处 history 反查 → 三个真相源同时漂\n\n## 典型正例\n\n- ✅ Slack daily anchor → `data\u002F\u003Ctopic>-daily-anchor.json` 一个文件，所有调用读它\n- ✅ Worker spawn 抽到 `scheduler.spawnWorker()`，cron \u002F inject \u002F 手动触发都走它\n- ✅ Stream lifecycle 集中到一个 controller 类，6 个 touchpoint 都调它\n\n## Gotchas\n\n- ❌ 「这次先复制一份，以后再统一」——以后没有了，drift 立刻发生\n- ❌ 「我加个缓存做加速」——缓存是派生层但写也走它就变成第二个 SoT\n- ❌ 把「文档」当 SoT，但代码里硬编码值不引用文档——文档腐化必至\n- ⚠️ 派生层必须**只读**派生；任何能写的派生层都是新 SoT\n\n## 与其他 skill 的关系\n\n- `state-assumptions-before-acting` → 把「我假设 SoT 是 X」显式化让 Karry 拦截\n- `terse-intent-classifier` → 短指令意图歧义就是「用户意图层 SoT 数量 > 1」的早期检测\n- `truth-ladder` → 状态汇报阶梯本身就是「状态 SoT 单一律」的具体落地（attempted\u002Fobserved\u002Fconfirmed 不允许并存为同一事的真相）\n","# Single Source of Truth — 真相源单一律\n\n## When to Use\n\n- 设计新模块 \u002F 新流程时一个概念有多处可能维护其值\n- 排查 drift 类 bug（A 处和 B 处不一致 \u002F 状态错乱 \u002F 定义冲突）\n- 重构时考虑合并散点逻辑、共享 worker 创建路径、状态机 touchpoint 对齐\n- 用户问「这个值在哪定义的？」「为什么 A 和 B 不一样？」\n\n## 核心定律\n\n**对任何一个概念，其 source of truth 的数量 = 1**。\n\n数量 > 1 → 维护人会 drift，时间会 drift，bug 必至。\n\n## 三个维度（同模式不同表现）\n\n| 维度 | 反模式 | 来源 fact |\n|------|--------|----------|\n| **用户意图** | 单歧义词不澄清，在多 turn 里各自假设 | fact_53 |\n| **代码逻辑** | worker 创建散点，每处自己 spawn，不抽共享 | fact_34 |\n| **运行时状态** | stream lifecycle 6 个 touchpoint 各管各的 arm\u002Fclear | fact_96 |\n\n## Workflow\n\n1. **定位 SoT**：面对一个概念先问「它的 source of truth 在哪？」\n2. **数 SoT 数量**：若 > 1 → 必须处置\n3. **二选一处置**：\n   - **集中**：合并到单一 owner（一个文件 \u002F 一个函数 \u002F 一个 anchor 文件）\n   - **派生**：保留一个 SoT，其余从它**只读派生**（不允许独立写）\n4. **禁止各自维护**：每个分支自己写自己的 = drift 已发生\n\n## 典型反例\n\n- ❌ 用户问 `可以` 你假设是 A 意图执行；下一个 turn 又来个 `可以` 假设是 B → 两次假设独立 drift\n- ❌ scheduler 一处 fork worker，cron 又自己 fork，调试时谁也不知道用哪个\n- ❌ stream start 在 A，append 在 B，stop 在 C，error path 在 D 各自 setState → lifecycle 必断\n- ❌ Anchor ts 一处写文件、一处 in-memory 缓存、一处 history 反查 → 三个真相源同时漂\n\n## 典型正例\n\n- ✅ Slack daily anchor → `data\u002F\u003Ctopic>-daily-anchor.json` 一个文件，所有调用读它\n- ✅ Worker spawn 抽到 `scheduler.spawnWorker()`，cron \u002F inject \u002F 手动触发都走它\n- ✅ Stream lifecycle 集中到一个 controller 类，6 个 touchpoint 都调它\n\n## Gotchas\n\n- ❌ 「这次先复制一份，以后再统一」——以后没有了，drift 立刻发生\n- ❌ 「我加个缓存做加速」——缓存是派生层但写也走它就变成第二个 SoT\n- ❌ 把「文档」当 SoT，但代码里硬编码值不引用文档——文档腐化必至\n- ⚠️ 派生层必须**只读**派生；任何能写的派生层都是新 SoT\n\n## 与其他 skill 的关系\n\n- `state-assumptions-before-acting` → 把「我假设 SoT 是 X」显式化让 Karry 拦截\n- `terse-intent-classifier` → 短指令意图歧义就是「用户意图层 SoT 数量 > 1」的早期检测\n- `truth-ladder` → 状态汇报阶梯本身就是「状态 SoT 单一律」的具体落地（attempted\u002Fobserved\u002Fconfirmed 不允许并存为同一事的真相）\n",{"name":5,"provenance":34,"description":7},"user-authored","main","cb33813b8990e4602b7c2d501659f77ebba5999f","profiles\u002F.claude\u002Fskills\u002Fsingle-source-of-truth",8,"https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb","https:\u002F\u002Fgithub.com\u002FKarryViber","2026-05-14 18:44:03",{"source":8,"skillName":5,"commands":43,"prompt":53,"zipAvailable":54},[44,47,50],{"tool":45,"command":46},"npx","npx skills add KarryViber\u002FOrb --skill single-source-of-truth",{"tool":48,"command":49},"bunx","bunx skills add KarryViber\u002FOrb --skill single-source-of-truth",{"tool":51,"command":52},"pnpm","pnpm dlx skills add KarryViber\u002FOrb --skill single-source-of-truth","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fsingle-source-of-truth\u002FSKILL.md",true,[],[57,91,105,128,147,160],{"skillNo":58,"name":59,"nameZh":6,"description":60,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":61,"licenseFileUrl":62,"sourceHtmlUrl":63,"categories":64,"keywords":73,"publishedAt":29},"01M70G0637CFCHAY3DYTMYS07K","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","Apache-2.0","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fwebapp-testing\u002FSKILL.md",[65,70],{"categoryNo":66,"categoryName":67,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":71,"categoryName":72,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000009","前端开发",[74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],"webapp","testing","webapp testing","playwright","screenshots","ui","behavior","web","for","with","browser","logs","toolkit","debugging","frontend","local","applications",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":29},"01M70FZXCJ5AHJ3JW2Q12F04TA","vendor-doc-actionability","对外合作文档（交付文档 \u002F POC 文档 \u002F Solution Doc \u002F 提案书）必须为每个「需对方执行」的动作写清具体操作入口（URL \u002F 工单系统 \u002F 脚本路径 \u002F 联系人 + 联系方式 \u002F 步骤编号）。Use when 给客户、vendor、合作方写交付文档、POC 文档、Solution Doc、提案书；或检视已有对外文档是否抽象到无法执行。","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fvendor-doc-actionability\u002FSKILL.md",[],[98,99,100,101,102,25,103,26,104,28],"vendor","doc","vendor doc actionability","poc","文档","提案","URL",{"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":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":119,"publishedAt":29},"01M70FZARY5P7VRJKVFATTCVX9","vendor-api-param-validation","第三方 API \u002F SDK 集成开工前，强制先列参数 checklist 并对照官方文档逐项验证（名称 \u002F 类型 \u002F 必填 \u002F 默认 \u002F 上限），通过后再编码——不是「写完再调通」。Use when 新接 vendor API\u002FSDK（Slack \u002F LongPort \u002F freee \u002F LLM API 等）、既有集成追加新 endpoint 或新字段、用户说「调通某接口」「接入 X」「集成 X」。","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fvendor-api-param-validation\u002FSKILL.md",[111,114],{"categoryNo":112,"categoryName":113,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":115,"categoryName":116,"taxonomyType":117,"taxonomyTypeDesc":118},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[120,121,98,122,123,124,125,102,126,25,26,28,127],"vendor api param validation","validation","api","slack","sdk","llm api","checklist","endpoint",{"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":15,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":135,"publishedAt":29},"01M70FYW81TRN7VAS8WTN08STH","truth-ladder","状态放行三层阶梯（attempted \u002F observed \u002F confirmed）—— 汇报任务、API、命令、消息或外部动作状态时强制分层，避免把\"动作已发起\"误写成\"结果已达成\"。Use when 准备写「任务已完成」「API 返回成功」「exit code 0」「用户已收到」「ok:true」类状态汇报；或在 cron 报告 \u002F Slack 回报 \u002F project status \u002F receipt 中表达完成度时。","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Ftruth-ladder\u002FSKILL.md",[134],{"categoryNo":115,"categoryName":116,"taxonomyType":117,"taxonomyTypeDesc":118},[136,137,138,122,139,26,25,140,141,142,143,144,145,123,146],"ladder","truth ladder","ok","code","exit","true","status","报告","cron","project","project status",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":29},"01M70FYTESF5WQYBVRX8BXYJQF","thread-object-realignment","长 thread 切题后的对象重定协议——thread 历史 ≥5 条且检测到切题信号时，回复前必做「用户最后显式问题对象 vs 待发回复对象」一致性校验，不一致则改写或反问。Use when Slack thread 历史 ≥5 条且当前用户消息出现切题信号（主题词突变、问句指向新实体、时间线跳跃、出现「另外」「话说」「回到 X」「换个话题」等切题语，或 ≥3 turn 后用户显式问题对象与最近 assistant 回复对象不同）。","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fthread-object-realignment\u002FSKILL.md",[],[154,155,156,123,157,28,158,26,159,25],"object","thread","thread object realignment","校验","slack thread","assistant",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":61,"licenseFileUrl":164,"sourceHtmlUrl":165,"categories":166,"keywords":170,"publishedAt":29},"01M70FYFC1Y2J16FJFEFQ5WYRE","theme-factory","Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors\u002Ffonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Ftheme-factory\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Ftheme-factory\u002FSKILL.md",[167],{"categoryNo":168,"categoryName":169,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000015","视觉设计",[171,172,173,174,175,176,177,178,83,179,180,86,181,182,183,184,185,82,186,187],"theme factory","factory","theme","apply","styling","fly","generate","artifact","fonts","can","artifacts","you","themes","pages","landing","slides","SET"]