关于 launchdarkly-flag-drift
launchdarkly-flag-drift 是一项检查代码中的 LaunchDarkly 功能标志回退值是否与相关环境的默认规则值一致的技能。它指导谨慎地核对、修正、验证并准备 PR,同时保留标志评估逻辑。
主要功能
- 01解析标志键与环境
- 02比较各环境默认规则值
- 03定位 SDK 回退默认值
- 04仅修正默认值,不改评估逻辑
- 05验证修改并准备 PR
适用场景
- 01核对代码回退值与 LaunchDarkly 配置
- 02查找不同调用中的默认值差异
- 03处理环境间默认规则不一致
- 04准备经过验证的回退默认值修改
MCP 相关
该技能要求配置远程 LaunchDarkly MCP 服务。它使用 get-flag 等工具读取特定环境的标志配置,也可选用工具查找标志和枚举环境。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ launchdarkly/ ai-tooling --skill launchdarkly-flag-drift安装后在 Claude Code 中输入/launchdarkly-flag-drift确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
marketplace.jsonREADME.mdreferences/pr-template.mdsdk-default-patterns.md详细介绍
LaunchDarkly 标志漂移检测
你正在使用一项技能,它将指导你检查某个功能标志的代码中的 SDK 回退默认值是否偏离了其 LaunchDarkly 默认规则(fallthrough),并在偏离时协调代码。你的任务是从 LaunchDarkly 确定该标志当前的默认规则值,在代码中定位每次 SDK 求值传入的默认参数,对两者进行比较,并且仅在两者不同时,更新代码中的默认值,使其保持一致。你绝不会移除该标志或更改其求值逻辑。
前置条件
此技能要求你的环境已配置远程托管的 LaunchDarkly MCP 服务。
必需的 MCP 工具:
get-flag:获取标志在特定环境中的配置(fallthrough、variations、offVariation)。Fallthrough 因环境而异,因此每个关键环境都要调用一次。
可选的 MCP 工具:
list-flags:如果用户只通过名称描述标志,则查找标志键get-environments:列出项目的环境,以确定哪些环境是关键环境get-flag-status-across-envs:快速查看标志在各环境中的状态(在分别获取每个get-flag结果前,可快速发现跨环境差异)
核心概念:SDK 回退默认值不等于 Off Variation
每次 SDK 求值调用都会接受一个回退默认值:当 LaunchDarkly 无法访问、客户端尚未初始化或标志不可用时,返回此值。它是代码端的安全值,不同于标志的 offVariation(标志关闭时提供的值),也不同于其 fallthrough(没有任何定向规则匹配时提供的默认规则)。
此技能将一项特定的不变量视为“正确”:代码中的回退默认值应与当前默认规则(fallthrough)值一致。两者不一致即为漂移。协调两者可确保发生故障时返回的值,与大多数用户在其他情况下会收到的值保持一致。
核心概念:一个代码默认值,多个环境
代码中的回退默认值是编译进已部署代码的单个值。然而,标志的 fallthrough 是按环境配置的,不同环境之间可能有所不同(例如,production、eu-production 和 federal 可能各自提供不同的默认规则)。因此,必须在代码运行所涉及的每个关键环境中确定 fallthrough,而不能只检查一个环境。
- 如果关键环境中的 fallthrough 一致,则该共同值就是预期默认值。按常规进行协调。
- 如果它们不一致(例如,EU 提供
true,而 Federal 提供false),单个代码默认值就无法与所有环境匹配。这种差异本身就是一项发现:应明确指出,并确认哪个环境对当前构建具有权威性,而不是默默地协调到其中一个环境。请参阅“边缘情况”。
只检查一个环境是此技能得出错误或误导性结果的最常见原因,因此务必先确认全部关键环境。
有些团队会有意将回退值设为保守值/关闭值。遇到不匹配时,应将其作为发现指出,而不一定自动修改。请参阅“边缘情况”。
工作流
步骤 1:确定标志键和关键环境
- 获取标志键。 如果用户按名称描述了标志,请使用
list-flags解析其键。继续之前请先确认。 - 确定关键环境。 回退值因环境而异,而且代码中的同一个默认值必须适用于已部署代码服务的每个环境。比较之前,请先确定完整的环境集合:
- 如果一个构建服务于多个生产级环境(例如
production、eu-production、federal),则它们全部都是关键环境。 - 如果构建仅面向一个环境(例如仅面向某个区域或租户的部署,如仅面向 Federal 的构建),则该环境是唯一的关键环境。
- 查看仓库中的相关信息(部署配置、CI 中的环境名称、SDK 密钥接线方式),并与用户确认。如果环境集合不明确,请使用
get-environments列出已有环境。不要假设只有一个production环境。
- 如果一个构建服务于多个生产级环境(例如
步骤 2:从 LaunchDarkly 确定预期默认值
针对每个关键环境调用一次 get-flag。对每个环境,读取:
fallthrough:默认规则。如果它指向单个variation(一个索引),则该索引对应的值就是解析后的值。如果它是百分比rollout,则不存在单个默认值,请停止并按边缘情况处理。variations:将fallthrough.variation(索引)映射到variations[index].value。解析出的值就是该环境的预期默认值。offVariation和标志类型:这些信息可用于比较,也有助于发现类型不匹配。
然后对照各环境进行判断:
| 关键环境之间的情况 | 预期默认值 |
|---|---|
| 全部解析为相同的值 | 该共同值就是预期默认值。继续步骤 3。 |
| 解析为不同的值 | 跨环境不一致。 单个代码默认值无法满足所有环境。不要自动选择。 报告各环境的值,并确认哪个环境对当前构建具有权威性(或者应先在 LaunchDarkly 中解决不一致)。请参阅边缘情况。 |
(get-flag-status-across-envs 可快速提示环境之间是否存在差异,但编辑前务必使用 get-flag 解析实际的回退值。)
切勿猜测回退值。务必通过 get-flag 解析。
步骤 3:定位代码中的每个默认值
找出代码中评估该标志的每个位置,尤其要确认传递给 SDK 调用的默认值/回退参数。在整个代码库中搜索标志键,然后识别每处命中的默认值。
- 默认值通常是
variation(...)/*Variation(...)调用的最后一个位置参数(例如boolVariation("<key>", context, <default>))。 - 团队通常会封装 SDK。请检查为每个标志声明一次默认值的封装层/注册表/配置层、基于注解或结构体标签的默认值,以及生成的默认值文件。
有关各语言和抽象层的完整模式,以及如何区分默认值参数与上下文参数,请参阅 SDK 默认值模式。
第 4 步:比较并决策
比较之前先对两侧进行规范化(JSON/数字/类型注意事项请参阅边缘情况),然后:
| 结果 | 操作 |
|---|---|
| 关键环境在回退值上不一致 | 停止——不存在唯一的预期默认值。 报告各环境的值,并在编辑前确认此构建以哪个环境为准(或先在 LaunchDarkly 中解决差异)。不要自动将值统一到某一个环境。 |
| 代码中的默认值在所有关键环境中都与预期默认值匹配 | 没有偏差。 报告 drift_detected: false 并停止。不要创建 PR。 |
| 代码中的默认值不同 | 检测到偏差。继续执行第 5 步进行校准。 |
| 多次求值对应的代码默认值不同 | 存在偏差。将它们全部校准为预期值,并注明之前存在不一致。 |
第 5 步:校准代码中的默认值
仅更新默认值/回退参数,使其与预期值匹配。
- 不要更改求值逻辑、分支或非目标路径的行为。
- 不要移除标志或其求值逻辑。
- 如果默认值位于生成文件中,请勿手动编辑。更新唯一事实来源(构造函数/注册表/注释),并使用项目的代码生成命令重新生成。在摘要中注明
requires_generation: true。
示例(修改前后),预期默认值 = true:
// Before: outage returns false even though the default rule now serves true
const enabled = await ldClient.variation('new-checkout-flow', context, false);
// After: fallback default reconciled to match the fallthrough
const enabled = await ldClient.variation('new-checkout-flow', context, true);
周围的 if (enabled) { ... } else { ... } 分支保持不变。
第 6 步:提交前验证
运行项目配置的检查,并将范围限定为已更改的文件。从 package.json 脚本、Makefile、AGENTS.md/CLAUDE.md/CONTRIBUTING.md 或 CI 配置中查找检查项。通常包括:格式检查、lint、类型检查、构建和相关测试。
必须停止: 如果有任何检查失败且无法修复,请勿提交或推送。应缩小更改范围。绝不发布未通过格式检查/lint/类型检查/构建/测试的代码。
第 7 步:创建拉取请求
仅在验证通过后创建。使用 references/pr-template.md。描述中必须说明:标志键、检查过的关键环境及其解析后的回退值、代码默认值的修改前后值,以及仅更改了 SDK 回退默认值(标志及其求值逻辑均予以保留)。
- 遵循仓库的贡献规范(分支命名、提交风格)。首先检查
AGENTS.md/CLAUDE.md/CONTRIBUTING.md。 - 清晰的默认方案:分支使用
fix/flag-default-drift-<flag-key>,提交使用fix: sync in-code default for <flag-key> to match fallthrough。
第 8 步:输出结构化摘要
生成包含以下字段的简洁摘要:
flag_key: <key>
environments_checked: [<env>: <resolved fallthrough value>, ...]
environments_diverge: true | false
drift_detected: true | false
old_default: <in-code value before, or n/a>
new_default: <expected value / value written, or n/a>
files_modified: [<paths>]
pr_url: <url or null>
requires_generation: true | false
notes: <anything the reviewer should know, incl. any cross-environment divergence>
边缘情况
| 情况 | 操作 |
|---|---|
| Fallthrough 是百分比发布 | 不存在单一默认值。报告各值的分配比例,不要自动编辑,并询问用户回退值应代表哪个值。 |
回退值看起来是有意设得较保守(与 offVariation 或安全值一致) | 指出不匹配,并在更改前确认用户意图。有些团队会有意将回退值设为安全值。 |
| 代码中的默认值位于生成文件中 | 编辑事实来源并重新生成;切勿手动编辑生成的输出。设置 requires_generation: true。 |
| 代码默认值与变体的类型不匹配 | 在 PR/摘要中标记为错误;默认值和变体的类型应一致。 |
| JSON/对象/浮点数默认值 | 按规范化后的值而非字符串形式比较({"a":1} == { "a": 1 },0 == 0.0)。 |
| 未找到标志或环境不正确 | 告知用户;检查键是否有拼写错误,并确认环境。 |
动态标志键(flag-${id}) | 自动检测可能不完整;标记为需手动审核。 |
关键环境的 fallthrough 不一致(例如,eu-production 提供 true,federal 提供 false) | 单个代码内默认值无法匹配所有环境。如果构建仅面向一个环境,则以该环境的值为准,并注明其他环境。如果构建面向多个存在差异的环境,则不要默默选择其中一个——列出每个环境的值,并确认哪个环境具有权威性;或者建议先在 LaunchDarkly 中解决差异。 |
| 构建面向单一环境(区域或租户专属部署) | 将该环境视为唯一关键环境;其他环境的 fallthrough 与此构建的默认值无关。 |
| 标志涉及多个代码仓库 | 此技能仅适用于当前仓库。注明其他也引用此键的仓库,以便分别协调。 |
不要做的事
- 不要移除标志或其求值逻辑;此技能只会修改默认参数。
- 除回退默认值外,不要更改求值逻辑、分支逻辑或关闭路径行为。
- 不要只检查一个环境;解析此构建所服务的每个关键环境中的 fallthrough。
- 关键环境的 fallthrough 不一致时,不要依据某个环境的 fallthrough 进行协调——单个默认值无法满足有差异的环境,因此应先指出差异并确认哪个环境具有权威性。
- 不要手动编辑生成文件;应从事实来源重新生成。
- 没有漂移时不要创建 PR。
- 不要猜测 fallthrough 值;应通过
get-flag解析。 - 不要提交无法通过格式检查、lint、类型检查、构建或测试的代码。