契约漂移审计方法论如何系统化核查 Caffeine 文档承诺与实现行为的偏差【免费下载链接】caffeineA high performance caching library for Java项目地址: https://gitcode.com/gh_mirrors/ca/caffeine导读本文围绕 Caffeine 仓库中面向 AI 审计 Agent 的契约漂移审计技能文档audit-contract-drift/SKILL.md展开完整还原其“先读文档、再追踪实现”的逆向审计方法论如何从公开 API 的 Javadoc 中枚举行为承诺如何把每一条承诺追踪到所有应当履行它的代码路径以及如何用“契约漂移”这一统一口径收敛 javadoc 承诺与实现行为之间的静默矛盾。读完本文你将掌握一套可直接复用的 API 契约审计清单、常见漂移模式库以及针对 Caffeine 核心接口与视图asMap、集合视图、批量操作、synchronous()往返、序列化往返的逐点核查框架。说明本文中“技能文档”指 .claude/skills/audit-contract-drift/SKILL.md配套的审计执行框架见 .claude/agents/auditor.md文中所引 Javadoc 与实现均来自本仓库当前源码未引入仓库之外的外部断言。一、什么是契约漂移Contract Drift1.1 技能文档给出的核心定义技能文档开门见山地界定了这一类审计的独特定位“大多数审计读代码这个审计先读文档然后把每一条承诺追踪到所有应当履行它的实现路径。这里要抓的 bug 不是并发缺陷或算术缺陷——而是 javadoc 承诺与代码实际行为之间的静默矛盾。”契约漂移审计的输入不是“某个方法写得对不对”而是“文档承诺了什么、所有相关路径是否一致地兑现了承诺”。技能文档据此定义了漂移的判定标准“一条路径如果使用了与契约承诺不同的等价性、顺序或可见性就是一个契约漂移发现。同样一条在往返round-trip过程中静默降级配置的路径也是。”配套的执行框架 .claude/agents/auditor.md 对此给出了佐证Caffeine 核心实现的锁层级、节点生命周期等“机械事实”记录在 .claude/rules/concurrency.md 中而哪些看似可疑的行为属于有意设计如 weight0 条目是用户可见的 pinning 特性、EXPIRE_TOLERANCE是有意为之的过期语义、瞬态负weightedSize是可接受的最终一致则在 .claude/docs/design-decisions.md 中说明——契约审计的职责是识别文档与实现的偏差而不是把有意设计误报为缺陷。1.2 与其它审计的边界Caffeine 仓库的.claude/skills/目录下还有大量姊妹技能契约漂移审计与它们的区别在于audit-linearizability关注并发下的线性化顺序属于正确性证明范畴audit-adversarial无设计上下文的敌意全面审查audit-contract-drift关注“文档说了什么 vs 代码做了什么”的静默矛盾是唯一一个以文档为第一阅读对象的审计。根据 .claude/CLAUDE.md 的审计选择表文档化行为与实现漂移的疑虑应运行/audit-contract-drift其使用场景是“Documented behavior vs. implementation drift”。二、契约清单从哪些文档枚举行为承诺2.1 第一来源Caffeine.java 构建器 Javadoc技能文档要求以 Caffeine.java 中每个构建器方法 javadoc 里的bNote:/b与bWarning:/b块为最高优先级契约来源。以下是在当前源码中实际存在、可直接作为核查锚点的示例等价性语义翻转强相关技能文档点名的第一类weakKeys() 的bWarning:/b块承诺使用该方法后缓存将以身份比较判定键的相等性其asMap视图因此会在技术上违反 Map 规范与IdentityHashMap同理。同时承诺键已被 GC 回收的条目可能仍被estimatedSize()计数但“绝不会对读写操作可见”。weakValues() 的bNote:/b块承诺使用该方法后缓存以身份比较判定值的相等性并给出“弱值不擅长做缓存优先考虑 softValues”的工程建议。类级 JavadocCaffeine.java 顶部统一承诺“默认使用 equals 比较若指定了 weakKeys键改为身份比较若指定了 weakValues 或 softValues值改为身份比较”。过期与刷新expireAfter*、refreshAfterWrite相关方法承诺时长约束与“过期”在边界上的定义。refreshAfterWrite的bNote:/b明确承诺“刷新期间抛出的所有异常将被记录日志然后吞掉”。类级 Javadoc 承诺过期条目可能被estimatedSize()计数但“绝不会对读写操作可见”可通过scheduler(Scheduler)提供过期条目的及时移除。容量与逐出maximumSize、maximumWeight承诺逐出触发时机与摊销行为类级 Javadoc 承诺“若指定了最大容量条目可能在每次缓存修改时被逐出”。监听器removalListener、evictionListener承诺通知的时机与方式且均有“must not在回调中修改缓存”或“异常不会被传播”之类的bWarning:/b。2.2 第二来源核心接口的全部方法 Javadoc技能文档点名的接口均存在于caffeine/src/main/java/com/github/benmanes/caffeine/cache/下Cache.java每个方法都要核查尤其关注 “must”、“will”、“guarantees”、“for any reason” 这类强承诺词汇。例如其类级 Javadoc 承诺“实现预期是线程安全的可被多个并发线程安全访问”get方法承诺映射函数“在同一键上至多应用一次”、且映射函数必须不得在计算期间修改本缓存。LoadingCache.java、AsyncCache.java、AsyncLoadingCache.java同上逐方法核查。Policy.java每个方法的文档化行为。用户侧契约接口Weigher.java、Expiry.java、RemovalListener.java、RemovalCause.java。其中 RemovalCause.java 本身就是一个浓缩的契约字典EXPLICIT用户显式移除、REPLACED值被替换条目并未真正移除、COLLECTED键/值被 GC 回收、EXPIRED过期时间戳已过、SIZE因容量约束被逐出并承诺wasEvicted()对后三者返回true。任何路径若在文档未承诺的时机触发或遗漏这些 cause都构成漂移候选。2.3 第三来源内部义务Internal Obligations技能文档明确要求把.claude/rules/*.md与各模块内部类 Javadoc 中“callers must”式的内部契约也纳入清单例如jcache 模块的EventDispatcher要求每个发布事件的线程都必须通过awaitSynchronous/ignoreSynchronous排空同步监听器队列异步操作必须向 in-flight 集合注册。对这些内部义务要逐一验证每一个调用点包括不经过明显入口的执行器线程路径与 refresh 路径是否履行。仓库规则文件中有对应佐证例如 .claude/rules/async-cache.md 记录了异步缓存异常传播与 future 完成的内部义务.claude/rules/concurrency.md 记录了写缓冲区任务不丢失、drain 状态机等内部约定。2.4 每条契约要记录什么技能文档要求为每条契约记录三要素契约的精确措辞、激活该契约的配置组合、受影响的操作集合。这是后续逐路径追踪的索引缺一不可。三、追踪矩阵把每条承诺映射到全部实现路径技能文档给出了一个明确的“追踪矩阵”每条契约都要沿以下路径逐一核对直接 API 调用Cache/LoadingCache/AsyncCache上的直接方法调用asMap()视图方法size、isEmpty、containsKey、containsValue、get、put、remove(k)、remove(k,v)、replace、compute*、merge、equals、hashCode集合视图asMap().keySet()/values()/entrySet()contains、remove、removeAll、retainAll、removeIf、iterator、spliterator批量操作putAll、getAll、getAllPresent、invalidateAllAsyncCache.synchronous()往返同步视图是否与异步缓存履行相同的契约序列化往返反序列化后的缓存是否仍履行关于过期时长、loader 是否存在等承诺对每一条都要问两个问题这条路径使用的等价性、顺序或可见性与契约承诺一致吗往返过程中配置是否被静默降级只要答案是否定的就是一个契约漂移发现。配套的审计框架 .claude/agents/auditor.md 为这类追踪提供了两条实用准则生成代码溯源PS.java、WSSMS.java等节点类是代码生成的字段与方法形态的实际定义在caffeine/src/javaPoet/java/com/github/benmanes/caffeine/cache/的AddX.java生成器中。审计字段或方法时必须先溯源到生成器不能只在BoundedLocalCache中下结论配置矩阵测试可能只覆盖矩阵中的一种配置如强引用值而未覆盖弱引用值因此“现有测试通过”不是契约成立的证据必须说明测试覆盖的具体场景与发现路径是否一致。四、七种常见漂移模式检查清单技能文档显式列出七种要优先核查的漂移模式这是全文最具实战价值的部分4.1 弱/软缓存上的身份比较 vs equals 比较weakKeys/weakValues/softValues承诺身份比较但使用o.equals(value)或Collection.contains(value)的视图集合可能反而应用了用户的 equals 语义。核查点asMap()及三个集合视图的所有contains/remove/iterator路径。4.2 基数与存在性的不对称被文档描述为“将 in-flight 异步值视为不存在”的方法必须与同一视图上的size、isEmpty、equals、hashCode和迭代器保持一致。核查点异步缓存中 in-flight 条目在查询、变更、基数方法三套口径下的可见性是否自洽。4.3 “for any reason”通知承诺removalListener被文档承诺“为任何原因触发”但异步路径可能对 null 或异常完成的结果丢弃通知。核查点AsyncCache完成路径上监听器触发的完备性。4.4 跨版本序列化跨版本间被重命名或默认值不同的序列化字段可能在往返时静默丢失配置或直接抛异常。核查点序列化代理对字段的读写是否与当前配置一一对应。4.5 同实例返回语义例如compute(k, (k,v) - v)被文档描述为一种行为但实现无论是否真的改变值都会更新时间戳/权重。核查点compute 族方法在“返回同一实例”时的副作用是否符合文档。4.6size()被文档化为估计值技能文档特别提示这是显式豁免explicit out只要在 size 与逻辑存在性产生分歧的每个位置确实都文档化为“估计值”就不构成漂移。核查点estimatedSize相关文档是否在所有相关接口位置保持一致口径。4.7 同步视图与异步视图的分歧synchronous()视图的asMap()可能对 in-flight 条目在查询、变更、基数方法之间出现不一致处理。核查点AsyncCache.synchronous()往返后的行为一致性。五、发现的标准形态锚定漂移的两端技能文档对每条最终发现给出了严格的落盘格式——必须同时锚定契约端与实现端并给出最小用户可观察场景契约来源文件路径 javadoc 片段承诺了什么分歧实现文件路径 方法实际做了什么最小可观察场景一个文档与代码确实产生分歧的用户可复现场景。配套的 .claude/agents/auditor.md 输出契约进一步要求每条发现包含位置文件方法、一句话问题摘要、严重度critical/high/medium/low、证据、被违反的不变量/契约、置信度high/medium、定价Pricedhigh/critical 必须附实测证据、验证测试想法。例如其示例验证命令./gradlew :caffeine:test --tests BoundedLocalCacheTest.methodName -Pcomputeasync -Pvaluesweak这条命令同时印证了仓库测试体系的配置矩阵能力.claude/CLAUDE.md 中记录了-Pkeys/-Pvalues/-Pcompute/-Pstats等过滤旗标CI 在 40 个分片上跑完整矩阵也说明契约审计中的每一条漂移都应落到某个具体配置组合上去验证。六、证据边界与执行纪律技能文档与配套审计框架对“什么能算证据”划了清晰的红线写作与执行时同样适用以源码证据为准不依据先前审计历史下结论“先前的审计没有发现问题”不是证据设计决策文档.claude/rules/design-decisions.md、.claude/docs/design-decisions.md是机械事实代码有意如此可用于排除误报但不能替代对代码的独立分析high/critical 级别发现必须构建可运行 witnessJUnit 方法、jshell 片段或针对caffeine/build/libs/caffeine-*.jar的 main实测定价且要在用户真实配置Ticker.systemTicker()、公共线程池下复现仅在FakeTicker或直接执行器下复现的应视为仪器伪影并降低严重度无法从源码静态确认的并发问题应升级到动态工具测试选择依据见 .claude/docs/testing.mdFray 用于同步点交错、LinCheck 用于普通字段竞争、jcstress 用于弱内存发布对应测试源位于caffeine/src/frayTest、caffeine/src/lincheckTest、caffeine/src/jcstress。七、最小可执行的审计工作流综合技能文档与配套框架一次契约漂移审计的完整流程可浓缩为枚举从 Caffeine.java 的 Note/Warning 块、四个核心接口、Policy.java 与四个用户侧契约接口、.claude/rules/内部义务中产出“契约 激活配置 受影响操作”三要素清单追踪按第三节的六类路径矩阵逐条映射尤其不要遗漏asMap视图、集合视图、批量操作、synchronous()往返、序列化往返这五类间接路径对照用第四节七种漂移模式做靶向扫描锚定每条发现按第五节格式锚定契约端与实现端给出最小可观察场景定价对 high/critical 发现构建 witness 实测标注运行配置与测得数值输出报告写入审计输出目录约定见 .claude/docs/audit-output.md并按 finding-taxonomy 分类置信度标注遵循 .claude/agents/auditor.md 的 high/medium 分级与“不得静默丢弃中等置信度怀疑”的纪律。这套方法论的价值在于它把“文档与实现不一致”这一模糊的直觉变成了可枚举、可追踪、可锚定、可复现的工程流程——先建立契约清单再沿路径矩阵逐点核对最后用最小可观察场景与实测定价让每一条发现都可被审阅与裁决。【免费下载链接】caffeineA high performance caching library for Java项目地址: https://gitcode.com/gh_mirrors/ca/caffeine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考