系统架构与微服务接入总览
本技术设计说明书(TRD)规定了「拍拍·谛听」(PaiPai DiTing)基于拍拍近 100 个微服务的源代码、中间件契约与环境配置,构建高保真「四层业务知识金字塔」的完整技术实现方案。
L1 确定性事实 → L2 接口卡片 → L3 服务画像 → L4 全局拓扑
Saga 补偿 + Outbox 本地事务表 + MANUAL_ARBITRATION 仲裁闭环
Vearch 向量分级索引 (DiskIVFPQ 磁盘向量 + 内存倒排压缩)
3秒按键防抖 + 本地 500 符号缓存 + 令牌桶限流防击穿
flowchart TB
subgraph B1 ["【第一块 · 离线静态解析与语义蒸馏流水线】Java 17 CLI + Spring Boot 3 + LangChain4j"]
direction TB
subgraph B1_A ["1. 静态解析编译端 (Java 17 CLI)"]
direction LR
J1["<b>[源码识别]</b><br/>100+ 微服务多模块识别"]
J2["<b>[SymbolSolver]</b><br/>跨模块符号与类型求解"]
J3["<b>[中间件探针]</b><br/>JSF / JMQ / Ducc / MyBatis"]
J4["<b>[AST 剪枝]</b><br/>框架日志与监控噪音过滤"]
J1 --> J2 --> J3 --> J4
end
subgraph B1_B ["2. AI 语义蒸馏引擎 (Spring Boot 3 + LangChain4j)"]
direction LR
P1["<b>[Tarjan DAG]</b><br/>强连通分量破环拓扑"]
P2["<b>[方法规则蒸馏]</b><br/>百字中文规则 (<1.5K Token)"]
P3["<b>[L2 业务卡片]</b><br/>接口摘要聚类 (<2.5K Token)"]
P4["<b>[L3 服务画像]</b><br/>领域边界与独占表归属"]
P1 --> P2 --> P3 --> P4
end
B1_A ==>|ServiceGraph 内存管道 · 零磁盘开销| B1_B
end
subgraph B2 ["【第二块 · 知识金字塔实体与内网双擎存储底座】JED MySQL + 京东 Vearch + JimDB"]
direction LR
D1[("<b>[JED MySQL]</b><br/>L1 拓扑边 · L2 结构卡片 · code_hash")]
D2[("<b>[JimDB 缓存]</b><br/>拓扑邻接表预热 (<10ms 展开)")]
D3[("<b>[京东 Vearch]</b><br/>L3 职责画像 + L2 语义向量索引")]
D1 --- D2 --- D3
end
subgraph B3 ["【第三块 · 业务消费网关与三大研发终端协同】两阶段混合检索 + 研发场景落地"]
direction LR
W1["<b>[Web 智能工作台]</b><br/>PRD 需求秒级圈定微服务<br/>存量代码排他互斥冲突预警"]
W2["<b>[JoyCoder Agent 助手]</b><br/>标准只读 MCP 协议通信<br/>7 大原子工具排障证据链闭环"]
W3["<b>[JoyCoder AI IDE 协同]</b><br/>本地 Sidecar 实时上下文感知<br/><200ms 编码阶段分片防灾雷达"]
W1 ~~~ W2 ~~~ W3
end
B1 ==>|结构化与向量数据双写| B2
B2 ==>|只读沙箱高并发召回| B3
classDef jStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef pStyle fill:#fffbeb,stroke:#d97706,stroke-width:1.5px,color:#78350f;
classDef dStyle fill:#ecfdf5,stroke:#059669,stroke-width:1.5px,color:#064e3b;
classDef qStyle fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.5px,color:#4c1d95;
class J1,J2,J3,J4 jStyle;
class P1,P2,P3,P4 pStyle;
class D1,D2,D3 dStyle;
class W1,W2,W3 qStyle;
四层知识金字塔 · 全息穿透交互工作台
L1 层:AST 符号求解与 100% 编译级技术契约
JavaParser + ASM 静态求解 · 零模型幻觉在无模型介入的情况下,通过确定性语法树与依赖分析,提取不可变的技术事实基座:
| 分析维度 | 代码级确定性事实 | 源码位置与元数据 |
|---|---|---|
| 对外 RPC 契约 | @JsfProvider 导出 OrderExportServiceImpl#submitOrder | trade-order-service/OrderExportServiceImpl.java#L88 |
| 下游 RPC 依赖 | 调用 PromoCalcJsfService#calcOrderPrice (超时 800ms, 重试 0) | trade-order-service/pom.xml 引入 promo-client:4.0.5 |
| JED 分库分表 | 单表写入 order_info_0038 (分片键 user_pin='jd_user_882') | trade-order-service/OrderMapper.xml#insertOrder |
| 异步事件解耦 | 本地事务表写 outbox_event,Worker 扫描投递 order_create_topic | trade-order-service/OrderOutboxScanner.java#L45 |
| Ducc 动态开关 | 绑定动态配置项 promo.tiered.stack.enabled (默认: false) | DuccPropertyInjector: promo.tiered.stack.enabled |
L2 层:接口与链路业务卡片 (含 Ducc 动态开关实时联动计算)
言犀大模型单方法蒸馏 (<2.5K Token)• 用户实名认证通过
• 风控等级 <= LEVEL_3
• 限购黑名单校验通过
• L1行: 满减 6.67元
• L2行: 满减 6.67元
• L3行: 满减 6.66元 (微调)
• 校验类:
OrderValidator:105• 算价类:
PromoSplitEngine:214• 事务键:
order_id + pay_id
L3 层:微服务业务职责画像 (点击切换微服务目录)
一级路由索引与表独占矩阵| 核心业务职责 | 负责全渠道订单生命周期编排、状态机跃迁推进(WAIT_PAY → PAID → CLOSED)、Outbox 本地消息发布与分布式逆向 Saga 取消协调。 |
| 独占核心数据表 | order_info_0000~0099(100库按 pin 分片)、order_item_0000~0099、outbox_event_00~31(禁止其他任何微服务直连跨库写)。 |
| 核心暴露契约 | OrderExportService#submitOrder (JSF)、OrderCancelService#cancelOrder (JSF)、order_status_topic (JMQ)。 |
| 外部依赖半径 | 上游: API-Gateway, 购物车;下游: 促销算价(JSF), 库存中心(JSF), 支付中心(JSF/JMQ), 仓储履约(JMQ)。 |
L4 层:跨微服务端到端全局业务流 (Saga 逆向补偿步进器)
trade-order-service 调用 promo-engine 冻结优惠券 → 本地写 WAIT_PAY 记录并拉起收银台。stock-center-service 基于 JimDB Redis Lua 脚本预占实物库存配额,生成 lock_token 并在订单表落库。trade-pay-service 扣款成功,向 JMQ 投递 pay_success_notify → 订单状态机利用 version 乐观锁安全跃迁为 PAID。fulfillment-service 实物分拣因风控/超区/缺货拒单,投递 fulfillment_rejected 事件 → 驱动订单跃迁为 CANCELING。组件怎样分工
系统由四大核心子系统分工协同,严格遵循“解析与推理分离、确定性拓扑与大模型蒸馏分离”的设计哲学:
| 子系统 | 核心职责 | 技术选型与部署 | 输出资产 |
|---|---|---|---|
| 1. 静态代码分析端 (Java CLI) | 解析近 100 个微服务的 Java 源码、XML 配置、POM 依赖与 MyBatis Mapper,执行 AST 符号求解与 @JProfiler 降噪剪枝。 |
Java 17 + JavaParser 3.25 + Maven 独立可执行 CLI | 输出结构化中间图谱 ir_service_graph.json,确立 100% 确定性的 L1 事实。 |
| 2. 语义蒸馏与知识服务 (Spring Boot 3 + LangChain4j) | 基于 Java 内存 DAG 拓扑自底向上并发调度,组织 Map-Reduce 提示词编排,调用内网言犀大模型生成 L2 卡片与 L3 服务画像,提供 mcp-java 与 REST API。 | Java 17+ / Spring Boot 3 / LangChain4j / CompletableFuture | 输出符合 JSON Schema 的 L2 规则卡片与 L3 微服务画像。 |
| 3. 混合存储底座 (JED + Vearch) | JED (MySQL 8.0) 存储全量 L1 拓扑边、L2 规则卡片 JSON 与 AST 代码哈希;Vearch 存储微服务画像与入口规则的 768/1024 维语义向量。 | 京东内网 JED MySQL + Vearch 向量检索集群 | 提供精准符号检索与语义向量检索的双引擎底座。 |
| 4. 统一接入终端 (Web / Agent / IDE) | Web 需求分析工作台、JoyCoder Agent 自动化排障 MCP 插件、JoyCoder AI IDE 本地编码约束感知插件。 | React Web / JoyCoder MCP Server / IDE Sidecar | 端到端支撑日常产品方案定界、复杂故障排查与本地编码防事故。 |
四层业务知识模型的推导与产出
知识库自底向上分为四层,每一层均具备明确的数据结构和代码事实支撑:
| 知识层级 | 读取的核心输入 | 产出的核心知识资产 | 存储引擎 | 消费场景与输出形态 |
|---|---|---|---|---|
| L1 技术契约与事实 | Java 源码、XML、POM、MyBatis Mapper、Ducc 配置 | 100% 确定性的 JSF 拓扑、JMQ 生产消费边、逻辑表读写映射、JimDB 锁前缀、Enum 字典 | JED (MySQL) | 精确上下游影响面评估(改接口/表会影响谁) |
| L2 入口业务卡片 | L1 事实、入口方法源码、下层方法业务摘要 | 每个对外接口或消费者的业务说明书:意图、前置校验、核心计算分支、Ducc 控制效果、状态机 | JED (MySQL) + Vearch | 存量规则冲突检测、代码改动行定位 |
| L3 微服务职责画像 | 本服务全量 L2 卡片、核心归属表清单、对外能力目录 | 单服务职责边界说明书(1,500 字内):负责什么、管哪张表、对外暴露哪些能力 | JED (MySQL) + Vearch | 全局检索一级路由索引:新需求秒级锁定 3~5 个服务 |
| L4 全局业务域流程 | 跨服务 RPC/消息依赖图谱、跨服务时序要求 | 交易、营销、履约等业务域全景时序图、跨服务最终一致性补偿路径 | JED (MySQL) | 端到端流程理解、跨系统重大重构评审 |
先建立100多个服务的接入清单
- 可部署单元纳管:以独立微服务应用为最小解析单元。一个 Git 仓库包含多个可部署模块时分别建档;
- Maven 多模块分层识别:
- 契约层 (
EXPORT_MODULE):识别-export、-client、-rpc模块,提取对外 DTO、入参校验注解(@NotNull等)与业务状态枚举Enum; - 核心业务层 (
SERVICE_MODULE):识别-service、-domain、-core模块,作为业务逻辑蒸馏主体; - 数据持久层 (
DAO_MODULE):识别-dao、-mapper模块,提取表读写关系; - 适配接入层 (
ENTRY_MODULE):识别-web、-worker模块,提取对外 Controller、JSF 实现类与 JMQ 消费者。
- 契约层 (
- 配置文件与常量预折叠:
- 扫描
important.properties、application*.yml并抓取 Ducc 线上只读快照,构建占位符字典Map<Placeholder, RealValue>,在 AST 分析前将所有${jsf.alias.xxx}、${jmq.topic.xxx}还原为真实线上值。
- 扫描
构建调度与依赖放行原则
- DAG 任务调度:
- L1 解析阶段:100 个微服务通过
CompletableFuture并行执行 AST 求解,装配为不可变内存图谱对象ServiceGraph(可按需输出ir_service_graph.json供离线审计); - L2 蒸馏阶段:单服务内部按方法调用树逆拓扑序执行(先分析叶子方法,再逐层向上传递中文摘要,绝不塞入底层源码);
- L3 与 L4 阶段:服务画像与全局业务域流程并行构建,L3 负责单服务索引,L4 负责跨服务串联。
- L1 解析阶段:100 个微服务通过
- 失败隔离机制:
- 某一个微服务由于构建依赖缺失导致解析受阻时,系统将其标记为
PARTIAL_BLOCKED并详细记录诊断日志,不阻塞其他微服务的正常知识提取与入库; - 在上层检索时,清晰标明该服务“技术事实待补齐”,杜绝以偏概全。
- 某一个微服务由于构建依赖缺失导致解析受阻时,系统将其标记为
详细数据采集与分析定义见 TRD 01 L1 技术事实 与 TRD 02 L2 入口规则。
下一章 · L1:提取技术契约与静态事实 →L1:提取技术契约与静态事实
L1 层是整个知识库的“事实底座”,核心目标是通过对近 100 个微服务的源代码与配置文件进行纯静态编译级解析,100% 确定性地提取跨服务调用关系、消息拓扑、数据表读写映射及环境配置,绝不产生大模型幻觉。
编译级符号解析与二方包挂载
为彻底解决老旧代码中类型推断失败和常量丢失问题,Java 静态扫描端(jd-kb-java-scanner)采用 JavaParser + JavaSymbolSolver 架构:
- 二方包类库加载与闭源字节码逆向:
- 通过挂载微服务本地 Maven 仓库缓存,加载
xxx-export.jar与公共二方包; - 针对部分二方包 无源码(仅提供
.class二进制 JAR) 的场景,扫描器集成基于 ASM 与 Fernflower 的字节码元数据解析器,直接提取类的方法签名、泛型 DTO 字段结构与 Jackson 注解,防止符号解析退化为UnsolvedSymbolException,保障类型推断 100% 闭环;
- 通过挂载微服务本地 Maven 仓库缓存,加载
- Spring 依赖注入多态实现(Interface Polymorphism)路由消歧:
- 当核心业务接口(如
OrderProcessor)存在多个@Service实现类(如SopOrderProcessor、FbpOrderProcessor)时,扫描器结合@Qualifier、@ConditionalOnProperty、@Profile以及工厂模式路由键进行静态求值; - 针对运行时动态根据单号前缀路由的场景,扫描器在 L1 调用图构建 多态候选分支(Candidate Branch) 并打标
POLYMORPHIC_ROUTING,并在 L4 全局流程中沿业务域标签(SOP商家单 vs FBP自营单)分流展开,避免粗暴合并或单点遗漏;
- 当核心业务接口(如
- 常量与枚举追踪:准确解析诸如
TopicConstants.ORDER_CREATED或OrderStatusEnum.WAIT_PAY.getCode()的底层静态取值,避免把常量变量名误当做物理字符串; - 输入指纹与缓存:每个微服务建立源码文件、effective POM 与依赖库的 SHA256 综合指纹。文件未改动时直接复用历史 IR 包,大幅加速扫描效率。
京东中间件异构探针详细规范
存量微服务历经多年迭代,同一类中间件存在 XML、注解与工具类二次封装三种形态。扫描器通过统一的中间件探针(Middleware Probes)将其统一抽象为标准 URN:
| 中间件类型 | 扫描源文件 / AST 探针点 | 归一化提取的契约 URN (Contract URN) |
构建设定的确定性拓扑边 |
|---|---|---|---|
| JSF 暴露 (Provider) | <jsf:provider interface="..." alias="...">@JsfProvider(interfaceClass=..., alias="...") |
jsf://{interfaceFQN}#{methodName} |
注册为本服务对外可被调用的 RPC 契约 |
| JSF 调用 (Consumer) | <jsf:consumer interface="..." alias="...">@JsfConsumer(interfaceClass=...) private X x; |
jsf://{interfaceFQN}#{methodName} |
Service A --[JSF_CALL]--> Service B |
| JMQ 消息消费 | <jmq:listener topic="...">@JmqListener(topics={"..."})MessageListener.onMessage |
jmq://{resolvedTopicName} |
Service B --[JMQ_SUBSCRIBE]--> Topic T |
| JMQ 消息发送 | MessageProducer.send(new Message(topic,...))内部封装如 MqHelper.send(TopicEnum, ...) |
jmq://{resolvedTopicName} |
Service A --[JMQ_PUBLISH]--> Topic T |
| Ducc 动态开关 | @LafValue("${ducc.key:default}")@Value("${ducc.key}")ConfiguratorManager.get(...) |
ducc://{duccKey} |
标记具体方法与分支受此 Ducc 开关动态控制 |
| JimDB 缓存与锁 | jimClient.setNx("LOCK_" + ...)jimClient.get(...) / hSet(...) |
jimdb://{keyPrefix} |
提取防重幂等锁及缓存读写规则 |
跨服务怎样对齐
在百级微服务架构下,跨服务依赖包含 RPC 同步调用与 MQ 异步事件流两类核心通路,必须在 L1 编译阶段实现精准对齐:
- JSF 契约的精确对齐:通过提取消费方的
@JsfConsumer/ XML<jsf:consumer>声明的接口全限定名与方法签名,与全库所有微服务的@JsfProvider建立唯一拓扑边。针对多机房或同名别名(alias),匹配注册中心元数据; - JMQ 主题的发布-订阅对齐:生产者
MessageProducer.send(topic, payload)与消费端@MessageListener(topics = "...")建立消息拓扑,并通过 Payload DTO 类结构核验跨服务消息体的版本兼容性; - 断链与悬挂接口诊断:当消费方调用的 JSF 接口或订阅的 JMQ Topic 在全库中找不到提供方时,标记为
UNRESOLVED_CALL,录入架构健康度与技术债务清单,并在影响面雷达中高亮预警。
持久层血缘提取与动态分库分表归一算法
针对 MyBatis、动态分表名与自研 DAL 封装,扫描器执行统一的归一化管道:
flowchart TB
subgraph ScanInput["【第一块 · 源码解析与语法树提取】"]
direction LR
A["<b>[持久层扫描]</b><br/>MyBatis XML / @Select / 自研 DAL"]
B["<b>[标签剥离与内联]</b><br/>展开 <sql> 片段,消除 if/where 干扰"]
C["<b>[JSqlParser 语法树]</b><br/>提取物理表名与 CRUD 操作类型"]
A --> B --> C
end
subgraph ShardDecision["【第二块 · 动态分片特征判别】"]
D{"检测动态分表特征<br/>含 ${shardIdx} / bind / _00~_99?"}
end
subgraph NormalizedOutput["【第三块 · 逻辑表归一与元数据打标】"]
direction LR
E["<b>[收敛归一为逻辑主表]</b><br/>打标 is_sharded=true · 提取路由键"]
F["<b>[普通业务单表]</b><br/>打标 is_sharded=false · 无分片限制"]
end
ScanInput ==> ShardDecision
ShardDecision -- "命中分片特征 (是)" --> E
ShardDecision -- "单表未分片 (否)" --> F
classDef procStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef branchStyle fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#78350f;
classDef shardStyle fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#064e3b;
classDef singleStyle fill:#f8fafc,stroke:#64748b,stroke-width:1.5px,color:#334155;
class A,B,C procStyle;
class D branchStyle;
class E shardStyle;
class F singleStyle;
- XML 动态标签平铺:自动内联
<sql id="...">片段,剥离<if>、<where>动态标签,使用JSqlParser严格提取SELECT / INSERT / UPDATE / DELETE的表名与操作字段; - MyBatis-Plus / 注解提取:扫描
@TableName、@Table注解;针对BaseMapper<OrderPO>自动提取泛型 PO 类的注解表名; - 动态分表名 AST 模拟求值与自动归一(Logical Table Canonicalizer):
- 针对 XML 中使用
<bind name="tableName" value="'order_info_' + shardKey" />,或 Java 业务层中通过"order_info_" + (pin.hashCode() % 100)动态拼接表名的场景,扫描器内置静态表达式求值器,自动解析其前缀模式与分片基数; - 包含
${shard}、${tableIdx}变量后缀,或以_00~_127等纯数字结尾的物理表,一律自动收敛归一为逻辑主表名(如order_info); - 元数据打标
is_sharded = true、提取分片键字段(如user_pin)与分片范围;在线需求助手与 IDE 插件检测到涉及分表时,强制发出“查询必须携带分片键,严禁全表广播”的安全预警。
- 针对 XML 中使用
生产级分库分表归一实现:ShardedTableCanonicalizer.java
package com.jd.knowledge.extractor.parser;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.util.TablesNamesFinder;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 基于 JSqlParser 的 SQL 表血缘提取与分库分表逻辑归一化解析器
*/
@Component
public class ShardedTableCanonicalizer {
// 匹配物理分表后缀:如 _0000~_1023、_00~_99、_${shardKey}、#{tableIndex}
private static final Pattern SHARD_SUFFIX_PATTERN =
Pattern.compile("^([a-zA-Z0-9_]+?)(?:_([0-9]{2,4}|\\$\\{[^}]+\\}|#\\{[^}]+\\}))+$");
public record TableLineageResult(
String logicalTable,
String rawPhysicalTable,
boolean isSharded,
String detectedShardingKey
) {}
public List<TableLineageResult> parseSqlTableLineage(String cleanedSql, Set<String> knownShardingKeys) {
try {
Statement statement = CCJSqlParserUtil.parse(cleanedSql);
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> rawTableNames = tablesNamesFinder.getTableList(statement);
List<TableLineageResult> results = new ArrayList<>();
for (String rawTable : rawTableNames) {
Matcher matcher = SHARD_SUFFIX_PATTERN.matcher(rawTable);
if (matcher.matches()) {
String logicalName = matcher.group(1);
// 启发式探测分片键:优先取已知业务分片键字典,默认匹配 user_pin / order_id
String shardingKey = knownShardingKeys.stream()
.filter(k -> cleanedSql.toLowerCase().contains(k.toLowerCase()))
.findFirst()
.orElse("user_pin");
results.add(new TableLineageResult(logicalName, rawTable, true, shardingKey));
} else {
results.add(new TableLineageResult(rawTable, rawTable, false, null));
}
}
return results;
} catch (Exception ex) {
// 解析容错:降级正则兜底提取
return fallbackRegexExtraction(cleanedSql);
}
}
private List<TableLineageResult> fallbackRegexExtraction(String sql) {
// 正则降级保障解析可用性
return List.of(new TableLineageResult("unknown_table", "unknown_table", false, null));
}
}
基于 @JProfiler 的 AST 调用树降噪剪枝
为彻底防止大模型被框架样板代码撑爆窗口,扫描器在遍历方法体时执行严格剪枝:
- 核心业务节点识别:凡带有京东 UMP
@JProfiler注解、@Transactional注解、读取@LafValue的分支、抛出业务异常(throw new BizException)的方法,100% 完整保留; - 噪音剔除:纯 Getter/Setter、
BeanUtils/MapStruct字段拷贝、log.info/error日志打印、UMP 监控埋点代码、通用工具类内部实现全部通过 AST 剔除,源码压缩率达 80% 以上。
生产级 JavaParser 源码降噪剪枝:MethodNoisePrunerVisitor.java
package com.jd.knowledge.extractor.ast;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.visitor.ModifierVisitor;
import com.github.javaparser.ast.visitor.Visitable;
import java.util.Set;
/**
* 基于 JavaParser ModifierVisitor 的方法级 AST 噪声剪枝器
* 剥离 log 打印、UMP 性能埋点、MDC 上下文等样板代码,保留核心业务判定分支与 RPC 调用
*/
public class MethodNoisePrunerVisitor extends ModifierVisitor<Void> {
private static final Set<String> NOISE_METHOD_PREFIXES = Set.of(
"log.info", "log.debug", "log.trace", "log.warn",
"logger.info", "logger.debug", "logger.trace", "logger.warn",
"MDC.put", "MDC.remove", "MDC.clear",
"Profiler.count", "Profiler.registerInfo", "Ump.count"
);
@Override
public Visitable visit(MethodCallExpr n, Void arg) {
// 递归检查子表达式
super.visit(n, arg);
return n;
}
@Override
public Visitable visit(ExpressionStmt n, Void arg) {
// 识别语句是否为独立的日志打印或监控埋点
if (n.getExpression().isMethodCallExpr()) {
MethodCallExpr call = n.getExpression().asMethodCallExpr();
String fullCallSignature = call.toString().trim();
for (String noisePrefix : NOISE_METHOD_PREFIXES) {
if (fullCallSignature.startsWith(noisePrefix)) {
// 从 AST 语法树彻底移除此独立表达式语句
return null;
}
}
}
return super.visit(n, arg);
}
@Override
public Visitable visit(MethodDeclaration md, Void arg) {
// 若为单行 getter / setter,直接剪枝跳过不入知识库
if (isTrivialGetterSetter(md)) {
return null;
}
return super.visit(md, arg);
}
private boolean isTrivialGetterSetter(MethodDeclaration md) {
String name = md.getNameAsString();
if ((name.startsWith("get") || name.startsWith("is")) && md.getParameters().isEmpty()) {
return md.getBody().map(b -> b.getStatements().size() <= 1).orElse(true);
}
if (name.startsWith("set") && md.getParameters().size() == 1) {
return md.getBody().map(b -> b.getStatements().size() <= 1).orElse(true);
}
return false;
}
}
产出格式与模型定义详见不可变内存图谱对象 ServiceGraph(支持流式直通与按需导出 ir_service_graph.json 供离线审计与归档)。
静态 AST 盲区破局:静态代码图与生产 APM 运行时双网融合
虽然基于 JavaParser 与字节码 ASM 反编译能够提取 95% 以上的标准 Spring / JSF 静态调用拓扑,但在生产实际复杂遗留系统中,仍存在三大物理盲区:
- Spring 容器动态 Bean 获取:如
applicationContext.getBean(serviceName)或依赖注入字典Map<String, Handler>; - 底层反射与泛化调用:如通过反射
Method.invoke()或 JSF 通用网关$invoke(); - MyBatis 动态拼接与分表:如
${tablePrefix}_order动态表名或存储过程调用。
为彻底消除静态盲区,「拍拍·谛听」设计并实现了 「静态 AST 代码图 + 生产 APM 运行时 Trace」双网交并融合架构:
1. 静态未决调用边打标(UNDETERMINED_DYNAMIC_EDGE)
- 扫描器在语法树中检测到动态 Bean 获取或反射调用时,在图数据库中生成一条占位边:
ServiceA -[UNDETERMINED_CALL {expression: "context.getBean(type)"}]-> UnknownTarget; - 绝不大模型盲猜目标,保证编译级输出的 100% 诚实度与确定性。
2. 离线抽取生产 APM (UMP / SGM) 运行时调用链
- 更新流水线异步订阅生产环境近 7 天的调用链日志(采样率 0.1% ~ 1%);
- 聚合提取真实的 RPC 调用三元组:
(Caller: trade-order, Method: submit, Callee: trade-pay, Interface: PayExportService#pay); - 结合调用频率与拓扑权重,过滤掉极低频的探针检测流量。
3. 双网交并算法与置信度打标
- 融合引擎将静态未决边与 APM 实际链路对齐,将
UnknownTarget替换为真实微服务,并标记边的属性为EDGE_SOURCE: RUNTIME_APM_VERIFIED(置信度 99%); - 若某条调用边既有静态 AST 严密证据,又有线上 APM 流量佐证,则标记为
CONFIRMED_GOLDEN_PATH(黄金主干链路)。
L2:提取入口规则与生成业务卡片
L2 层是整个知识库中“业务规则的直接载体”,核心目标是通过对单微服务内部的 AST 方法调用树进行自底向上 Map-Reduce 蒸馏,将底层晦涩的 Java 源码提炼为结构化、可追溯的代码级《接口业务说明书》。
为什么采用自底向上树状蒸馏?(防幻觉铁律)
在真实业务代码中,一个对外入口(JSF 或 Controller)顺着调用链往往深入 4~6 层,涉及十几个类和几千行源码。如果将几千行代码一次性塞入大模型,必然超出言犀模型的有效注意力窗口,产生严重幻觉与逻辑遗漏。
本系统严格执行 「单次请求恒定 < 3,000 Token」 的树状两级蒸馏协议:
flowchart TB
subgraph Step1 ["【第一块 · 逆拓扑提炼】Step 1:底层叶子方法规则蒸馏 (<1.5K Token)"]
direction LR
L1A["<b>checkLimit()</b><br/>限购数量校验 (60行)"]
L1B["<b>checkCoupon()</b><br/>优惠券叠加排他分支"]
L1C["<b>isDegrade()</b><br/>Ducc 动态降级开关"]
L1D["<b>tryLock()</b><br/>JimDB 分布式防重锁"]
L1A ~~~ L1B ~~~ L1C ~~~ L1D
end
subgraph MidLayer ["【第二块 · 模块汇聚】Step 2:子模块语义聚类 (Map-Reduce 汇聚)"]
direction LR
M1["<b>PromoService</b><br/>促销算价与优惠分摊业务摘要"]
M2["<b>StockManager</b><br/>锁库与防重降级业务摘要"]
M1 ~~~ M2
end
subgraph Step2 ["【第三块 · 入口合成】Step 3:JSF 核心入口业务说明书卡片生成 (<2.5K Token)"]
direction LR
R["<b>OrderExportServiceImpl#submitOrder</b><br/>JSF 入口源码 + 模块摘要列表"]
FACTS["<b>100% 确定性编译级事实注入</b><br/>(JED 表: order_info · 下游 JSF/JMQ · Ducc)"]
OUT["<b>L2 结构化接口业务说明书卡片</b><br/>(JSON Schema 严苛模式核验)"]
R --> OUT
FACTS --> OUT
end
Step1 ==>|AST 逆拓扑聚合| MidLayer
MidLayer ==>|汇总各模块规则| Step2
classDef leafStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef midStyle fill:#fffbeb,stroke:#d97706,stroke-width:1.5px,color:#78350f;
classDef entryStyle fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#4c1d95;
classDef factStyle fill:#f1f5f9,stroke:#475569,stroke-width:1.5px,color:#0f172a;
classDef outStyle fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#064e3b;
class L1A,L1B,L1C,L1D leafStyle;
class M1,M2 midStyle;
class R entryStyle;
class FACTS factStyle;
class OUT outStyle;
- Step 1(底层叶子方法提炼):
- 提取单个方法(30~100 行),喂入:
方法源码 + 引用业务枚举字典 + 读取的 Ducc 开关 + 团队黑话词典; - 言犀模型输出百字 JSON 摘要:包含前置拦截条件、核心计算分支、状态变更与副作用。单次请求
< 1,500 Token,翻译准确率达 90% 以上。
- 提取单个方法(30~100 行),喂入:
- Step 2(入口层汇总为 L2 卡片):
- 分析对外入口时,绝不拼入底层子方法的原始 Java 源码,而是拼入
入口方法代码 + Step 1 生成的下层子方法中文摘要列表 + 静态分析提取的确定性外部依赖(表/下游JSF/JMQ); - 言犀模型汇总输出标准的 L2 业务说明书。单次请求
< 2,500 Token。
- 分析对外入口时,绝不拼入底层子方法的原始 Java 源码,而是拼入
基于 LangChain4j @AiService 的规则结构化提炼实现
系统采用 Spring Boot 3 + LangChain4j 的声明式 @AiService 架构,将 AST 静态事实与分段业务摘要直接映射为强类型的 Java 17 Record,由底层 JSON Schema 语法引导大模型进行确定性输出:
package com.jd.knowledge.distillation.service;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import dev.langchain4j.service.spring.AiService;
import java.util.List;
/**
* 基于 LangChain4j 声明式 AI 服务的 L2 规则提炼引擎
*/
@AiService
public interface L2RuleDistillationService {
record Precondition(
String condition,
String errorCode,
String failureBehavior
) {}
record SideEffect(
String targetResource,
String effectType,
String rollbackPolicy
) {}
record EntryRuleCard(
String docId,
String serviceCode,
String contractUrn,
String implMethodFqn,
String businessName,
String businessIntent,
List<Precondition> preconditionsAndValidations,
List<String> coreBranchDecisions,
List<SideEffect> sideEffects,
List<String> downstreamDependencies,
List<String> activeDuccSwitches
) {}
@SystemMessage("""
你是京东核心交易系统资深架构专家。你的任务是将输入的 Java 接口代码、底层方法摘要及静态依赖事实,
客观、严密地归纳为一份标准化的 L2 接口业务卡片。
【严格要求】
1. 严禁幻觉:所有前置校验与业务分支必须在提供的代码或摘要中有确切依据;
2. 区分 Ducc 动态开关与硬编码分支;
3. 输出必须完全匹配 EntryRuleCard 强类型 JSON Schema 契约。
""")
@UserMessage("""
请提炼以下核心入口的 L2 业务规则卡片:
微服务标识: {{serviceCode}}
接口契约 URN: {{contractUrn}}
实现类与方法: {{implMethodFqn}}
【静态编译级事实】
读写数据表: {{tables}}
下游 JSF 依赖: {{downstreamJsf}}
关联 Ducc 开关: {{duccKeys}}
【已解析的底层子方法业务摘要】
{{childMethodSummaries}}
【入口方法 AST 代码】
```java
{{entryMethodCode}}
```
""")
EntryRuleCard distillEntryRule(
@V("serviceCode") String serviceCode,
@V("contractUrn") String contractUrn,
@V("implMethodFqn") String implMethodFqn,
@V("tables") List<String> tables,
@V("downstreamJsf") List<String> downstreamJsf,
@V("duccKeys") List<String> duccKeys,
@V("childMethodSummaries") String childMethodSummaries,
@V("entryMethodCode") String entryMethodCode
);
}
祖传千行上帝方法(God Method)切分规范
针对核心老服务中单方法长达 600 ~ 1,500 行的极端情况,系统内置 AST 语义分段器:
- 严禁按固定字符粗暴截断,而是按 Java 顶层
BlockStmt语句列表,以闭合的if-else、switch、try-catch完整块进行贪心打包,切分为若干个 ≤ 120 行的独立语义段; - 先并发提炼每个语义段的业务含义,再在方法级别进行轻量级 Reduce 合并,确保长方法逻辑无缝覆盖。
L2 接口业务卡片标准结构(JSON Schema 契约)
每张 L2 业务卡片在生成后,严格包含以下强类型结构,并存入 JED MySQL 与 Vearch 向量库:
{
"docId": "order-service:jsf:com.jd.order.export.OrderExportService#submitOrder",
"serviceCode": "jd-order-core",
"entryType": "JSF_PROVIDER",
"contractUrn": "jsf://com.jd.order.export.OrderExportService#submitOrder",
"implMethodFqn": "com.jd.order.service.impl.OrderExportServiceImpl#submitOrder",
"businessName": "正向提交订单核心接口",
"businessIntent": "接收前端提单请求,完成限购与防重校验、调营销算价、预占库存、落订单主子表并发送提单成功消息",
"preconditionsAndValidations": [
"JimDB 防重幂等锁校验:5秒内禁止相同 pin + 购物车重复提单",
"用户状态校验:黑名单用户抛出 ORDER_USER_BLOCKED 异常拦截"
],
"coreBusinessRules": [
"【拆单规则】自营与 POP 混购商品按商家与温层拆分为不同子单,最大拆单数受 Ducc 控制",
"【优惠分摊】调用营销算价接口分摊满减金额,实付金额抵扣后不得低于 0.01 元"
],
"duccSwitches": [
{
"key": "ducc.order.submit.skipStockLock",
"effect": "大促极限降级开关,为 true 时跳过同步预占库存,改为异步扣减"
}
],
"stateTransitions": [
"订单主表初始状态写入为 OrderStatusEnum.WAIT_PAY (10: 待支付)"
],
"sideEffects": {
"dbReads": ["order_config"],
"dbWrites": ["order_main", "order_item_detail"],
"jimdbKeys": ["JIM_ORDER_SUBMIT_LOCK_"],
"downstreamJsfCalls": ["com.jd.promo.export.PromoCalcJsfService#calcOrderPrice"],
"producedJmqTopics": ["jmq_topic_order_created_v2"]
},
"coreCodeChain": [
"OrderExportServiceImpl#submitOrder",
"OrderExportServiceImpl#checkSubmitIdempotent",
"OrderSplitManager#validateAndPreviewSplit"
]
}
自动化质检门禁(Hallucination Gate)
[!NOTE] 纯 Java 17 全栈质检与编排机制 门禁流水线全部基于 Java 17 原生实现:基于 Java Record 建模
EntryRuleCard强类型实体,通过network.ntt:json-schema-validator与 Jackson 原生执行 100% 模式核验;大模型生成与结构化反序列化全程通过 LangChain4jAiServices驱动,不产生任何中间磁盘临时文件,内存直通 JED 与 Vearch。
在生成的数据入库前,必须通过四道自动化代码与语义门禁:
- 结构完整性与 JSON 校验:严格校验必填字段,自动修复首尾 Markdown 标记;
- 确定性依赖防伪核验(Grounding Check):核对卡片中出现的数据库表名、下游 JSF 接口、JMQ Topic 是否与 L1 静态提取的元数据一致。若模型输出了静态集合之外的虚构实体,立即拦截并触发降温纠错重试;
- 领域术语与代码字段双向词表(Bilingual Synonym Map)防误杀:
- 建立电商交易领域专业词汇与代码 DTO 字段双向映射库(如“实付现金” ↔
actual_cny_fee、“优惠分摊” ↔discount_allocation_amt); - 门禁在执行参数核验时,允许使用标准领域术语或代码真实字段名,避免将符合业务语境的正确语义提炼粗暴判定为幻觉误杀;
- 建立电商交易领域专业词汇与代码 DTO 字段双向映射库(如“实付现金” ↔
- Map-Reduce 锚点核验(Anti-Semantic Drift):
- 入口卡片强制记录引用的底层叶子 AST 节点 ID 清单(
leaf_fact_ids); - 若上层卡片提炼中出现了脱离任何叶子节点代码事实的全新断言(如无代码依据声称“该入口支持花呗分期”),门禁自动识别为“二次汇总语义漂移”,直接阻断入库并告警;
- 入口卡片强制记录引用的底层叶子 AST 节点 ID 清单(
- 空泛套话过滤:剔除“处理业务逻辑并返回”等字符过短且无实质业务语义的废话。
产出规范详见 TRD 03 L3 服务画像 与 TRD 04 L4 全局业务。
L3:说明一个服务负责什么
L3服务画像(Service Profile)是连接微观代码实现(L1技术事实、L2入口规则卡片)与宏观业务拓扑(L4全局业务)的聚合中枢。在京东百级微服务架构下,研发与业务人员无法逐一阅读成千上万个代码文件;服务画像以可部署微服务应用(App/Service)为核心单元,将散落的JSF接口、JMQ消息监听、MyBatis分库分表与Ducc动态配置,自动聚合为结构化的服务能力目录、核心领域资产归属、上下游依赖拓扑与副作用边界。
L3服务画像为问答引擎与JoyCoder Agent提供一级路由与上下文剪枝能力,使系统无需在检索初期加载全量代码,即可秒级锁定目标服务与职责范围。
按应用和实现范围归集入口
服务画像的构建输入来源于L1 AST解析产物及L2入口卡片集,覆盖系统注册的100多个微服务应用。同仓库多模块(Multi-Module Maven)项目根据部署构件(Jar/War)拆分为独立的服务画像;存在双活机房或灰度分组的服务,共用服务主身份,并在画像中保留环境与配置差异。
flowchart TB
subgraph L1_L2_Inputs["【第一块 · 输入】底层事实与规则输入"]
direction LR
JSF["<b>[JSF 契约]</b><br/>@JsfProvider 接口清单"]
JMQ["<b>[JMQ 消息]</b><br/>@MessageListener 消费主题"]
DB["<b>[MyBatis]</b><br/>order_info_0000~0099 独占表"]
L2Cards["<b>[L2 卡片]</b><br/>结构化前置条件与状态机"]
JSF ~~~ JMQ ~~~ DB ~~~ L2Cards
end
subgraph L3_Aggregator["【第二块 · 管线】服务画像聚合流水线"]
direction LR
ModGroup["<b>[Maven 拆分]</b><br/>Jar/War 部署边界划分"]
EntityCluster["<b>[表独占聚类]</b><br/>写主权矩阵与边界识别"]
LLMSummary["<b>[言犀提炼]</b><br/>能力树与业务承诺提炼"]
ASTVerifier["<b>[AST 门禁]</b><br/>100% 代码事实锚定核验"]
ModGroup --> EntityCluster --> LLMSummary --> ASTVerifier
end
subgraph L3_Profile_Output["【第三块 · 产物】结构化微服务画像输出"]
direction LR
CapDir["<b>[能力目录]</b><br/>结构化业务能力树"]
AssetMap["<b>[资产矩阵]</b><br/>核心独占表归属矩阵"]
DepTopo["<b>[中间件边界]</b><br/>RPC 与 JMQ 上下游拓扑"]
Boundaries["<b>[事务承诺]</b><br/>Saga 副作用边界与补偿保障"]
CapDir ~~~ AssetMap ~~~ DepTopo ~~~ Boundaries
end
L1_L2_Inputs ==>|输入事实与业务规则| L3_Aggregator
L3_Aggregator ==>|输出标准画像模型| L3_Profile_Output
classDef inStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef procStyle fill:#fffbeb,stroke:#d97706,stroke-width:1.5px,color:#78350f;
classDef outStyle fill:#ecfdf5,stroke:#059669,stroke-width:1.5px,color:#064e3b;
class JSF,JMQ,DB,L2Cards inStyle;
class ModGroup,EntityCluster,LLMSummary,ASTVerifier procStyle;
class CapDir,AssetMap,DepTopo,Boundaries outStyle;
自动化归集与能力提取机制
传统手工维护的服务画像往往在微服务迭代中迅速失效。系统采用自底向上自动化归集与架构师轻量标注相结合的模式:
- 入口清单完整清点:解析服务所有暴露端点,包括对外RPC(JSF Provider)、事件驱动入口(JMQ Consumer)、定时任务(TBSchedule/ElasticJob Worker)及内部HTTP运维接口。未成功解析或未归属能力的入口保留在
pending_entries诊断列表,严禁用部分成功掩盖全量资产。 - 领域包结构与事务聚类:根据Maven模块职责(如
order-service-client、order-service-core、order-service-worker)与Spring注解边界进行初步聚类。 - 读写分离与主表所有权识别:通过L1持久层AST事实,清点该服务执行
INSERT/UPDATE/DELETE操作的数据库表集合,确定该服务作为 唯一写入方(Single Writer) 的核心领域对象(如order_service独占order_info与order_item主写权限)。
怎样形成职责说明
服务画像的职责说明拒绝宽泛模糊的自然语言概括,必须精确表达:该微服务对哪些核心实体负责、提供哪些标准业务能力、触发何种状态跃迁、以及与下游服务的交接契约。
结构化服务画像 Schema
构建任务生成的画像严格遵循标准化JSON Schema,并持久化于 JED 数据库与 Vearch 向量索引中:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ServiceProfileL3",
"type": "object",
"required": ["service_id", "service_name", "domain", "cluster", "core_entities", "capabilities", "dependencies", "sharding_tables"],
"properties": {
"service_id": { "type": "string", "description": "微服务应用ID,如 trade-order-service" },
"service_name": { "type": "string", "description": "中文业务名称,如 交易核心订单服务" },
"domain": { "type": "string", "description": "所属业务域,如 交易域 (Trade)" },
"git_repo": { "type": "string", "description": "Coding 源码仓库地址" },
"cluster": { "type": "string", "description": "部署集群标识,如 cfa-trade-prod" },
"core_entities": {
"type": "array",
"items": {
"type": "object",
"required": ["entity_name", "write_tables", "read_only_tables"],
"properties": {
"entity_name": { "type": "string" },
"write_tables": { "type": "array", "items": { "type": "string" } },
"read_only_tables": { "type": "array", "items": { "type": "string" } }
}
}
},
"capabilities": {
"type": "array",
"items": {
"type": "object",
"required": ["capability_id", "name", "description", "entry_points"],
"properties": {
"capability_id": { "type": "string" },
"name": { "type": "string" },
"description": { "type": "string" },
"side_effects": { "type": "array", "items": { "type": "string" } },
"entry_points": { "type": "array", "items": { "type": "string" } }
}
}
},
"sharding_tables": {
"type": "array",
"items": {
"type": "object",
"required": ["logical_table", "sharding_key", "sharding_count", "algorithm"],
"properties": {
"logical_table": { "type": "string" },
"sharding_key": { "type": "string" },
"sharding_count": { "type": "integer" },
"algorithm": { "type": "string" }
}
}
},
"dependencies": {
"type": "object",
"required": ["downstream_jsf", "published_jmq", "consumed_jmq", "jimdb_caches", "ducc_namespaces"],
"properties": {
"downstream_jsf": { "type": "array", "items": { "type": "string" } },
"published_jmq": { "type": "array", "items": { "type": "string" } },
"consumed_jmq": { "type": "array", "items": { "type": "string" } },
"jimdb_caches": { "type": "array", "items": { "type": "string" } },
"ducc_namespaces": { "type": "array", "items": { "type": "string" } }
}
}
}
}
京东核心微服务画像实例:交易订单服务 (trade-order-service)
| 画像维度 | 提取内容与事实依据 | 展开后读取的底层证据 |
|---|---|---|
| 基础身份 | trade-order-service (交易核心订单服务),应用分组:cfa-order-prod |
Coding 仓库分支、POM配置、部署环境 |
| 负责的核心实体 | OrderMain(订单主实体)、OrderItem(订单明细行) |
JED 分库分表:order_info_0000~0099,order_item_0000~0099 |
| 主责能力 | 1. 预占并拆分订单;2. 下单主事务提交;3. 订单状态跃迁机维护;4. 逆向取消补偿驱动 | 对应 4 个核心能力节点及下属 42 个 L2 规则卡片 |
| 对外暴露接口 | JSF 接口 24 个(包含 OrderCreateExportService、OrderQueryExportService) |
L1 JSF 契约详情、字段入参校验、别名与跨机房分发规则 |
| 消息交接边界 | 1. 接收支付完成消息(Topic: pay_success_notify);2. 发布订单就绪待履约消息(Topic: order_ready_fulfillment) |
JMQ Consumer / Producer 拓扑,包含序列化类及死信队列设置 |
| 分库分表约束 | 物理表 100 库 100 表,分片键:user_pin(高 4 位取模),支持 order_id 基因路由查询 |
MyBatis Mapper XML 中 SQL 动态表名解析事实 |
| 外部强依赖 | 1. 促销系统 JSF;2. 库存中心 JSF;3. JimDB 缓存集群(防重占锁);4. Ducc 交易配置中心 | L1 调用图出度边、超时重试配置与熔断降级策略 |
核心资产归属与拓扑画像
在百级微服务架构中,系统严禁跨服务直接读写数据库。微服务画像明确标识每个微服务独占的数据资产与共享缓存空间:
flowchart TB
subgraph CoreTrade ["【第一块 · 核心交易与支付领域】(独占数据写资产)"]
direction LR
TOS["<b>[trade-order-service]</b><br/>提单编排 · 状态机 · Saga 逆向调度"]
DB_Order[("<b>[JED 分库分表]</b><br/>order_info_0000~0099 (独占写)")]
TPS["<b>[trade-pay-service]</b><br/>收银台核销 · 渠道对账 · 退款流水"]
DB_Pay[("<b>[JED 分库分表]</b><br/>pay_record_00~31 (独占写)")]
TOS ==>|独占写主表| DB_Order
TPS ==>|独占写流水| DB_Pay
end
subgraph DependencySupport ["【第二块 · 履约与营销支撑领域】(共享与缓存资产)"]
direction LR
SCS["<b>[stock-center-service]</b><br/>物理仓配额管理 · 高并发原子预占"]
Redis_Stock[("<b>[JimDB 缓存集群]</b><br/>sku_stock_lock_* (分布式锁)")]
PMS["<b>[promo-engine-service]</b><br/>券叠加排他 · 门槛满减 · 比例分摊"]
Ducc_Promo[("<b>[Ducc 规则中心]</b><br/>promo_rule_config (动态热更新)")]
SCS ==>|原子锁占用| Redis_Stock
PMS ==>|监听动态配置| Ducc_Promo
end
CoreTrade ==>|JSF RPC 同步锁库与算价| DependencySupport
TPS -.->|JMQ pay_success 消息通知| TOS
classDef sStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef aStyle fill:#fffbeb,stroke:#d97706,stroke-width:1.5px,color:#78350f;
class TOS,TPS,SCS,PMS sStyle;
class DB_Order,DB_Pay,Redis_Stock,Ducc_Promo aStyle;
怎样避免画像把职责说大
服务画像的文字说明通过大模型从L2卡片汇总生成,极易发生“过度泛化”与“职责越界幻觉”(例如将订单服务描述为“负责全链路资金退回与银行对账”)。系统建立AST反向核验门禁:
| 潜在幻觉场景 | 幻觉表现 | AST反向核验规则与拦截策略 |
|---|---|---|
| 无代码依据的夸大 | 模型声称:“订单服务确保用户微信/银行卡退款到账” | 检查L1调用图:订单服务仅调用了支付服务JSF接口或发送了退款MQ,未直连任何银联/网联通道。强制拒收该断言,重写为“订单服务负责向下游发起退款受理请求”。 |
| 事务一致性承诺说大 | 模型声称:“下单过程保证订单创建与库存扣减绝对强一致” | 检查L1控制流:库存采用异步RPC或消息机制,且存在补偿Worker。拦截并标记为“最终一致性(包含重试与反向补偿)”。 |
| 分库分表越权 | 模型声称:“订单服务提供按商户维度实时聚合统计查询” | 检查MyBatis分片键:分片键仅为user_pin,且无二级索引或ES异构库支持。系统警示“该查询需要全分片广播,非原生支持能力”。 |
| 灰度实现混淆 | 两个部署环境或灰度版本逻辑不同,模型合并为一个统一定义 | 系统比对实现范围(Git Commit / 分支):按Profile版本保留双副本,不可自动合并不兼容规则。 |
当模型服务离线或推理异常时,画像生成管线将自动退回到基于AST事实的硬聚合模式(直接展示L1/L2实体与契约清单),保证服务核心资产与依赖拓扑的100%可用性。
画像怎样更新和使用
服务画像不仅是供研发查阅的文档,更是多智能体排障、问答路由与IDE静态分析的核心导航索引。
sequenceDiagram
autonumber
participant Client as [研发终端 (Web / JoyCoder / MCP)]
participant Engine as [统一查询与路由引擎]
participant L3Index as [L3 服务画像索引 (JED + Vearch)]
participant L2Store as [L2 规则卡片库]
participant L1Graph as [L1 AST 确定性调用图]
rect rgb(239, 246, 255)
Note over Client,L3Index: 阶段一:L3 粗粒度语义路由与服务剪枝 (剪除 98% 无关微服务)
Client->>Engine: 输入业务问题 / 研发排障请求 ("订单取消为何未释放库存")
Engine->>L3Index: 检索混合索引 (词法倒排 + 1024 维语义向量)
L3Index-->>Engine: 命中 Top-2 服务: trade-order-service, stock-center-service
end
rect rgb(254, 243, 199)
Note over Engine,L2Store: 阶段二:L2 细粒度接口规则深入
Engine->>L2Store: 按命中微服务过滤加载取消与库存释放规则卡片
L2Store-->>Engine: 返回规则分支、互斥条件矩阵、Ducc 开关与幂等键
end
rect rgb(240, 253, 244)
Note over Engine,L1Graph: 阶段三:L1 编译级代码事实与路径求证
Engine->>L1Graph: 查询两个服务间的 RPC / JMQ 拓扑边与超时重试配置
L1Graph-->>Engine: 返回确定性调用链路与代码行级行号凭据
Engine-->>Client: 生成带行级代码引用的权威技术解答
end
更新与增量触发机制
- 代码提交驱动:Xingyun CI Webhook接收到指定微服务的Merge事件,触发L1增量AST分析。若该微服务的方法签名、分库分表SQL或JSF契约发生变更,标记其L3画像为
STALE状态。 - 轻量增量重聚:系统无需全局重算100个微服务,仅对变更服务及其直接上下游(1-hop)执行依赖拓扑刷新。
- 架构师标注继承(Human Override):存储于
kb_human_annotation中的人工业务标注(如人工修正的核心能力中文名、安全级别、核心维护人ERP),在底层代码更新重新聚合时完全保留,不被模型覆盖。
产出规范详见 TRD 04 L4 全局业务 与 TRD 05 查询与接入。
L4:把多个服务连成一项业务
在京东百级微服务架构下,单项核心业务(如正向结算下单、逆向售后取消、高并发秒杀履约)从不在单一服务内闭环,而是跨越交易订单、支付结算、促销算价、库存中心、仓储履约等数十个分布式系统。
L4全局业务(Global Business Topology)的核心职责是将微观服务与入口卡片(L1-L3)沿分布式事务与事件流缝合为端到端端拓扑。它通过 AST 静态拓扑分析与事件溯源机制,自动识别跨服务的同步 RPC 依赖、异步 JMQ 消息解耦、分布式状态跃迁机,以及故障发生时的重试、降级与反向补偿路径。
场景要求和代码入口分别准备
全局业务流还原采用顶层业务场景契约驱动与底层微服务调用图反向追踪双向对齐的架构:
flowchart TB
subgraph DualInput["【第一块 · 双向输入驱动源】业务规约与编译事实双驱动"]
direction LR
subgraph TopDown["顶层业务规约 (Top-Down)"]
direction TB
BizReq["<b>[业务流定义]</b> 正向提单 / 逆向退款 / 仓储拦截"]
StateSpec["<b>[状态机规范]</b> WAIT_PAY → PAID → CANCELING → CLOSED"]
BizKeys["<b>[全局业务键]</b> order_id, pin, pay_id, sku_id"]
BizReq --- StateSpec --- BizKeys
end
subgraph BottomUp["微服务代码事实 (Bottom-Up)"]
direction TB
L1RPC["<b>[L1 RPC 契约]</b> JSF 消费方与提供方 AST 契约"]
L1MQ["<b>[L1 JMQ 注解]</b> 生产者与消费者注解/XML"]
L2State["<b>[L2 状态卡片]</b> 状态机跃迁与事务副作用卡片"]
L1RPC --- L1MQ --- L2State
end
end
subgraph StitchingEngine["【第二块 · 核心编排引擎】分布式链路缝合与拓扑编排"]
direction LR
RPCTracer["<b>[JSF RPC 对齐]</b> 同步调用边跨服务匹配"]
MQTracer["<b>[JMQ 消息匹配]</b> Topic 发布/订阅契约对齐"]
TxReconstructor["<b>[事务拓扑重建]</b> 分布式 Saga 补偿链路推导"]
CompletenessAudit["<b>[悬挂审计]</b> 全链路覆盖率与断链诊断"]
RPCTracer --> MQTracer --> TxReconstructor --> CompletenessAudit
end
subgraph OutputView["【第三块 · 全景资产交付】"]
direction LR
GlobalTopo["<b>[L4 全局业务拓扑与故障雷达]</b><br/>跨 5+ 核心微服务全景数据流 · 动态爆炸半径推导 · 代码行级精准穿透凭据"]
end
DualInput ==>|输入双向规约与符号边| StitchingEngine
StitchingEngine ==>|编译对齐与拓扑缝合| OutputView
classDef topStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef botStyle fill:#f0fdf4,stroke:#059669,stroke-width:1.5px,color:#064e3b;
classDef procStyle fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#78350f;
classDef outStyle fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#4c1d95;
class BizReq,StateSpec,BizKeys topStyle;
class L1RPC,L1MQ,L2State botStyle;
class RPCTracer,MQTracer,TxReconstructor,CompletenessAudit procStyle;
class GlobalTopo outStyle;
- 场景边界定义:由业务架构师或标准PRD定义起点端点(如 API 网关
POST /order/submit)与预期终态目标(如订单归档ORDER_CLOSED或进入仓储WMS_DISPATCHED)。 - 代码入口归属清查:自动化引擎在100多个微服务仓库中扫描候选入口。任何未能在代码中找到调用链归属的“业务声称步骤”均标记为
UNVERIFIED_REQUIREMENT;任何存在真实调用但脱离主链路的入口标记为ORPHAN_ENTRY。
沿对象和条件展开步骤
全链路业务流程的还原并非简单的调用图拼接,而必须保证业务对象标识一致性、数据流传递正确性与分支条件互斥性。
sequenceDiagram
autonumber
participant GW as [API 网关 / Edge]
participant Promo as [promo-engine / 促销算价]
participant Stock as [stock-center / 库存中心]
participant Order as [trade-order / 订单核心]
participant Pay as [trade-pay / 支付结算]
participant JMQ as [JMQ 消息总线]
rect rgb(239, 246, 255)
Note over GW,Order: 阶段一:提单校验、促销分摊与分布式预占
GW->>Order: 1. 提交订单 (order_id, pin, items)
activate Order
Order->>Promo: 2. JSF: 验证券可用性与分摊优惠
Promo-->>Order: 2.1 返回最终应付金额与优惠券冻结凭据
Order->>Stock: 3. JSF: JimDB Redis 分布式预占库存 (sku_id, num)
Stock-->>Order: 3.1 返回库存预占成功标识 (lock_token)
Order->>Order: 4. 本地事务: JED 分库分表插入 order_info (WAIT_PAY)
Order->>JMQ: 5. 发送延迟订单创建超时消息 (order_delay_close_topic)
Order-->>GW: 6. 返回下单成功及收银台拉起参数
deactivate Order
end
rect rgb(240, 253, 244)
Note over Pay,Order: 阶段二:用户支付成功确认与仓储派发事件驱动
Pay->>JMQ: 7. 发布支付成功消息 (pay_success_notify_topic)
JMQ->>Order: 8. @MessageListener: 消费支付完成事件
activate Order
Order->>Order: 9. 状态跃迁: WAIT_PAY -> PAID (基于 version 乐观锁)
Order->>JMQ: 10. 发布订单就绪待出库事件 (order_ready_fulfillment)
deactivate Order
end
跨服务链路对齐的核心算法规则
- 跨服务调用边连接依据:
- 同步 JSF RPC:消费方 XML 别名(
alias)或注解@JsfConsumer声明的接口全限定名、方法签名与提供方@JsfProvider进行全局唯一匹配。多机房同名服务按注册中心拓扑解析默认集群路由。 - 异步 JMQ 消息:提取生产方
MessageProducer.send(topic, message)与消费方@MessageListener(topics = "...")的主题一致性。进一步通过 AST 符号推导核对消息体载荷(Payload DTO 类定义)的序列化兼容性。 - Transactional Outbox 本地事务表与异步消息的血缘缝合:针对订单或支付采用写本地事务表(如
local_msg_queue/outbox_event)再由独立 Worker 轮询发送 JMQ 的架构,系统建立了“业务主写表 → Outbox 表字段 → 发送 Worker → 下游消费者”的双跳显式血缘规则库,杜绝将其误判为断链悬挂。
- 同步 JSF RPC:消费方 XML 别名(
- QLExpress / Aviator 动态规则脚本的 AST 表达式还原:
- 针对营销算价与风控中大量使用 Ducc 动态分发脚本引擎(如
expressEngine.execute(ruleExpr, context))的黑盒场景,系统通过接入 Ducc 配置快照,内建 QLExpress 语法解析器,将诸如user.isPlus && order.actualPay >= 100的动态字符串转化为结构化前置规则条件,打破动态脚本盲区。
- 针对营销算价与风控中大量使用 Ducc 动态分发脚本引擎(如
- 业务标识传播与上下文传递:
- 提取跨服务 RPC 入参与返回值的参数映射。例如,订单服务传给支付服务的
trade_no是否即为其主表中的order_id;若参数发生包装(如封装进CreatePaymentRequest.bizContext),AST 符号求解器通过上下文数据流展开追踪。
- 提取跨服务 RPC 入参与返回值的参数映射。例如,订单服务传给支付服务的
- 分支条件与状态机互斥核验:
- 跟踪主链路上的分支守护条件。若上游返回码为
STOCK_LOCKED_FAIL,则链路绝不向下游支付分支展开,而是直接转向“释放优惠券”与“抛出业务异常”的错误处理分支。
- 跟踪主链路上的分支守护条件。若上游返回码为
恢复路径还要检查谁会再次处理
在分布式电商系统中,RPC 超时、网络抖动与并发资源冲突是常态。L4业务层必须深入还原故障场景下的重试、对账与反向补偿闭环:
flowchart TB
subgraph HappyPath["【第一块 · 正向链路主干】Saga 逆向退款标准主干"]
direction LR
Step1["<b>[1. 申请取消]</b><br/>状态推进至 CANCELING"]
Step2["<b>[2. 支付退款]</b><br/>JSF 同步调用 / MQ 异步通知"]
Step3["<b>[3. 优惠券退回]</b><br/>promo-engine 解冻资产"]
Step4["<b>[4. 库存解锁]</b><br/>stock-center 释放 JimDB 配额"]
Step5["<b>[5. 终态收敛]</b><br/>原子跃迁至已关闭 CLOSED"]
Step1 --> Step2 --> Step3 --> Step4 --> Step5
end
subgraph FailureHandling["【第二块 · 异常感知与重试分支】分布式故障防护"]
direction LR
FailPay["<b>[支付超时]</b><br/>渠道受理中,写本地事务表"]
FailCoupon["<b>[退券抖动]</b><br/>RPC Timeout 进入重试队列"]
DLQ["<b>[JMQ 死信队列]</b><br/>3次重试失败投递 DLQ"]
FailPay --- FailCoupon --- DLQ
end
subgraph CompensateClose["【第三块 · 自动补偿与人工兜底收敛】防资损与死锁双闭环"]
direction LR
WorkerScan["<b>[后台补偿 Worker]</b><br/>分库扫表重试 (分布式锁防并发重入)"]
ManualAudit["<b>[人工仲裁看板]</b><br/>超过重试阈值 (10次) 路由至财务专席"]
WorkerScan --> ManualAudit
end
Step2 -. "超时/失败" .-> FailPay
Step3 -. "失败/重试耗尽" .-> FailCoupon
FailCoupon -. "3次失败" .-> DLQ
FailPay ==> WorkerScan
DLQ ==> WorkerScan
WorkerScan -. "补偿成功恢复" .-> Step5
classDef happyStyle fill:#f0fdf4,stroke:#059669,stroke-width:2px,color:#064e3b;
classDef failStyle fill:#fef2f2,stroke:#dc2626,stroke-width:1.5px,color:#991b1b;
classDef workerStyle fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#78350f;
classDef auditStyle fill:#f5f3ff,stroke:#7c3aed,stroke-width:2px,color:#4c1d95;
class Step1,Step2,Step3,Step4,Step5 happyStyle;
class FailPay,FailCoupon,DLQ failStyle;
class WorkerScan workerStyle;
class ManualAudit auditStyle;
生产级分布式补偿技术机制
- 消息可靠性与死信队列保障:
- JMQ 消费异常时,捕获异常并不直接吞没,而是触发重试机制(默认重试间隔指数退避)。重试达到上限后路由至死信队列(DLQ),并在 L4 拓扑中显式暴露死信监控与告警节点。
- 后台对账扫描 Worker(兜底闭环):
- 每一个关键跨服务交接均需配套后台扫表 Worker(如
OrderCancelCompensationWorker)。系统在 AST 分析中识别此类 Worker 的执行逻辑:查询处于中间状态(如REFUND_PENDING且持续超过 15 分钟)的记录,重新驱动调用下游退款查询或券回退接口。
- 每一个关键跨服务交接均需配套后台扫表 Worker(如
- JimDB 分布式防重锁与幂等保障:
- 检查恢复入口是否包含基于
JimClient.setNX或数据库唯一索引uk_order_action的防重保护,防止补偿 Worker 与正向回调并发执行导致“重复退款”或“超额退券”。
- 检查恢复入口是否包含基于
- 不可逆失败的终态仲裁与强制平账闭环 (
MANUAL_ARBITRATION):- 针对银行卡注销、原支付通道单边账彻底冻结、或营销券模板已物理下线无法补发等永久性不可逆失败,扫表 Worker 在重试耗尽(默认 10 次)后,将订单分布式状态推进至
MANUAL_ARBITRATION(待人工仲裁平账),杜绝状态机无限卡死在COMPENSATING中间态; - 知识库系统自动关联挂载财务/客服人工平账工单入口,确立“自动重试 → 幂等防重 → 人工平账”的 100% 终态闭环。
- 针对银行卡注销、原支付通道单边账彻底冻结、或营销券模板已物理下线无法补发等永久性不可逆失败,扫表 Worker 在重试耗尽(默认 10 次)后,将订单分布式状态推进至
- 金融级超时幽灵交易 (Phantom Request) 防御机制:
- 针对 RPC 调用
ReadTimeoutException无法判断下游是否实际落库的场景,客户端强制生成确定性refund_seq = HASH(order_id, item_sku, attempt); - 依赖本地数据库表唯一约束
UNIQUE KEY uk_order_req (order_id, refund_seq)先行占位,超时后状态机转为REFUND_SUSPENDED挂起,严禁盲目重试,交由补偿 Worker 调用下游查询接口核实确定性状态。
- 针对 RPC 调用
- 分布式锁原子释放 Lua 脚本与 Spring 事务后外发 (Transactional Outbox):
- 锁释放一律采用核验 Token 的原子 Lua 脚本(
if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end),辅以 1/3 TTL 周期自动续期的 Watchdog 守护线程; - 跨服务 JMQ 消息外发严格挂载于
TransactionSynchronizationManager.registerSynchronization的afterCommit()阶段,杜绝本地事务回滚却泄漏幽灵消息。
- 锁释放一律采用核验 Token 的原子 Lua 脚本(
- 极端消息乱序到达与逆向早到占位防御(Anti-Preemption Tombstone / 墓碑占位机制):
- 痛点场景(先发后至):在网络严重抖动时,用户在前端以毫秒级极速点击“立即取消”,导致取消消息
order_cancel_topic先于延迟的提单消息order_create_topic到达下游履约或支付服务;若此时简单判为“单据不存在”而直接丢弃,数秒后提单消息到达并成功入库,将导致订单永久卡死在出库中且资金扣除,引发严重资损。 - 防御机制(墓碑占位与逆向穿透):
- 当逆向取消请求先于订单创建到达时,系统强制在 JimDB 与本地事务表写入带 TTL(默认 30 分钟)的墓碑记录:
INSERT INTO order_cancel_tombstone (order_id, status, expire_time) VALUES (?, 'PRE_CANCELLED', NOW() + INTERVAL 30 MINUTE); - 后续迟到的提单消息在执行落库事务前,先核查是否存在对应的
PRE_CANCELLED墓碑。若命中,则直接在事务内将提单终态原子置为CLOSED并生成取消凭据,不再调用下游锁库与发货接口; - 该机制与 JimDB 分布式防重锁双剑合璧,在百级微服务异步解耦架构下彻底杜绝分布式消息乱序导致的资损泄漏。
- 当逆向取消请求先于订单创建到达时,系统强制在 JimDB 与本地事务表写入带 TTL(默认 30 分钟)的墓碑记录:
- 痛点场景(先发后至):在网络严重抖动时,用户在前端以毫秒级极速点击“立即取消”,导致取消消息
- 跨组织外部通道黑盒隔离与离线批处理对账冲正机制(External Blackbox Channel Boundary & Offline Reconciliation):
- 痛点场景(跨企业状态机不可见):在逆向全链路中,退款终态涉及外部银行通道(微信支付、支付宝、银联清算)的资金到账(T+1~T+3)或第三方外部物流开放平台(顺丰/中通)状态回传。企业内部代码静态分析只能解析到“本地插入待补偿记录,并发送了退款请求 MQ”,无法从源码层面完全还原跨企业外部金融系统的物理终态与长周期悬挂状态。
- 防御机制(边界隔离与离线冲正卡片):
- 外部黑盒通道边界划分:L4 拓扑图在跨组织调用处显式打标
EXTERNAL_CHANNEL_BOUNDARY,将内部代码强闭环与外部长时异步通道进行物理隔离,内部状态机停留在REFUND_GATEWAY_SUBMITTED(已报送网关); - 离线对账批处理 (Daily Reconciliation Worker):次日凌晨拉取银行与支付通道日终流水文件,核对单边账与长悬单;
- 冲正与平账补偿卡片:如果银行返回交易失败或退回,触发
RefundCorrectionJob执行资金链路冲正与人工平账工单,实现 100% 财务终态闭环。
- 外部黑盒通道边界划分:L4 拓扑图在跨组织调用处显式打标
覆盖结果怎样交付
L4 全局业务拓扑最终以两份形式交付:面向业务与排障的结构化 DAG 拓扑,以及全量代码覆盖与断链审计台账。
覆盖与断链分类标准
| 链路连接状态 | 状态说明 | 呈现方式 | 系统处置动作 |
|---|---|---|---|
| VERIFIED (已闭环确认) | RPC/JMQ调用关系代码证据齐全,业务标识透传完整,具备完备的超时重试或补偿逻辑。 | 绿实线连接 | 可作为自动化生成技术方案及PRD合规检查的权威依据。 |
| INFERRED (推断关联) | 存在语义匹配的Topic或同名接口,但由于动态配置(Ducc动态读取)或跨团队二方包未完全解析,推断相连。 | 蓝虚线连接 | 标为“候选拓扑”,提示研发架构师进行一键确认或补充源码仓库。 |
| UNRESOLVED (调用断链) | 代码中调用了下游 JSF 接口,但注册中心或本地代码仓中未找到对应的 Provider 实现类。 | 橙色感叹号警告 | 记录缺失微服务清单,要求在接入清单中补充下游依赖仓库。 |
| NO_COMPENSATION (缺失补偿) | 发现远程调用存在网络异常分支,但仅有 logger.error,无重试、无消息重发、无扫表 Worker 兜底。 |
红色高危警告 | 作为技术债务与系统隐患,在排障雷达中强制亮灯提示。 |
O1的流程产物
作为全链路系统测试基准,O1(履约永久拒绝后的分布式逆向取消与补偿场景)展现了典型的跨服务分布式协调全貌。
O1 逆向全链路分布式拓扑数据结构
{
"$schema": "http://json-schema.org/draft-07/schema#",
"business_scenario_id": "SCN-ORDER-CANCEL-COMPENSATE-01",
"title": "履约拒绝触发全链路逆向退款与资源回退补偿",
"trigger_entry": "fulfillment-service: @MessageListener(fulfillment_rejected_topic)",
"root_business_key": "order_id",
"execution_graph": [
{
"node_id": "N1_INTERCEPT",
"service": "fulfillment-service",
"action": "校验履约状态,确认不可逆拒绝,发布拦截消息",
"downstream_topic": "fulfillment_cancel_event_topic",
"status": "VERIFIED"
},
{
"node_id": "N2_ORDER_STATE",
"service": "trade-order-service",
"action": "消费拦截消息,状态机推进: PAID -> CANCELING,开启分布式取消主流程",
"compensation_worker": "OrderCompensateScanJob",
"status": "VERIFIED"
},
{
"node_id": "N3_PAY_REFUND",
"service": "trade-pay-service",
"action": "JSF同步调用: 退回实付现金 (原路返回银行/微信/京豆)",
"idempotent_key": "refund_seq_${order_id}",
"status": "VERIFIED"
},
{
"node_id": "N4_PROMO_RESTORE",
"service": "promo-engine-service",
"action": "JSF调用: 解冻并返还优惠券资产 (若已过期则执行延期补券策略)",
"status": "INFERRED",
"note": "券延期策略由Ducc动态开关控制,依赖Ducc运行态生效配置"
},
{
"node_id": "N5_STOCK_RELEASE",
"service": "stock-center-service",
"action": "JMQ异步驱动: 释放 JimDB Redis 预占库存与仓库实物排产锁",
"status": "VERIFIED"
},
{
"node_id": "N6_ORDER_FINISH",
"service": "trade-order-service",
"action": "终态核验: 支付退款确认 + 券退回确认 + 库存释放确认,状态跃迁 -> CLOSED",
"unclosed_risk": "若券服务超时,补偿Worker重试上限后挂起于 COMPENSATING 状态等待人工对账",
"status": "VERIFIED"
}
]
}
通过将散落的 L1 技术事实与 L2 规则卡片缝合为上述 L4 全局拓扑,研发在应对复杂线上故障或撰写新需求技术方案时,可一览全链路涉及的微服务交互节点、潜在单点瓶颈与补偿死角。
问答、Agent和IDE怎样使用知识
业务知识库构建完成后,必须以极低延迟、高精准度与严格权限隔离驱动终端研发工具链。系统提供统一的知识服务层(Knowledge Service Layer),支撑三大核心入口:
- Web端交互工作台:面向产品经理、架构师与业务研发的结构化问答、拓扑大屏与方案生成。
- JoyCoder 自动化 Agent:面向多轮自主深度排障、跨服务溯源与技术规格书起草的只读 MCP 协议接口。
- JoyCoder AI IDE 插件:面向工程师编码现场的代码补全前置约束、实时分库分表分片键检测与改动爆炸半径预警。
三个入口共同遵守什么
无论请求来自网页、Agent 还是 IDE 插件,系统均通过统一的网关执行身份认证、权限鉴定、审计留痕与只读沙箱隔离:
flowchart TB
subgraph Clients["【第一块 · 消费终端】三大日常研发工具场景"]
direction LR
Web["<b>[Web 工作台]</b> 需求定界 / 冲突预警"]
Agent["<b>[JoyCoder Agent]</b> 7大只读 MCP 探针"]
IDE["<b>[JoyCoder IDE]</b> 架构约束 / 爆炸半径"]
Web ~~~ Agent ~~~ IDE
end
subgraph Gateway["【第二块 · 统一知识网关】安全与流控中枢"]
direction LR
Auth["<b>[ERP/CAS]</b> 单点登录认证"]
RBAC["<b>[RBAC 鉴权]</b> 多租户数据权限"]
Sandbox["<b>[只读沙箱]</b> Read-Only Guard"]
AuditLog["<b>[调用审计]</b> 不可变版本水印"]
Auth ~~~ RBAC ~~~ Sandbox ~~~ AuditLog
end
subgraph CoreEngine["【第三块 · 核心计算引擎】混合检索与图遍历引擎"]
direction LR
HybridSearch["<b>[混合检索]</b> JED 倒排 + Vearch 向量"]
RRF["<b>[RRF 重排]</b> 倒数排名融合重排"]
GraphEngine["<b>[图遍历]</b> AST 调用图与半径推导"]
HubPruning["<b>[枢纽剪枝]</b> 通用工具节点过滤"]
HybridSearch ~~~ RRF ~~~ GraphEngine ~~~ HubPruning
end
subgraph Storage["【第四块 · 内网双擎存储底座】"]
direction LR
L1_L4_JED[("<b>[JED MySQL]</b><br/>L1~L4 实体 / AST 哈希")]
Vearch_Index[("<b>[京东 Vearch]</b><br/>1024 维语义向量索引")]
L1_L4_JED --- Vearch_Index
end
Clients ==>|统一 REST/gRPC 接入| Gateway
Gateway ==>|安全只读沙箱调度| CoreEngine
CoreEngine ==>|并发召回与拓扑遍历| Storage
classDef clientStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef gwStyle fill:#f8fafc,stroke:#475569,stroke-width:1.5px,color:#0f172a;
classDef coreStyle fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#78350f;
classDef dbStyle fill:#ecfdf5,stroke:#059669,stroke-width:1.5px,color:#064e3b;
class Web,Agent,IDE clientStyle;
class Auth,RBAC,Sandbox,AuditLog gwStyle;
class HybridSearch,RRF,GraphEngine,HubPruning coreStyle;
class L1_L4_JED,Vearch_Index dbStyle;
接入通用契约原则
- 统一只读约束(Read-Only By Design):
- 知识服务接口仅暴露
GET查询与图遍历能力,严禁任何写库、修改代码仓或变更运行态配置的接口暴露。
- 知识服务接口仅暴露
- 严格的研发数据权限与敏感代码动态脱敏(RBAC & Security Sanitization):
- 依赖京东内部统一 ERP/CAS 鉴权。研发人员只能检索其所在部门或经授权的 Coding 仓库知识;
- 在调用
get_evidence返回代码片段前,网关强制通过安全脱敏过滤器,对硬编码密钥、数据库连接密码、AK/SK 与涉密专有算法变量进行自动掩码脱敏(如password = "******"),防止机密外泄。
- 不可变证据链(Immutable Evidence Chain):
- 所有返回的技术结论必须附带底层 L1/L2 证据的确定性版本指纹(Commit Hash + File Path + Line Range + Rule Card ID)。回答或建议一旦生成,其依赖的技术事实版本被冻结,杜绝“动态漂移导致的技术误判”。
问答先确定要证明什么
面对研发或产品提出的复杂业务问题(如“为什么订单已经支付完成,但出库状态一直停滞在待下发?”),检索系统坚决摈弃简单的朴素向量匹配(Naive RAG),采用 精确符号倒排与语义向量双阶段混合检索(Two-Stage Hybrid Retrieval) 配合图遍历。
flowchart TB
subgraph Step1["【第一阶段 · 查询解析与意图分流】"]
direction LR
Query["<b>[用户 Query / 排障描述]</b><br/>业务诉求 / 类名 / 异常堆栈 / 表名"]
Split["<b>[查询解析与意图识别]</b><br/>符号抽取 · 实体识别 · 语义泛化"]
Query --> Split
end
subgraph Step2["【第二阶段 · 三路并行召回与 RRF 融合重排】"]
direction LR
Direct["<b>[符号一票直达]</b><br/>精确类名/方法名/表名穿透"]
Lexical["<b>[JED 倒排词法检索]</b><br/>Top-50 自然语言/黑话命中"]
Dense["<b>[Vearch 向量检索]</b><br/>Top-50 1024维语义向量命中"]
RRF["<b>[RRF 倒数排名融合重排]</b><br/>Score = w_lex/(60+r_lex) + w_vec/(60+r_vec)"]
TopK["<b>[优质候选资产集]</b><br/>Top-10 聚焦画像与卡片"]
Direct --> TopK
Lexical --> RRF
Dense --> RRF
RRF --> TopK
end
subgraph Step3["【第三阶段 · 拓扑图展开与证据链装配】"]
direction LR
GraphTraverse["<b>[JimDB 拓扑展开]</b><br/>3跳 BFS 毫秒级拉取调用方与表"]
Evidence["<b>[上下文证据链装配]</b><br/>交付方案生成或 IDE 爆炸半径雷达"]
GraphTraverse --> Evidence
end
Step1 ==>|识别出符号与文本向量| Step2
Step2 ==>|Top-K 实体锚点| Step3
classDef qStyle fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a;
classDef pathStyle fill:#f8fafc,stroke:#475569,stroke-width:1.5px,color:#0f172a;
classDef directStyle fill:#fef2f2,stroke:#ef4444,stroke-width:2px,color:#991b1b;
classDef rrfStyle fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#78350f;
classDef endStyle fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#064e3b;
class Query,Split qStyle;
class Direct directStyle;
class Lexical,Dense pathStyle;
class RRF rrfStyle;
class TopK,GraphTraverse,Evidence endStyle;
1. 混合检索与 RRF 融合打分公式
系统针对微服务知识库兼具“高精度代码符号(如 OrderCreateExportService.submit)”与“模糊业务概念(如 拆单后满减优惠重算)”的特征,采用倒数排名融合算法(Reciprocal Rank Fusion, RRF)进行加权融合:
RRF_Score(d) = [ w_lex / (k + r_lex(d)) ] + [ w_vec / (k + r_vec(d)) ]
- 其中
k = 60为平滑常数; r_lex(d)为 JED 倒排词法检索中实体d的排名(未命中则设为∞);r_vec(d)为 Vearch 语义向量检索中实体d的排名;w_lex = 0.65(当 Query 包含 CamelCase 标识符、SQL 表名或包含双引号精确匹配时动态提升至0.85),w_vec = 0.45;- 代码符号精准匹配“一票直达”通道:当检测到查询输入为确定性全限定类名、异常名(如
DuplicateSubmissionException)或 SQL 表名时,直接激活直通索引,将词法权重置为w_lex = 1.0,跳过向量模糊相似度计算,避免长尾精准代码被语义软融合稀释。
2. 业务同义词图谱 (Thesaurus) 与低置信度“主动反问澄清机制”
面对产品与运营人员的大促口语(如“万人团拼购”、“跨年破价补贴”)与底层代码严肃大驼峰(如 MarketingReverseSettlementDubboServiceImpl)之间的语义断层,「拍拍·谛听」引入词表对齐与交互澄清双保险:
- JED 业务同义词与大促代号字典 (
kb_biz_thesaurus):- 建立结构化多级词表映射:
- 口语/黑话:
万人团、拼购大促、跨年破价 - 对应底层业务标识:
activity_type = 108、PromotionTypeEnum.GROUP_BUY、微服务trade-promotion-engine
- 口语/黑话:
- 支持架构师与业务运营在 Web 工作台动态导入与补充。
- 建立结构化多级词表映射:
- 主动反问澄清机制 (Active Clarification Gate):
- 当 RRF 检索 Top-1 综合得分低于置信度阈值(
RRF_Score < 0.70)且 Top-1 与 Top-2 得分差值< 0.05时,系统判定用户意图存在多路径歧义; - 此时系统坚决拒绝大模型硬猜,而是直接向用户输出澄清反问选项(例如:“您是指‘营销结算服务的逆向补贴链路’还是‘售后退款服务的资金原路退回’?”);
- 用户点击后携带消歧上下文继续精准检索,从根源上杜绝大模型在冷启动阶段的语义漂移。
- 当 RRF 检索 Top-1 综合得分低于置信度阈值(
3. AST调用拓扑遍历与枢纽节点剪枝(Hub-Node Pruning)
当检索定位到核心方法或入口后,系统沿 L1 AST 调用图展开上下游依赖。
- JimDB 内存调用拓扑图缓存(In-Memory Adjacency List):
- 为避免在线排障与 IDE 频繁轮询在 JED MySQL 执行多层递归慢查询(Recursive CTE),系统将百级微服务的调用拓扑压缩为邻接表预热至 JimDB (Redis);
- 3-hop 深度展开在内存中仅需
< 10ms即可完成遍历,从架构上彻底消除数据库死锁与连接池耗尽隐患。
- 入度异常枢纽节点剪枝规则:
- 为防止在调用图中遭遇通用底层工具类导致“爆炸半径失控”,图遍历引擎实施剪枝:
| 节点类型 | 判定特征 | 剪枝策略 |
|---|---|---|
| 通用日志框架 | org.slf4j.Logger.*, Log4j.* |
直接剪枝:忽略所有调用边,不计入业务上下文。 |
| 性能监控埋点 | @JProfiler, UmpProvider.*, MDC.* |
直接剪枝:不参与业务逻辑与事务流转分析。 |
| 基础工具方法 | StringUtils.*, JsonUtil.*, BeanUtils.* (入度 > 50) |
直接剪枝:阻断扩散,防止遍历漫延至无关业务类。 |
| 通用数据访问基类 | BaseMapper.*, SqlSessionTemplate.* |
保留参数边:保留操作的表名实体,阻断非业务调用边。 |
图遍历算法默认设定:最大遍历深度 $Depth_{max} = 3$,单次最大检索节点数 $Nodes_{max} = 100$。
Agent怎样继续调查
JoyCoder 等自主智能体(Agent)在执行复杂技术攻关、架构重构设计或线上排障时,通常需要多次交互式深入取证。系统通过标准的 Model Context Protocol (MCP) 协议暴露 7 个原子化只读工具(与 schemas/tool-contracts.schema.json 强类型契约严格对齐):
7个标准只读 MCP 工具清单
| MCP 工具名称 | 输入参数 (JSON Schema) | 输出内容 | 典型使用场景 |
|---|---|---|---|
search_knowledge |
query, types, page_size, cursor |
RRF 融合排序后的候选微服务、接口与规则卡片摘要列表 | 针对模糊业务描述或错误日志定位责任微服务与规则 |
get_business_rule |
rule_id, revision_id |
L2 入口规则卡片:前置条件、状态机跃迁、Ducc 开关、副作用矩阵 | 分析特定业务方法(如订单取消)的内部处理逻辑与分支 |
get_business_flow |
flow_id 或 (entity_id, event_id) |
L4 全局端到端流程:包含正向主干、异常分支与 Saga 补偿对账任务 | 理解跨交易、支付、履约的完整业务闭环与最终一致性 |
get_contract |
contract_id, binding_filters, revision_id |
L2 接口与数据契约:JSF RPC 签名、JMQ Topic、MyBatis 表分片键 | 核验接口入参/出参 DTO、服务别名与分库分表分片键约束 |
trace_impact |
target, change_type, diff, workspace_revision |
上下游 AST 调用链图拓扑(带 Hub-Node 剪枝)与改动爆炸半径评估 | 评估代码修改可能波及的上下游系统与全表扫描风险 |
get_evidence |
evidence_id, segment_id, line_range |
不可变源码事实证据:代码片段高亮、AST 语法树节点、Commit Hash指纹 | 最终生成研发报告或技术方案时引用不可辩驳的代码证据 |
build_context |
task, workspace, symbols, context_budget_tokens |
专为 IDE 与 Agent 编码定制的精炼上下文打包(AST 差异、适用性、Token 预算控制) | 赋能 JoyCoder Agent 在有限小窗口内获取精确局部知识上下文 |
智能体排障实战调用序列:排查“优惠券未退回”
sequenceDiagram
autonumber
participant Agent as [JoyCoder Agent 研发助手]
participant MCP as [拍拍·谛听 MCP 服务 (7大标准只读工具)]
rect rgb(239, 246, 255)
Note over Agent,MCP: 阶段一:混合检索定位目标微服务与规则
Agent->>MCP: 1. search_knowledge(query="履约拒绝后优惠券为何未退回", types=["MICROSERVICE","RULE"])
MCP-->>Agent: 命中 trade-order-service 与 promo-engine-service
end
rect rgb(254, 243, 199)
Note over Agent,MCP: 阶段二:提取核心入口规则与静态调用拓扑展开
Agent->>MCP: 2. get_business_rule(rule_id="rule:order_cancel_restore")
MCP-->>Agent: 返回取消主规则:先退款,退款成功后异步发 JMQ 触发退券
Agent->>MCP: 3. trace_impact(target="OrderCancelConsumer.onMessage", change_type="BEHAVIOR")
MCP-->>Agent: 发现下游包含: PromoRestoreExportService.refundCoupon (JSF)
end
rect rgb(240, 253, 244)
Note over Agent,MCP: 阶段三:AST 源码事实取证与根因判定
Agent->>MCP: 4. get_evidence(evidence_id="ev:promo_refund:112_145")
MCP-->>Agent: 返回源码证据:若券处于 EXPIRED 状态,必须 Ducc 开关 promo.auto.delay=true 方可补券
Note over Agent: Agent 汇总不可变证据链,得出根本原因:<br/>该订单优惠券已过有效期,且线上 Ducc 开关未开启自动延期
end
Java MCP Server 官方 SDK 实现规范 (io.modelcontextprotocol.sdk:mcp-java)
系统基于官方 Java MCP SDK (io.modelcontextprotocol.sdk:mcp-java) 与 Spring Boot 3 构建只读 MCP 工具服务,为 JoyCoder 等 Agent 提供强类型只读 Tool 暴露:
package com.jd.knowledge.mcp.server;
import com.jd.knowledge.domain.dto.*;
import com.jd.knowledge.service.*;
import io.modelcontextprotocol.sdk.spec.McpSchema.Tool;
import org.springframework.stereotype.Component;
import java.util.*;
/**
* 基于官方 mcp-java SDK (io.modelcontextprotocol.sdk:mcp-java) 的「拍拍·谛听」只读工具集
* 遵循严格的只读约束与脱敏规范,赋能 JoyCoder Agent 自主探查与研发提效
*/
@Component
public class KnowledgeMcpToolProvider {
private final KnowledgeSearchService searchService;
private final BusinessRuleService ruleService;
private final GlobalFlowService flowService;
private final ContractMetaService contractService;
private final CallGraphImpactService impactService;
private final AstEvidenceService evidenceService;
private final WorkspaceContextService contextService;
public KnowledgeMcpToolProvider(
KnowledgeSearchService searchService,
BusinessRuleService ruleService,
GlobalFlowService flowService,
ContractMetaService contractService,
CallGraphImpactService impactService,
AstEvidenceService evidenceService,
WorkspaceContextService contextService) {
this.searchService = searchService;
this.ruleService = ruleService;
this.flowService = flowService;
this.contractService = contractService;
this.impactService = impactService;
this.evidenceService = evidenceService;
this.contextService = contextService;
}
/** 1. 跨微服务知识与符号双阶段混合检索 (RRF 倒数排名融合) */
public SearchResultDTO search_knowledge(String query, List<String> types, int pageSize, String cursor) {
return searchService.hybridSearch(query, types, Math.min(pageSize, 20), cursor);
}
/** 2. 提取方法级 L2 业务规则卡片 (前置校验、Ducc开关、读写表) */
public BusinessRuleCardDTO get_business_rule(String ruleId, String revisionId) {
return ruleService.findRuleCard(ruleId, revisionId);
}
/** 3. 查询 L4 全局端到端业务流与 Saga 补偿对账拓扑 */
public BusinessFlowDTO get_business_flow(String flowId, String revisionId) {
return flowService.getGlobalFlow(flowId, revisionId);
}
/** 4. 查询 L2 接口契约定义、JMQ 拓扑与分库分表分片键 */
public ContractMetaDTO get_contract(String contractId, String revisionId) {
return contractService.getContractDetail(contractId, revisionId);
}
/** 5. 展开上下游 AST 调用拓扑图与爆炸半径评估 (带 Hub-Node 剪枝) */
public CallGraphImpactDTO trace_impact(String targetSymbol, String changeType, int depth) {
int boundedDepth = Math.min(Math.max(1, depth), 3);
return impactService.traverseAndEvaluate(targetSymbol, changeType, boundedDepth);
}
/** 6. 提取不可变 AST 源码事实证据与 Commit 指纹 (自动脱敏) */
public AstEvidenceDTO get_evidence(String evidenceId, String segmentId, String lineRange) {
return evidenceService.fetchSanitizedEvidence(evidenceId, segmentId, lineRange);
}
/** 7. 构建 IDE 增量编辑与 Agent 推理上下文 (含 Token 预算控制) */
public ContextPackageDTO build_context(String task, String workspace, List<String> symbols, int contextBudgetTokens) {
return contextService.packageContext(task, workspace, symbols, Math.min(contextBudgetTokens, 3500));
}
}
IDE怎样判断依据是否适用
在工程师使用 JoyCoder AI IDE 编写或审查代码时,系统通过轻量级后台 Sidecar 进程实时感知当前编辑器上下文,实现 <200ms 的低延迟代码守护。
flowchart TB
subgraph IDE_Context["【第一块 · IDE 上下文感知】Sidecar 本地轻量毫秒捕获"]
direction LR
Editor["<b>[光标焦点]</b><br/>Active File & 行号位置"]
LocalAST["<b>[Tree-Sitter]</b><br/>本地增量 AST 语法解析"]
GitBranch["<b>[Git 状态]</b><br/>Commit / Branch / Diff 变更"]
Editor ~~~ LocalAST ~~~ GitBranch
end
subgraph DecisionEngine["【第二块 · 实时判定引擎】低延迟规则推导 (<200ms)"]
direction LR
RuleMatcher["<b>[模式匹配]</b><br/>方法签名与分片键模式"]
VersionCheck["<b>[版本比对]</b><br/>code_hash 差异核验"]
ConstraintChecker["<b>[架构约束]</b><br/>ShardingKey / 幂等键校验"]
RadarRenderer["<b>[IDE 渲染]</b><br/>Gutter 悬浮与诊断波浪线"]
RuleMatcher --> VersionCheck --> ConstraintChecker --> RadarRenderer
end
subgraph UIAlertBlock["【第三块 · 就地诊断与防护预警】"]
direction LR
UIAlert["<b>[IDE 高危阻断预警]</b><br/>SQL 缺少分片键 user_pin,将引发 1024 分表全广播扫描"]
FixSuggest["<b>[智能修复建议]</b><br/>自动在 WHERE 子句补全 user_pin 索引绑定"]
UIAlert ==> FixSuggest
end
IDE_Context ==>|注入本地上下文| DecisionEngine
DecisionEngine ==>|命中规则并校验适用| UIAlertBlock
classDef ctxStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef engineStyle fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#78350f;
classDef alertStyle fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b;
classDef fixStyle fill:#f0fdf4,stroke:#059669,stroke-width:2px,color:#064e3b;
class Editor,LocalAST,GitBranch ctxStyle;
class RuleMatcher,VersionCheck,ConstraintChecker,RadarRenderer engineStyle;
class UIAlert alertStyle;
class FixSuggest fixStyle;
JoyCoder AI IDE 本地毫秒级爆炸半径雷达
🔍 爆炸半径雷达推导报告 (耗时: 38ms · JimDB 本地缓存命中)
🔴 HIGH RISK · 高危架构阻断| 变更代码定位 | OrderMapper.xml#queryOrderByStatus (第 48 行) |
| 核心风险描述 | SQL 变更缺少分片键 user_pin |
| 底层集群影响 | 导致 JED 执行 100 库全表广播扫描;直接威胁集群连接池吞吐 |
| 上游受累服务 | 波及上游 2 个服务:jd-order-core、trade-open-gateway |
| IDE 治理建议 | IDE 阻断动作:触发本地提交阻断门禁,强制要求补齐分片键 user_pin 或使用分布式二级索引。 |
IDE 实时守护核心场景
- MyBatis 分库分表分片键检测(Sharding Linting):
- 开发者在 XML 或 Mapper 接口中编写针对
order_info的SELECT语句; - IDE 插件在 50ms 内匹配到该表的分库分表规则(ShardingKey:
user_pin); - 若
WHERE条件中仅有order_id而无user_pin,立即提示:“该查询未包含用户分片键,若必须按订单号查询,请确保使用带基因路由的order_id算法或走分布式二级索引”。
- 开发者在 XML 或 Mapper 接口中编写针对
- 改动爆炸半径实时预警(Blast Radius Radar):
- 开发者修改了核心服务对外暴露的 JSF 接口方法签名;
- IDE 插件通过调用拓扑索引,实时在编辑器右上角展示:“当前方法被下游 7 个微服务引用(包含 12 个线上消费者),变更将造成不兼容中断,请创建新别名或升级版本号”。
- 版本适用性守护(Version Drift Protection):
- 本地代码已进行未提交改动(Dirty Workspace)时,插件明确标注:“知识库依据基于基线版本 Commit
a8f3b2,检测到当前文件包含本地修改,改动行影响已动态重估”。
- 本地代码已进行未提交改动(Dirty Workspace)时,插件明确标注:“知识库依据基于基线版本 Commit
规范实现细节与环境部署见 TRD 06 更新发布与运行 与 TRD 07 合同与验收。
代码变化后,知识怎样更新
在京东持续交付体系中,上百个微服务每日产生上千次代码提交(Merge Request)。如果每次变更都全量重新解析数千万行源码与重构全库索引,将导致计算资源枯竭与服务严重滞后。
更新与发布引擎的核心目标是:通过行级与方法级 AST 指纹比对,实现精准的增量失效与脏节点拓扑扩散(Dirty Node Propagation),并保障 JED 关系数据与 Vearch 向量索引的双引擎原子生效。
每一层重算什么
当 Xingyun CI 监听到代码合并(Merge Request Merged)事件后,触发针对变更仓库的增量更新流水线。更新器以Git Commit 变更的 AST 差量作为最小重算单元:
flowchart TB
subgraph Trigger["【第一阶段 · CI 增量捕获】行云流水线自动化触发"]
direction LR
GitMR["<b>[Xingyun CI Webhook]</b><br/>Git Push / MR Merged 自动触发"]
Meta["<b>[元数据提取]</b><br/>仓库名 / 分支 / Commit / 变更文件"]
GitMR --> Meta
end
subgraph DiffEngine["【第二阶段 · AST 增量门禁与差量比对】"]
direction LR
JavaDiff["<b>[JavaParser AST]</b><br/>语义差量比对"]
MethodHash["<b>[SHA-256]</b><br/>归一化方法哈希 code_hash"]
DirtyCheck{"code_hash<br/>是否实质变化?"}
JavaDiff --> MethodHash --> DirtyCheck
end
subgraph BranchAction["【第三阶段 · 分支处置:0 Token 旁路 vs 局部染色扩散】"]
direction LR
subgraph BypassGroup["0 Token 极速旁路 (非功能改动)"]
direction TB
Bypass["<b>[0 Token 旁路]</b><br/>仅改动注释/空行/日志<br/>跳过 AI 重算,复用老摘要"]
end
subgraph PropagationGroup["局部染色重算 (业务逻辑实质变更)"]
direction LR
DirtyL1["<b>[L1]</b> 更新方法 AST 事实"]
DirtyL2["<b>[L2]</b> 重新蒸馏业务卡片"]
DirtyL3["<b>[L3]</b> 刷新画像 STALE 状态"]
DirtyL4["<b>[L4]</b> 拓扑全链路重新验证"]
DirtyL1 --> DirtyL2 --> DirtyL3 --> DirtyL4
end
end
Trigger ==> DiffEngine
DirtyCheck -- "否: 仅改动格式/注释" --> BypassGroup
DirtyCheck -- "是: 业务逻辑实质变更" --> PropagationGroup
classDef trigStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef diffStyle fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#78350f;
classDef bypassStyle fill:#f0fdf4,stroke:#059669,stroke-width:2px,color:#064e3b;
classDef dirtyStyle fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#991b1b;
class GitMR,Meta trigStyle;
class JavaDiff,MethodHash,DirtyCheck diffStyle;
class Bypass bypassStyle;
class DirtyL1,DirtyL2,DirtyL3,DirtyL4 dirtyStyle;
脏节点扩散算法(Dirty Node Propagation)
- 方法级指纹计算(Method-Level
code_hash):- 提取方法体 AST 节点,移除注释、空白符及变量重命名干扰后计算 SHA-256。若哈希未变,立即终止扩散。
- 局部拓扑向上扩散:
- L1 局部更新:更新该方法节点属性及其直接出度边(Callees);
- L2 入口重算:若该方法是公开端点(JSF Provider、JMQ Listener),触发该入口的 L2 规则重新提炼;若为内部私有方法,沿调用图入度边(Callers)向上回溯至最邻近的 L2 暴露入口;
- L3 / L4 级联重验:若修改影响了接口契约入参或事务副作用,重新生成 L3 微服务画像中的能力说明,并在 L4 全局流程中核对下游调用链是否发生断裂。
- 公共基础包“级联更新风暴”防御机制(Butterfly Effect Guard):
- 当多服务共享的公共基础二方包(如
trade-common-dto.jar)发生合并时,更新器执行契约级语义差量过滤(Contract Semantic Diffing); - 若仅新增了可选字段、扩展了非抽象工具方法、或改动字段未被任何上层微服务的 L2 卡片分支条件引用,流水线判定为“非破坏性兼容更新”,直接终止向上层扩散,仅刷新 L1 静态类型元数据;
- 彻底杜绝一个底层基础包改动引发全网 100 个微服务被全部标记为 DIRTY 的雪崩灾难,保护内网言犀大模型配额与 CI 队列吞吐。
- 当多服务共享的公共基础二方包(如
对象和检索索引怎样一起生效
系统采用由 JED (MySQL) 存储结构化事实实体 与 Vearch 存储非结构化语义向量 组成的一体化存储架构。
核心存储物理表结构 DDL (JED MySQL)
1. 微服务画像表 (kb_service_profile)
CREATE TABLE `kb_service_profile` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`service_id` VARCHAR(64) NOT NULL COMMENT '微服务唯一标识,如 trade-order-service',
`service_name` VARCHAR(128) NOT NULL COMMENT '中文业务名称',
`domain` VARCHAR(64) NOT NULL COMMENT '所属业务域',
`git_repo` VARCHAR(256) NOT NULL COMMENT 'Coding 源码仓库地址',
`cluster` VARCHAR(64) NOT NULL COMMENT '集群标识',
`profile_json` MEDIUMTEXT NOT NULL COMMENT 'L3画像完整JSON (含能力树/拓扑/依赖)',
`version_hash` VARCHAR(64) NOT NULL COMMENT '当前画像对应的 Git Commit Hash',
`generation_id` BIGINT UNSIGNED NOT NULL COMMENT '发布代际ID',
`status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '状态: ACTIVE / STALE / RETIRED',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_service_gen` (`service_id`, `generation_id`),
KEY `idx_domain` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='L3 微服务核心画像表';
2. 入口规则卡片表 (kb_entry_rule)
CREATE TABLE `kb_entry_rule` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`rule_id` VARCHAR(64) NOT NULL COMMENT '规则唯一标识 (UUID/业务规则ID)',
`service_id` VARCHAR(64) NOT NULL COMMENT '所属微服务',
`entry_point` VARCHAR(256) NOT NULL COMMENT '入口类与方法签名',
`protocol` VARCHAR(32) NOT NULL COMMENT '协议: JSF / JMQ / REST / WORKER',
`rule_json` MEDIUMTEXT NOT NULL COMMENT 'L2卡片完整JSON (前置条件/状态跃迁/副作用)',
`code_hash` VARCHAR(64) NOT NULL COMMENT '方法体 AST 语义归一化哈希',
`file_path` VARCHAR(256) NOT NULL COMMENT '源码文件相对路径',
`start_line` INT NOT NULL COMMENT '起始行',
`end_line` INT NOT NULL COMMENT '结束行',
`generation_id` BIGINT UNSIGNED NOT NULL COMMENT '发布代际ID',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_rule_gen` (`rule_id`, `generation_id`),
KEY `idx_service_entry` (`service_id`, `entry_point`(191)),
KEY `idx_code_hash` (`code_hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='L2 入口业务规则卡片表';
3. 架构师人工标注覆盖表 (kb_human_annotation)
CREATE TABLE `kb_human_annotation` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`target_type` VARCHAR(32) NOT NULL COMMENT '标注对象类型: SERVICE / RULE / FLOW',
`target_key` VARCHAR(128) NOT NULL COMMENT '目标唯一键 (如 service_id 或 rule_id)',
`override_json` TEXT NOT NULL COMMENT '人工修正内容 (修正职责描述/调整业务域/设定标签)',
`bound_ast_hash` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '绑定时方法的 AST 签名哈希,防止代码重构后幽灵覆盖',
`annotator_erp` VARCHAR(64) NOT NULL COMMENT '标注人 ERP 账号',
`audit_status` VARCHAR(32) NOT NULL DEFAULT 'APPROVED' COMMENT '审批状态: APPROVED / STALE_NEEDS_RECONFIRM / REVOKED',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_target` (`target_type`, `target_key`),
KEY `idx_status` (`audit_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='架构师人工业务标注覆盖与生命周期表';
[!NOTE] 幽灵标注守卫机制:当底层方法签名发生剧烈重构或被物理删除时,流水线检测到
bound_ast_hash失效,自动将状态流转为STALE_NEEDS_RECONFIRM,暂停向上覆盖并向标注人 ERP 推送确认工单,防止脏数据污染知识库。
Vearch 向量空间规范 (Vearch Space Schema)
为平衡亿级微服务代码向量的高性能检索与物理内存占用,系统采用分级存储策略:高频的 L3 服务画像采用 MemoryOnly 引擎保障毫秒级路由;大容量的 L2 入口卡片采用 DiskIVFPQ 倒排乘积量化存储,内存节省 65% 以上。
{
"name": "knowledge_card_space",
"partition_num": 3,
"replica_num": 2,
"engine": {
"index_size": 100000,
"retrieval_type": "IVFPQ",
"retrieval_param": { "ncentroids": 2048, "nsubvector": 64 }
},
"properties": {
"card_id": { "type": "keyword", "index": true },
"service_id": { "type": "keyword", "index": true },
"domain": { "type": "keyword", "index": true },
"entry_type": { "type": "keyword", "index": true },
"generation_id": { "type": "integer", "index": true },
"content_summary": { "type": "string" },
"embedding": {
"type": "vector",
"dimension": 768,
"index": true,
"store_type": "DiskIVFPQ"
}
}
}
双引擎原子发布机制(Blue/Green Generation Switch)
为杜绝更新过程中用户查到“半新半旧”的技术事实,发布引擎采用发布代际(generation_id)蓝绿切换策略:
sequenceDiagram
autonumber
participant Worker as [提取构建 Worker]
participant JED as [JED MySQL (关系存储)]
participant Vearch as [Vearch 向量引擎]
participant Pointer as [全局代际指针 (JimDB / Ducc)]
rect rgb(239, 246, 255)
Note over Worker,Vearch: 阶段一:新代际双写构建与数据隔离 (不可见预热)
Worker->>Worker: 1. 批量重算完成,生成新代际 gen_id = 1002
Worker->>JED: 2. 批量写入实体 (标记 generation_id = 1002, 初始不可见)
Worker->>Vearch: 3. 批量写入向量 (携带 generation_id = 1002 过滤标签)
end
rect rgb(254, 243, 199)
Note over Worker: 阶段二:全链路发布校验门禁与冒烟评测
Worker->>Worker: 4. 执行冒烟测试:核验核心接口检索与拓扑链路可用性
end
rect rgb(240, 253, 244)
Note over Worker,Pointer: 阶段三:原子切换生效指针 (零停机秒级生效)
Worker->>Pointer: 5. CAS 原子更新 ACTIVE_GENERATION_ID: 1001 -> 1002
Note over JED,Vearch: 线上所有终端查询立即切换为代际 1002<br/>零停机时间,无脏读风险,杜绝半新半旧
end
基础二方包重构:P0/P1 分级背压调度队列与大模型过载时的 AST 硬聚合降级
当全域共享的基础通用 DTO 包(如 trade-client-dto.jar)合并破坏性变更时,数百个微服务可能同时被标记为 Dirty Node,引发 LLM 重算任务瞬间打满调度队列。系统设计了分级背压与无损降级双层防护:
- 分级背压调度队列(Tiered Backpressure Queue):
- P0 级(核心黄金链路):如
trade-cart、trade-order、trade-pay,压入高优先级队列,分配独占 LLM 并发通道,30 秒内完成增量刷新; - P2 级(非核心与离线服务):如报表、后台管理服务,写入低优先级延迟队列,在凌晨闲时(01:00~06:00)批量调度;
- P0 级(核心黄金链路):如
- 大模型服务过载时的“零损耗硬聚合降级”:
- 若大模型 API 出现超时、503 报错或 Token 配额打满,更新流水线自动切断大模型重算链路,启动纯 AST 硬聚合模式;
- 知识库直接展示代码提取的确定性结构(接口签名、参数列表、调用拓扑、读写数据表),仅暂缓展示自然语言总结摘要,确保整个知识库检索和调用链路 100% 高可用,绝不阻塞上线流水线。
生产级高可用与缓存三防架构(穿透、击穿、雪崩)
面对数万次高频检索与大促流量洪峰,底层存储与缓存层构筑了三级防护:
- 防穿透:所有对微服务名、接口类名、数据表名的查询,在进入 JED / Vearch 之前,先经过 JimDB 中的全量布隆过滤器(Bloom Filter)。不存在的代码符号直接拦截并返回“未收录”,杜绝利用随机字符串恶意刷爆存储;
- 防击穿:针对大促期间的高频热点接口卡片(Hot Keys,如下单主流程接口),在缓存失效瞬间,利用 JimDB
setNx分布式互斥锁,仅允许 1 个请求回源重算,其余请求等待或读取旧版本快照(Stale-While-Revalidate); - 防雪崩:JED 关系数据与 Vearch 缓存过期时间统一增加
TTL + Random(120s~600s)离散扰动,彻底消除整点集中失效风险。
消息和Worker退出后怎样恢复
在分布式大规模构建中,面对 Worker 容器缩容、GC 超时或网络闪断,系统必须具备严格的任务可靠性与幂等恢复机制。
- JMQ 任务队列与事务确认:
- 更新任务作为可靠消息投递至 JMQ 构建队列(包含重试次数与追踪 ID)。Worker 成功完成 JED 写入与校验后,才执行
ack()确认;若 Worker 崩溃未确认,JMQ 自动将任务重新分配给其他节点。
- 更新任务作为可靠消息投递至 JMQ 构建队列(包含重试次数与追踪 ID)。Worker 成功完成 JED 写入与校验后,才执行
- 租约锁与递增提交标记(Lease & Attempt Token):
- 调度器为每个正在执行的任务分配 10 分钟租约(基于 JimDB
SET NX PX)。Worker 在提交结果时核对attempt_token;因 GC 停顿超时的“僵尸 Worker”即使在稍后苏醒,其提交请求也会被数据库版本号乐观锁拒绝,防止旧结果覆盖新结果。
- 调度器为每个正在执行的任务分配 10 分钟租约(基于 JimDB
旧版、撤权和删除怎样处理
- 历史版本归档与软删除:
- 废弃的旧版本在切换后保留 14 天代际只读镜像,支持故障回溯与审计重现;超过 14 天的数据自动异步归档至离线冷存储(CFS/对象存储),并从 Vearch 内存索引中物理淘汰。
- 微服务下线与接口废弃:
- 若微服务在 Xingyun 体系中下线,系统自动在 L3/L4 画像中将该节点标记为
DEPRECATED,同时触发下游所有消费方系统的“断链预警”报告。
- 若微服务在 Xingyun 体系中下线,系统自动在 L3/L4 画像中将该节点标记为
- 安全权限撤销即时生效:
- 当工程师在京东 ERP 发生部门调岗或离职时,SSO/CAS 权限变更事件通过 MQ 实时广播至知识服务网关,10分钟内强制废弃其本地 Token,立即阻断敏感业务系统知识的访问。
验收体系与基准评测标准详见 TRD 07 合同与验收。
怎样检查设计和产物
业务知识库系统的工程验收必须脱离主观评价,建立在 严格的数据契约验证(Contract Verification)、全链路故障注入(Fault Injection)以及历史 PRD 真值基准集(Ground-Truth Benchmark) 之上。
系统验收涵盖两大部分:
- 分层数据契约静态校验:验证 L1 至 L4 四层数据模型是否 100% 符合 JSON Schema,是否具备可追溯的行级代码指纹;
- 端到端量化基准验收:在真实百级微服务输入下,对检索精准率、爆炸半径召回率、问答事实一致性与 IDE 响应延迟进行量化考核。
四层分别交付什么
系统每一层产物都必须具备独立可验证的技术标准与交付检查项:
| 知识层级 | 核心可检查交付物 | 自动化机器验收标准 (Machine Check) | 人工架构师抽检标准 (Human Audit) |
|---|---|---|---|
| L1 技术事实 | 标准化 AST IR 语法包、JSF 契约元数据、JMQ 拓扑关系、MyBatis 分库分表规则表 | 1. 100% 注册服务完成语法解析; 2. 契约无未知未解析类型; 3. 分库分表提取准确率 100%。 |
抽检 20 个复杂 XML 动态 SQL,确认分片键解析无遗漏。 |
| L2 入口规则 | 结构化规则卡片(包含前置条件、状态跃迁矩阵、副作用列表、异常分支) | 1. 100% 符合 EntryRuleCard JSON Schema;2. AST 反向核验拦截率 100%(虚构参数拦截); 3. 方法提取覆盖率 > 92%。 |
抽查 50 个核心交易入口,核对状态机分支与代码实现严格一致。 |
| L3 服务画像 | 微服务画像(核心能力目录、独占资产矩阵、上下游依赖拓扑、集群部署标识) | 1. 100+ 微服务画像完整生成; 2. 核心数据表(如 order_info)独占归属映射无冲突;3. 跨服务直连 DB 反模式零漏报。 |
业务架构师核验 5 个核心领域服务画像能力描述无职责扩大。 |
| L4 全局业务 | 端到端端拓扑流程(正向主链路、逆向取消链路、分布式补偿与死信队列拓扑) | 1. 跨服务 RPC 与 JMQ 拓扑连通率 > 90%; 2. 所有分布式悬挂节点标出; 3. 关键业务线全闭环。 |
专家走查正向提单与逆向退款场景,确认重试与补偿逻辑完整。 |
按同一份O1输入验收
系统将“O1 基准(履约永久拒绝触发全链路逆向退款与资源补偿)”作为分布式多服务联动验收标准,并辅以 20 套历史真实生产 PRD 黄金测试集,执行全自动化量化评测。
flowchart TB
subgraph BenchmarkInputs["【第一阶段 · 黄金基准输入规约】"]
direction LR
CodeRepo["<b>[5大核心交易微服务源码]</b><br/>trade-order · trade-pay · promo-engine<br/>stock-center · fulfillment"]
StandardPRD["<b>[20套真实生产 PRD 规约集]</b><br/>涵盖跨店满减 · 拆单分摊 · Saga 逆向补偿"]
CodeRepo ~~~ StandardPRD
end
subgraph AutoEvaluator["【第二阶段 · 自动化量化评测流水线】五维全覆盖"]
direction LR
SchemaValidator["<b>[Schema 校验]</b><br/>100% 模式契约核验"]
PrecisionCalc["<b>[P@5 精准率]</b><br/>两阶段混合重排评估"]
BlastRecall["<b>[爆炸半径召回]</b><br/>下游影响面 0 漏报"]
ConsistencyJudge["<b>[代码一致性]</b><br/>反向 AST 代码行比对"]
LatencyBenchmark["<b>[端到端延迟]</b><br/>P95 < 1.5s / IDE < 200ms"]
SchemaValidator --> PrecisionCalc --> BlastRecall --> ConsistencyJudge --> LatencyBenchmark
end
subgraph ScoreReport["【第三阶段 · 自动化量化验收雷达大屏】(全绿交付基线)"]
direction LR
Metric1["<b>[检索精准率 P@5]</b><br/>实测 94.2% (基线 ≥ 92%)"]
Metric2["<b>[爆炸半径召回率]</b><br/>实测 98.7% (基线 ≥ 98%)"]
Metric3["<b>[代码事实一致性]</b><br/>实测 96.5% (基线 ≥ 95%)"]
Metric4["<b>[增量构建保鲜耗时]</b><br/>实测 118s (基线 < 3min)"]
Metric1 ~~~ Metric2 ~~~ Metric3 ~~~ Metric4
end
BenchmarkInputs ==>|注入基准测试集| AutoEvaluator
AutoEvaluator ==>|自动化打分判定| ScoreReport
classDef benchStyle fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px,color:#1e3a8a;
classDef evalStyle fill:#fffbeb,stroke:#d97706,stroke-width:2px,color:#78350f;
classDef scoreStyle fill:#f0fdf4,stroke:#059669,stroke-width:2px,color:#064e3b;
class CodeRepo,StandardPRD benchStyle;
class SchemaValidator,PrecisionCalc,BlastRecall,ConsistencyJudge,LatencyBenchmark evalStyle;
class Metric1,Metric2,Metric3,Metric4 scoreStyle;
1. 20 套历史 PRD 基准评测集指标要求
| 验收核心指标 | 工业级量化达标门槛 | 评测计算公式与执行方案 |
|---|---|---|
| 检索精准率 (Precision@5) | ≥ 92% | 抽取 200 个高频业务/技术问题,前 5 个召回结果中包含标准微服务与规则卡片的比例。 |
| 爆炸半径召回率 (Blast Radius Recall) | ≥ 98% | 注入 50 处核心方法签名修改,比对系统计算出的上下游影响节点与人工专家静态全走查结果的重合率(容忍过度召回,严禁关键调用漏报)。 |
| 代码-规则一致性 (Fact Consistency) | ≥ 95% | 将生成的 L2/L3 业务规则与底层代码事实进行反向校验,杜绝任何臆测参数或不存在的事务承诺。 |
| 混合检索响应延迟 (P95 Latency) | < 1.5s | 在 100+ 微服务、10 万张规则卡片规模下,并发 50 QPS 压测两阶段检索流水线。 |
| IDE 上下文响应延迟 (P95 Latency) | < 200ms | IDE 插件根据本地光标变动,匹配分库分表与规则的实时交互延迟。 |
| 增量重算效率 (Incremental Build Time) | < 3min | 单次典型 MR(变更 5 个文件、12 个方法)从 Webhook 触发到索引生效的全程耗时。 |
2. 负向变异与故障注入测试用例 (Fault Injection Tests)
为验证系统的鲁棒性,评测套件在 O1 输入上执行变异与破坏性注入,系统必须表现出预期的防御行为:
| 注入故障场景 | 破坏性变异操作 | 预期系统表现与防御动作 |
|---|---|---|
| 断链与悬挂调用 | 人为删除支付服务对外的 JSF Provider 接口声明 | L1 标记接口断链,L4 逆向流程拓扑中该节点亮起黄色 UNRESOLVED 警告,且无法通过发布门禁。 |
| 分库分表跨分片违规 | 在订单查询 SQL 中移除 user_pin 条件,仅保留普通时间过滤 |
IDE 与 L2 静态分析引擎立即触发高危警报:“检测到无分片键全表广播风险”。 |
| 模型幻觉注入 | 诱导模型输出“订单取消时负责用户银行卡利息补差” | L2/L3 AST 证据链核验门禁自动拦截该断言,因无代码调用证据直接驳回。 |
| 无业务变更的代码格式变动 | 仅对方法增加换行、修改代码格式或调整注释 | code_hash 判定一致,增量更新流水线在 1 秒内阻断脏节点扩散,零计算成本退出。 |
| 补偿死信缺失 | 移除券回退消费者重试失败后的死信队列与扫表 Worker 逻辑 | L4 全局拓扑将该环节标记为红色高危 NO_COMPENSATION,并生成系统可用性隐患工单。 |
全量契约测试代码详见工程根目录下 tools/verify_contracts.py,全流程一键构建与生成详见 tools/build_docs.mjs。
架构设计决策与技术深潜 FAQ (Architecture Rationale & Technical Deep-Dive)
针对百级微服务业务知识库的底层编译、存储分级、并发控制与增量一致性保障等关键技术决策,以下提供系统级的深度机制解析:
01 Q1(防模型幻觉):LLM 生成 L2 规则卡片与 L3 服务画像时,如何从架构上杜绝逻辑幻觉?
① 确定性数据流:RPC Provider/Consumer 契约、MyBatis 表名、JMQ 拓扑完全由 JavaParser + SymbolSolver 静态编译直出,不经大模型推理;
② 单方法树状分治:大模型单次请求仅接收清洗后的单方法代码片段,避免千行上下文引发的注意力稀释;
③ 门禁双向核验:大模型生成的规则 JSON 必须经过
ASTVerifier 校验,若卡片声称调用的方法或依赖在 L1 拓扑中不存在,立刻阻断写入并降级为纯 AST 契约清单。
02 Q2(知识保鲜时效):微服务持续高频 Merge,知识库如何做到 45 秒内增量保鲜?
① 方法级指纹比对:对变更代码先清洗掉空白符与注释,计算规范化 AST 哈希
code_hash,未变化的方法直接命中缓存复用(0 Token 消耗);② 脏节点精准传播:仅对发生实质变更的方法调用言犀重算(耗时 2~3 秒),并仅沿反向调用链(
caller_methods)向上回溯受影响的 1~3 张卡片;③ 毫秒级代际切换:更新完毕后通过 JimDB 原子更新
ACTIVE_GENERATION_ID,完成无锁零停机蓝绿切换。
03 Q3(二方包防雪崩):二方公共 DTO 包升级时,如何防止触发全网百级微服务全部重算的雪崩?
当
trade-common-dto.jar 发布新版本时,静态分析器首先执行差量核验:若仅新增了可选属性或扩展了无副作用枚举,判定为向后兼容改动,直接阻断向上扩散;仅当检测到破坏性变更(字段类型改变、字段删除、序列化 UID 变更)时,才精准定位并通知实际受累的消费者微服务。
04 Q4(核心源码安全):如何确保业务代码资产在分析与推理全生命周期中的物理隔离与零泄漏?
① 物理隔离环境:分析 CLI、存储端(JED + Vearch)与推理端(言犀 ChatRhino)均部署于京东内网隔离网段,绝不向外网发送任何 HTTP 请求;
② 无生产写权:知识服务 Worker 仅挂载只读 Git 访问凭证与只读查询数据库,不具备任何线上写入权限;
③ 调用水印与审计:每次知识拉取均记录 ERP 审计日志,并以隐形版本水印标记响应结果,全链路防越权与追溯。
05 Q5(上帝方法切分):如何解决老系统中数千行“上帝方法”超长上下文超限问题?
① 噪音剥离:预处理阶段自动移除所有日志记录、监控打点、通用参数非空校验(代码降噪超 40%);
② 子逻辑块拆分:基于 AST 独立分支切分子模块,单模块蒸馏严格限制在 1,500 Token 以内;
③ 中文语义汇总:入口汇总时拼接“子模块中文摘要”而非 Java 原始代码,入口级摘要控制在 2,500 Token 以内,彻底规避模型上下文窗口溢出。
06 Q6(Ducc 动态脚本穿透):线上动态规则引擎(如 QLExpress / Aviator)的脚本字符串如何纳入静态分析?
① 配置数据事实化:拉取 Ducc 配置快照,将动态规则表达式作为配置事实存入 L1 实体表;
② 表达式语义还原:内置专用 QLExpress 语法解析器,将动态表达式(如
user.isPlus && order.actualPay >= 100)转化为标准前置校验抽象树,与静态代码拓扑无缝拼接。
07 Q7(高并发分布式防重):多渠道并发发起退款时,系统如何避免重复退款与资损?
① 第一道(JimDB 锁):入口执行
SETNX lock:order:cancel:${orderId} (TTL=30s),并发竞争者直接被拦截排队;② 第二道(状态机乐观锁):采用
UPDATE order_info SET status='CANCELING', version=version+1 WHERE order_id=? AND status='PAID' AND version=?,确保跃迁仅成功一次;③ 第三道(全局凭据):退款流水落库唯一不可变凭据
RF1,支付中心与优惠券资产中心以凭据作为幂等扣减与返还标识。
08 Q8(异步消息血缘缝合):Transactional Outbox 本地事务表异步发消息,静态分析如何不误判断链?
系统专门定义了“业务写表 → Outbox 表字段 → 发送 Worker → JMQ 消息 Topic → 下游消费 Listener”的确定性双跳血缘规则库,通过 AST 符号求解自动建立异步调用边,将异步消息链路与 RPC 同步链路同等清晰编排,绝不产生虚假断链。
09 Q9(架构师标注留存):人工补充的高价值业务背景与团队黑话,在代码更新后如何持久继承?
人工标注数据持久化于独立的
kb_human_annotation 数据表中。当底层微服务代码发生 Merge 触发自动化重聚时,聚合管线首先读取对应的人工标注快照,并以最高优先级覆盖自动生成的相应字段,确保“架构师的业务智慧只增不减、历久弥新”。
10 Q10(量化收益与 ROI):技术方案落地后,如何通过自动化度量体系验证业务成效?
① 需求定界准确率 ≥ 90%:输入 PRD 秒级圈定 3~5 个目标服务及关键入口(传统切片 RAG 仅 < 30%);
② 影响面召回率 = 100%:通过 AST 编译级调用图展开上下游依赖,确保漏评率严格为 0;
③ 研发效能提升 ≥ 40%:技术方案编写耗时从 3 天压缩至 2 小时,排障根因定位从 4 小时压缩至 3 分钟以内。
企业级安全合规、源码防泄密与权限管控
在大规模企业内网落地微服务逆向知识库时,系统必须兼顾“知识全景透明”与“信息安全合规”的平衡:
1. 源代码敏感信息脱敏过滤器(Sensitive Data Sanitizer)
在 AST 静态分析并向 JED 与 Vearch 写入实体前,执行强制脱敏清洗:
- 密钥与密码脱敏:命中
password、secret、accessKey、privateKey、token等敏感变量赋值或配置文件时,统一自动打码替换为******,防止硬编码密码流入向量库与 LLM Prompt; - 个人隐私数据(PII)屏蔽:符合国内手机号正则
1[3-9]\d{9}或身份证号格式的字符串常量,自动转换为掩码形态(如138****0000); - 物理环境脱敏:对外契约仅保留标准逻辑名与 URN,自动擦除物理机真实主机名(Hostname)与内网宿主机 IP。
2. Prompt 注入防御与内网推理隔离沙箱
- 双向内容安全网关:所有发送至言犀大模型的 Prompt 与模型返回的文本,必须流经内部合规过滤器,拦截针对系统提示词的逆向越狱攻击(Jailbreak Prompts);
- 纯内网隔离部署:所有 LLM 调用、向量检索与代码解析计算节点 100% 部署于京东自建私有云安全 VPC,严禁任何公网外联通道,杜绝数据外泄风险。
3. 基于京东 ERP 的 RBAC 角色权限与微服务行级隔离
- 权限角色矩阵:
- 普通研发 / 测试:可查阅授权业务域内的 L1~L4 实体与调用拓扑;
- 业务产品经理 (PM):专注查阅 L2 入口说明书、L4 业务全景与名词白话翻译,屏蔽底层字节码等纯技术实现;
- 核心架构师:拥有全局跨域拓扑查阅权,以及人工背景批注、词表导入、代际回滚管理权限;
- 外包与非全职人员:对敏感核心业务域(如
trade-pay支付中心、risk-engine风险控制中心)实施行级数据屏蔽,仅展示接口黑盒契约签名,不展示内部业务规则与数据表结构。
合同详表
采集分析
1 采集批次
采集请求包含repo_id、commit_sha、environment、deployment_refs、config_snapshot_refs和requested_capabilities。禁止在一次扫描过程中跟随移动分支继续拉取新内容。分支仅用于解析目标Commit,解析完成后固定输入。
构建元数据保留Maven模块、依赖坐标、版本、制品校验和、源代码附件及Java语言级别。公共export包只提供字节码时,记录可读取的类型和签名范围,缺失方法体作为已知限制。
| 输入 | 基础提取 | 扩展提取 |
|---|---|---|
| Java与构建依赖 | 类、方法、签名、类型、继承、注解 | 可达关系、条件、控制依赖与数据依赖 |
| Spring与JSF | Bean、Provider、Consumer、声明位置 | alias和环境绑定、代理与扩展配置 |
| JMQ | 生产与消费声明、Topic表达式 | 事件结构、过滤、序列化与幂等使用点 |
| SQL与映射 | 表、操作类型、映射关系 | 字段、动态条件、路由与计算血缘 |
| 配置 | 键引用、默认值及加载位置 | 实际取值、灰度、生效时间与刷新方式 |
| 发布与治理 | 制品、部署环境与契约绑定 | 同时运行版本与调用观察 |
2 解析顺序
先建立模块、类型、Bean和配置索引,再识别入口和框架适配点。随后解析调用与数据访问,最后在全局范围对齐契约。JavaParser及符号解析器作为候选基础库;对反射、运行时生成代理和内部封装的覆盖通过适配样本验证。
入口包括JSF、HTTP、Color等网关绑定、JMQ、定时任务、批处理和内部事件。每种入口携带声明证据与解析状态。JProfiler只用于排序和辅助识别,不作为唯一入口或规则筛选条件。
内部封装通过适配规则声明类名、方法签名、参数用途和结果语义。适配规则有版本、样例和负责人。名称包含send、lock或query不能直接作为副作用证据。
3 调用与复杂语法
多态调用先返回候选实现,再用Bean绑定、分发键、泛型和配置缩小范围。策略矩阵保存每个实现的条件,不能将所有策略规则当作同时执行。候选过多时分批解析,并保留完整候选清单。
Spring代理路径与AspectJ织入方式分别记录。Spring官方文档说明代理模式的self-invocation会绕过advice,AspectJ织入则不同,因此仅看注解不足以认定切面生效。Spring代理机制
异步调用记录任务提交、Lambda或回调体、等待关系、异常出口和超时。事务保存传播、回滚条件和跨线程边界;不能把数据库事务自动延伸到RPC或JMQ消费。提取事务入口、挂起/恢复、提交/回滚出口、rollback-only设置及提交后回调的注册和执行位置。事务内SQL记录条件和受影响行数判断;条件写返回0不构成状态迁移。REQUIRES_NEW等独立事务按实际生效代理路径单独建边界,不从调用栈顺序推断其与外层共同回滚。数据库事务回滚不能撤回已发送RPC或消息;若发送使用outbox、事务消息或提交后回调,需找到相应提交及投递证据,缺少时保留外部副作用可能已发生。
调用图中互相递归的一组方法称为强连通分量(SCC)。调度器将这一组方法一起计算,原始调用边仍保留;摘要怎样迭代见第11节。大方法按控制结构分段,片段带上外层条件、进入片段时可用的变量和返回出口。拆分后无法保留这些信息时,记录受影响方法及预算失败原因,不输出完整规则。
4 SQL 配置与字段映射
MyBatis include先按命名空间展开,动态SQL保存条件分支。注解SQL、MyBatis-Plus、自研DAL、存储过程引用和SQL字符串构造分别登记支持状态。WRITE语句中的SELECT、子查询与JOIN可能同时产生读取关系。
分表归一由路由配置、实体映射和物理元数据共同支持。带数字后缀只是候选;候选分片键与确认路由键分开。字段传递需要追踪PO、DTO、序列化别名与转换表达式,关注金额单位、状态码和缺省值。
配置解析保留键引用与加载关系,再结合环境和框架加载方式求值。Ducc不被假定为所有项目的最高优先级。运行中动态刷新时,配置快照声明观察时间及取值范围。
5 IR包
| 文件 | 内容 | 校验 |
|---|---|---|
| manifest.json | 包版本、服务与Commit、依赖制品、分析器和输入哈希 | 文件清单与校验和一致 |
| analysis_input.json | 第6节的规范化分析输入及固定的外部IR包引用 | 内容摘要与manifest.input_digest相同 |
| entities.jsonl | 类型、方法、入口、契约、事件及资源 | 实体ID不重复,版本范围明确 |
| relations.jsonl | 调用、读写、绑定、生产与消费关系 | 起止ID可解析,类型合法 |
| source_segments.jsonl | 原文与清洗片段映射 | 指定Commit下定位和哈希可核验 |
| config_bindings.jsonl | 配置引用、候选值与生效证据 | 缺失或歧义不自动填值 |
| diagnostics.jsonl | 失败、歧义、缺失依赖与不支持语法 | 与受影响对象和范围关联 |
| coverage.json | 已发现、成功解析、失败和排除数量 | 分母来源、排除规则可审查 |
| branch_ledger.jsonl | 条件、出口、副作用和规则映射基线 | 分支ID唯一,排除与未知有原因 |
jsonl按行存一条对象。包身份使用现有manifest中的 scan_id,清单仍遵守IR manifest 0.1。下面约定文件内的记录与引用,业务规则由后续提取阶段生成。
记录字段与引用
记录ID在一个scan_id内跨文件唯一。实体、关系、证据片段和诊断分别使用不同ID前缀。引用统一写成 {"scan_id": "scan:order:1", "record_id": "method:refund"};引用当前包时也不省略scan_id,避免合并多个包时重名。跨包引用的scan_id和manifest校验和写入analysis_input.json,读取方先检查外部包清单,再按record_id取记录,不能去当前最新包寻找同名记录。
| 记录 | 最小字段 | 读取约束 |
|---|---|---|
| 技术实体 | record_id、kind、implementation_ref、evidence_refs | implementation_ref保存stable_id、implementation_scope和revision_id,三者缺一时不作为已定位实现 |
| 技术关系 | record_id、kind、source_ref、target_ref、candidate_target_refs、resolution_status、evidence_refs、diagnostic_refs | 关系两端引用实体记录;下述解析状态决定目标是否可用 |
| 原文片段 | record_id、source_type、locator、content、content_hash | CODE定位含仓库、Commit、文件和行范围;配置及治理记录定位到固定归档修订;content_hash对应本条content |
| 诊断 | record_id、code、affected_refs、message、evidence_refs | affected_refs指向已登记的实体或关系,不用自由文本代替受影响范围 |
| 配置绑定 | record_id、consumer_ref、config_key、source_refs、value_resolution、value、evidence_refs | UNKNOWN时value为空且说明缺少哪份配置;空值本身仍可能是已确认值 |
| 分支台账 | record_id及第12节的branch_id、symbol_revision、guard_ref等字段 | record_id用于包内外定位,branch_id用于分支到规则的核对 |
关系为RESOLVED时,target_ref必须指向唯一的已登记实体,candidate_target_refs为空;为AMBIGUOUS时,target_ref为空,候选列表逐项指向已登记实体;为UNRESOLVED时,target_ref为空、candidate_target_refs为空,诊断写明还缺哪种定位依据。只有名称、Topic表达式或未知类名时,将其保存为关系的match_keys,不为它生成虚构实体。业务流程仅沿RESOLVED关系连接确定步骤,其他关系作为待核对调用点展示。
发布时先把记录引用解析成实体的implementation_ref,再检查相应实现是否属于候选发布清单。IR里的局部ID不作为发布后的对象ID;跨包引用能够读到,也不代表该实现已经被纳入当前发布。关系还可按类型携带callsite_id、guard_ref、字段映射或绑定条件,这些信息不能在从IR转成发布对象时丢弃。
退款调用记录例
以固定的订单包 scan:order:1 和支付包 scan:payment:1 为例。下表列出关系所引用的记录,两个包均需按各自manifest校验后读取。
| 所在包与文件 | record_id | 记录内容 |
|---|---|---|
| 订单包 entities.jsonl | method:refund | METHOD;implementation_ref为sym:order:refund / sv:order:1 / symrev:order:refund:1 |
| 支付包 entities.jsonl | method:refund | METHOD;implementation_ref为sym:payment:refund / sv:payment:1 / symrev:payment:refund:1 |
| 订单包 source_segments.jsonl | source:refund-call | 固定Commit中paymentFacade.refund(request)的源码片段及定位、内容哈希 |
| 订单包 source_segments.jsonl | source:payment-binding | 固定治理归档中,示例环境与alias对应订单调用方、支付提供方及refund签名的记录 |
| 订单包 source_segments.jsonl | source:event-send | 固定Commit中sender.send(topic, event)的源码片段;event的具体类型尚未解析 |
订单包relations.jsonl中保存下列两条记录。为便于阅读,此处以JSON数组列出;文件中每条对象独占一行。
[
{
"record_id": "relation:refund-call",
"kind": "CALLS",
"source_ref": {"scan_id": "scan:order:1", "record_id": "method:refund"},
"target_ref": {"scan_id": "scan:payment:1", "record_id": "method:refund"},
"candidate_target_refs": [],
"resolution_status": "RESOLVED",
"evidence_refs": [
{"scan_id": "scan:order:1", "record_id": "source:refund-call"},
{"scan_id": "scan:order:1", "record_id": "source:payment-binding"}
],
"diagnostic_refs": []
},
{
"record_id": "relation:event-send",
"kind": "PUBLISHES",
"source_ref": {"scan_id": "scan:order:1", "record_id": "method:refund"},
"target_ref": null,
"candidate_target_refs": [],
"resolution_status": "UNRESOLVED",
"match_keys": {"topic_expression": "topic", "event_type": null},
"evidence_refs": [{"scan_id": "scan:order:1", "record_id": "source:event-send"}],
"diagnostic_refs": [{"scan_id": "scan:order:1", "record_id": "diagnostic:event-type"}]
}
]
对应的diagnostics.jsonl记录为:
{
"record_id": "diagnostic:event-type",
"code": "EVENT_TYPE_UNRESOLVED",
"affected_refs": [{"scan_id": "scan:order:1", "record_id": "relation:event-send"}],
"message": "发送点的事件类型尚未解析,不能匹配消费方",
"evidence_refs": [{"scan_id": "scan:order:1", "record_id": "source:event-send"}]
}
第一条关系通过两个包各自的method:refund定位到不同实现,再取得其完整implementation_ref。第二条记录只保留发送点与诊断,没有指向不存在的消息实体,也不推导消费者。补齐事件类型后,重新产出带新输入摘要的IR记录;旧包内容不改写。
6 错误与重入
任务按授权隔离范围、处理阶段和 input_digest 去重。输入摘要由规范化的分析输入计算,包含应用与模块、仓库及Commit、实际classpath和制品校验和、effective POM与profile、JDK和编译参数、生成源码摘要、部署及配置修订、requested_capabilities、分析预算与策略、框架适配规则版本和analyzer_version。追加跨包IR输入时,也纳入所引用包的scan_id与清单校验和。
同一提交先做入口扫描,再要求字段传播,requested_capabilities已经变化,必须创建新任务。降低或提高分析深度、更新内部SDK适配规则,也会改变输入摘要。只有输入摘要相同且产物校验通过时复用结果;失败产物用于恢复任务,不作为成功结果交付。输入项缺失用明确的缺失状态参与摘要,不能当成空配置或零依赖。
分析输入保存为 analysis_input.json,文件纳入IR清单。对象键按固定次序编码;能力集合去重排序,classpath、配置优先级等有顺序含义的数组保留原序。input_digest对这份规范化内容计算SHA256;不得用请求到达时间、临时目录或数组偶然顺序影响任务身份。源码与产物复用仍需校验当前读取权限,不跨授权范围共享未脱敏内容。
仓库拉取失败与单文件解析失败分开处理。后者允许输出部分IR,但manifest标记PARTIAL,diagnostics列出受影响入口。符号解析失败可以保留语法关系候选,不能转成已确认调用。
7 分析器验收样本
每个探针至少包含声明可识别、间接封装、歧义和不支持四类样本。关键样本包括方法重载、同名包、Map策略、AOP自调用、泛型export包、异步异常、动态表名、多事件Topic和字段单位转换。另包含DTO别名修改、集合共享后修改、条件更新0行、更新后抛异常回滚、独立事务成功而外层回滚,以及提交后回调未执行。比较提取对象与专家标注,不以进程退出成功作为解析通过。
8 百级服务清单与跨仓库对齐
接入单元是可部署应用,不等同于Git仓库。采集器建立service_id → repo_id + module_path → artifact_digest → commit_sha映射,另存环境、部署实例及有效时间。同仓库多应用分开登记;多个应用共用的export包按制品坐标和校验和登记一次,再记录各自依赖版本。无法取得源码映射的制品标为SOURCE_UNMAPPED,不能用仓库最新分支代替。
服务清单来自应用与部署目录,并与仓库、JSF提供方和JMQ消费方交叉核对。每项记录inventory_revision、owner_ref、source_access、analysis_state、last_success_input、exclusion_reason。没有权限、已停用、非Java、尚未登记分别计数。覆盖率分母使用指定清单修订,不能只统计扫描成功的仓库。
每个目录来源保存查询范围、来源修订、分页结束标记及获取状态。全量目录拉取失败、权限只覆盖部分应用或分页未完成时,清单只能声明已发现范围,不能声称100多个服务都已纳入。目录之间的差异按“应用无仓库映射、部署无登记应用、治理端点无提供方、消费者无源码、仓库模块未部署”分类;别名映射有来源和修订,未匹配项保留到后续对账。
入口清单对照源码声明、网关/服务治理、调度目录、消费绑定及领域场景逐项合并。定时入口保留调度表达式、时区、启停配置、租户/分片参数、扫描选择条件和游标;批处理保留批次成员边界、逐项成功/失败、检查点和重跑范围;对账及补偿保留发现待处理记录的条件、修复动作及回执。仅知道定时方法名称不足以把它连接到失败流程;连接需要相同对象选择条件及状态守卫证据。人工工单、文件导入和外部回调无法读取实现时,登记边界契约和资料缺口,不从Java扫描分母中静默删除。
跨仓库关系按下面的证据建立,关系对齐器保留match_basis、candidate_targets、resolution_status。模型可建议候选名称,不能直接确认绑定。
| 边界 | 对齐键与证据 | 无法唯一定位时 |
|---|---|---|
| JSF调用 | 接口全名、方法参数、消费端制品版本,再结合alias、环境和提供方部署 | 保留候选提供方及各自适用范围 |
| HTTP或网关 | 网关路由到应用的绑定、方法、路径模板与请求结构 | 仅有相同URL文本不确认跨服务边 |
| JMQ | 环境、Topic、事件类型、序列化结构、消费组与过滤表达式 | 不明确eventType或过滤条件时只保留订阅候选 |
| 数据资源 | 数据源身份、Schema、路由与逻辑表、字段映射 | 同表读写只建立数据依赖,不自动推断执行顺序 |
| 定时与批处理 | 调度任务绑定、执行入口、输入输出资源 | 没有触发关联时保留独立入口 |
运行观测只在能映射部署版本的时间窗口内补充边;无法关联版本的调用记录作为待核对线索。对齐结果保留静态、部署、观测三组证据,避免一次调用记录覆盖其他合法实现。
9 分区构建与覆盖报告
先为全部授权应用登记入口、契约和资源扫描任务,成功的清单形成全局索引,并行按业务入口展开深度分析;个别应用失败不设为全局屏障。跨服务对齐使用全局契约索引,任务调度按应用与输入哈希分区;公共包变化只重算实际引用该版本的应用。每个阶段独立保存产物,单仓库失败不会阻塞其他仓库,但引用该仓库的流程必须显示缺口。
覆盖报告同时给出应用、入口、跨服务边和规则分支四个维度。入口记录发现来源、是否完成符号解析、可达分支是否分析以及终止原因。达到深度、节点或Token上限的入口记为部分完成,不能从分母移除。业务流程覆盖另由领域样本核对,不能从技术扫描比例换算。
10 构建上下文与符号解析
分析输入固定effective POM、启用的profile、JDK与编译参数、模块源集、生成源码清单以及最终依赖图。保存依赖仲裁后的实际classpath,不直接将POM中声明的版本作为运行依赖;Maven的传递依赖、scope和版本仲裁会改变选用制品。Maven依赖机制
优先读取可核验的构建产物及生成源码。必须构建才能补齐Lombok或注解处理产物时,构建在独立任务环境中执行,使用只读源码与受限依赖访问,不执行发布步骤。构建失败仍可做语法级提取,输出analysis_level=SYNTAX_ONLY及缺失类型;不能以相同FQN从另一个应用的classpath补齐。
解析按调用点进行:先确定声明签名,再在当前应用classpath和Bean绑定中计算可能目标。每个调用点保存declared_target、possible_targets、dispatch_kind、binding_evidence、resolution_status。possible_targets逐项引用implementation_ref及作用范围,不因stable_id相同而合并灰度目标;跨仓库匹配后仍保留调用方与被调方各自service_version_ref。桥接方法指向其实现映射;同名类冲突、反射或动态脚本缺少目标时返回未解析边。所有参数到形参、返回值到接收点的关系都带callsite_id,避免将不同调用上下文的参数混接。
11 方法摘要与字段传播
方法摘要保存参数读取、返回表达式、对象字段写入、外部调用、异常出口及其守卫条件,并引用构成摘要的IR节点。局部分析先求方法内部关系;只有目标入口、业务标识、规则条件和变更字段相关的切片才跨方法展开。该分层借鉴CodeQL对局部与全局数据流的区分,不将CodeQL列为内网部署依赖。CodeQL Java数据流
字段传播区分三种语义:COPY保留值,TRANSFORM保留可解释转换,INFLUENCES只表明依赖。amount → amount > 0只能说明影响,不能声称金额值流入布尔结果。集合项用字段路径和元素选择条件定位;无法确定索引或Map键时保存通配访问与歧义,不能与指定明细混为一条确定链。可变对象引用传递只建立别名候选,不直接标记其字段值为COPY。摘要区分对象身份、分配点、读写位置与调用上下文:callee可能修改传入DTO或共享集合,返回前后的字段需分别追踪。无法解析points-to或内部封装写集合时,对可能受影响字段保留未知写入,不能继续沿旧值作确定计算;必要时扩大为对象级影响并报告精度下降。
对无法读取实现的内部SDK,用带版本的语义摘要描述参数、返回、字段副作用和异常。没有摘要时保留未知影响,不能假设调用无副作用。自研JSON封装、Bean复制、消息发送和DAL优先建立适配样本;适配版本变化会使使用该模型的摘要失效。
对第3节的递归方法组,先计算各方法的本地摘要;某方法摘要变化时,把组内调用它的方法放回待计算队列,直到一轮计算不再改变摘要哈希。达到迭代或关系上限仍未稳定时,记录 FIXPOINT_INCOMPLETE 及受影响的方法。摘要缓存使用第6节定义的实际输入摘要和方法修订,不仅比较方法文本。
12 分支台账与遗漏检查
在模型提取前,静态分析器为入口可达范围建立branch_ledger。每项包含branch_id、symbol_revision、guard_ref、outcome_kind、effect_refs、exit_ref、evidence_ids、resolution_status,覆盖if/switch、提前返回、异常出口、条件SQL和策略分发。循环保存循环条件、单次动作与退出语义,不枚举不可界定的所有迭代路径。
提取结果必须将每个台账项关联到规则节点、明确的非业务原因或未解析项。非业务排除项需要exclusion_rule_id及来源,不能让模型单凭“无关代码”删除字段复制、默认值和序列化。检查器反向查找没有来源台账的规则节点,防止补写源码不存在的条件。
分支覆盖只统计已识别范围:分母是该输入版本中发现的台账项,分子是有规则关联或经复核排除的项。另报解析失败文件、缺失依赖、未知入口和未解析调用;台账覆盖达到全部也不代表未知区域无业务规则。台账随IR提供branch_ledger.jsonl,并进入文件清单与校验和检查。
13 异步业务操作与幂等证据
对支付回调、补偿、消息消费等入口,提取事件ID与业务关联键的赋值和使用点,分别标记投递去重键和业务操作键。分析器追踪幂等查询、唯一约束或条件写、状态变更及确认消息的控制位置;只有方法名含deduplicate或lock不构成幂等证据。相同键不同参数如何处理也应保留,避免将新的业务操作误归为重试。
超时路径记录远程调用是否已发出、是否保存原操作标识、是否存在结果查询、重试及对账入口。无法确认远端结果时输出未知效果,不能把catch分支自动建成“远端未执行”。业务恢复入口与消息重投分开登记,重投可能只有消费恢复,不一定重新执行业务副作用。
对历史报价、原支付和退款金额,沿持久化字段、DTO与调用参数追踪来源及转换。配置读取时间、报价决策时间、支付事实时间和补偿执行时间分别记录;当前配置快照不能替代历史决策凭据。字段映射缺失时停止金额血缘,不以业务常识补出原价减优惠的计算。
14 金额限额与业务身份的提取
分析器对分摊方法同时提取参与集合、适用过滤、权重来源、金额单位、舍入及余分处理。稳定排序是否来自line_id、数据库排序或集合遍历必须有原文依据。仅提取divide调用或最终总额不足以还原最大余数分配;缺少排序证据时标记ALLOCATION_ORDER_UNKNOWN,不能编造哪一行获得余分。
部分退款从金额使用点反向追踪到原分摊凭据、行或子单、capture、历史确认退款及占用记录。先读取余额再申请退款,与在同一业务提交边界检查并占用余额,是不同的并发语义。分析器记录读条件、聚合键、唯一约束、条件更新、受影响行数判断与提交位置;只有出现锁方法或注解不能证明不会超退。
payment_id含义由声明和关联关系确认,不预设它同时代表意图、尝试和实收。多次尝试、迟到回执及重复实收处置分别建立路径;退款参数映射必须指向实际capture。用order_id取得“最新支付记录”后退款可能选错实收,作为待核对使用点保留,而不是按命名自动确认映射。
幂等提取增加三层检查:消息投递标识、业务退款意图、渠道执行操作。保存各层键的生成来源、适用范围与参数冲突分支。两个compensation_id指向同一退款意图时仍属于同一业务诉求;同一行的两个不同合法意图仍受同一行权益及capture限额约束。缺少任一限额或原子占用证据时,只能报告已识别的局部防护。
占用、接收、超时、确认、拒绝与释放均进入分支台账。特别核对“超时释放占用”“重试生成新操作”“重复确认累加退款”及“先退券再确认退款”等分支。查询端可据此解释潜在风险,但不能仅凭发现一条调用关系给出运行中已超退的结论。
知识模型
规则独立保存,接口卡片、服务画像和业务域概览引用规则生成。卡片与画像的字段、入口归集和读取约束见阅读视图。
1 对象与关系
| 对象 | 标识范围 | 主要内容 |
|---|---|---|
| BusinessEntity | 业务域与概念 | 名称、定义、别名、标识字段及边界 |
| BusinessRule | 规则稳定ID | 适用对象、条件、动作、例外、证据 |
| Capability | 领域能力ID | 职责、输入输出概念、入口与副作用 |
| BusinessFlow | 流程ID与修订 | 触发、步骤、分支、结束和补偿 |
| StateTransition | 实体状态机与迁移ID | 前后状态、事件、守卫条件和动作 |
| TechnicalEntity | 仓库、制品或资源命名空间 | 方法、接口、事件、表、字段、配置等 |
| Assertion | 断言修订ID | 关系或规则内容、证据、来源与有效范围 |
| Evidence | 内容与定位标识 | 来源、版本、原文定位、采集记录和校验和 |
关系包含IMPLEMENTS、GUARDS、TRANSITIONS、PARTICIPATES_IN、CALLS、READS、WRITES、PUBLISHES、SUBSCRIBES、BINDS_TO、DEPENDS_ON、SUPPORTED_BY、CONTRADICTS和REPLACES。关系携带方向、版本、条件和来源;同一对实体可以存在多种关系。
领域人员按业务含义审核概念合并。名称相同只产生候选别名,不能据此合并订单主单、子单和履约单。不同领域对同一术语有不同定义时,保留领域限定。
2 标识与版本
entity_id和rule_id标识持续维护的对象;revision_id标识不可变内容版本;snapshot_id标识某次查询使用的发布清单。对象重命名保留旧标识与跳转,语义发生拆分则建立新对象并记录替代关系。
Java方法的稳定键包含所属模块或制品命名空间、声明类全限定名、方法名与擦除后的参数类型;不可变符号修订另带源码Commit、制品校验和及完整JVM描述符。构造器、桥接方法、生成方法分别标识,不将编译器生成的方法当成新业务规则。DTO字段使用所属类型和字段路径定位;集合元素和嵌套对象不能只用字段名匹配。表字段至少包含数据源、Schema、逻辑表和字段名。
发布成员键为member_kind、stable_id、implementation_scope。业务对象使用GLOBAL范围,修订内保留多实现绑定;技术对象的implementation_scope使用service_version_ref,区分同一符号在灰度部署中的不同实现。implementation_ref固定stable_id、implementation_scope、revision_id,关系端点及规则实现引用使用该三元组;候选目标分别列出各自三元组与适用范围。裸stable_id只用于身份检索,不能在多实现快照中直接解析执行版本。
JSF逻辑契约与alias、环境等绑定实例分别保存。JMQ事件与Topic分开,消费组与业务过滤条件属于消费绑定。共享Topic下的不同事件不能自动合并。
3 业务规则
规则合同采用schema_version=0.2,0.1作为历史格式保留。规则记录采用条件树。叶子节点描述字段或配置与值的比较,组合节点描述AND、OR、NOT。每个条件节点可以引用源码片段;暂时无法解析的表达式用OPAQUE节点保存原文与原因。
| 字段 | 含义 | 校验要求 |
|---|---|---|
| rule_id / revision_id | 规则及不可变修订 | 在相应命名空间唯一 |
| subject / entity_refs | 业务主题与对象 | 对象引用可解析 |
| scope | 环境、人群、渠道、版本范围 | UNKNOWN显式保存 |
| predicate | 条件树 | 操作符、类型、单位匹配 |
| effects | 拒绝、计算、路由、状态与副作用 | 顺序和条件可表达 |
| exceptions | 例外及核验状态 | 空集合与未知分开 |
| config_dependencies | 配置引用 | 绑定证据和作用范围 |
| evidence_ids | 支持或反驳证据 | 每个重要断言有证据 |
| derivation_kind / review_status / freshness / resolution_status | 来源方式、审阅结果、新鲜度和解析状态 | 四个权威字段分别保存,定义见第9节 |
| lifecycle(可选) | 旧客户端使用的兼容展示标签 | 仅由权威状态投影,不参与发布、查询或审阅判定 |
金额采用十进制字符串和币种,比例记录计算口径与舍入规则。用整数分还是小数元由源码证据确认。NULL、字段缺失、空字符串、空集合和零分别表示,避免把默认值带入不适用的分支。
三态求值用于未知配置或缺失字段。FALSE AND UNKNOWN为FALSE,TRUE AND UNKNOWN为UNKNOWN。UNKNOWN不自动解释为允许或禁止。范围不明的生产规则只能作为条件解释返回。
4 证据与断言
代码证据包含repo_id、commit_sha、path、symbol_id、start_line、end_line、content_hash和segment_id。行号只对指定Commit有效。清洗片段必须保存回到原文的映射,网页链接不能替代证据内容与版本。
配置证据包含命名空间、键、环境、快照版本、生效范围、采集时间和有效值来源。对于凭证配置,只保存类型和来源引用,模型不能读取明文值。
运行证据保存观察窗口、采样说明、部署关联和脱敏业务关联键。PRD和人工说明保存作者、修订、范围和审阅记录。外部文档中的业务意图与代码行为冲突时,两条断言并存,建立CONTRADICTS关系。
证据来源可分为静态提取、治理绑定、运行观察、文档说明和专家确认。候选程度不编码为一个通用百分比。规则核验状态、证据新鲜度和覆盖情况分别报告。
5 业务流程与状态迁移
流程步骤包含step_id、capability_ref、guard、input_bindings、outputs、completion和evidence_ids。步骤间关系区分SEQUENCE、PARALLEL、EVENT_TRIGGER、RETRY和COMPENSATE。分支声明互斥或可并存;缺少证据时保留UNKNOWN。
异步步骤至少区分消息提交、投递、消费处理和业务完成。标识订单号、业务单号等关联键的传递,不归档真实用户数据。失败路径要说明重试条件、幂等标识、死信或人工处理入口。
状态迁移记录业务实体、前状态、触发事件、守卫条件、后状态及动作。枚举中存在一个值,不证明所有迁移都能到达该值;数据库更新语句也不能单独证明端到端流程完成。持久状态变化还要关联执行条件、受影响行数、提交边界与失败出口。SQL调用成功、方法正常返回、事务已提交和其他系统已观察到结果分别取证;事务后来回滚时,不能保留其数据库写入为已完成迁移。
流程实例关联与流程模板分别建模。关联映射保存来源/目标对象类型、字段路径、转换、关联基数和成员确定依据;订单拆为多个履约单、多个退款合并进批次分别属于一对多或多对一,不能压成一个相等订单号。批次完成需要成员集合、分页或游标范围及截止条件;“所有已观察成员成功”不证明未观察成员不存在。时间窗口只能缩小候选,不单独确认关联。
外部交接步骤记录交接对象、请求或工单契约、责任边界、可见回执及恢复入口证据;人工受理与人工完成分别表达。只有交接契约时,可以确认当前系统把事项交出,外部内部处理仍未知。流程终点同时记录完成范围:本系统处理完成、交接完成或业务目标完成,不能以MANUAL_HANDOFF代替业务目标成功。
业务覆盖台账引用场景清单的固定修订,并将入口、分支、恢复、外部边界和完成条件逐项关联到流程修订和证据。台账声明范围及版本;COVERED表示对应义务已按检查要求映射,BLOCKED表示缺证据或分析失败,EXCLUDED要求范围排除理由与复核依据。对象没有出现在技术图中,不能成为排除理由。
台账采用业务覆盖合同0.1。ledger_revision固定台账修订,snapshot_id、inventory_revision与scope固定知识、清单及声明范围;obligations逐项引用期望来源、入口、流程和证据,unassigned_entry_refs保存反向对账缺口。inventory_reconciled只在来源清点及差异处理完成后为true。DECLARED_SCOPE_COMPLETE要求没有BLOCKED、未归属入口及未决项,且所有EXCLUDED均有原因、证据和审阅引用;这些检查不能证明未登记的企业业务不存在。排除审阅绑定台账修订、知识快照、义务ID、声明范围、排除理由及证据摘要;其他义务的review_ref不能借用。清单、范围或理由变化后重新审阅,完整性结果同时披露授权范围内的排除项,不能只显示一个“完整”标记。
6 审阅与纠错
用户提交纠错时关联对象修订、问题描述和证据。审阅人员可以接受、驳回或要求补充;接受后新增知识修订,不直接改写旧版本。新代码改变证据时,原审阅记录保留,但知识状态转为待刷新或待复核。
高风险业务优先核对条件、例外和金额计算。用于阅读的短摘要单独生成,不限制结构化规则的长度。生成摘要失败不能导致完整规则丢失。
7 模型验收例
| 输入情况 | 应保存或返回 | 错误表现 |
|---|---|---|
| 有券种条件和Ducc分支 | 两个条件及组合方式 | 只保存“禁止叠券” |
| 配置快照缺失 | UNKNOWN及取证需求 | 使用代码默认值声称当前生产状态 |
| 方法重载 | 不同参数签名 | 后扫描的方法覆盖前者 |
| Topic相同但eventType不同 | 多个事件与消费绑定 | 合成一个无条件流程 |
| 专家描述与代码冲突 | 两条断言及冲突关系 | 模型自行选择其中一个并隐藏分歧 |
8 规则执行语义
predicate描述一条规则的进入条件;effects按源码语义保存有序动作,每项包含effect_id、kind、target_ref、expression、guard、sequence、outcome、control_ref、exception_region_ref、evidence_ids。outcome区分CONTINUE、RETURN、THROW和ASYNC_SUBMIT。control_ref引用IR控制上下文,exception_region_ref引用异常处理区,无异常区时为null。异常捕获后继续执行、替换返回值和finally中的动作单独记录;“拒绝后不执行后续动作”由控制边表达,不能由展示顺序推测。
赋值和金额计算保留表达式树、输入引用、单位转换及舍入位置。例如“逐明细四舍五入后求和”与“求和后四舍五入”保存为不同规则。COMPUTE动作的expression必须非null。expression采用带类型的literal、ref、call树,literal值按声明类型校验;CALL允许零参数,operator限定为已解析的操作名或符号,未解析调用使用OPAQUE。暂不支持的计算保留原文表达式与OPAQUE原因。合同用于记录源码语义,查询端不执行源码表达式或模型生成程序。回答允许用已确认事实或显式假设,通过固定公式进行受控十进制说明性计算,并记录输入依据、公式、精度及结果;例如解释83.33减已确认30.00后为53.33。这不是实际可退额度查询,不授予退款资格,也不代替业务系统的并发校验或交易裁决。例外条目描述覆盖原规则的业务条件;Java异常出口属于执行语义,不混入业务例外列表。
条件树保存源码的求值顺序和短路关系,组合节点的evaluation_order为SHORT_CIRCUIT_LEFT_TO_RIGHT、EAGER_LEFT_TO_RIGHT或UNKNOWN。比较节点保留ref与value,value_type为STRING、BOOLEAN、INTEGER、DECIMAL或ENUM,金额或度量可带unit;IN的value是相同元素类型的数组。IS_NULL、IS_MISSING属于单目操作,不要求value。CONST保存布尔value及evidence_ids,用于已解析的恒真或恒假条件。GT、GE、LT、LE仅接受INTEGER或DECIMAL;枚举排序需要先解析为有依据的数值关系,否则保留OPAQUE。业务三态求值只用于无副作用的已解析条件;方法调用可能修改状态、抛异常或依赖当前时间时,不把条件重排或化简。条件的类型检查不能证明可达性,无法证明互斥的分支仍保留候选关系。跨步骤合并守卫前先核对值来源和读取时点:同一订单字段在两次读取之间可能已经变更,重试和异步回调中的同名字段不能视为同一个不可变值。证据只支持数据依赖时,不升级成值相等或执行先后关系。
9 断言范围与审阅失效
每条断言的scope引用服务版本集合、环境、业务时间区间和配置上下文。时间区间使用带时区的半开区间[valid_from, valid_to),采集时间另记observed_at。business_time.resolution为KNOWN时,两端必须是date-time;未知端点标为未知,不能解读成无限有效。源码规则可以只有代码范围;“当前生产成立”的断言必须有部署和配置范围依据。
核验信息分开保存derivation_kind、review_status、freshness、resolution_status:前者区分静态推导、模型解释和人工录入;review_status为UNREVIEWED、ACCEPTED或REJECTED;freshness为CURRENT、STALE或UNKNOWN;resolution_status为RESOLVED、AMBIGUOUS、UNRESOLVED或CONFLICT。Schema仍允许可选的 lifecycle 字段,供旧客户端展示候选、已审阅、冲突、待刷新或失效标签;它不是第二套权威状态,不能驱动发布、查询或审阅流程。完整结果始终携带四个权威字段,客户端不能因 lifecycle=REVIEWED 跳过新鲜度或冲突检查。例如review_status=ACCEPTED且freshness=STALE时,页面应同时显示“已审阅、待刷新”。兼容标签与权威字段不一致时,接收方记录不一致并按权威字段处理,不反向改写四个字段;RETIRED 标签也不能代替来源禁用或发布墓碑的实际检查。
人工确认绑定target_revision、evidence_digest、scope_digest、review_policy_version。来源或范围发生变化时,原确认仍适用于旧修订;新修订重新进入核验。人工补充与源码不一致时保留两条断言并建立冲突,不用人工描述覆盖代码证据。业务对象合并或拆分记录旧新ID映射、理由和适用版本,已发布快照继续解析到原身份。
10 合同与语义检查
entity_refs为必填字段,引用规则所属的业务对象。Schema检查字段类型、必填项、条件操作与字面值,不负责证明引用存在或源码语义正确。
服务端在接收及发布时检查同一规则内effect_id和sequence唯一,时间范围满足valid_from早于valid_to,以及entity_refs、control_ref、exception_region_ref、证据和implementation_ref均可在声明范围内解析。null异常区表示没有关联异常区,不能用于掩盖解析失败;失败范围进入unresolved。金额单位、控制出口及规则条件是否与原文相符仍需对应语义检查。
11 业务操作、决策凭据与多维状态
跨服务操作独立记录operation_id、operation_kind、business_key_refs、request_digest、idempotency_key_ref、result_state、evidence_ids。这是被分析业务的操作模型,不是知识服务提供的支付、扣券或退款执行接口。result_state区分NOT_STARTED、REQUESTED、UNKNOWN_RESULT、CONFIRMED和REJECTED;超时或连接中断只支持UNKNOWN_RESULT,不能推断远端执行失败。业务幂等需同时识别键范围、相同键参数冲突处理与状态提交边界,消息投递标识不能替代业务操作标识。
报价、风控或路由产生的决策凭据记录凭据ID、引用规则修订、输入范围、结果摘要及有效期。后续步骤若读取已持久凭据,就保留该历史引用,不因当前配置改变而重新解释为按新规则执行。金额来源区分原价、优惠、实付、已退款与可退金额;每个计算引用原字段、单位和适用交易,不能仅凭名称都是amount而串接。
长流程的完成状态可由多个实体和子操作共同决定,使用状态维度、各维度关联键及join条件表达。退款确认、券退回确认、订单终态更新是不同完成事实;没有等待或条件检查证据时不自动添加join。静态状态迁移说明“满足条件时允许迁移”,运行实例已迁移则需要对应对象、版本、时间和结果证据。单个运行观察不能把整个流程升级为已验证。
12 分摊、支付实收与退款权益
金额事实使用amount、currency、scale、amount_kind、basis_ref,amount为十进制字符串;amount_kind区分原价、优惠分摊、实收、已确认退款和在途占用。basis_ref关联分摊凭据或资金事实,不能只记录一个没有来源的amount。相同币种也不代表金额可以相加:订单采纳实收、重复实收和优惠权益属于不同口径。
分摊凭据记录allocation_revision_id、allocation_policy_revision、scope_ref、line_allocations、rounding_mode、remainder_order、evidence_ids。每行保留line_id、子单归属、优惠适用范围、原价、优惠分摊与现金权益。金额精度、舍入位置和余分排序均来自实现或明确政策;不能每次部分退款重新按当前剩余行做比例分配。分单改变履约归属不自动改变原金额分摊,确有重分摊时产生新凭据并显式记录旧新映射。
支付对象分为payment_intent、payment_attempt与capture。一次意图可有多个尝试,尝试超时不证明未扣款;每个成功实收由capture_id独立标识。accepted_capture_refs记录订单采纳哪些实收及对应权益,其他成功capture仍是资金事实,但不能重复增加商品权益。晚到成功不能覆盖已有capture或把两笔270.00合成为一笔订单540.00。
退款分别记录refund_intent_id、refund_operation_id、capture_id、target_scope、allocation_revision_id、requested_amount、confirmed_amount、reserved_amount、result_state、observation_ref。refund_intent_id标识经业务接受的退款诉求,refund_operation_id标识一次可重试执行;重试、消息重放和不同补偿协调方都不新建同一意图。两次合法的部分退款可以具有不同意图,但必须共享相同权益限额。业务意图的生成来源、目标范围和参数摘要需要证据,不能用自然语言相似度判定去重。
对于同一目标权益,已确认退款C、在途占用H及新申请N须满足C + H + N ≤ 原现金权益;同一capture的累计确认和占用也须满足其实际可退上限。占用转确认是同一操作的状态迁移,不同时计入C和H。拒绝后的释放需要证据证明该操作不再可能成功;超时、消息丢失和协调进程退出不满足这个条件。额度不是一条不随时间变化的规则,它是指定资金观察范围下的事实计算。
退券权益独立记录原核销引用、政策修订、适用行集合、触发条件及已执行恢复操作。本例L1退款完成才可能满足退券政策,L2退款和重复实收C1返还都不因此获得退券权。相同退券权益只能被确认一次;新compensation_id不产生第二份权益。
完成状态使用completion_target.kind区分退款操作、行权益、子单补偿和订单整体,completion_target.target_refs定位对应目标;完成条件另引用所需操作及证据。某退款确认只证明该操作完成,L1关闭不证明S1或O2关闭。这些字段描述被分析业务的事实与规则,不构成知识服务的资金写接口。
流程与覆盖
1 任务划分
仓库内先按Maven模块固定源码和classpath。方法摘要按调用依赖计算,互相递归的方法作为一组迭代,做法见调用与复杂语法。入口任务引用可达的方法摘要,同一公共方法不因被多个入口调用而重复提取;入口各自的条件和调用参数另行保留。
业务模块指领域人员确认的入口分组,例如“优惠报价”或“订单补偿”;Maven模块、包目录和微服务另按技术结构登记。分组保存入口引用、适用范围及确认记录;分组未确认时先返回入口规则,流程组装不采用模型猜测的分组。分组只建立入口与已有规则的引用,不产生一份可以单独修改的“模块规则”。跨服务流程按契约、事件和对象关联连接步骤。调用方很多时分批读取其规则,保留每条规则ID、入口参数与条件。
| 任务类型 | 输入 | 输出 |
|---|---|---|
| L1方法摘要 | 固定源码、实际依赖、调用及字段关系 | 可复用的参数、返回值、副作用和分支摘要,不是正式业务规则 |
| L2入口规则提取 | 一个入口实现、可达方法摘要、外层条件与调用参数 | 入口对应的正式规则候选、分支映射、证据及缺口 |
| L2任务内分片(按需) | 当前入口的一组可达分支及共享输入清单 | 分片候选;由入口任务去重和核对后提交,不独立形成模块规则 |
| 入口卡片 | 契约、可达规则、副作用 | L2阅读视图及对象引用 |
| 服务画像 | 能力、入口、实体和依赖 | L3职责、边界及覆盖说明 |
| 业务流程 | 事件、能力、关联键与运行证据 | 流程候选、失败和补偿路径 |
CodeWiki按依赖图划分模块,再由下层模块生成上层文档。这里采用分层阅读视图,规则条件、对象关联和完成条件仍保存为独立对象,供流程组装和覆盖检查读取。
2 JoyAI调用协议
模型适配层按任务记录model_id、prompt_version、input_digest、output_schema_version与generation_parameters。输入只包含授权范围内的必要片段;固定系统约束不能被源码注释覆盖。
预算分别控制输入、输出、并发和重试。输入超限前先按规则ID和引用去重,再分段或分批。压缩必须保留条件、异常和依赖,截断发生时输出PARTIAL。无法满足Schema的生成结果进入失败队列,不继续生成上层画像。
JoyAI是否支持严格结构输出、Embedding和重排以内部接口实测为准。缺少严格结构输出时做本地Schema校验;缺少重排模型时保留融合排序,并在评测中比较差异。模型版本更换产生新提取版本,不覆盖旧结果。
3 检查与审阅
结构检查验证必填字段、操作符、类型和引用。实体检查确认表、契约和配置名有来源。语义检查以分支台账核对规则引用和遗漏,核对否定、数值、单位与例外;能够由类型、表达式与引用比较的项目确定性执行,剩余语义交给复核。规则冲突分别检查相同范围和不同版本,不能把不同灰度条件误报为逻辑矛盾。
排除审阅逐项验证绑定的台账修订、义务、范围和来源摘要。审阅记录必须与本次排除项匹配。范围或期望集合变化后重新审阅。报告列出获批排除项及适用范围,覆盖结论也限定在该范围内。
自动检查后,金额计算、状态迁移和跨服务补偿等对象仍需优先进行人工语义审阅。检查器将失败分类为可纠错生成、证据不足、解析缺失或人工语义复核,分别处理。
| 检查失败 | 下一步 | 发布限制 |
|---|---|---|
| JSON损坏或字段不合法 | 有限纠错重试,保留原响应 | 对象不得进入正式读模型 |
| 引用了无证据实体 | 回查IR或拒收断言 | 不允许靠替换名称掩盖错误 |
| 条件和原文矛盾 | 重提取并加入语义复核 | 相关规则不升级为已审阅 |
| 证据缺失 | 回补采集或保留未知 | 不声称当前线上行为 |
| 部分对象失败 | 标记受影响能力与流程 | 仅在覆盖声明完整时发布允许的部分 |
4 版本状态
构建状态为CREATED、COLLECTING、ANALYZING、EXTRACTING、VALIDATING、INDEXING、READY、PUBLISHED,失败进入FAILED,主动取消进入CANCELLED。任务可以从失败阶段重试,但产物只追加新attempt,不原地篡改已发布内容。
PUBLISHED表示版本已开放查询。规则是否经过审阅另有状态;发布清单同时列出候选对象、未解析范围与检查结果。
5 JED与Vearch发布协议
- 在JED事务内保存不可变知识修订、发布草稿和outbox事件。
- outbox投递器发送JMQ消息,Worker按event_id和目标版本幂等构建Vearch文档。
- 检查目标代际的实体数、文档数、删除标记及过滤可见性;只收到写入成功响应不能视为查询可见。
- 生成READY发布清单,绑定graph_generation、index_generation与embedding_version。
- 使用比较并交换更新范围内active_release指针。在线请求在开始时固定该指针,后续工具调用复用同一发布版本。
Vearch部署是否支持所需的标量过滤和可见性检查需验证。若原生能力不满足,按独立Space或其它内网允许的隔离方式管理索引代际。JED与Vearch不假设跨库事务。
6 回滚与存储保留
回滚切换到仍可用的旧发布清单,不在原版本中删除新文档。旧索引和证据需保留到在途查询结束及保留策略允许清理。具体保留周期由内网规范和成本测量决定。
引用旧快照的请求若无法继续服务,返回VERSION_UNAVAILABLE,不静默切换当前版本。模型重新生成的回答会记录所用发布版本,便于复核当时的依据。
7 从技术关系组装业务流程
场景清单怎样进入分析
业务负责人先从PRD、操作流程、故障处理记录和业务人员确认中整理场景清单。分析器另行发现代码入口,两份输入分别保存;不能用已经扫描到的路径反过来定义全部应覆盖业务。每次组装引用场景清单的固定修订,至少包含下列内容。
| 输入项 | 需要填写什么 | 订单补偿示例 |
|---|---|---|
| 场景与负责人 | scenario_ref、业务负责人引用及确认记录 | 履约拒绝后的订单补偿;订单域负责人确认 |
| 资料修订 | PRD、操作记录或确认材料的固定修订与段落、行定位 | 订单补偿设计某修订中的“超时恢复”段落 |
| 触发与对象 | 触发事件、前置状态、业务对象及关联标识 | 履约永久拒绝;关联订单、原支付及券核销记录 |
| 正常路径 | 该场景预期完成的动作及顺序约束 | 已确认支付、已核销券时,分别处理退款与退券 |
| 异常路径 | 拒绝、乱序、超时或部分成功时要检查的分支 | 退款超时仍保留原操作;退款确认但退券失败时保持部分补偿 |
| 恢复与外部交接 | 重试、查询、对账或人工入口,以及交接后的返回条件 | 沿原退款操作查询;退券失败由关联原补偿的任务重试 |
| 完成条件 | 要确认哪些结果、写入哪些状态;完成针对哪个对象 | 退款确认、退券确认及订单终态写入均成立,才完成本例订单补偿 |
资料尚未确认某条恢复路径时,清单保留这项待核对要求,不补写假定的入口名称。业务负责人确认需要检查的路径与完成条件,研发确认对应入口、对象映射和实现证据。两者意见不一致时记录差异,不能直接把该项从清单移除。
覆盖台账沿用 scenario_ref 和 expected_source_refs:每个核对项的expected_source_refs指向上述固定修订的归档材料及具体来源片段,负责人和确认记录保存在该来源记录中。正常及异常分支、恢复、外部交接和完成条件分别对应现有obligations中的BRANCH、RECOVERY、EXTERNAL_BOUNDARY和COMPLETION项,触发入口使用ENTRY项。扫描发现的入口写入entry_refs,已还原步骤写入flow_refs,实现依据写入evidence_refs;缺少映射的核对项保持BLOCKED,未匹配场景的入口进入unassigned_entry_refs。
从场景入口展开步骤
业务流程以“触发事件、业务对象、完成条件”为边界,例如订单提交到履约单创建。提取任务先固定入口和对象标识,再沿控制、调用、字段及事件关系展开;服务画像只辅助命名与分组,不作为流程连接依据。
- 从入口提取校验、决策、计算、状态写入和外部副作用,记录每个动作的前置条件与异常出口。
- 沿参数赋值、返回值、持久化和消息字段追踪业务标识。保存
source_field、target_field、transform、evidence_ids;名称相似但没有映射证据时停止标识传播。 - 将相邻技术动作组合为能力步骤。步骤保留全部原始动作ID与顺序,公共工具调用可以折叠显示,但其影响业务结论的条件和异常不得折叠丢失。
- 按已对齐的契约和事件连接跨服务步骤。RPC返回只代表调用完成;消息发送成功只代表提交阶段。业务完成必须指向相应状态写入、回执或可核对的完成事件。
- 分别形成正常、拒绝、重试与补偿路径。找不到补偿实现时标为未发现,不根据方法名或业务常识补写。
流程边记录from_step、to_step、edge_type、guard、correlation_mapping、version_scope、evidence_ids、resolution_status。步骤的技术动作引用明确implementation_ref,流程展开按实现范围选择边,禁止用裸stable_id回退读取某个最新修订。每条路径累计适用条件;互斥配置的边不能串联。异步关系缺少关联键映射时可展示候选上下游,但不宣称已还原同一业务实例的执行过程。
同一逻辑规则在多个入口重复执行时,先保存各实现修订,再建立业务规则的实现集合。只有条件、动作、单位和适用范围一致且有复核记录时才合并业务身份;重复代码和相似摘要不足以合并。发生分歧时保留多实现差异,查询按入口选择。
8 发布检查的最小条件
每次发布绑定validation_policy_version和检查报告。缺少来源哈希、存在悬空引用、无法按member_kind与implementation_scope解析成员版本、权限标签缺失或索引代际不一致时,阻止该发布生效。候选断言不因发布自动升级为已审阅。
某应用失败但其他结果可发布时,发布清单逐应用声明成功输入、沿用旧修订和缺失范围。沿用旧知识必须标出原Commit及待刷新状态;引用失败应用的流程返回部分覆盖。新部署已替换旧版本时,不得把沿用规则用于断言当前生产行为。
语义审阅按对象进行。涉及金额或补偿的候选可以供调查读取,面向业务的结论必须展示未审阅状态;与证据冲突的断言仅用于呈现冲突,不进入无条件结论。质量阈值由标注集确定,结构和引用检查不依赖阈值豁免。
9 提取任务的输入输出合同
Worker输入包含task_id、task_kind、input_digest、source_scope、ir_refs、branch_ledger_refs、dependency_summary_refs、allowed_entity_ids、output_schema_version。源码片段带外层条件与符号位置,依赖摘要带原始证据引用;模型遇到未知调用时只能返回取证需求,不能以常识补写被调方法行为。
输出包含assertions、branch_mappings、entity_candidates、evidence_requests、unresolved。branch_mappings记录台账项到规则条件、动作或异常出口的映射。evidence_requests声明需要的符号、配置或关系,服务端校验范围后读取,再创建有新输入哈希的子任务;模型不直接访问任意仓库地址。
实体候选先按已有标识匹配,再提交别名或新概念建议。生成器不能创建一个没有定义和来源的全局业务实体。多次生成的结果按语义键、输入与规范化内容哈希去重;出现不同条件时保留冲突候选,不能用后一次输出覆盖前一次。
上层组合使用结构化断言和原始证据引用,不以入口卡片或服务摘要作为唯一输入。某子任务失败时,上层结果保留缺口及影响对象,禁止将缺失子规则解释为没有限制。模型重试只解决格式和可定位的提取错误,重复产生无来源条件时终止该任务并进入复核。
构建计划与输入清单
跨应用任务按固定计划组合,不按结果到达顺序拼接。内部记录分为三种,完整O1例子见四层构建任务与产物。这些记录用于构建编排,不增加查询工具。
| 记录 | 固定内容 | 使用方式 |
|---|---|---|
| 构建计划 | build_id、plan_revision、baseline_snapshot_id、scope、sources、tasks | sources逐项固定来源修订与摘要;tasks声明阶段、目标、策略版本和依赖槽位 |
| 任务输入清单 | manifest_id、plan_revision、task_id、source_set_digest、strategy_revision、source_refs、bindings、unresolved | bindings逐槽位固定上游生产任务、attempt、fence、result_id、结果摘要、实际产物及诊断;input_digest取整份清单的规范化摘要 |
| 任务结果清单 | result_id、plan_revision、producer、target_ref、input_manifest_ref、input_digest、status、artifacts、diagnostics、inherited_unresolved | producer固定task_id、attempt与fence;artifacts逐项列产物身份、类型及内容摘要;结果一经提交不可变 |
计划中的依赖槽位包含slot、producer_task_id、expected_target、required_output_kinds和on_failure。on_failure为BLOCK或PARTIAL:前者缺少合格输入就不启动该任务,后者允许保留诊断、生成已解析范围。此选择在计划中固定,Worker不能遇错后自行放宽。L2以入口及可达分析范围作为任务目标;L3以应用实现为目标;L4以场景修订为目标。任务图不得有调度循环,方法内部递归仍由L1摘要迭代处理。
计划中的task_id标识预期节点,执行任务键由plan_revision、task_id与input_digest共同确定。manifest_id不可复用于不同内容;样例用规范化内容摘要生成身份。输入变化产生不同执行任务,同一输入的基础设施重试才增加attempt。producer及结果输入摘要共同定位一次实际执行,不能只凭task_id读取最近一次结果。
任务结果status为COMPLETE、PARTIAL或FAILED。COMPLETE只表示本任务声明的处理范围已完成,不表示规则已经人工确认;候选、冲突、待刷新等状态随对象及inherited_unresolved继续传递。FAILED不得携带可消费产物,必须提供诊断。PARTIAL必须给出未完成范围;合法的局部产物仍按类型和引用检查,格式损坏的模型输出不能伪装为局部规则。
调用上下文怎样固定
构建计划为每个L2任务通过现有source_refs引用一条L2_ANALYSIS_SELECTION来源。该来源固定revision_ref、content_digest和以下内容,由计划编排器根据本次要求分析的入口与调用范围选择;Worker不能自行换成同一IR包里的另一调用方。
首次构建尚无IR记录时先完成L1,再按下述新计划修订与复用登记方式固定选择记录和已有L1产物,放行L2。不能提前猜测包内记录ID,也不能在原计划中补写来源。O1任务图展示选择已固定后的计划。
| 选择记录字段 | 内容与检查 |
|---|---|
| mode | ENTRY_ONLY只分析入口自身;CALL_CONTEXT代入指定调用方前提。两种模式都须显式填写 |
| entry_ref、entry_implementation_ref | 前者以scan_id + record_id定位IR入口记录,后者固定该记录的stable_id、implementation_scope和revision_id;实现范围须与任务target_ref一致 |
| caller_entry_ref | CALL_CONTEXT必填,定位调用方入口记录;调用方实现与版本由该记录读取 |
| call_path_refs | CALL_CONTEXT必填,按调用顺序引用从调用方入口到目标入口的调用点关系;每个调用点保留其参数映射,不能只指定一个同名方法 |
| guard_refs、parameter_mapping_refs | CALL_CONTEXT显式列出所选外层条件与实参映射的IR记录引用;无外层守卫时guard_refs可为空,不能用空数组代替未找到的条件 |
ENTRY_ONLY不携带调用方字段。CALL_CONTEXT要求调用路径和参数映射非空。所有IR引用均须位于本任务依赖槽位实际固定的包中;记录须存在、类型匹配,且调用路径、守卫和参数映射相互对应。调用或条件尚未解析时保留缺项,不能猜一组上下文运行。缺少选择记录、目标不符或必要引用不可定位时,不生成可执行输入清单。
选择记录的内容与摘要一同进入任务输入清单。切换调用方、调用点或所选守卫,即使入口和IR包未变,也要创建新的选择修订和输入清单;不得复用原上下文的规则结果。L2结果沿原有input_manifest_ref保留这次选择,L3、L4读取规则时同时核对其调用适用范围,不把某调用方的前提推广到目标接口的全部调用方。
IR局部引用只用于读取构建产物。发布对象仍通过记录中的implementation_ref定位,不能将record_id直接写成发布对象标识。O1样例中的退款选择引用订单履约拒绝入口、退款调用点、支付确认与永久拒绝条件,以及原实付到退款参数的映射;退券和汇合选择为ENTRY_ONLY。样例IR附有这些引用的合成记录索引,仅用于核对任务交接,不代表已经运行Java分析。
逐项放行与失败传播
调度器为任务取得每个依赖槽位的已提交结果,按以下次序检查:
- 核对生产任务属于同一计划,目标等于expected_target;再核对结果登记中的attempt、fence及提交状态。阶段结果与下一阶段outbox仍按原子提交约束保存。
- 核对结果的input_digest对应生产任务的固定输入清单,所需产物类型齐全、内容摘要一致、引用范围与权限有效。其他计划中同名或同类型的产物不能补进来。
- 上游仍在排队或运行时返回WAITING,不把暂未完成改写成“没有规则”。上游取消或预算耗尽要先保存明确失败或部分结果,再执行该槽位的on_failure策略。
- BLOCK槽位只接受COMPLETE结果;PARTIAL槽位可接受合法的局部产物或失败诊断。采用失败诊断时不生成该依赖对应的确定规则、流程边或完成条件;缺口保留生产任务、受影响目标及原因,并传播到下游覆盖结果。
- 所有槽位都有明确结果且符合策略后,保存不可变输入清单,再领取执行任务。每个槽位和来源摘要都参与input_digest;没有产物的失败槽位也参与,不能当作空依赖删除。
O1中,订单、支付和券的L1任务先并行执行;退款、退券、完成规则分别绑定所需IR。支付画像读取支付入口、退款规则和已确认分组;补偿流程读取三个应用的关系、三条规则和场景义务,两者分别放行。退券规则失败时,支付画像仍可构建;补偿流程只能生成带退券缺口的部分结果。入口卡片失败不影响原规则的可用性,也不是L4的失败原因。
输入变化、重试与候选发布
基础设施重试沿用原输入清单,新attempt和fence按既有任务规则递增;迟到的旧attempt不得登记新结果。下游已经固定的result_id不会被上游后续成功结果替换。需要消费补齐结果时,生成新的输入清单和下游任务;旧结果继续解释当时使用了什么资料。
补读新证据、新增消费者或改变范围时,生成新的计划修订或明确的子计划,重新列出来源与依赖。复用已有产物也要在新计划中登记其固定修订、来源摘要与适用范围,不能读取其他计划的活动结果指针。新的业务输入不使用原任务身份重试。
候选发布固定选用的结果清单和产物修订。发布器逐项核对产物引用属于该候选集合,诊断及沿用旧修订的原因进入覆盖和新鲜度记录。READY之后补到一个成功结果,需要创建新候选修订,不能修改旧清单。构建计划、产物完整性和业务语义审阅分别检查,不能以任务COMPLETE代替规则ACCEPTED。
10 流程候选的相容性与终止条件
每次组装从一个明确触发点出发,使用队列保存step_ref、business_entity_ref、correlation_mapping、accumulated_scope、path_guard。扩展一条边前检查契约版本、业务标识映射和适用范围;已确认不相容的边不连接,未知相容性保留为候选并说明缺失证据。
路径守卫核对只使用已解析的无副作用条件及可证明相同的输入值。相同来源和值版本的常量、枚举及数值区间出现矛盾时,拒绝该组合并保留矛盾依据。例如同一未改变的orderType不能在一条同步路径中同时满足VIRTUAL与PHYSICAL。未发现矛盾只表示尚未排除该候选,不能证明路径可执行;OPAQUE调用、共享可变对象、外部状态或时间函数使相容性保持未知。跨重试、消息和再次查库时分开值版本;status先为PENDING后为CONFIRMED不是同一时点的矛盾,不得误删合法恢复路径。当前设计不承诺对任意Java表达式完成可满足性求解。
生产场景逐步骤核对动作发生时的部署、配置和输入版本。同一步骤使用的部署与配置范围需相容;缺少动作时点或生效依据时,保留历史或代码层候选。整条业务可能跨越发布窗口,不要求报价、退款与恢复任务同时部署过。跨窗口连接还要核对持久化对象、消息结构、字段转换及兼容策略:旧报价沿用原凭据,恢复任务按执行时实现解释,消息分别保留发送与消费时版本。只有部署时间前后相接,仍不足以证明两个步骤属于同一次业务。
并发步骤只有在等待、汇合、回调或业务完成条件有证据时才建立join。共享订单号不证明先后关系,同一trace也不能单独证明业务因果。重试回到同一处理步骤时保留循环边、尝试条件和幂等键;补偿是新的动作与结果,不等于原事务回滚。
展开在业务完成、明确拒绝、可识别人工处理入口、未知边界或预算耗尽时终止,分别记录COMPLETED、REJECTED、MANUAL_HANDOFF、UNRESOLVED、TRUNCATED。人工处理入口也要有任务或流程证据。循环检测按步骤、关联映射和范围进行,检测到环只停止重复展开,不删除环边。
提交边界参与完成条件检查。数据库更新后外层抛异常且回滚时,流程不能继续标记数据库状态已生效;条件更新0行则沿未满足守卫或竞争失败路径展开。独立事务、已发出的远程副作用和本地事务分别判断,不把一次回滚统一涂抹为“所有操作均未执行”。提交后监听器只注册但未确认执行时,保留等待或未解析节点,不能直接跨到下游完成。
发布前检查流程的每条边均有来源,每个确定的完成节点均有完成证据,每个未解析终点均进入覆盖说明。流程正常路径通过,不会自动使异常、重试与补偿路径通过;各路径族分别报告检查结果。
单入口展开结束后,还需按同一业务场景合并独立触发入口:超时扫描、对账修复、回调重试、运营工单与重放任务可能没有从原在线入口出发的调用边。只有选择条件、对象关联和恢复守卫均有证据时才接回流程;共同写一张表或读取同一订单号只产生候选。定时到期使用业务截止条件和时间语义,不把扫描任务的调度频率误写成业务有效期。
发布检查将领域场景期望与入口发现结果做双向对账,再逐项核对覆盖台账。未归属入口、未解析恢复条件、未知批次成员范围和无完成证据都使对应场景保持PARTIAL。DECLARED_SCOPE_COMPLETE表示指定范围内的义务已核对完成,结果同时记录范围、版本、来源和审阅记录。该状态不用于判断生产实例是否执行,也不覆盖未登记的企业业务。外部系统负责的步骤只检查声明的交接条件,内部过程未知时仍标为未还原。
流程复核人员确认业务目标、入口归属、路径义务及排除项,技术复核人员确认映射、守卫、契约与版本证据。两类决定分别留存;未形成一致判断的义务保持BLOCKED。只读问答、Agent和IDE均读取同一覆盖台账,不因页面隐藏候选节点而将流程升为完整。
11 乱序、补偿汇合与实例证据
流程组合先区分静态允许路径、声明的运行条件和已观察业务实例。没有运行证据时可以解释“退款与退券均确认后才能完成”,不能回答某订单已经完成。实例证据必须同时匹配业务关联键、操作标识、结果状态及适用版本;相同order_id或同一trace不足以证明退款和退券属于同一次补偿。
OpenTelemetry消息链路约定用链接关联消息创建与消费上下文,也允许一个消费Span处理一批消息。本设计据此把运行链路用于发现候选调用,再核对逐条业务关联;是否能从UMP取得这些字段仍需内部核验。
乱序事件进入尚未满足前置条件的步骤时,保留等待核验状态及恢复触发。恢复触发可能来自后续事件、状态查询或对账任务,必须有实现证据。未知前置事实不转换为false,也不因后来收到某事件就倒推出此前所有步骤成功。
恢复检查还要覆盖两个处理器同时执行的情况。拒绝处理器先读到支付未知,支付处理器随后确认支付并检查“没有待处理拒绝”,最后拒绝处理器才保存等待标记;此时只等下一条支付消息,可能永远无人重评。分析器需找到同一订单事实的协调方式,以及事实写入与重新评估安排的提交关系。例如,在同一订单事务中保存事实、递增状态修订并写入持久待办;恢复任务按该修订读取事实,提交前再检查修订,遇到竞争则重新评估。消息只负责唤醒,待办扫描负责补上消息丢失或进程中断。也可采用有相同可恢复保证的其他实现,但仅有“重试方法”不足以证明这一点。
缺少协调或持久恢复依据时,记录 RECOVERY_WAKEUP_UNPROVEN,对应恢复义务保持BLOCKED。验收分别交错事实读取、事实写入、等待标记写入和重评提交,不能只交换两条完整消息的顺序。已确认永久拒绝后,重评不得再创建该履约操作的正常派发;拒绝前已经发生的派发则保留为历史事实。
补偿分解为各自可重试的业务操作,分别保存请求、结果未知、成功和拒绝路径。RPC超时后若远端可能已接收,流程保留UNKNOWN_RESULT并沿原业务幂等键取证;没有状态查询或重试证据时终止为UNRESOLVED,不生成新操作补齐流程。消息重复是否重复副作用,由业务幂等和事务边界决定,不由消费次数决定。
完成汇合读取每个子操作的确认事实,再检查业务总状态写入是否成功。退款完成但退券失败只能支持部分补偿;数据库写入失败后的恢复也必须有路径。对账、人工处理或永久失败没有实现证据时保留缺口,不把所有异常路径自动连到完成节点。
退款回执先与原操作核对,再参与完成判断。至少核对原支付或capture、退款操作、目标权益、金额、币种及终态语义;事件名称含Confirmed并不能代替这些检查。O1的单次全额退款要求原操作为70.00 CNY,同一支付及补偿编号下的30.00回执仍不能证明70.00已退。字段缺失或核验实现未取得时保留未知;已取得的回执与原操作不符时记录冲突。若实际源码没有检查,保存这一实现事实及风险,不能替源码补出校验后宣称已防护。不同部分退款可以有各自金额,核对对象是各自原操作,不能统一要求等于整单实付。
业务恢复预算耗尽与知识分析预算耗尽分别表达。前者可使被分析业务进入MANUAL_REQUIRED等状态,后者只导致知识结果TRUNCATED。原幂等请求返回已接收记录并不等于最终结果;若实现以回执推进,流程必须保留等待回执节点。待处理事件后续满足条件时,还要解析恢复分支是否抑制原正常路径,例如永久拒绝待核验后进入补偿,不再派发履约。
12 部分退款与并发补偿的组装
同一订单下的路径按capture_id、refund_intent_id、refund_operation_id、target_scope、allocation_revision_id区分。共享order_id只建立归属关系,不将不同实收、不同退款意图或不同行权益合并成同一条补偿。重复实收返还与商品退款使用不同业务原因及目标范围,即使都调用同一个退款接口也分别解释。
并发安全断言需要组合额度读取、占用提交、重复意图识别和结果入账四类证据。逐个服务都存在幂等函数不证明跨协调方不会超退。发现多个合法部分退款并行时,同时核对行权益和capture限额;若两处限额不能共同约束提交,保留REFUND_CAPACITY_ATOMICITY_UNKNOWN,不升级为已确认防护。
对UNKNOWN_RESULT保留原refund_operation_id和占用,不将其自动归入可退余额。迟到结果沿原操作推进,确认将占用转为已退款,重复确认不再次累加。若已有释放证据又收到同一操作成功,知识中记录矛盾和实际处理分支,不能删除其中一条事实来制造一致状态。
流程按目标范围分别判断完成:退款操作完成、L1现金权益退尽、券恢复、S1补偿完成以及O2整体完成各有条件。本场景S2继续履约,不能因S1所有退款结束而输出订单整体关闭。没有枚举目标集合或不知道哪些子单仍在运行时,整体完成判定保留未知。
规则快照固定代码和政策,资金观察另有观察范围。生成“可退53.33”前必须同时取得原权益83.33、已确认30.00和该范围在途占用;只给一个observed_at而未说明资金记录是否来自一致观察,也不能证明该额度仍可用。缺少资金事实时保留条件式,不调用业务写接口验证推测。
检索问答
模型参与问题拆解与解释;实体解析、权限、版本和分页由查询服务执行。
1 查询路径
| 问题 | 首选入口 | 后续取证 |
|---|---|---|
| 某规则为什么限制 | 概念、规则和异常码 | 条件、配置及原文 |
| 一项业务如何完成 | 流程、实体和事件 | 能力、契约、失败和补偿 |
| 某符号在哪里实现 | 精确符号和类型索引 | 绑定、实现与调用者 |
| 修改会影响谁 | 目标和变更类型 | 字段使用、行为依赖及消费关系 |
| 新需求应改哪里 | 能力、规则、流程并行召回 | 入口、冲突及影响路径 |
同步问答使用问答请求合同及请求示例:request_id、question、scope和assumptions必填,snapshot_id与budget可选。assumptions只是明确给定的条件,不接受客户端填写证据身份。问题中的环境、时间及业务对象仍由question_frame解析,不能用请求文本越过scope授权;多轮省略快照时只表示新查询,不能静默续用旧轮次。
问题先区分单条规则解释、业务路径说明、完整业务清点和改动影响分析。“完整业务”必须给出业务对象、触发集合、目标终态及明确的外部交接边界;按单个入口找到一条成功路径不足以回答完整业务。用户可以限定环境、服务、业务域和版本。服务端先解析可访问范围,再固定知识快照。问题存在歧义且会改变业务结论时,返回待确认项;不影响查找的歧义可以列出多种条件回答。
GraphRAG分别处理具体实体问题与资料整体问题。这里将规则取证和业务清点分开;清点结束由入口与场景台账判定,不使用社区摘要数量作为完成条件。
2 召回和排序
精确符号、词项和向量各自产生候选。业务术语扩展使用带领域范围的别名;扩展词保留原始问题,避免同义词把查询带入其它业务域。L3画像用于提示相关服务,不能硬过滤所有规则与流程候选。
排名融合按候选位置计算,不直接相加余弦与全文分数。初始实验可以使用RRF,rank从1开始,缺席列表不贡献分数;k、权重与候选窗口在标注集上比较。RRF的排名融合定义可参考Elastic官方说明,这里借用算法说明,不引入Elasticsearch作为部署要求。
候选先按entity_id + revision_id去重。同一规则的多个切片只保留最佳名次,其余切片作为证据候选,防止长文档占据结果。融合后以固定排序键fusion_score DESC、entity_id ASC、revision_id ASC消除并列抖动;排序配置和候选窗口随query_id固定。已解析的精确对象ID直接读取对象,不用语义排名替代身份定位。
权限与发布成员过滤先于召回候选进入模型。Vearch无法表达所需过滤时,改用授权分区或关闭该次向量召回;全库Top-K后再过滤只能作为二次防护,不能声称召回完整。词项召回由内部允许的全文组件提供适配;尚未确认组件时,使用JED中的规范化名称、别名、符号及倒排词项表作受限检索,并标明长文本检索能力缺失。
排序还考虑范围匹配、证据版本、解析状态和命中位置。候选业务知识与已审阅结果都可以出现,但要分别标识。重排模型不可用时回退到已验证的融合策略,不能调用外部模型。
3 关系展开
关系查询按入口、调用点、字段和事件限定范围。每次展开返回已知边数、展示数、未解析项和next_cursor。总量只统计有权限范围;不通过数字暗示不可访问服务数量。
对于公共服务的高扇出,先返回按依赖类型分组的清单,再根据变更内容选择证据。上下文预算只影响本次展示,不能修改持久关系。全量清点采用分页或异步任务,并明确是否结束。
搜索分页仅遍历本次固定候选集,不能标为全库清点完成。关系清点按授权发布成员逐批枚举,保存访问集合与未展开前沿;enumeration_complete=true要求前沿为空且没有未解析目标或失败分区。客户端读完搜索页只代表候选集结束。
4 变更分类
| 变更类型 | 分析重点 | 不能省略的检查 |
|---|---|---|
| 内部逻辑 | 条件、错误、默认值和副作用 | 签名不变时的行为兼容性 |
| DTO或消息字段 | 赋值、序列化、读取和校验 | 缺失值、旧消费方与回放 |
| 枚举或状态 | 条件判断、switch、存储及展示 | 未处理状态和非法迁移 |
| 数据表字段 | 读写SQL、PO映射和计算 | 分片、索引与跨库访问 |
| Ducc与规则配置 | 作用范围、默认值和刷新 | 灰度、缓存及配置失效 |
请求change_type取LOGIC、FIELD、STATE、TABLE_FIELD或CONFIG,依次对应内部逻辑、DTO或消息字段、枚举或状态、表字段及配置变更。影响结果包含target、impact_type、paths、evidence_refs、version_scope,未决项放入外层unresolved。DEPENDENCY_ONLY表示存在关系;POTENTIAL表示路径可能受影响;SUPPORTED表示已找到与变更有关的使用点。SUPPORTED仍不是运行验证完成。
遍历状态为(entity_revision、callsite、field_path、direction、guard),不能只按entity_id去重,否则同一方法的不同字段和条件会被吞并。字段变化沿参数映射、序列化、读取点和控制依赖传播;遇到无法解析的变换保留POTENTIAL并记录中断点。方法行为变化向调用者传播时读取返回值使用、异常分支和副作用依赖,不将所有调用者升级为SUPPORTED。
路径保存有序关系修订,合并相同目标时保留不同条件路径与中断原因。循环以访问状态去重并保留回边;达到节点或路径上限时记录未展开前沿,后续分页继续同一遍历状态。不存在路径只说明当前图未找到,不能排除未解析反射或未接入消费方。
5 问答生成和证据展示
每条主要结论引用规则修订及证据,回答区分代码实现、生产配置和运行观察。流程图中候选边使用不同线型;同一条路径上的多个版本不能拼成一个假想的确定流程。
历史订单跨版本时,按实际动作分别读取原报价与后续恢复的依据。问答结果以knowledge_contexts列出所用固定快照和引用,具体读取及授权规则见历史订单的跨版本取证。各动作按自己的时点解释,不能把新恢复规则改写成原报价时就已生效。
证据不足时返回能确认的范围和缺少的信息。例如“代码在开关关闭时拒绝叠加,当前生产开关快照不可用”,不能替换成“生产不支持叠加”。没有搜索命中、没有权限和检索故障分别处理。
6 在线调查预算
预算包含工具次数、源码读取字节、图节点数、深度、输入输出Token与截止时间。服务端维护已读证据与访问集合,重复读取优先复用,循环调用达到预算时返回PARTIAL。分页使用cursor,长任务使用task_id读取结果;query_id用于追溯本次调查,不作为独立工具调用的续接凭据。后续调用仍使用相同快照或显式开启新查询。
Prompt只获得完成当前问题所需的片段。源码、文档或注释中的工具调用指令仅作为内容读取。引用通过服务端映射生成,模型不得自行拼接生产文件地址。模型提出检索词、字段或对象引用时,执行器使用类型化参数与转义后的字面值,不把模型文本直接拼成SQL、图遍历语句或代码平台查询DSL;确需使用通配或正则时走单独允许的操作及复杂度限额。执行器在每次调用时检查读取范围和成本上限,Prompt中的限制不能替代这些检查。
Sourcegraph Deep Search用搜索和代码导航连续调查,并展示执行过的搜索与已读文件。这里的证据账本还记录未完成取证和停止原因,用于区分证据齐全、无新增结果和预算耗尽。
7 问答验收
同一版本和权限下,网页、工具和IDE取得的规则条件应一致。问答测事实正确、条件遗漏、证据支持和未知处理;影响分析分别测召回与误报。评估人员检查结论证据,而不是只检查文字是否通顺。
8 问题解析与回答判定
查询先形成question_frame:用户问题、目标对象候选、问题类型、环境、业务时间、人群或渠道、工作区版本及待澄清字段。省略环境时默认解释代码,返回scope_basis=CODE_ONLY;询问“现在”“线上”时要求部署和配置时间范围。用户所填时间不是证据有效时间,两者分别保存。
澄清仅针对会改变结论且不能分情况解释的字段。例如“订单取消”同时指主单取消和履约撤单时,返回候选对象让用户选择;查询某字段的使用方则可直接返回多种授权范围内的匹配项。澄清过程不生成确定业务结论。
查询规划器将问题拆成待证明项,例如“券种条件、活动范围、叠加开关、例外分支”。每项记录已读取规则、支持与反驳证据、未解析范围。检索与关系展开仅为补齐这些项服务;一次调查轮次包含已计划的检索与取证调用;连续两轮没有新增对象或证据,且没有待执行的独立取证动作时停止。该阈值作为查询策略配置记录,不把停止原因解释成证据充分。
| 状态 | 判定 | 返回行为 |
|---|---|---|
| ANSWERABLE · 可回答 | 结论所需条件和证据在指定范围内齐全 | 返回结论及逐项引用 |
| INSUFFICIENT_EVIDENCE · 证据不足 | 已调查但没有可支持的结论,仍有缺口或预算截断 | 返回PARTIAL、空claims及缺口或截断原因 |
| PARTIALLY_ANSWERABLE · 部分可回答 | 部分事实成立,其余条件或证据缺失 | 返回已确认部分与未决项 |
| NEEDS_CLARIFICATION · 需澄清 | 对象或范围歧义会改变结果 | 返回澄清字段,不猜默认业务含义 |
| CONFLICT · 存在冲突 | 同一适用范围存在相反断言 | 列出各自版本与依据,不投票选一个 |
| NOT_FOUND · 未找到 | 授权检索正常完成但没有命中 | 说明检索范围,不等同业务不存在 |
| 协议错误 · 执行失败 | 关键读取、授权或版本依赖失败 | 返回协议错误,不包装成未找到 |
问答专用结果记录answer_state、claims、clarifications、coverage,由问答接口和SSE completed承载,不作为七个检索工具通用信封的顶层扩展。需澄清或存在冲突时使用PARTIAL;未找到使用EMPTY。每个claim包含text、rule_revision_refs、evidence_refs、scope、verification_status。生成器只能引用本次已读取且有权限的证据ID;服务端检查引用存在性与版本,语义支持另由评测和必要的复核判断,不能因ID合法就认定结论正确。
完成前重新检查所用证据的访问权限。原文已经进入模型上下文时,废弃该次尚未交付的生成结果,以仍获授权的证据重新生成;无法重建时停止并返回授权变化。仅删除引用或句子不能消除模型已吸收的撤权内容。已保存的答案和导出同样重新授权,不能直接重放。流式finding同样逐次授权,已发送给客户端的数据无法通过服务端撤回,因此不提前发送未授权片段。
9 多轮上下文与需求定位
跨轮次还保存原始问题的最小必要文本和用户明确提供的假设;这些内容仍是非证据输入,不能因进入会话就升级为事实。会话保存已选择对象、范围、快照和引用,不把上一轮自然语言回答当成证据。追问改变环境、版本或业务对象时重新解析范围;旧结论保留原快照,不能隐式带入新查询。
需求定位返回候选改动点及选择理由,每项列出现有规则、入口、数据或消息变化、影响使用点和待确认问题。没有实现依据的新增需求标为NEW_CAPABILITY,不能为了给出文件路径而虚构已有实现。影响列表使用字段读取、条件依赖与副作用路径解释;公共基础服务的普通调用关系单独列为依赖,不直接计入业务改动清单。
10 查询计划与证据账本
每个query_id固定normalized_question、resolved_scope、snapshot_id、policy_epoch、retrieval_policy_version。查询计划由服务端校验,模型只提出工具和参数建议。执行器拒绝计划范围之外的仓库、未注册工具和任意URL读取,不执行源码、构建脚本或模型生成代码。
证据账本逐次记录tool、argument_digest、result_ids、evidence_ids、elapsed、budget_delta、failure_code。待证明项使用obligation_id关联这些记录,状态为OPEN、SUPPORTED、CONFLICTED或UNRESOLVED。已审阅规则可以支持结论,但回答包含新推导时必须另列推导依赖,不沿用原规则的审阅标记。
对于“全部调用方”“所有例外”等清点问题,计划采用枚举路径,不以向量Top-K代替遍历。结果同时报告examined_scope、enumeration_complete、unresolved_frontier;没有可靠分母时省略百分比。业务完整性引用覆盖台账修订,不能从命中服务数、已生成卡片数或读完末页推导。回答的coverage.business_assessment携带ledger_revision、snapshot_id、closure、required_for_answer;台账缺失时不生成完整性声明,记录COVERAGE_BASIS_MISSING。required_for_answer由服务端问题计划确定:整条业务、所有入口/例外/补偿、全量影响等问题为true;查询单条规则时可为false。前者要求台账在所问范围内DECLARED_SCOPE_COMPLETE,PARTIAL时使用部分回答或证据不足;后者仍可依据充分的局部证据回答,但不能顺带宣称整条业务完整。按覆盖范围答复“已接入版本中发现的消费方”,不把未接入服务默认为零。
技术目标按完整发布成员键定位。相同stable_id对应多个implementation_scope时,先保留各实现的版本和作用条件;只有查询环境、部署或配置证据能唯一缩小范围时才选择实现。未消除的歧义进入未决项,业务问答返回NEEDS_CLARIFICATION或分情况说明,不以最近发布时间取代范围判断。
历史答案、导出和会话重读均核对原查询所属主体、客户端及当前来源权限。query_id只定位结果,不授予访问资格。其他用户收到问题文本后,按自己的权限发起新查询,不直接读取原用户的历史答案。审计保存访问对象和决策摘要,常规日志不记录完整Prompt、凭证或源码正文。会话中的假设、实例标识及临时代码按用途和租约清理;取消任务不会自动删除已归档来源,但停止为本次查询继续收集新证据。Sourcegraph的搜索、导航和来源记录可作为调查流程参考,结果访问按本设计执行。Deep Search
11 实例问题与业务规则的证据边界
“为何这笔订单退款70元”和“退款规则如何计算”不是同一种查询。前者需要该实例的原支付流水、退款范围、已退金额和适用规则版本;后者可以只读代码与契约。七个知识工具不直接调用交易接口,也不凭订单号访问生产数据库。实例证据只能来自已授权归档资料或另行批准并完成设计的只读业务数据适配器;没有适配器时,返回INSTANCE_EVIDENCE_MISSING。
用户或场景夹具提供的金额与状态属于输入假设。原价100元、满减20元和券优惠10元只能算出应付现金70元,不能证明已经支付。用户另行给出“实付70元”时,回答可以按这个条件计算,并说明仍缺原支付、已退和在途记录。假设保留在问题上下文中,不能注册成已验证运行证据或升为已审阅知识。需要断言真实订单状态时,缺少实例证据的部分使用PARTIALLY_ANSWERABLE或INSUFFICIENT_EVIDENCE。
证据账本为每条待证明项区分RULE、INSTANCE_FACT和USER_ASSUMPTION。规则证据支持退款计算口径;原支付与退款流水支持实例金额;退款确认、退券结果及订单终态共同支持完成结论。任何一类缺失都不能由另一类替代。业务完成判断核验的是状态及其关联键,不是最后收到一条事件的时间。
历史报价和支付金额按quote_id、payment_id及其固定规则版本解释。当前Ducc值仅支持当前配置范围,不用于重算旧订单;退款申请已受理或调用超时不能推断资金结果。补偿存在多个独立子状态时,逐项返回确认、失败、处理中或未知,避免把退款成功概括为整笔补偿完成。
12 金额问题的对象范围与观察依据
“还能退多少”先定位金额属于哪个对象:原订单、子单、订单行、已实收capture、退款意图或退款操作。支付attempt只表示尝试,不能替代capture;同一支付意图下的两次成功实收也不能自动合并成双倍商品权益。若对象不同会改变结果,返回待澄清项或按对象分别解释,不能只按order_id汇总金额。
可退金额至少受两个独立上限约束:业务行的可退权益,以及所选capture的未退、未占用资金。计算分别扣除各自范围内已确认退款和仍可能成功的在途占用,再检查申请同时满足两个上限。同一退款占用可以同时关联行与capture,但不能在一个合计式中扣减两遍。capture仍有余额不代表对应商品满足退款条件,行仍有退款权益也不代表任意capture可用于出款。
分单或部分退款使用原分摊修订、适用行集合、币种、精度和余分规则。行分摊已落库时,回答引用原分摊结果,不能按当前行排序重新分配尾差。部分退款不能简单按“此次退款金额/订单金额”重新分摊优惠;适用方法须有规则及凭据证据。
每条结论使用basis_type区分RULE、CONDITIONAL与INSTANCE_OBSERVATION。CONDITIONAL引用用户明确给出的assumption_refs;INSTANCE_OBSERVATION引用已授权实例观察observation_refs。模型计算没有改变依据性质,正确算术也不能把用户假设升级为实例事实。
knowledge snapshot固定代码与规则,observed_at和source_revision固定某次实例观察。多个服务各自返回数据,不等于取得共同资金快照。observation_sets中的VERIFIED_COMMON_CUT必须引用证明共同切面的证据;仅有相近时间戳、同一query_id或相同知识快照时,使用INDEPENDENT_READS或UNKNOWN。对需要共同观察才能成立的实时额度结论,缺少切面依据时降为条件化计算或保留未知。
超时、请求接收和已确认退款分别处理。退款结果未知时,在途占用仍可能对应实际退款;没有“不再可能成功”的终止证据,不把占用释放后计算可再次退款金额。当前观察与后来收到的成功回执冲突时,重查原操作及观察顺序,不把迟到回执计为第二笔退款。
资金状态观察、用户假设与规则快照共同决定回答缓存身份。相同K3下新增在途申请或退款确认后,旧额度解释只能作为历史观察重读;页面和工具保留其as-of含义,不因刷新界面就标为当前可退。无法取得实例证据时,七工具仍可解释规则,不调用交易写接口补齐数据。
接入合同
HTTP、内部JSF和MCP适配层共用查询服务。
1 公共请求
请求体包含schema_version、request_id、scope、snapshot_id和budget。scope至少表达业务域或仓库范围、环境与用途。身份来自服务端验证过的凭证,不能相信请求体中的user_id或任意仓库列表。
首次请求可以省略snapshot_id,由服务解析生效版本并返回。同一取证分支的后续查询传回该版本;历史交易需要另一版本时,按第18节建立明确的子调查。cursor是不透明的服务端游标,绑定权限摘要、查询哈希、快照及排序,不接受客户端手工改变范围。
2 工具目录
| 工具 | 输入 | 返回 |
|---|---|---|
| search_knowledge | query、types、scope、cursor | 命中对象、摘要、来源、下一页 |
| get_business_rule | rule_id、revision_id或snapshot_id | 完整条件、动作、例外、证据 |
| get_business_flow | flow_id与可选revision_id,或entity与event;cursor | 步骤、分支、补偿、未确认边 |
| get_contract | contract_id、snapshot_id | 签名、字段、事件及绑定 |
| trace_impact | target、change_type、diff、budget | 影响路径、类别和引用 |
| get_evidence | evidence_id、line_range或segment_id | 经授权的证据片段与定位 |
| build_context | task、workspace、symbols、diff、budget | 与任务相关的上下文包 |
MCP工具声明inputSchema与outputSchema,并返回structuredContent。针对只读取文本的客户端,同时返回序列化JSON文本;适配器按协商的协议版本提供能力。tools/list按当前调用身份只列可调用工具,调用时重新授权;列表变化按协商能力通知。目录分页游标与业务结果游标分开,不能互换。MCP工具规范
3 返回示例
{
"schema_version": "0.1",
"request_id": "req-example",
"query_id": "query-example",
"snapshot_id": "release-example",
"status": "PARTIAL",
"items": [{
"id": "rule:promo:dong-tiered-stack",
"revision_id": "revision-example",
"type": "BUSINESS_RULE",
"summary": "命中特定活动并选择东券时,依据配置决定是否拒绝叠加",
"verification_status": "CANDIDATE",
"matched_fields": ["subject"],
"evidence_refs": ["evidence:example:source-branch"]
}],
"unresolved": [{"code": "CONFIG_SCOPE_UNKNOWN", "target": "ducc.promo.allowDongCouponStackTiered"}],
"truncated": false,
"next_cursor": null
}
OK要求items非空、unresolved为空且未截断;EMPTY要求items与unresolved均为空且未截断。有未决项时使用PARTIAL,即使没有截断也成立。EMPTY只表示在已声明范围内没有结果,不能作为业务不存在的证明。truncated表示展示或预算截断,next_cursor只为可分页结果提供;非空时truncated=true且status=PARTIAL。最后一页可为OK,表示该页无未决项且候选集已结束,不表示业务全库覆盖。需要补充证据时通过unresolved说明。
4 错误约定
| code | 含义 | 调用方处理 |
|---|---|---|
| INVALID_ARGUMENT | 参数或Schema不符 | 修正请求,不盲目重试 |
| REQUEST_CONFLICT | request_id已绑定不同输入 | 使用新request_id |
| ACCESS_DENIED | 无权执行或访问 | 交给用户或权限流程 |
| NOT_FOUND | 授权范围内目标不可见或不存在 | 更换标识或检索,不推断隐藏对象 |
| VERSION_UNAVAILABLE | 指定知识版本或临时上下文无法读取 | 显式选择新版本并开启新查询,不静默回退 |
| CURSOR_EXPIRED | 游标状态超过保留范围 | 使用原查询条件开启新查询,旧分页不能续接 |
| AUTHORIZATION_CHANGED | 调查期间有效授权范围改变 | 停止旧游标及结果回放,按新范围开启查询 |
| RATE_LIMITED | 无可用调用额度,任务未启动 | 按retry_after_ms退避 |
| DEPENDENCY_UNAVAILABLE | 内部依赖不可用 | 根据retryable和退避策略重试 |
| INTERNAL_ERROR | 服务执行失败 | 提供query_id供排查 |
| RESULT_NOT_READY | 异步问答尚未形成最终结果 | 按状态接口给出的间隔继续查询 |
| REVISION_CONFLICT | 任务状态已被其他操作推进 | 重新读取状态,不覆盖新修订 |
协议错误、业务空结果与工具执行失败分别映射到HTTP、JSF或MCP语义。使用MCP时,工具执行失败通过工具错误结果表达,不能把所有错误都转换为成功文本。
HTTP与JSF适配器的错误对象包含code、message、retryable和可选query_id,message不暴露未授权目标。HTTP使用400表达参数错误,401或403表达认证与授权失败,404表达授权范围内未找到目标,409表达版本状态冲突,429表达配额限制,503表达可重试依赖故障。业务查询得到部分证据时返回正常结果体并标记PARTIAL,不使用HTTP失败伪装业务未知。
5 IDE上下文
workspace使用第9节的repos数组,每个仓库固定Commit与Diff完整性;目标符号由build_context的symbols传入。Diff限于请求范围,附base_commit。服务核对知识与工作区关系,返回EXACT、ANCESTOR、AHEAD、DIVERGED或UNKNOWN;共同祖先关系必须由版本图计算,不能按分支名判断。
开发分支的新实现尚未入库时,工具返回相关旧规则与版本差异;Diff中的代码只作为本次临时证据,不自动进入发布知识。引用链接包含仓库、Commit、路径与行范围,IDE适配器转换为本地符号跳转或内部代码平台地址。
build_context按优先级返回当前任务直接规则、契约使用点、影响路径和证据片段,说明预算及未包含的内容。跨仓库权限不足时返回可见部分,不补写隐藏服务细节。
6 流式结果与长任务
问答界面的SSE事件包含event_id、query_id、snapshot_id、event_type、payload和terminal。事件类型为scope_resolved、evidence_found、finding、completed或failed。finding标为provisional,完成前可以修订;completed给出最终结果版本和引用集合。
长任务提供创建、状态查询、结果分页和取消操作。创建以client_id、已验证主体和request_id构成去重键。输入摘要覆盖规范化的完整业务请求,包括问题、范围、指定快照、预算和assumptions;同一键、同一摘要返回原task_id,不增加调查预算。同一request_id把“退款结果未知”改成“退款已确认70元”时,返回REQUEST_CONFLICT,调用方使用新request_id创建调查。
assumption_id在一个请求内必须唯一,同ID出现两次即返回INVALID_ARGUMENT。计算摘要时按assumption_id排序,对象键按固定次序编码,文本内容不改写。省略项保留省略状态参与摘要;第一次接收请求时固定实际知识快照、预算和查询策略,重试不因生效版本或默认配置变化重新解析。凭证不参与业务摘要,身份由去重键和每次授权检查约束。
去重记录保留期限和结果租约由接入配置公布;记录到期不重放旧副本,客户端用新request_id明确创建新调查。任务服务生成单调递增task_revision,取消与完成竞争使用条件更新,先提交的终态生效;取消请求返回当前终态而不把已完成任务改成CANCELLED。取消成功后,执行器丢弃迟到模型结果并停止事件发布。断线重连携带event_id;事件已过保留范围时返回恢复方式而不是重复启动任务。event_id只在task_id内单调有序,客户端以(task_id,event_id)去重;重连可重复交付事件,不承诺恰好一次。恢复事件或终态结果前重新授权,AUTHORIZATION_CHANGED使旧事件缓存不可重放。completed事件的结果和分页结果共同指向不可变result_revision;分页结束前不能将provisional finding当作最终答案。界面SSE与MCP传输是两套协议,不将同名SSE端点混用。
7 客户端验收
验证Schema兼容、版本固定、权限继承、分页稳定、取消、超预算及依赖失败。JoyAI的工具调用能力、内部Agent平台身份透传和IDE对MCP的支持分别形成接入记录。公开开源能力不能代替内部版本验证。
8 身份传递与连续工具调用
调用方注册client_id和允许的工具、业务域及数据用途。用户代理模式的有效权限取用户权限与客户端权限交集;无人值守Agent使用独立服务身份,不继承创建者的全部权限。身份和委托关系由接入层验证,scope只能收窄范围。具体凭证机制按内部身份平台接入结果确定,查询协议不接受客户端自报身份。
典型调用顺序为search_knowledge → get_business_rule/get_contract → get_evidence → trace_impact。第一次结果返回快照;同一取证分支的其余调用携带该快照和各自request_id。query_id用于关联调查记录,不是授权凭据。每次读取重新校验权限,快照固定不代表权限固定。
| 约束 | 处理 |
|---|---|
| revision_id与snapshot_id同时给出 | 校验该修订属于快照,否则返回VERSION_UNAVAILABLE |
| 游标与新问题、范围或排序混用 | INVALID_ARGUMENT,不从头静默重查 |
| 权限在翻页间发生变化 | 原游标失效,要求以新授权范围重新查询;不显示原隐藏总量 |
| 重复request_id | 同身份、同输入复用任务状态,读取原结果前重新授权;不同输入返回REQUEST_CONFLICT(HTTP 409) |
| 客户端要求过大预算 | 采用客户端额度、调用预算和服务限额的最小值,返回实际额度 |
| 取消长任务 | 状态转CANCELLED,停止后续调度;已发出的模型调用不能保证立即终止,迟到结果不再发布 |
长任务状态为QUEUED、RUNNING、SUCCEEDED、PARTIAL、FAILED或CANCELLED,终态不反转。创建接口返回task_id,状态、分页及取消接口均校验同一有效身份范围。SSE仅传状态与结果事件,重连不会新建任务;事件过期后读取任务状态与最终结果。
业务不足使用PARTIAL与unresolved,调用失败使用错误对象。EVIDENCE_INSUFFICIENT、BUDGET_EXHAUSTED、CONFIG_SCOPE_UNKNOWN属于未决项代码:工具已执行且取得部分结果时不得转成失败信封。尚未启动即无调用额度时返回RATE_LIMITED。成功信封约束公共字段,items按第10节的工具输出类型校验。
第一次调用先取得可用范围
客户端初始化时调用 GET /kb/v1/session/options?cursor=&page_size=20。服务从已验证身份与客户端配置中取交集,返回options_revision、expires_at、archive_sources、repositories及next_cursor。分页固定授权摘要和选项修订;页大小为1至100,后续页带原cursor。权限变化时原游标失效。它是接入配置读取接口,HTTP与JSF适配器共用,不增加第八个知识工具;MCP客户端由已核验的宿主适配器加载。宿主不能取得这些选项时,实例调查与工作区接入明确标为不可用。
每个归档选项包含可见名称、option_ref、namespace、对象类型、scope、保留起点、已完成归档的水位,以及默认回看窗口和单次最大区间。每个仓库选项包含repo_id、名称、登记的远端别名、scope及knowledge_versions。后者只列当前身份可读且保留中的知识版本,每项为snapshot_id、可读名称、该仓库Commit与is_active。候选过多时仓库选项按(repo_id,snapshot_id)分项分页,客户端按repo_id归并;单页没有历史候选不代表不存在,需完成选项分页。没有可用项时返回空列表,不泄露隐藏来源或仓库数量。选项不是访问凭据,后续请求仍重新授权;记录到期返回VERSION_UNAVAILABLE,客户端重新取得选项。
用户选择业务系统后,网页或Agent宿主调用 POST /kb/v1/instances/prepare:提交request_id、options_revision、source_option_ref、object_kind、object_id及time。time为{mode: RECENT}或{mode: RANGE, from, to}。只有一个可用业务系统时可以带入;多个系统时必须选择,不跨所有namespace试探同号订单。
RECENT从已登记归档水位W向前取配置窗口D,固定区间为[max(保留起点,W-D), W)。这里的W是已完整归档区间的排他上界,不是最后一条记录的时间戳。窗口和截点返回页面供核对;每份命中仍显示自己的观察时间。RANGE使用用户指定的起止时间,校验先后、保留范围、归档水位与区间上限,超出时返回INVALID_ARGUMENT,不静默裁切。没有可用归档水位则返回DEPENDENCY_UNAVAILABLE,页面说明尚无可查询归档。
成功返回preparation_id、固定snapshot_id、scope、instance_selector、resolved_at、expires_at与limited_to_retention。后者只标记RECENT区间是否因保留起点缩短。宿主将返回的scope、snapshot_id和instance_selector原样带入search_knowledge;查询本身重新检查授权与时间范围,不把preparation_id当权限。无命中时显示所查区间,用户可改选历史范围后发起新查询,不能称订单不存在。各记录的独立观察不会因同时命中而成为同一时点的资金状态。
准备请求按主体、客户端和request_id去重,摘要覆盖完整输入。重试沿用已固定的水位与快照;输入变化返回REQUEST_CONFLICT。新时间查询使用新request_id,租约到期不偷偷换水位。网页生成的问答查询计划保存这份准备结果;外部Agent保存它并继续调用原七工具。
9 IDE版本匹配与临时代码
版本关系以工作区Commit W和知识中同仓库Commit K比较,定义如下。工作区含多个仓库时逐仓库、逐implementation_scope计算,同一仓库的多个灰度实现分别返回version_matches行,不能给整个工作区只打一个EXACT标签。
| 关系 | 判断 | 上下文处理 |
|---|---|---|
| EXACT | W=K | 仍需检查未提交Diff,已入库知识只覆盖基线 |
| ANCESTOR | K是W的祖先,且K≠W | K作为旧依据,计算K到W及未提交Diff的变化 |
| AHEAD | W是K的祖先,且K≠W | 知识包含工作区尚未具备的改动,不能作为当前实现 |
| DIVERGED | 两者互非祖先且有共同祖先 | 分别说明分叉,按可取得的祖先证据比较 |
| UNKNOWN | Commit或祖先信息不可得 | 不作版本兼容判断,返回缺失原因 |
工作区提交repos[],每个仓库记录repo_id、commit_sha、dirty、diff_completeness。diff_completeness为FULL_WORKTREE或SELECTED_FILES,FULL_WORKTREE同时列出未上传的二进制、未跟踪及忽略文件类别,不能只凭dirty=false认定服务端已核验工作区。
Diff请求携带repo_id、base_commit、path、base_blob_hash、patch以及删除、重命名、二进制和未跟踪文件标记。base_blob_hash为基线文件原始字节的SHA256,不是Git blob OID;计算时不归一换行、编码或空白。content_hash按提交内容的原始字节计算,客户端与服务端使用相同字节表示。服务验证补丁是否能应用于声明基线;缺文件、哈希不符或只提供选区时,分别标明BASE_MISMATCH或DIFF_INCOMPLETE。不把未提供的本地文件视为未改动。
所有path均为仓库相对路径,拒绝绝对路径、越界路径与符号链接逃逸;补丁不触发文件系统写入或构建执行。新增文件提交完整内容和内容哈希,删除文件引用基线哈希,重命名同时记录old_path与new_path。二进制内容只登记变更,不能输入Java解析器。
临时代码放入隔离的查询覆盖层。workspace_revision的输入定义见覆盖层存储,包含实际构建与依赖输入、基线、Diff及上传完整性。先解析变更符号,再将删除、覆盖和新增关系应用于本次分析;旧符号的已知调用方仍用于影响调查。未解析的覆盖层不能继承旧实现的已审阅状态。临时内容按会话保留策略清理,不进入发布索引。
build_context返回workspace_revision、version_matches、rules、rule_applicability、contracts、impact_paths、evidence_segments、omitted、budget_usage。各片段注明来源为已发布快照或工作区覆盖层。先容纳直接约束与冲突,再容纳契约和影响证据;context_budget_tokens限定最终交付给IDE的上下文正文;服务扣除身份/版本说明、规则边界和输出封装后分配片段,按JoyAI接入时确认的tokenizer_id计数。budget_usage同时返回tokenizer_id、context_token_count、effective_context_budget_tokens,三者必须成组提供;服务端核对计数不超过实际额度。旧客户端未取得这些字段时,无法确认上下文适合自身模型窗口。调用端目标模型不同时必须重新计数,不把字符数当Token数。最小直接约束及其反例仍放不下时,返回PARTIAL、omitted和BUDGET_EXHAUSTED,不能交付只有允许条件却丢掉禁止分支的上下文。超预算移除完整片段并记录省略原因,不切断规则条件。
IDE本地跳转前,使用证据定位中的 file_content_hash 核对当前整文件。字段缺失或哈希不匹配时,打开该证据绑定的固定文件或片段视图;WORKSPACE证据打开对应覆盖层,不能用其基线Commit替代补丁后的内容。此时不跳转到当前工作区同一行。哈希口径见第14节。
从本地文件取得仓库和符号
IDE适配器先将本地Git远端与初始化返回的已登记remote_aliases匹配,再取得repo_id。匹配只使用受信配置中的别名,去除可识别的传输格式差异;不按仓库短名称合并,也不把用户提供的远端当下载地址。凭证、URL查询串及本地绝对路径不进入请求。匹配多项时显示有权读取的候选供选择;无匹配时提示登记来源,不能虚构repo_id。
适配器从该仓库选项的knowledge_versions取得参考知识版本。当前工作区基线Commit唯一匹配一个候选时,可带入该snapshot_id并在IDE显示版本;匹配多个候选时让开发者选择;没有匹配时使用明确标记的当前版本,后续按版本比较处理。候选为空时提示知识尚不可用,不自行编造版本。Commit匹配只用于选择参考知识,不能据此判定规则仍适用,依赖、配置与未提交改动仍需核验。多个仓库必须选择同一可读知识快照中包含的成员;无法同时匹配时由用户明确使用当前快照或拆成分别标注的调查,不能混装成一份上下文。
选中方法或字段后,适配器调用 POST /kb/v1/workspaces/resolve-targets,提交request_id、options_revision、snapshot_id、scope、task、完整workspace及selections。每个选区携带repo_id、仓库相对path、当前整文件file_content_hash、line_start和line_end。服务核对输入范围、补丁及文件原始字节哈希,在隔离覆盖层解析当前位置对应的符号;不执行构建或用户代码。
返回resolution_id、snapshot_id、workspace_input_digest、expires_at、status、targets和unresolved。targets列出symbol_ref、仓库、路径、完整签名、PUBLISHED或WORKSPACE来源及selection_index。选区覆盖多个方法时返回NEEDS_SELECTION,显示签名供用户选择,不把第一个方法当目标。解析失败返回UNRESOLVED与缺少的文件或依赖;只有准确定位且无缺口才返回RESOLVED。
build_context的symbols使用服务返回的symbol_ref;Java展示签名和文件行号不属于合法引用。既有稳定符号ID仍可使用,但服务须在指定仓库、实现及版本中唯一定位。新增方法使用覆盖层登记的临时引用,绑定主体、客户端、参考快照、实际workspace输入摘要及租约;它不会成为已发布知识成员。调用build_context时重传同一workspace,将选定引用填入symbols,服务核对绑定后复用解析结果。编辑、依赖或上传范围变化时必须重新定位,旧引用返回VERSION_UNAVAILABLE;同一请求标识换输入返回REQUEST_CONFLICT。
workspace_input_digest按规范化workspace对象计算:对象键排序、数组保持原序、字符串字节不改写;它包含已声明的依赖和构建输入。服务实际取得的制品、解析能力及策略另按覆盖层输入合同固定,复用时两部分都须一致。快照、scope和task不塞进这个摘要,分别保存并核对。
仅输入需求描述时可以提交selections为空,随后以symbols为空调用build_context,按task在授权范围内检索候选并保留待核对项。目标尚未定位时,结果只列候选影响;需要用户选择时,选定后重新调用。未找到仓库时不提交workspace。
IDE首次定位样例从本地远端和选区生成build_context请求,复用原O1新增恢复方法的Diff与符号。
10 七个工具的参数与结果约束
公共请求包含schema_version、request_id、scope、snapshot_id、budget及arguments。首个请求的snapshot_id可空;服务端解析后返回非空快照。scope中的repo_ids、domain_ids、environment、purpose取服务端授权交集,未知标识不自动扩展到全库。budget是调用方请求的上限,字段为max_tool_calls、max_source_bytes、max_graph_nodes、max_depth、max_input_tokens、max_output_tokens、deadline_ms;省略值采用客户端配置,服务端拒绝负值并应用自身上限。
| 工具 | arguments约束 | items中的对象 |
|---|---|---|
| search_knowledge | query非空;types为对象类型集合;page_size为正整数;cursor可空。INSTANCE_OBSERVATION模式独立使用,必填instance_selector,见第15节 | SearchHit:id、revision_id、type、summary、matched_fields、evidence_refs、verification_status;实例命中另带observation及可选knowledge_refs |
| get_business_rule | rule_id必填;revision_id可选,须属于当前快照。返回一个对象;目标不可见时NOT_FOUND | RuleDetail:rule_id、revision_id、scope、predicate、effects、exceptions、config_dependencies、evidence_ids、derivation_kind、review_status、freshness、resolution_status |
| get_business_flow | flow_id与(entity_id,event_id)二选一;revision_id仅能与flow_id同用。cursor、page_size可选。后者匹配多个流程时返回候选,不替用户选一个 | FlowDetail:flow_id、revision_id、trigger、completion、steps、edges、coverage、evidence_refs |
| get_contract | contract_id必填;revision_id可选,必须属于当前快照和授权范围;binding_filters可选,只缩小环境或alias范围 | ContractDetail:contract_id、revision_id、kind、signature、fields、bindings、evidence_refs |
| trace_impact | target为已解析对象或符号引用;change_type为LOGIC、FIELD、STATE、TABLE_FIELD或CONFIG;diff或workspace_revision可选,二选一,禁止同时给出;cursor可空 | ImpactItem:target、impact_type、change_ref、paths、usage_points、version_scope、evidence_refs;含工作区路径时必须返回reference_sources |
| get_evidence | evidence_id必填;segment_id和line_range二选一或都省略。请求范围超出归档原文时INVALID_ARGUMENT,不静默截断 | EvidenceSegment:evidence_id、segment_id、source_type、origin、locator、content、content_hash、source_content_hash、redactions;归档用INSTANCE_ARCHIVE,整文件哈希位于locator.file_content_hash |
| build_context | task非空;workspace必填;symbols为目标符号集合;context_budget_tokens为正整数;Diff遵守第9节 | ContextBundle:workspace_revision、version_matches、rules、rule_applicability、contracts、impact_paths、evidence_segments、omitted、budget_usage |
RuleDetail采用业务规则Schema 0.2,四维核验字段为必填,lifecycle仅可作为兼容展示投影;外层工具信封仍使用0.1,两层版本独立。SearchHit只承诺定位信息,不把summary当作完整规则。RuleDetail与FlowDetail按其对象模型返回条件和版本;ContractDetail的fields保存嵌套字段路径、类型、缺省值与序列化映射。default_resolution为KNOWN时要求default_value,允许其值为null;ABSENT表示确认未定义默认值,UNKNOWN表示尚未确认,这两种状态不返回default_value。bindings保存候选与确认状态。EvidenceSegment的locator使用结构化仓库、Commit、路径和行范围,source_type=CODE要求repo_id、commit_sha、path和正整数行范围均非空;WORKSPACE中的commit_sha表示补丁基线,workspace_revision标识实际覆盖内容,不把基线Commit当作覆盖后内容版本。非代码来源至少提供固定仓库版本与路径,或locator.source_ref指向内网归档源记录;source_ref不能是模型生成的任意URL。内容被脱敏时列出脱敏原因与区间;原文哈希source_content_hash与返回内容哈希content_hash分开,不能用前者校验后者。origin=PUBLISHED的证据带snapshot_id,不带workspace_revision;origin=WORKSPACE的证据带workspace_revision与source_context_id,不带snapshot_id;origin=COMMIT_SOURCE用于未入知识库的固定Commit源码,例如共同祖先,带source_context_id并在locator中固定repo_id与commit_sha,不带workspace_revision或snapshot_id。外层ContextBundle仍固定参考知识快照,覆盖层证据只说明本次工作区内容,不能反向声称已发布。
rule_applicability逐条关联rule_revision_id、symbol_refs、state与reasons。APPLIES表示已核对当前工作区范围仍适用,INVALIDATED表示改动已使该规则依据失效,UNKNOWN表示无法判断。UNKNOWN和INVALIDATED必须说明原因,Schema拒绝空reasons;引用的规则修订须存在于当前包的rules中。工作区提交一致不自动产生APPLIES,还需检查Diff与规则依赖。
所有items对象必须声明具体类型或绑定工具专属Schema。工具输出在服务端序列化前校验;失败返回INTERNAL_ERROR和query_id,不能将损坏对象交给客户端猜字段。未知主版本返回INVALID_ARGUMENT;同一主版本的客户端忽略已声明可扩展的可选字段,必填字段或枚举语义变化升级协议版本。
11 传输映射
HTTP接口采用POST /kb/v1/tools/{tool_name},请求与成功响应使用上述JSON合同。JSF提供等价的invoke(toolName, request),业务类型在公共DTO中显式区分;不将任意Java对象序列化作为协议。问答另用POST /kb/v1/answers接收question、scope与snapshot_id,同步返回AnswerResult,不占用搜索工具的items类型,也不在同一成功响应中混入task_id。问答请求使用AnswerRequest0.1,回答继续使用AnswerResult 0.2,两者版本独立;输入身份、范围、预算及request_id处理沿用工具调用规则。异步问答由调用方显式选择POST /kb/v1/tasks,任务请求引用相同AnswerRequest内容,创建响应保持202与task_id;同步超出调查预算返回PARTIAL,不静默切到异步。
长任务使用POST /kb/v1/tasks创建,GET /kb/v1/tasks/{task_id}读取状态,POST /kb/v1/tasks/{task_id}/results按游标取结果,POST /kb/v1/tasks/{task_id}/cancel取消。创建返回HTTP 202及task_id、state、query_id、snapshot_id;同步工具不会在同一成功信封中有时返回知识、有时返回任务。选择同步还是异步由客户端明确指定入口;预算不足时同步调用返回PARTIAL。
MCP发布的inputSchema/outputSchema必须是客户端可直接校验的自包含JSON Schema:将本项目URN引用的规则、工作区和工具信封定义打包到本地$defs,保留递归引用,不依赖客户端读取仓库文件或公网。每个工具目录声明绑定合同摘要;发布前对导出Schema与内部Schema运行同一组正反例,防止打包时丢失oneOf、条件约束或additionalProperties。若客户端不支持所选Schema能力,不发布“完整支持”的工具目录,使用已核验的适配合同。
MCP tools/call的arguments映射公共请求,structuredContent承载成功信封;文本内容为同一JSON的序列化形式,不另外生成可能不一致的摘要。JSON-RPC参数或方法错误使用协议错误,工具执行错误使用isError=true;PARTIAL属于成功执行结果。七个工具声明只读,但权限检查不依赖客户端对工具注解的信任。标准MCP任务能力仅在客户端与服务端协商支持时映射内部task_id,不把HTTP任务接口直接宣称为MCP标准工具。MCP工具规范
HTTP型MCP入口验证令牌受众、有效期和作用域,每次请求均验证;不把IDE传来的其他平台令牌透传给源码或配置服务。下游访问由受控服务身份或内部认可的委托机制完成。STDIO适配器从本机安全配置取得凭证,禁止将凭证写入项目文件或作为工具参数。内部身份平台若无法满足选定MCP授权规范,先使用受控HTTP/JSF客户端,不声称支持通用远程MCP授权。MCP授权规范
异步问答的创建与续读
POST /kb/v1/tasks当前只托管ANSWER类型的异步问答,请求体直接为AnswerRequest 0.1,不另套payload,也不接受Agent程序或工具调用数组。外部Agent连续调用七工具时,由客户端保存每次请求、结果引用、快照和游标;恢复时重新授权并从已完成步骤继续。已有临时证据或游标失效时重新查询该步骤,不能将重新开始说成恢复原任务。
任务创建返回202,正文为task_id、task_revision、state=QUEUED、query_id和解析后非空snapshot_id。GET /kb/v1/tasks/{task_id}返回同一组身份,加task_type=ANSWER、state、result_revision、next_poll_after_ms和error。未结束时result_revision为空,轮询间隔由服务给出;SUCCEEDED或PARTIAL携带不可变结果修订;FAILED带错误对象;CANCELLED不交付未完成答案。所有字段和状态约束见首次使用合同。
POST /kb/v1/tasks/{task_id}/results请求为result_revision、cursor、page_size,cursor首次为空,page_size为1至100。服务只读取已结束的SUCCEEDED/PARTIAL结果,否则返回RESULT_NOT_READY。返回task_id、result_revision、items、next_cursor。结果序列先有一个kind=ANSWER的完整AnswerResult 0.2,再有可选kind=SOURCE_INDEX的结论到证据引用索引;不在分页中截断一个规则条件、一个结论或答案正文。每页至少一项,next_cursor为空时结束。SOURCE_INDEX只复列该答案已有claim_id和evidence_refs,不增加新的结论或授权。
游标固定任务、结果修订、页大小、排序、主体与客户端及授权摘要。后续页传原result_revision、页大小与游标;混入另一任务或更改页大小返回INVALID_ARGUMENT。重放同一游标返回相同页序列,授权变化则停止回放并返回AUTHORIZATION_CHANGED,结果已回收返回VERSION_UNAVAILABLE,事件已过期时,不从旧事件重建最终结果。读取每一页时核对整个答案及其必要来源的当前权限,不能只删掉来源索引后继续返回答案。分页结束表示该结果已读完,业务覆盖状态另按覆盖台账判断。
POST /kb/v1/tasks/{task_id}/cancel请求为request_id与expected_task_revision,响应复用任务状态。非终态且修订不匹配返回REVISION_CONFLICT并允许重新读取状态;已成为终态时返回当前终态,不改成CANCELLED。取消与完成按同一条件写入竞争,已取消任务拒收迟到结果。取消命令按主体、客户端、任务及request_id去重,换输入返回REQUEST_CONFLICT。读状态与取消均要求原任务所属的调用主体、客户端和当前权限;不可见任务统一NOT_FOUND。
O1断线续查样例覆盖创建、查状态、两页结果、完成后取消和运行中取消。事件流沿第6节协议;断线先查状态,不再POST创建。纠错重答和带详情对象的内部问答使用各自接口,保存完整输入;不得丢弃额外字段后转交此公共入口。
12 版本比较与上下文失效
版本比较先验证仓库身份和Commit对象,再计算祖先关系。浅克隆缺失祖先时可从授权版本服务补齐;补齐失败返回UNKNOWN。Git可能返回多个最佳共同祖先,服务保留merge_bases[],标记MULTIPLE_MERGE_BASES,不能任取一个合成确定基线。Git merge-base
上下文包绑定workspace_revision、snapshot_id、policy_epoch、context_policy_version。工作区内容、基线、依赖制品、构建配置、上传范围或分析策略改变时,IDE立即使原包退出当前编辑上下文,不能等新包返回后才停用。原包保留为历史;已经使用它生成、但尚未采用的建议也标记为旧工作区结果。新分析失败时不回退到旧包充当当前依据。
客户端维护本地工作区序号和当前分析请求,将request_id与发出时的序号、完整输入摘要关联;本地序号不新增为工具协议字段。返回时,响应必须属于当前请求,工作区序号与输入摘要也必须仍与发送时相同。否则该结果只供历史查看,不能覆盖较新的上下文。服务端按本次输入产生workspace_revision,并按既有合同校验包内引用;后续影响调查使用这个修订。用户再次编辑时,即使较早请求尚未返回,也先停用对应上下文。
包中每条规则记录适用的工作区符号与失效原因。EXACT仅说明Commit一致,不能证明当前未提交代码符合该规则。有限检查包含请求A发出后继续编辑、请求B先完成而A后到、依赖改变但Diff相同,以及B失败时不得恢复A为当前包,见交叉审阅检查。
IDE向模型发送上下文时分开封装任务指令与证据文本。仓库内AGENTS.md、注释、PRD中的操作指令是待分析内容,不获得本知识服务的工具执行权限。ContextBundle只返回调查与修改依据,不执行写文件、提交代码或发布操作。
13 多实现目标的读取规则
发布成员键为(member_kind, stable_id, implementation_scope)。业务规则在GLOBAL范围读取一个业务修订,修订内部保留多技术实现;技术符号和关系必须定位到具体implementation_scope与revision_id,不能仅以stable_id取最新实现。
trace_impact的target只有id与kind,服务端先按固定快照和scope列出可见实现。Diff或workspace_revision可进一步关联仓库、制品与工作区基线;它们不能自动证明生产灰度范围。仍有多个实现时,按实现分别调查并在version_scope及证据中保留差异;若请求要求唯一执行路径但无法消歧,返回PARTIAL与IMPLEMENTATION_AMBIGUOUS,不任取一条。当前请求合同没有任意implementation_scope覆写参数,调用方只能收窄已支持的scope或提供工作区依据。
get_business_flow以flow_id和revision_id读取确定修订;revision_id必须是授权快照成员。只给flow_id且存在多个适用修订时,返回候选及IMPLEMENTATION_AMBIGUOUS,不拼接不同版本。cursor绑定最初定位参数、快照、授权摘要、固定排序及已返回步骤集合;后续页只能改变page_size以缩小页,不扩大初始预算。流程分页使用稳定步骤ID,页内边的两端均返回步骤,边界步骤允许重复;客户端按(flow_id,revision_id,step_id)合并,不能按标题合并。每页coverage说明当前页的结构缺口,末页仅代表读取结束;完整业务判定仍取业务覆盖台账。
get_contract的contract_id定位逻辑契约,binding_filters只筛选环境和alias。相同签名与字段修订可以返回多个bindings;签名或字段默认值存在版本差异时,不能拼成一个ContractDetail。未指定revision_id且无法消歧时,返回PARTIAL、空items与IMPLEMENTATION_AMBIGUOUS;Agent用search_knowledge取得可见契约的id和revision_id,再携带revision_id读取。服务端检查该修订在快照中的成员归属、实现范围与当前权限,不按全库修订ID直读,也不回退到最新修订。这样候选发现与精确读取构成可完成的调用链。
语义校验还包括:引用成员属于快照、关系端点修订一致、SUPPORTED具有使用点、Flow部分覆盖或Context省略项向外层PARTIAL传播。JSON Schema负责字段结构,不能代替这些关联检查。
14 合同文件与语义检查
七工具合同中的$defs/{tool}Request与$defs/{tool}Result分别用于输入和输出校验;文件顶层的tool/request/result只是离线合同测试容器,不作为HTTP请求额外包装。输入示例见七工具请求,返回示例见七工具结果。工作区合同、问答合同和规则合同独立维护版本。
通过Schema后仍执行语义校验:scope与身份取交集,确认修订属于快照;按实现范围解析关系;检查证据及行范围;核对Diff所属仓库、基线和哈希;计算Commit关系与多个共同祖先;汇总嵌套未决项到外层PARTIAL。完整读取候选规则不等于规则已确认,未审阅状态保留在对象中;影响问题缺少所需使用点时必须标明证据不足。
当前合同属于详细设计草案。联调前以schema_id和规范化Schema内容摘要锁定合同;严格additionalProperties客户端不能把同一版本号理解为任意字段兼容。服务仅在双方确认相同合同摘要后发送新字段,未升级端收到PARTIAL及覆盖未知提示,不静默丢掉完整性信息后标OK。形成已发布接口后,新增必填项、枚举值或约束收紧必须升版本并保留显式兼容适配。
实例归档检索、INSTANCE_ARCHIVE、整文件哈希、路径来源表和跨版本knowledge_contexts均属于需单独核对合同摘要的能力。MCP导出的输入、输出Schema同时声明已启用的字段和枚举。旧端未协商实例模式时不开放该查询;未取得整文件哈希时只打开固定证据视图,不能把字段缺失解释成文件一致。
证据定位的语义检查还需确认start_line≤end_line、行范围存在且片段属于声明来源。redactions的offset按返回content的Unicode码点、零起点半开区间计算;非BMP字符按一个码点,区间不得越界或重叠,不能以UTF-16下标混用。原文与返回内容哈希均按各自UTF-8字节计算;定位、脱敏区间和哈希不一致时拒绝序列化,不让IDE跳转到错误位置。
代码证据的locator可带 file_content_hash,表示来源整文件原始字节的SHA256,不归一换行、编码或空白。PUBLISHED和COMMIT_SOURCE使用固定Commit中的文件;WORKSPACE使用应用本次补丁后的文件。它与片段原文的source_content_hash、返回片段的content_hash分别计算。无法取得整文件校验依据时省略该字段,客户端只打开固定证据视图,不能用片段哈希代替文件哈希。
枚举、标识和SHA256格式只约束形状,不能证明仓库、证据或文件实际存在。查询不得为通过校验而生成占位证据ID。
影响路径的node_refs使用可解析到确定实现的引用ID,edge_refs使用确定关系修订的引用ID,不能放裸stable_id。只含已发布成员的路径可沿用原格式:节点解析为完整implementation_ref,边解析为relation_revision_id,逐项校验其属于当前快照及授权范围。
包含工作区节点或边时,ImpactItem必须提供 reference_sources[],完整覆盖该项paths中全部node_refs和edge_refs。每条来源记录包含ref_id、kind(NODE或EDGE)、origin(PUBLISHED或WORKSPACE);PUBLISHED只带snapshot_id,WORKSPACE只带workspace_revision。按(kind, ref_id)唯一登记,重复、缺项或相互冲突的来源均不通过校验。仅有发布路径时也可提供这份来源表,但提供后同样完整核对。version_scope只作汇总,不代替逐引用来源。
服务端按引用登记解析来源:发布成员须属于本次参考快照;工作区成员须属于请求指定、或本次Diff生成的覆盖层,且该覆盖层绑定同一参考快照、主体和客户端。图中只使用应用补丁后的有效关系;已删除的旧调用可作为历史影响依据单独说明,不能重新接入当前工作区路径。每次读取与返回均校验授权及租约,客户端自报origin或版本编号不授予访问权。
例如O1退款已确认、退券失败,研发在工作区新增退券恢复方法,调用K1中已有的退券接口。新方法及新调用边登记为WORKSPACE,原接口登记为PUBLISHED;返回的路径说明这次修改怎样连接旧实现,不宣称恢复方法已经上线或已经处理O1。
15 场景查询的连续取证
同一取证分支中,客户端使用固定snapshot_id调用各工具;每次request_id不同。涉及历史报价与后续恢复版本时,按第18节分别请求各快照。query_id用于归集服务端执行记录,不能替代取证参数或授权。跨调用复用的结果必须保留原工具、参数摘要、对象修订与证据ID;自然语言摘要不是下一步读取的身份依据。
新增字段尚未存在于知识快照时,trace_impact以已有消息契约为target,change_type=FIELD,并提供含新增字段的Diff或工作区覆盖层。不能伪造一个已入库字段ID。消费方未读取新字段仍可能受影响:需要检查未知字段策略、缺省值、反序列化失败、路由分支及旧消息回放。仅订阅同Topic的消费者仍为DEPENDENCY_ONLY,找到与变更有关的具体读取或反序列化使用点后才可标SUPPORTED。
get_evidence读取的内容可能包含交易实例标识。返回前沿用证据对象权限并脱敏;仅拥有源码权限不自动拥有订单、支付或券流水权限。工具不能因一个订单号出现在问题中就自行调用退款、退券或其他写业务接口。
按订单查已归档的观察
Agent只有订单O1时,先按首次范围选择取得业务系统、归档区间和知识版本,再调用search_knowledge,types只填INSTANCE_OBSERVATION,并提交instance_selector:namespace、object_kind、object_id、observed_from和observed_to。namespace指向已登记且获授权的归档范围,object_id在该命名空间内精确匹配;观察时间采用半开区间,服务检查起点早于终点及范围上限。query可以说明要查退款、退券或订单状态,但不能扩大选择器。实例类型不能与规则、流程等类型混查,也不触发生产数据库或交易接口查询。
归档索引只有在来源资料已证明对象关联时,才把支付、退款或券记录连接到O1。SearchHit中的observation沿用问答观察结构,id等于observation_id,revision_id等于source_revision,两处evidence_refs相同。knowledge_refs可以列出归档实际执行版本对应的已授权知识成员,包含snapshot_id、object_type、object_id和revision_id。Agent按这些快照分别读取历史规则和恢复实现;映射缺失时返回HISTORICAL_BINDING_UNKNOWN,不能填入当前版本替代。命中状态仅用于展示,具体状态与金额仍需读取原始依据。
首个归档查询固定候选集及归档读取水位,cursor同时绑定选择器、参考知识快照、授权范围和排序。翻页期间新归档的退款回执不插入旧结果;需要新观察时重新查询。没有命中只表示该命名空间和观察区间内没有可见记录,不能推断订单不存在或退款未发生。
发现结果中的evidence_refs由服务端登记,随后仍用get_evidence读取。此类EvidenceSegment使用origin=INSTANCE_ARCHIVE,带source_context_id及固定的locator.source_ref、source_version,不带条目级snapshot_id或workspace_revision。外层snapshot_id保留调查所参考的知识版本;归档修订独立于它,例如K1发布之后收到的退款回执仍可与K1规则一起核对。登记的证据ID绑定调用主体、客户端、参考快照、归档修订和租约,每次续读检查当前权限与删除状态。租约到期返回VERSION_UNAVAILABLE;重新查询生成新的来源上下文,不把新归档内容写进旧引用。
临时证据先由服务端登记evidence_id,再由get_evidence读取。WORKSPACE与COMMIT_SOURCE的source_context_id绑定调用主体、客户端、基线snapshot_id、来源摘要和租约;后续请求使用同一快照并重新授权。临时证据不能仅凭ID跨用户共享,租约到期返回VERSION_UNAVAILABLE,不自动按原URL重新拉取并替换内容。快照只固定参考知识,不能把祖先源码登记为该快照已发布的成员。
FlowDetail涉及多维完成汇合时返回state_dimensions(name、correlation_refs、state_ref、evidence_refs)和completion_predicate。completion文字仅用于阅读;退款、券恢复、订单终态等两个以上维度的汇合必须有条件树及证据,不能只用一句“全部完成”。
独立工具请求各自返回query_id,Agent在客户端调查记录中串联请求与结果;相同snapshot_id不自动合并服务端调查。单次问答内部的多个取证动作可以共用该问答query_id。分页沿cursor绑定原查询,长任务沿task_id续读。服务按客户端身份累计配额,不能靠新query_id规避额度。
16 条件化金额与实例观察合同
AnswerResult使用独立的0.2版本承载复杂金额依据;七工具信封不随之变成交易执行协议。每条claim增加basis_type、assumption_refs、observation_refs。basis_type为RULE、CONDITIONAL或INSTANCE_OBSERVATION:规则结论引用规则/源码证据;条件化结论必须引用假设,可以同时引用已取得的观察,但计算结果仍限于ARITHMETIC_BOUND;实例结论必须引用实际归档观察。已有evidence_refs继续保存支持结论的来源,不接受模型为了填满数组而构造的运行证据。
顶层assumptions保存assumption_id、text,保留用户给定条件或合成样例来源;observations保存observation_id、observed_at、source_revision、subject_refs、evidence_refs。观察中的subject_refs须精确到计算所需的订单行、capture或退款操作,不能以订单号代替所有资金关联。
observation_sets记录observation_set_id、observation_refs、consistency_status、proof_evidence_refs。consistency_status为VERIFIED_COMMON_CUT、INDEPENDENT_READS或UNKNOWN。VERIFIED_COMMON_CUT要求可授权读取的共同切面证明;知识snapshot_id、模型生成时间、各源时间戳接近均不构成证明。语义校验核对观察版本、业务关联与切面范围,Schema只能检查字段存在。
claim可携带calculation,字段为target_kind、target_refs、currency、allocation_revision_ref、capture_refs、formula、components、result、result_kind、observation_set_ref。components逐项保存name、amount、source_ref;金额使用十进制字符串,source_ref指向本次已声明的假设、观察或证据。formula是解释用的算式,不作为可执行表达式发送到业务系统。result_kind区分ARITHMETIC_BOUND与OBSERVED_AVAILABLE;前者是给定条件下的计算上限,不代表批准执行退款。
OBSERVED_AVAILABLE须有对应observation_set_ref及覆盖全部所需来源的已验证共同切面。未满足时返回ARITHMETIC_BOUND并注明假设,或以未决项返回证据不足。服务端检查每一components来源、金额单位、分摊修订、capture和目标范围一致,检查sum/min等计算与result相符。币种转换、不同capture余额混用、在途重复扣减都不能仅因结果是合法数字而通过。
Agent先用search_knowledge定位退款、分摊和幂等规则,再用get_business_rule/get_contract/get_evidence读取确定修订。七工具不提供余额锁定、退款申请或支付尝试重启;没有实例资料时不增加隐藏交易调用。IDE修改退款条件、舍入方法或占用释放分支时,以已有规则/符号为target、change_type=LOGIC展开影响,检查capture、行权益、分摊及回执使用点;不能凭需求中的订单或退款操作ID伪造技术实体。
observation_set_ref失效或来源权限变化时,按原结论实际使用的输入重新检查。新知识版本不能使旧实例观察变新,实例资料新鲜也不能使旧规则自动适用于新工作区。三端必须同时展示这两种版本边界。
17 完整性声明与客户端降级
Answer.coverage和FlowDetail.coverage中的business_assessment引用内部覆盖台账:ledger_revision、snapshot_id、closure和required_for_answer。服务端校验台账修订存在、与当前快照一致、边界匹配所问业务且仅包含已授权范围。台账closure为DECLARED_SCOPE_COMPLETE仅表示该业务边界内义务已核对,外部交接合同确认不表示已还原外部系统内部。台账为PARTIAL时流程coverage保持PARTIAL;问答只有required_for_answer=true时才因此降级,单规则问题不受无关业务缺口阻断。缺少该对象代表没有完整性证明,客户端不得自行显示“完整业务”。
Agent或IDE不支持某个必需能力时,由适配器返回具体缺口:不支持workspace覆盖层就只提供固定Commit资料,不把EXACT标在未提交文件上;无法呈现未决项或版本边界的客户端不得收到可供自动改动决策的简化成功文本。每个接入端记录合同摘要、身份模式、结构化结果、分页续读、取消/重连、工作区能力和上限;能力协商不扩大该客户端授权工具集合。
JoyAI调用超时按查询任务状态重试,不能反向触发业务补偿。模型输出的工具名和参数须经固定工具目录、Schema、预算及授权校验;模型不可用但已取得结构化资料时,只返回规则、证据及PARTIAL,未决项记录MODEL_UNAVAILABLE;没有可返回资料时按协议错误处理。工具元数据标识只读并不能替代服务端强制只读。问答流、Agent调用与IDE上下文复用同一证据读取和权限检查入口。
18 历史订单的跨版本取证
O1按K1中的报价规则形成70元实付,退券恢复后来可能由K2中的实现处理。每次工具调用仍只读取自己声明的快照成员;调查分别读取两份依据,不能把旧修订当成K2成员直接取出。
归档观察命中的 knowledge_refs 保存服务端已核对的 snapshot_id、object_type、object_id、revision_id。映射来自归档中的报价规则版本、部署或实际执行版本与发布成员的反查,不按采集日期猜知识版本。一个修订属于多个可读发布时,可选定其中一份并固定;实现仍有歧义时列出未决项。返回关联前先检查对象和发布的权限,无权读取的标识与数量不返回。
| 步骤 | 请求及结果 | 检查 |
|---|---|---|
| 找到订单归档 | 在O1限定范围搜索INSTANCE_OBSERVATION | 原报价与恢复记录各自保留来源修订及knowledge_refs |
| 读取原报价依据 | get_business_rule携带K1及r1 | r1必须是K1的授权成员 |
| 读取恢复依据 | 另开请求,携带K2及r2 | r2必须是K2的授权成员;不延续K1的游标 |
| 核对实际执行 | 读取对应归档观察与固定源码 | 记录能把该动作绑定到这个实现;“K2包含该实现”本身不证明O1执行过它 |
| 汇总 | 保留两组调用记录及各自版本 | 解释先后发生的动作,不拼成所有实现同时生效的流程 |
问答服务内部也按上述步骤取证。AnswerResult的 snapshot_id 保留主调查版本;同时使用其他发布时,返回 knowledge_contexts,每项包含snapshot_id、使用原因reason、已读取的rule_revision_refs和evidence_refs。列表包含主快照,每个快照只出现一次;只有一个知识版本时省略该字段。
服务端将规则修订和PUBLISHED证据逐项解析到列表中的授权发布,至少找到一个所属快照。未列出的版本、未实际读取的引用以及来源版本与动作不符的证据都不能支持结论。INSTANCE_ARCHIVE证据保持独立归档身份,不要求属于知识发布;其观察仍须绑定对象、操作和归档修订。knowledge_contexts不证明观察来自同一资金时点,金额的一致性检查仍按第16节执行。
旧发布已回收时返回PARTIAL与HISTORICAL_VERSION_UNAVAILABLE;无法建立业务记录到实现的关联时返回HISTORICAL_BINDING_UNKNOWN。仍有权限的固定原文可以作为原文证据解释,但不伪造已发布规则修订。每条分支继续检查当前权限,预算在同一次问答内合计。旧客户端未协商这些字段时只取得单版本结果及历史缺口,不能接收去掉版本来源的混合答案。
存储更新
JED保存对象修订、关系、证据引用与任务状态,Vearch保存派生检索文档。查询固定知识快照;授权和证据禁用状态在读取时重新判断。
1 逻辑表与约束
| 表 | 主要键与字段 | 写入与读取约束 |
|---|---|---|
| kb_entity | entity_id、kind、namespace、stable_key | namespace、kind、stable_key联合唯一 |
| kb_entity_revision | revision_id、entity_id、payload、content_hash | 内容不可变,同对象允许多个并行修订 |
| kb_relation_revision | relation_revision_id、relation_id、source_ref、target_ref、type、guard、implementation_scope | 端点固定implementation_ref或候选集合,发布时检查其成员与适用范围 |
| kb_assertion | assertion_revision_id、status、scope、payload | 审阅与内容变化产生新修订 |
| kb_evidence | evidence_id、source_version、locator、content_hash、access_ref | 定位与内容哈希固定,禁用状态另存 |
| kb_assertion_evidence | assertion_revision_id、evidence_id、stance | 支持和反驳分别存储 |
| kb_dependency | dependent_revision、dependency_ref、dependency_kind | 正反向可查,保留旧发布依赖 |
| kb_release | release_id、parent_id、scope、state、manifest_hash | READY后清单冻结;修改内容须新建发布 |
| kb_release_member | release_id、member_kind、stable_id、implementation_scope、revision_id、operation | release_id与member_key联合唯一;operation为UPSERT或TOMBSTONE |
| kb_index_generation | generation_id、release_id、embedding_version、manifest_hash、state | 一个代际只绑定一个不可变发布清单 |
| kb_active_release | scope_id、release_id、generation_id、lock_version | 单范围生效指针,比较并交换更新 |
| kb_task与kb_task_attempt | task_key、stage、attempt、input_digest、lease_owner、fence、state | 当前attempt和fence匹配才可提交结果 |
| kb_outbox | event_id、aggregate_id、aggregate_version、payload_hash、state、next_retry_at | 业务写入与待投递事件同事务 |
| kb_inbox | consumer_id、event_id、payload_hash、task_id、received_at | consumer_id与event_id联合唯一 |
| kb_query_lease | query_id、release_id、expires_at、state | 保护在途查询引用的版本 |
| kb_evidence_access | evidence_id、deny_state、policy_ref、updated_at | 撤销不依赖重建历史发布 |
| kb_review | review_id、target_revision、author、decision、evidence | 记录评审对象的具体修订 |
这些是逻辑表,不假定JED具备某种JSON索引或跨分片事务。事务内的任务、inbox和outbox须落在能共同提交的存储边界;平台验证不满足时,先调整分区键,不能把多次独立写入称为事务。
发布成员包括实体、关系、断言和派生视图;清单同时绑定证据集合摘要。snapshot_id对外对应release_id。成员键定义为member_key=(member_kind, stable_id, implementation_scope),唯一约束为(release_id, member_key)。同一业务对象使用implementation_scope=GLOBAL,每个快照解析到一个业务修订;该修订内部可以引用多个技术实现,不把多实现业务差异压成同一确定结论。
技术对象的implementation_scope绑定service_version_ref及必要的部署或配置作用范围,因此同一stable_id可在同一快照内存在正式版与灰度版等多个实现修订。范围标识必须稳定、可解析,不能只写“当前”或使用无定义的标签。关系与实现级断言采用相应作用范围;全局业务断言和派生业务视图使用GLOBAL,但引用保留具体实现。
关系端点使用implementation_ref={stable_id, implementation_scope, revision_id}。目标无法唯一确认时,保存带各自guard和scope的候选implementation_ref集合及解析状态,不把所有候选同时当作必经路径。业务实体端点明确引用GLOBAL修订。指定快照读取时,先核对端点所指member_key及revision_id属于该快照,再读取内容;缺成员、已删除或版本不符的端点不能作为有效边返回。禁止仅按stable_id选择唯一实现,也禁止缺成员时回退到最新记录。
父版本加增量覆盖可以减少重复成员。解析顺序为当前发布到父发布,对完整member_key首次命中的UPSERT或TOMBSTONE生效。删除一个灰度实现只作用于该implementation_scope;删除全部实现须枚举目标发布中的成员,不能用一个模糊的stable_id墓碑顺带删除其他范围。链深超过服务端限制前物化完整清单,物化结果须与原解析结果摘要相同;查询不自行截断父链。父发布被引用时不得清理其成员。
2 索引代际与发布提交
实体身份按namespace、kind、stable_key定位,实现读取再限定implementation_scope和revision_id;关系按端点implementation_ref与类型建立邻接访问。按stable_id查询只用于列举候选实现,不能跳过范围选择。相同证据文本可以共用内容存储,但必须保留各自授权引用,不能按内容哈希合并权限。
Vearch文档固定doc_id、entity_id、implementation_scope、service_version_ref、revision_id、generation_id、kind、domain、service、embedding_version、access_ref、content_hash。doc_id由代际、member_key、修订和切片标识生成,重试写入同一内容。规则按完整条件与证据关系切片,分片引用共同的规则修订。
发布器执行以下步骤:
- 固定父发布和输入集合,完成成员闭包检查,生成成员及预期索引文档清单。大清单可分桶保存有序ID与内容哈希摘要。
- 在JED保存发布草稿及outbox,构建Worker写入新索引代际。重试不更新已发布代际。
- 核对预期文档ID、修订、内容哈希及删除结果。计数相等只用于发现明显缺失,不能代替集合核对。
- 通过实际检索路径验证代际过滤、权限过滤、代表性正例与旧版本隔离,并确认全部预期写入已满足该部署的查询可见性条件。原生能力不足以证明完整可见时,不进入READY;使用可验证的独立Space方案或等待平台补齐。
- 冻结清单,将状态转READY。提交时检查
active_release=expected_parent且lock_version匹配,在同一JED事务中更新指针、记录发布审计和通知outbox。
指针切换是发布生效点。并发发布竞争失败时保留READY候选,重新计算与新父版本的差异后创建新发布;不得强制覆盖已生效结果。提交响应丢失后,发布器按release_id查指针及审计状态,不重复制造新发布。
候选发布失败时,旧发布仍可读取,变更来源、待刷新对象和失败阶段另行记录。失效范围与本次问题相关时,响应带原快照及未决项;只有旧证据的查询不能据此确认变更后的线上行为。查询历史规则时仍按原快照解释,不把发布时间较早本身当作规则错误。
graph_generation是发布中关系成员集合的摘要或标识,不另建一份可漂移的“最新图”。查询固定的元组为release_id、manifest_hash、index_generation、embedding_version。若Vearch不可用,查询可退化到该发布的精确对象和关系读取,并报告语义召回缺失。
embedding_version固定实际模型修订、向量维度、文本预处理、归一化及距离度量,不能只保存可能漂移的模型别名。查询编码器必须与目标代际使用同一配置摘要;模型端点更换但别名不变时,也按新编码器处理。旧编码器不可用则关闭该代际的向量召回,退回同一发布的精确或词项通道并报告降级;不能用新模型编码查询去搜索旧向量。迁移时另建代际并完成发布检查,缓存键同时绑定编码器及检索配置摘要。
3 增量失效
更新事件包含event_id、source_id、before_version、after_version、change_kind、source_digest、stream_id。代码、XML、配置、Schema、依赖包、文档和人工修订分别维护版本。
更新器先计算技术事实与证据差异,再沿kb_dependency反向找到方法规则、模块规则、入口视图和流程。传播依据是提取时记录的实际输入依赖,不等同于业务调用图。每个待重算对象保存触发源与路径,便于解释为何失效。
新旧依赖集合共同参与传播。删除方法、配置引用或调用边时,旧依赖仍触发上层重算;目标发布通过TOMBSTONE移除对象及不再成立的关系。重命名只生成身份映射候选,未经确认不迁移全部审阅状态。
新增入口、消费者、提供方或动态绑定可能没有旧依赖边,不能只沿kb_dependency找到旧上游。更新器还按契约、事件、资源和业务场景的匹配键查询受影响范围,重跑关系对齐及入口—场景对账。知识构建登记“查询依赖”:记录查过的命名空间、匹配条件、目录修订及候选集合,即使当时结果为空也保留;该范围新增成员会使旧的“未发现消费者”或覆盖结论失效。匹配条件不能可靠增量判断时,重新扫描该范围,而不是认定无影响。
业务覆盖台账作为带修订的派生视图进入发布成员,绑定应用清单、场景期望、入口清单、流程和检查报告。新增业务场景或入口、外部交接契约变化、人工排除项撤销均触发重算;代码没有变化也不能复用原完整性结论。事件接入另配全量目录对账,记录各来源水位及差异;对账失败保留旧范围和待刷新状态,不能用丢失事件后的空差异发布新鲜结论。
输入哈希不变的任务可复用产物;输入发生变化但业务语义恰好相同时,允许复用内容块,仍须生成新的来源绑定与依赖记录。否则下一次配置或源码变化会漏掉失效传播。
失效集合达到预算时保存未完成前沿并继续离线处理,不把截断结果当作完整新版本。允许部分发布时,清单逐对象标记沿用旧修订及未刷新原因;查询当前生产行为时不能忽略该标记。
CodeWiki的增量更新比较依赖图与当前代码,更新受影响模块及其上层文档。这里也按依赖确定重算范围,并将配置、部署绑定、授权和覆盖台账的变化纳入触发源。
4 事件幂等、恢复与乱序
接收Worker在同一JED事务中写inbox和待执行任务,提交后才确认JMQ消息。inbox表示已持久接收,不表示任务完成。调度器扫描待执行任务、超时租约和到期重试,不依赖消息再次投递才能恢复。
outbox投递器发送成功后更新投递状态。若发送成功而更新失败,允许重复投递;消费者按consumer_id与event_id去重。同一event_id携带不同payload_hash时隔离事件并告警,不按普通重复忽略。事件键按业务聚合设置有助于局部顺序,但本系统不依赖JMQ跨队列全局有序;版本检查仍在消费者执行。Debezium outbox说明
任务领取递增fence。阶段结果提交同时检查任务仍为RUNNING、attempt及fence未变、input_digest一致,并提交阶段产物和下一阶段outbox。租约过期的旧Worker即使完成模型调用也不能写回新任务。调用模型可能重复产生费用,但已提交知识修订只能生效一次。
基础设施重试仅针对暂时依赖故障,使用退避与抖动并受次数和总预算限制。输入缺失或契约不兼容属于永久输入错误,进入需处理状态,不按超时盲目重试。模型输出不满足Schema时,提取编排器可按检查与审阅创建有限纠错子任务和新attempt,携带校验错误及原始输入,仍受总预算约束。纠错耗尽后进入失败状态。重放保留原event_id;业务输入改变则使用新事件与新任务输入摘要。幂等键和变更必须处于同一原子提交边界,这与AWS幂等API对请求标识与副作用的要求一致。AWS幂等API设计
inbox保留范围不得短于允许的消息重放范围。清理前须有持久任务键或处理水位继续拦截旧消息;已超出可恢复范围的旧事件进入隔离队列,不能重新生成当前知识。
源码Commit不能按时间戳排序。stream_id区分分支或发布流;非祖先事件进入独立候选。配置按命名空间版本和作用范围排序,发现版本缺口时先补取基线;不能把“较晚收到”当成“当前生效”。
5 授权、缓存与派生内容
每个请求在检索前解析身份与授权范围。知识摘要、图节点名、统计数量和证据原文均属于受保护内容;仅过滤原文链接不足以避免泄露。跨权限来源生成的规则或摘要,默认要求读者具备全部支撑来源的读取权限;如需较宽范围的业务说明,应另建经审阅的脱敏修订及访问策略。
JimDB键包含工具名、参数摘要、release_id、有效权限摘要与policy_epoch。policy_epoch必须来自内部授权系统提供的可信变更标识或本系统可靠同步的授权版本;本地递增计数不能证明已经看见外部撤权。若无法确认授权新鲜度,受保护结果不命中旧缓存,转在线校验;校验不可用则拒绝读取。这一检查也作用于在途查询的最终结果、续页、结果回放及每个尚未发出的流式片段,不能用查询租约或缓存命中替代。权限服务恢复后重新校验当前授权,再决定是否继续返回;已经发送的片段无法追回。
知识版本固定不代表授权固定。读取证据、分页、返回最终答案和导出时重新校验所用对象;授权更新使游标和缓存失效。授权变更与内容读取的因果一致性是独立问题,不能由数据库快照替代。Google Zanzibar论文
证据被撤权或禁用后,已经在模型上下文中的内容也可能影响答案。服务废弃该生成结果,移除相关证据后重新生成,或返回无法继续;只删引用而保留原答案不够。已经传到客户端的内容无法追回,流式片段必须在发出前授权。
锁只协调任务。最终正确性依赖唯一约束、条件更新和fence,不依赖JimDB锁永久有效。审计记录保留身份引用、工具、范围摘要、版本、访问判定和结果状态,默认不记录完整Prompt、源码或用户Diff。
6 版本保留、删除与恢复
查询建立带到期时间的kb_query_lease,分页和长任务续租。续租失败或版本已回收时返回VERSION_UNAVAILABLE,不切换新版本。回收器先标记代际为RETIRING,阻止新租约,再确认无有效查询租约、无生效指针、无父版本依赖和保留要求,最后删除索引与成员。进程崩溃由租约到期回收,不依赖进程内计数。
业务删除通过新发布TOMBSTONE表达,旧发布可以保留历史。强制删除证据则先写即时禁用标记,阻止所有历史快照继续取证;再删除原文、派生摘要和索引缓存,传播受影响断言状态。历史清单不改写,读取时叠加禁用判定,避免不可变版本成为绕过删除的入口。
强制删除还要阻断重新生成。删除登记以受影响的来源身份及版本范围定位,记录delete_id、deny_epoch、受影响产物、清理进度与失败原因;同一内容哈希的其他合法来源引用独立判断,不能跨授权范围误删。构建任务和查询任务提交产物前再次核对输入来源的禁用状态及deny_epoch,旧Worker、消息重放和缓存命中都不能使已禁用输入重新进入索引、摘要、回答、上下文包或Agent任务记忆。依赖关系未能完整追踪时,暂停相关范围发布并登记清理缺口,不宣称已完成清理。
禁用立即生效与物理清理分别记录。原文、分析IR、模型原响应、Embedding、派生视图、导出暂存及查询覆盖层按引用清单清理或隔离;模型端是否保留输入与输出属于JoyAI接入核验项,不能由本地删除成功推断已清理。不可变审计可保留删除操作及非正文摘要,不保留被要求删除的明文副本。
回滚只切换到成员、证据和索引仍可读的发布,不能回滚授权或证据禁用状态。备份恢复先关闭受影响查询,按以下顺序检查:
- 加载独立保留的删除台账及可信禁用水位,确认授权服务能提供当前权限判定。
- 核对恢复的发布清单、成员内容哈希与索引代际。索引缺失时按该发布重新构建,不能用其他代际凑齐结果。
- 按删除台账重放清理,核对被禁用的原文、缓存和派生结果仍不可读。
- 保存各项检查结果,只开放通过检查的范围。删除水位或当前授权无法确认时,该范围继续关闭;开放后的每次请求仍执行授权检查。
来源重新获准采集与备份恢复不同。已经删除的来源需记录本次允许采集的来源身份、版本范围及授权依据,重新采集、建立新修订并通过发布检查;旧删除记录继续生效,不直接恢复旧证据引用、导出副本或缓存。只有权限恢复而来源未被删除时,重新核验当前授权即可,不必为相同内容制造新修订。
7 一致性不变量
| 不变量 | 检查位置 |
|---|---|
| 同一快照同一member_key只解析到一个修订或删除结果;同符号不同实现范围分别保留 | 成员发布检查与读取器 |
| 返回关系的每个implementation_ref均属于当前发布且可访问,歧义端点保持候选状态 | 图展开与最终响应 |
| 生效指针只指向验证完成的不可变清单和索引代际 | READY及提交事务 |
| 接收确认后的消息存在可恢复任务 | inbox与任务事务、恢复扫描 |
| 旧attempt不能覆盖新结果 | 阶段提交条件与fence |
| 撤权和强制删除不被旧快照、缓存或回滚绕过 | 读取出口与导出 |
| 清理不会删除有效查询及父发布仍引用的数据 | 租约与依赖检查 |
故障样本见验收矩阵。
8 历史交易与新发布的范围
知识更新事件与被分析业务的消息不是同一种事件。kb_inbox去重的是采集、提取和发布任务;业务PaymentSucceeded或RefundConfirmed中的message_id、payment_id及compensation_id属于业务证据。不能因为知识平台已有inbox机制,就推断订单服务具备相同幂等保障。
业务过程可能跨越多个知识发布。支付确认时引用的报价、规则版本和配置上下文属于交易事实,不能在知识K2发布后替换成K2的当前规则。回答某笔订单的补偿依据时,查询分别绑定交易采用的规则修订、各动作实际实现版本和观察窗口;交易事实未取得时,只返回条件说明,不能从代码推导O1实际执行过哪些动作。
归档索引为观察记录建立到已核对发布成员的反向引用,读取过程见历史订单的跨版本取证。原报价r1只属于K1时,在K1中读取;恢复实现r2属于K2时另开固定分支读取。保存两份查询记录及相应租约,回收时分别检查。K2的父发布指向K1,不代表r1仍是K2成员。无法取得旧发布或执行版本关联时,保留历史缺口。
配置变更创建新配置修订、来源绑定和依赖结果。若源码未改,Java方法体和局部分析摘要可以复用;与配置有关的规则有效范围、业务流程条件和问答索引需重新计算。已经形成的历史报价保持原规则与金额,是否允许重报价须有单独业务证据。
旧消息回放保存生产者事件契约修订、消费者实现修订和消费时配置。消息缺少新增字段时,解析器要读取消费者的缺省处理、反序列化及分支,不能用最新事件Schema替旧消息补值。找不到旧契约或消费实现时,影响分析返回兼容性未确认,不能因最新Schema可校验就判定回放安全。
9 查询临时证据与覆盖层存储
源码祖先、开发分支和未提交Diff可用于一次查询,但不属于已发布知识成员。查询证据登记保存evidence_id、origin、source_context_id、repo_id、commit_sha、workspace_revision、content_hash、owner_identity、client_id、baseline_snapshot_id、owner_scope、policy_epoch、lease_id、expires_at、deny_state。origin使用PUBLISHED、COMMIT_SOURCE、WORKSPACE或INSTANCE_ARCHIVE。COMMIT_SOURCE与WORKSPACE均带source_context_id,后者还绑定workspace_revision;前者的locator固定Commit,不伪造知识revision_id。临时证据对象自身不带snapshot_id,登记中的baseline_snapshot_id只约束本次调查的参考快照,不把临时原文变成发布成员。
实例归档登记另外保存namespace、object_kind、object_id、source_ref、source_revision、observed_at及归档读取水位。INSTANCE_ARCHIVE使用来源上下文绑定主体、客户端、参考快照、固定归档修订及租约;原业务记录不因被查询而成为发布成员。观察发现与续读约束见场景查询的连续取证。
证据正文仍使用按哈希归档的受控内容存储,查询证据登记负责授权和租约。evidence_id不能作为无授权读取令牌。get_evidence不用新增读取参数,通过不透明evidence_id在当前身份与client_id下解析登记,检查外层快照等于baseline_snapshot_id、当前授权、deny_state和租约。访问受限与不存在遵守相同的不可见语义;已能确认属于当前调用方但上下文过期时返回VERSION_UNAVAILABLE,不回退发布证据或源码最新分支。撤权及强制删除写即时禁用状态,仍在租约内也不能继续读取。
工作区覆盖层使用分析输入摘要固定实际构建、依赖制品、框架适配及分析策略,再纳入各仓库基线Commit、Diff原始字节摘要、diff_completeness和omitted_categories,生成workspace_revision。相同Diff分别按SELECTED_FILES与FULL_WORKTREE提交时,不能复用为同一解释范围。实际classpath、依赖制品或构建配置改变时,即使Java文件未改,也创建新分析修订并重算受影响规则。
来源缺失状态参与输入摘要。依赖制品或构建资料尚未取得时,返回具体未决项,相关规则适用性为UNKNOWN;不复用旧环境中的确定结论。首次解析后固定覆盖层成员与关系,后续输入变化创建新workspace_revision;旧覆盖层只在原查询租约内可读。相同文本跨身份复用存储块时,授权引用仍独立,不能复用别人的查询登记。
K2发布不会修改基于K1的上下文包。IDE若希望使用K2,显式创建新查询,将同一工作区重新与K2中选定实现比较并生成新包。此时需重新检查规则适用性、契约读取和证据权限,不能只替换ContextBundle的snapshot_id。覆盖层的生命周期与发布代际分别管理:回收K1前检查查询租约;回收覆盖层前检查临时证据租约与在途引用。
10 资金观察、业务额度与并发证据
知识快照固定的是代码、规则、契约与证据引用,不冻结退款服务的交易状态。回答“现在还能退多少”时,按实例观察合同分别记录observations与observation_sets:每条观察保留observed_at、source_revision、subject_refs和evidence_refs;观察集合以observation_refs引用它们,保存consistency_status及proof_evidence_refs。consistency_status仅使用VERIFIED_COMMON_CUT、INDEPENDENT_READS或UNKNOWN。相同采集时间或相同order_id不证明多个来源来自同一业务一致性截面。INDEPENDENT_READS表示各源独立读取,不能直接判为已证实矛盾;已经发现的金额或状态矛盾另作为CONFLICT及未决项返回。
OBSERVED_AVAILABLE必须有覆盖全部计算输入的VERIFIED_COMMON_CUT证明。缺少共同切面证明时,只能返回注明假设的ARITHMETIC_BOUND,或说明观察一致性未确认而不给金额;不把K3未变化当成额度未变化。证明应覆盖来源修订、业务关联、权益及capture范围,不能仅以观察字段齐全判定成立。
实例事实的缓存键除知识快照与权限外,还须带观察集合或来源版本。已经取得的旧观察可供历史解释,不能在新请求中显示为当前额度。退款确认、在途占用和原分摊凭据必须属于同一解释范围;少一个来源就不能将缺失金额当零。实例内容只在已有授权采集与证据归档范围内使用,本章不新增生产交易查询或退款接口。
业务退款至少涉及两类限额,分析器与质量检查器分别核对,不只检查一条总金额比较:
- 行或数量权益池:
已确认商品退款 + 在途商品退款占用 ≤ 原分摊给该权益的可退现金。 - capture资金池:
该capture全部已确认现金返还 + 全部在途现金返还占用 ≤ 原capture实收现金。
重复实收返还不消耗被订单采纳的商品权益,却消耗其所属capture的资金池。每笔返还保留purpose、capture归属和权益归属,不能把PI2下两个capture总额合并成O2的商品退款上限。券退回是另一个权益恢复动作,不加到现金退款金额中。
对并发申请,读取余额、判断、占用、创建或取得退款操作的关系必须有原子性证据。源码若只先查余额再独立写申请,记录RACE_WINDOW,不能因存在事务注解或分布式锁名称就认定无超退。若多个维度由同一权威事务管理,核对条件更新、唯一键及提交边界;若跨越不同事务域,核对各层保守占用和恢复顺序,禁止把独立写入描述为原子扣减。任一层未建立可靠占用前,不应在还原结果中认定已经满足发起现金退款的前提。
退款意图标识对应本次业务取消或退货权益;退款操作标识对应可重试的远端操作;compensation_id只是协调任务身份。相同退款意图在两个协调任务中出现时,应找到复用同一操作或拒绝冲突的证据。相同意图但金额、数量、capture或分摊版本改变,不能静默复用旧结果,也不能因生成新compensation_id绕过去重。此处判断被分析业务的幂等契约,与kb_inbox的知识任务去重无关。
UNKNOWN_RESULT、请求已接收或等待对账都保留在途占用。租约超时、Worker退出、查询上下文过期和补偿任务取消,不足以证明远端退款不会再成功。只有具有终局语义的拒绝或撤销证据,才能支持释放占用;随后收到冲突的成功回执时进入冲突处理,不把该回执套用到新退款操作。已确认退款从占用转入确认金额只发生一次,重复回执不能同时重复扣占用和累加确认。
锁顺序、超时和重试也属于恢复证据。多个权益与capture共同参与时,检查是否按稳定资源顺序申请,或是否有死锁检测、回滚及同意图重试;长期无法取得资源只支持待处理或人工处置,不证明已释放业务资金。在知识结果中保存这些依赖和缺口,不向Agent暴露可执行的资金锁操作。
运行治理
1 需要回答的问题
询问“东券能否与满减叠加”时,回答包含活动、渠道、配置、例外和适用版本。未指定环境时解释代码规则;解释当前生产行为时读取对应部署与配置。
Agent搜索规则、读取证据、查询字段使用方。工具结果返回版本、来源和未解析项,供后续调用使用。
AI IDE以当前工作区为起点。请求中提供仓库、Commit、正在修改的符号和Diff,服务返回相关规则、跨仓库契约及影响路径。服务端比较生产知识与工作区版本后,标明哪些规则仍适用、哪些需要重新分析。
业务覆盖检查以领域人员确认的范围、入口集合和版本为准。扫描完仓库后,还要检查这些业务要求是否都有实现依据。业务负责人先从现有流程、需求与运营资料登记场景、触发方式、参与对象、结束条件及外部交接;分析器从应用清单反向发现入口,两份清单逐项对账。每个场景能找到对应入口和流程,每个已发现入口也能映射到场景、技术支撑能力或有依据的排除项。无法归属的入口列入缺口清单,由领域人员确认归属;模型的相似度建议只供审阅。
业务边界包含在线交易、定时到期、对账修复、批次导入、消息重放及人工处置。没有Java源码的外部系统、运营动作和终端操作保留为明确交接节点,记录可取得的契约和返回条件。确认范围内业务已还原前,审阅人员逐项检查正常、拒绝、等待、恢复和终止路径。下单到退款的示例只覆盖其中一条路径。
2 设计约束
代码、配置、证据归档、模型调用和运行日志均留在京东内网。模型通过JoyAI接入,生成、Embedding和重排按实际可用能力分别配置。JED保存权威知识,Vearch保存派生检索索引,JMQ传递构建与更新事件,JimDB承担缓存与短期协调,Ducc保存本系统配置。
内部平台的数据接口原则上可申请使用。接口可达性、调用身份、历史保留和配额仍需逐项确认。缺少运行证据时,系统返回代码与配置分析结果,同时说明生效状态未确认。
模型通过JoyAI调用。JoyAgent/JDGenie作为候选调用端或编排框架,另行核验接入能力。能力登记按实际部署端点、版本和调用身份分别保存:生成模型、Embedding、重排、结构输出、工具调用,以及客户端的协议、分页、取消和委托授权。登记状态使用未核验、样本通过、接入通过或不支持,并关联验证输入与结果;接入通过须有内部环境的验证记录,开源仓库说明仅作参考。缺少工具调用能力时可由服务端固定流程编排只读查询,缺少Embedding时保留符号与词项查询;不据此调用外网模型或搜索服务。
采用公开Agent框架时只挂载本设计允许的只读知识工具,核对其默认搜索、代码执行、文件上传、任务记忆及遥测出口。第三方默认工具和外部端点不随框架一起启用;跨任务记忆属于受保护的派生结果,须保留来源授权与失效依据。接入验收须在内部运行时逐项检查这些控制。
3 组件边界
| 组件 | 责任 | 输出或依赖 |
|---|---|---|
| 数据采集器 | 拉取指定Commit、依赖、配置、发布与治理信息 | 带来源版本的采集批次 |
| Java分析器 | 解析入口、符号、调用、条件、数据访问和框架契约 | IR包及诊断 |
| 关系对齐器 | 关联跨仓库契约、事件、数据资源和部署绑定 | 有来源的关系版本 |
| 知识提取Worker | 通过JoyAI提取规则、状态、能力与流程候选 | 结构化断言及证据引用 |
| 质量检查器 | 校验协议、实体、条件和引用,归集冲突 | 可发布结果或待复核项 |
| 版本发布器 | 固定JED读模型与检索代际,切换生效指针 | 知识发布清单 |
| 查询服务 | 执行权限过滤、检索、图查询和上下文组装 | 结构化查询结果 |
| 接入适配器 | 适配HTTP、内部JSF及客户端支持的MCP | 保持相同语义的工具接口 |
Java分析器通过IR向知识提取Worker交付结果。Java构建使用独立资源,在线查询不触发全仓库扫描。公开资料中的框架实现可作算法参考,生产部署使用内网批准的依赖。
4 数据流和处理边界
采集器先保存源码与配置等证据,再提交解析任务。分析器输出技术关系;提取Worker引用这些关系生成业务断言。检查器通过结构、引用和范围检查后,发布器构建可查询版本。JED与Vearch采用异步一致的发布协议,不执行无保护的直接双写。
查询服务先确定身份、范围和版本,再调用检索与关系查询。它可以读取现有源码证据补充细节,但不执行仓库中的程序。问答生成结果与持久知识分开保存,用户追问不会直接修改已发布规则。
5 一致性边界
一个知识发布清单可以引用多个服务版本,其中每个服务版本绑定自己的Commit、制品与配置上下文。不同服务未必同时发布,也可能在生产中同时运行多个灰度版本。知识发布清单确定本次查询可读的版本;这些版本是否曾同时部署,需要另查部署记录。
运行观测具有时间范围。静态可达关系、治理绑定和观测调用分别保存,查询时按环境与版本组合。采样日志未记录的调用边仍保留静态候选状态。
6 故障与降级
| 故障 | 处理方式 | 对外表现 |
|---|---|---|
| 部分仓库无法构建或解析 | 保留成功事实与诊断,阻止受影响规则获得确认状态 | 可查询已覆盖内容,显示缺失范围 |
| JoyAI生成不可用 | 暂停业务提取,静态符号与关系查询继续服务 | 返回技术事实,提示业务解释暂不可用 |
| Vearch不可用 | 使用精确符号、JED对象查询和已有关系 | 标明语义召回降级 |
| 新版本索引构建失败 | 保留上一已发布版本,登记变更来源、待刷新对象及失败阶段 | 返回旧快照与本次问题涉及的失效范围;变更后的线上行为未确认,历史规则仍按旧版本解释 |
| 权限服务不可用 | 无法确认授权新鲜度时,阻止新请求、在途结果、续页、结果回放及尚未发出的流式片段;缓存命中不能跳过检查 | 返回授权依赖不可用,不返回受保护内容;权限恢复后重新校验,不沿用故障前的访问判定 |
| 配置快照过期 | 保留历史值及采集时间 | 不称其为当前配置 |
7 设计决定
| 编号 | 决定 | 依据与代价 |
|---|---|---|
| ADR-01 | 技术事实与业务断言分开 | 便于追溯和重算,增加引用管理成本 |
| ADR-02 | 规则与流程独立建模 | 支持跨服务业务检索,需要概念与身份治理 |
| ADR-03 | 离线构建与在线取证并存 | 回答细节时可以核验源码,需要查询预算 |
| ADR-04 | JED主数据与Vearch派生索引分离 | 便于回滚,需维护发布清单与索引代际 |
| ADR-05 | 同一知识服务提供三个入口 | 减少规则漂移,接口须保留机器可读结构 |
| ADR-06 | 业务服务不依赖新图数据库 | 先用有界邻接查询验证负载,深图查询能力另行评估 |
8 运行单元与资源隔离
采集、Java分析、模型提取、索引发布和在线查询分别部署为可独立限流的运行单元。Java分析进程按任务隔离工作目录、依赖缓存和内存;只解析仓库内容,不默认运行Maven插件、注解处理器或仓库脚本。确需构建生成源码时使用受限构建环境,保存工具链与依赖校验和,产物通过原有采集校验后进入IR。
模型适配层统一管理JoyAI端点、模型版本、任务配额与输入限制。在线问答、后台提取和Embedding使用独立队列及配额;后台全量重建不能占满在线容量。单应用失败重试设置上限和退避,等待外部依赖的任务释放执行槽位。调度器按应用公平取任务,公共依赖的大批更新拆成可恢复子任务。
查询服务保持无状态,查询会话、游标和长任务状态写入持久存储或可恢复记录。JimDB故障时可关闭结果缓存;游标所需的短期状态若已丢失,则返回恢复或重新查询的操作。证据原文按内容哈希保存在内网批准的文件或对象存储,JED保存定位与授权引用;具体存储产品通过内部能力核验确定。
| 测量项 | 采样单位 | 用途 |
|---|---|---|
| 解析成本 | 应用、模块、源码字节、符号数与边数 | 估算Java分析槽位及单任务内存上限 |
| 提取成本 | 任务类型、输入输出Token、重试次数 | 分离模型调用成本与失败放大 |
| 存储增量 | 修订、关系、证据字节、索引文档与保留代际 | 估算增长及回收空间,避免只按仓库数量估算 |
| 查询负载 | 问题类别、并发、读取片段、关系展开量 | 比较精确查询、业务问答与影响分析的资源差异 |
| 延迟与积压 | 各阶段等待和执行时间的分位数、最老待处理任务 | 区分容量不足、外部限流和异常任务阻塞 |
测量在代表性大小和框架分布的服务样本上进行,保留高扇出、巨型方法和共享库更新样本。资源估算采用各任务类别的到达率、服务耗时及并发配额;额外列出全量重建、模型升级与索引回滚所需的同时保留空间。机器规格按上述测量结果确定;服务数量本身不足以估算资源。
9 跨组件故障定位
日志贯通source_batch_id → scan_id → task_id/attempt → release_id和request_id → query_id → snapshot_id。记录阶段输入哈希、产物引用、错误分类与耗时,默认不写源码、完整Prompt、凭证或真实业务数据。模型原响应如需保留,进入受控审阅存储,沿用输入证据权限。
报警分别覆盖待处理积压、连续失败、未解析范围增长、索引核对失败、授权服务不可用和查询错误。每项指向可执行处置:暂停特定输入、重试失败阶段、切回保留版本或停用有问题的模型版本。发布回滚不撤销真实业务部署,只改变知识查询版本。
验收
同一笔订单从业务还原、问答到Agent和IDE的逐次输入与结果,见订单补偿的四条使用链路。其中归档发现、跨版本读取和工作区引用使用接口样例检查;并发重评与差异回执沿用订单补偿夹具。
1 问答与需求分析
产品操作与页面结果以业务问答与需求分析为准,覆盖PRD-QA和PRD-IMPACT要求。技术验收继续核对本章评测集与故障矩阵中的证据、版本及权限约束。
2 业务字典
业务目录、规则与流程详情以业务目录与规则流程为准。阅读视图的来源与入口覆盖按入口卡片与服务画像核对,纠错处理按维护操作核对。
3 影响分析
网页与IDE的影响呈现以AI IDE使用及需求分析为准。合同检查继续区分已确认影响、潜在影响与纯依赖,并检查固定版本下的使用点和证据。
4 知识维护
场景登记、审阅、纠错与发布的产品验收见知识核对、纠错与更新和产品验收。维护命令的身份、修订冲突及状态转换按维护操作检查;发布、删除与撤权故障继续采用本章矩阵。
5 评测集
领域专家提供正确答案与证据,至少覆盖规则条件、例外、流程分支、字段影响、配置变化、版本冲突、无答案及权限受限。历史需求使用发生前的快照;实现Commit作为核对资料之一,评测人员排除无关重构并补充遗漏影响。
| 维度 | 指标定义 | 分母与检查 |
|---|---|---|
| 入口解析 | 正确识别入口数 / 标注入口数 | 按XML、注解和封装分别统计 |
| 关系准确率 | 正确关系数 / 返回关系数 | 候选与已确认关系分开 |
| 关系召回率 | 找到的正确关系数 / 标注关系数 | 标明只覆盖已标注范围 |
| 规则保真 | 条件、动作、例外和单位的正确及遗漏数 | 不只评价摘要整体印象 |
| 问答引用支持率 | 被引用证据支持的结论数 / 已引用结论数 | 另测没有引用的重要结论 |
| 影响准确与召回 | 按变更类别计算 | 区分依赖、候选影响和使用点支持 |
| 未知处理 | 正确保留未知或澄清的样本数 / 应保留未知样本数 | 关注错误确定回答 |
| 接入一致性 | 三端在同版本同权限下的一致结果 | 条件与证据ID一致 |
评测报告给出样本数量、来源分布和错误分类。自动评分只辅助筛选,关键业务结论由领域人员复核。试点后确定发布阈值,设计不预设未经测量的百分比。
评测人员用相同的输入、授权范围、模型版本和预算比较三种方案:符号/词项查询、文本向量检索、技术关系与业务断言的混合查询。再逐项关闭关系展开、服务画像路由和重排,观察各环节对结果的影响。
报告同时列出候选量、Token和工具调用成本,预算增加带来的收益单独说明。未解析、长尾入口、跨域高扇出和版本冲突样本分别统计,不以单服务问题的平均成绩代替跨服务结果。质量统计只使用本项目评测集,公开框架成绩不计入分母。
6 故障验收矩阵
故障样本记录初始发布、注入点、恢复操作和最终断言。
| 注入位置 | 恢复操作 | 必须成立的断言 |
|---|---|---|
| JED业务与outbox事务提交后、投递前退出 | 重启投递器 | 事件最终可接收,业务修订未丢失 |
| JMQ发送成功、outbox标记前退出 | 重投同event_id | 同consumer只生成一个持久任务 |
| inbox和任务事务提交后、ACK前退出 | 重投及恢复扫描 | 返回既有task_id,任务仍可执行 |
| Worker租约到期后旧调用返回 | 新Worker先提交再放行旧Worker | 旧fence写入被拒绝,生效修订不变 |
| JoyAI超时或返回无效JSON | 执行有限重试 | 损坏输出不进入上层提取,预算与错误可查 |
| 新旧索引文档数相等但替换一个doc_id | 执行发布核对 | 集合摘要不符,READY失败 |
| 索引写入成功但查询暂不可见 | 执行查询可见性检查 | 生效指针保持旧值 |
| allow_stack由true改为false,候选索引失败,缓存中仍只有K1证据 | 分别询问“现在是否允许叠券”和“K1中的叠券条件” | 生效指针仍为K1;前者列出配置变更及待刷新规则,不肯定当前允许;后者按K1引用解释历史条件 |
| 两个发布同时基于同一parent提交 | 放行两个提交事务 | 只有一个CAS成功,另一发布不覆盖新父 |
| 指针提交成功但响应丢失 | 按release_id恢复 | 识别已生效,无重复发布和指针回退 |
| 配置变更但源码不变 | 处理配置事件 | 依赖规则、流程重新计算并记录触发源 |
| 删除方法或消息字段 | 对比新旧依赖 | 旧关系触发失效,新发布不返回悬空边 |
| 查询途中发布与回收同时发生 | 查询续租,回收旧代际 | 查询使用原发布,有效租约阻止删除 |
| 证据读入后撤权、生成尚未返回 | 触发最终授权校验 | 废弃受污染答案,重新生成或返回无法继续 |
| 查询已读入证据并命中缓存,随后权限服务不可用且policy_epoch新鲜度无法确认 | 请求下一页、最终结果与下一流式片段;服务恢复后重新校验授权 | 故障期间均不返回受保护内容,不重放旧缓存;恢复后只返回当前仍有权限的内容,已撤权结果不能继续发送 |
| 强制删除证据后回滚知识版本 | 激活可用旧发布 | 禁用标记仍生效,旧缓存及原文不可返回 |
| 强制删除后在途提取Worker返回 | 放行旧attempt提交 | 按来源禁用状态与deny_epoch拒绝,派生摘要和索引不能复活 |
| 从删除前备份恢复 | 关闭读取,加载可信删除台账,核对发布与当前授权,再重放清理 | 任一检查未通过时保持对应范围关闭;通过后未删除内容可按当前授权读取,被删除正文和派生结果仍不可见 |
| Embedding别名指向新模型 | 用旧发布发起向量查询 | 配置摘要不匹配时停用向量通道,不以新向量查询旧代际 |
| 游标期间权限收窄 | 继续原游标 | 拒绝复用,响应不泄露原隐藏数量 |
| 重放超出inbox保留范围的事件 | 触发旧事件检查 | 持久键拦截或隔离,不覆盖当前版本 |
| 查询预算耗尽 | 分页或继续调查 | 返回PARTIAL、停止原因和未完成范围 |
7 联合评审用例
评审使用合成的订单、营销和履约服务,检查三个使用端能否取得一致的规则与证据。
问答场景输入“东券是否允许与跨店满减叠加”。评审人员提供一段含活动条件、券种和开关分支的代码,但不给生产配置快照。预期回答说明条件与异常,标明生产取值未知,并引用具体分支;不能根据默认值推断生产是否允许。
Agent场景输入“订单创建事件增加叠券标识,哪些消费方需要检查”。工具先解析事件与Topic,再查消费绑定及字段读取。结果区分已找到相关读取或分支的消费方、仅存在订阅关系的服务和无法解析的消费端;每一类都有路径与证据。
IDE场景提供一个修改叠券判断的Diff,工作区Commit与知识快照分叉。上下文包标明DIVERGED,仅在共同祖先有可用知识或能取得对应源码证据时提供祖先比较;否则返回ANCESTOR_EVIDENCE_MISSING,并分开展示旧规则与当前Diff,不拼接为确定实现。评审人员检查新增逻辑是否会触发旧消费端的缺省行为,并核对引用是否来自各自声明的版本。
随后修改Ducc快照但不修改Java代码,确认规则进入刷新计算;再删除消费字段,确认旧图关系仍触发失效。三个端在同一发布版本和权限下,应返回相同rule_id、revision_id与证据引用。
8 四条链路的贯通验收
验收使用可审查的仓库夹具、配置快照、部署映射和人工答案。
| 链路 | 注入样本 | 必须核对的结果 |
|---|---|---|
| 多服务业务还原 | 同仓库两应用、共享export不同版本、JSF两alias、同Topic两事件 | 应用身份独立,调用与消息边按版本和过滤绑定,无串线 |
| 流程完成判定 | 订单提交成功、消息消费失败、补偿入口缺失 | 不把提交成功写成履约完成,保留失败和缺失补偿 |
| 业务问答 | 同名业务对象、灰度开关冲突、无生产配置、未知术语 | 分别澄清、分范围解释、保留未知及未命中,不统一输出确定答案 |
| Agent调用 | 搜索后翻页、旧游标改参数、身份收窄、请求重放 | 固定快照,拒绝非法游标和请求冲突,权限变化后不泄露原结果 |
| IDE接入 | 五种Commit关系、dirty文件、删除符号、补丁基线不符 | 逐仓库返回关系,覆盖层与历史证据分开,错误Diff不参与确定分析 |
| 三端一致性 | 同范围、同快照、同权限访问同一规则 | rule_id、revision_id、条件树及证据一致;文字摘要可不同 |
| 更新恢复 | inbox提交后进程退出、任务完成前重投、配置独立更新 | 待执行任务可恢复,无永久跳过,无重复修订,相关规则重新计算 |
每次验收保存输入哈希、分析器与模型版本、查询参数、结构化结果和人工判定。差异定位到条件节点、流程边或引用片段,修复后重跑对应样本及其受影响链路。文档页面检查与业务验收分别记录。
业务覆盖检查还包括以下反例:
| 样本 | 输入变化 | 必须核对的结果 |
|---|---|---|
| BC-INVENTORY | 应用目录分页未结束,已有仓库全部扫描成功 | 清单来源不完整;不报告全服务覆盖 |
| BC-ENTRY | 调度目录多出一个源码未识别的到期任务 | 入口对账保留差异,场景保持PARTIAL |
| BC-RECOVERY | 在线退款失败,另一个定时任务只修复特定状态 | 仅凭同表不连接;取得选择条件与关联证据后建立有守卫恢复边 |
| BC-BATCH | 批次分页只取到前100项且全部成功 | 不判批次完成;保留未知成员范围与剩余游标 |
| BC-SPLIT | 一个订单对应两个履约单,只取得一个成功回执 | 按一对多关系保留另一个目标,不判整单完成 |
| BC-MANUAL | 已创建工单但没有处理结果 | 只能确认交接或受理,业务目标未证明完成 |
| BC-NEW-CONSUMER | 新增消费者,旧图中没有它的依赖 | 匹配键及目录对账触发关系重算,原“无消费方”结论失效 |
| BC-ORPHAN | 已发现入口没有场景归属,其他场景均通过 | 未归属项仍在分母,不能通过全范围闭合检查 |
每个用例至少保存期望集合修订、目录来源状态、覆盖义务、映射证据、未归属入口和闭合结果。只有对明确义务的检查通过,才能计为COVERED;复核后的范围排除另列EXCLUDED,不算成功解析数。
9 评测样本与判分记录
每个样本保存case_id、dataset_revision、business_domain、service_refs、input_refs、snapshot_id、permission_profile、question_or_diff、expected_claims、expected_relations、required_evidence、forbidden_claims、expected_unknowns、annotation_status。expected_claims按条件、动作、例外、单位和范围拆分;标准答案须附依据及逐项判定条件。
评测集按业务场景和契约家族划分开发集、调参集与保留集。同一流程的改写问法、同一export接口的复制实现、相邻Commit的近重复样本必须在同组,避免以同源样本同时调参和报告成绩。历史需求评测固定需求提出时可获得的输入,后续实现仅供核验,不进入检索上下文。
标注分为独立初判和争议复核。规则条件或流程边有分歧时保存双方依据,裁定前标为DISPUTED,不计入正确或错误样本的分母。生产配置无法取得时,标准答案标为UNKNOWN;模型应指出缺失资料,而非推测配置值。
| 输出 | 最小判分单位 | 错误分类 |
|---|---|---|
| 规则 | 条件节点、动作、例外和范围 | 遗漏、添加、否定反转、单位错误、范围混用 |
| 流程 | 有向边、守卫、完成点和补偿边 | 错连、漏边、把提交当完成、跨灰度串线 |
| 问答 | 一条可核验claim及其引用 | 无依据结论、引用不支持、过期证据、应澄清却猜测 |
| 影响分析 | 目标与变更相关的使用点及路径 | 漏召回、纯依赖误报、错误版本、字段映射断裂 |
| IDE上下文 | 约束或片段及来源版本 | 错误覆盖层、引用错位、关键约束被预算删去 |
报告同时给出整体与按业务域、入口类型、变更类型分组的结果。未标注范围不进入召回分母;空分母记为不适用,不记满分。失败和超预算样本保留在任务完成统计中,不能只评价成功返回的样本。重复运行的结果全部纳入报告,列出结果范围和失败次数。
10 验收门槛与变更复核
发布检查分两类。引用完整性、版本一致、无悬空成员、权限隔离、幂等恢复和索引代际正确属于硬约束;任一失败阻止相应发布。语义质量按规则保真、流程边准确与召回、未知处理及影响分析分组判断,阈值由批准的标注基线确定,并记录在validation_policy_version,不从历史宣传指标继承。
无法回答全部业务不妨碍发布已覆盖知识,但必须公布对象级覆盖与未决范围。明确不支持的解析适配点、模型超预算与缺失配置不能被改写成“无规则”或“无影响”。问题台账的关闭需要样本结果、输入哈希和复核结论,正文补充说明只改变设计状态。
| 变更 | 必须复核的集合 |
|---|---|
| Java分析器或框架适配器 | 受影响语法、入口、调用与字段映射样本,再检查关联流程 |
| Prompt或生成模型 | 规则条件、异常、金额及流程样本,比较相同输入下的结构差异 |
| Embedding、分词或重排 | 固定授权范围下的召回、排名、未知及多义词样本 |
| 规则Schema或工具协议 | 正反例、旧客户端兼容、三端结构一致性 |
| 发布、缓存或权限实现 | 第6节故障样本和跨快照、撤权、回滚样本 |
评测运行保存run_id、case_id、system_revision、model_id、prompt_version、analyzer_version、schema_version、policy_version、actual_output_hash、scores、error_labels、reviewer_decision。线上纠错先变成独立样本,经复核后进入开发集;保留集不随修复随意改答案。
11 百级服务负载与接入验收
容量测量以应用清单为输入,统计每应用源码量、入口数、技术关系数、规则候选数和输入Token分布。构建负载覆盖全量首建、公共包变更、配置集中变更和单应用日常变更;在线负载覆盖规则读取、流程展开、高扇出影响分析及IDE上下文组装。平均服务规模不能代替最大应用与公共枢纽样本。
每类请求报告排队时间、处理时间、端到端分位数、读取节点与字节、模型调用与Token、缓存命中和PARTIAL原因。构建与在线查询分别限额;构建积压不得挤占已约定的查询资源。具体配额和延迟目标在内网实测后设定,不将文档阅读性能当作业务服务性能。
问答端、Agent和IDE各保存一份实际接入记录:客户端版本、认证方式、协议版本、所支持工具与Schema、分页及取消行为、最大响应和错误示例。兼容失败记入客户端能力矩阵。MCP和IDE分别按其协议验收,HTTP调用成功只计为HTTP接入结果。
接入记录分别验证JoyAI模型端点与Agent运行时。至少检查模型别名漂移、Embedding维度与预处理不符、工具调用不支持、默认公网搜索误启用,以及跨任务记忆撤权后重读。后两项要求内网出口和受保护记忆行为的实际证据;仅配置文件中出现“内网地址”或工具声明只读不能视为通过。
12 订单补偿场景的版本验收
订单补偿基线固定五个应用、两个promotion实现及退款退券语义。IDE与版本推演给出具体步骤。本节K1、K2对应其中的“配置基线”“配置更新版”;K2只更新配置知识,不表示订单恢复实现已发布。以下断言分别验证。
| 样本 | 输入与检查点 | 必须成立的断言 |
|---|---|---|
| SC-IDE-01 | K1中promotion存在两个实现,IDE只提供repo_id | 不任取最新Commit;分别返回实现关系或IMPLEMENTATION_AMBIGUOUS |
| SC-IDE-02 | 工作区与选定实现分叉,共同祖先源码可读但无知识 | 祖先原文可取证,来源为固定Commit源码;不伪造祖先规则修订 |
| SC-IDE-03 | 已生成上下文后修改未提交Diff | 产生新workspace_revision;原包不能继续标为当前工作区依据 |
| SC-IDE-04 | 读取覆盖层evidence_id | 同授权、同来源租约可读;换身份或租约过期不得返回正文 |
| SC-IDE-05 | K1查询执行时K2生效 | 旧查询继续K1;新查询固定K2;两者不共享未区分版本的上下文缓存 |
| SC-CFG-01 | allow_stack配置改变但源码不变 | 配置绑定与相关规则范围失效重算;历史quote_id和70.00实付不被重算 |
| SC-REPLAY-01 | 旧PaymentSucceeded缺stack_policy,新消费者回放 | 按旧事件结构与新消费者缺省分支分析;缺证据返回未知,不补造字段 |
| SC-COMP-01 | RefundConfirmed到达但coupon退回失败 | 补偿未完成;不能把退款请求或退款确认当成退券成功 |
| SC-AUTH-01 | coupon证据已进模型上下文后撤权 | 废弃该次生成;仍有授权证据时重新生成,否则停止;不能只删链接 |
样本结果记录每次调用的快照、实现范围、workspace_revision、证据来源和权限版本。对工作区与固定Commit证据的检查包括原始字节哈希、行范围、租约及获取身份。业务实例状态需要单独的实例证据;只有代码和合成输入的测试,只能通过规则解释与预期结果检查。
13 复杂退款与并发补偿验收
复杂退款基线固定AL1、PI2、C1/C2及RA/RB/RC;并发补偿推演记录具体时序。以下检查针对人工设计期望与后续业务证据,不以模型给出相同数字作为充分条件。
| 样本 | 输入变化 | 必须核对的结果 |
|---|---|---|
| CX-CAPTURE-01 | A1超时,A2的C2被订单采纳,A1迟到形成C1 | 两个capture分别保留;商品权益仍为270.00,不变540.00;C1返还与商品退款分开 |
| CX-RESERVE-01 | R0确认30.00,RA占用L1剩余53.33 | L1可再占用为0;RA超时不能恢复成53.33 |
| CX-INTENT-01 | RC用不同compensation_id请求同一L1取消 | 识别同refund_intent,复用或报告冲突,不新占用同一权益 |
| CX-DIMENSION-01 | RB同时占用L2的93.33 | L1与L2分别核对,C2合计确认与占用176.66,剩余93.34 |
| CX-CONFLICT-01 | 同意图改成另一个capture、金额或AL版本 | 拒绝或列出语义冲突,不按“重复请求”静默成功 |
| CX-UNKNOWN-01 | 退款请求超时、任务租约到期或Worker崩溃 | 业务占用仍存在;先恢复原操作,不因知识任务重试而创建新退款 |
| CX-TERMINAL-01 | 同操作先见拒绝、后收到成功 | 检查拒绝是否终局及来源版本;矛盾保留冲突,不将成功归入其他操作 |
| CX-CALLBACK-01 | 同成功回执重复到达 | 同操作确认金额只计一次,占用只转出一次 |
| CX-RACE-01 | RA/RC都读到旧余额后分别写申请 | 未见原子守卫时标RACE_WINDOW;不得判定设计满足防超退 |
| CX-DEADLOCK-01 | 两操作按不同顺序获取行权益与capture资源 | 需发现稳定顺序或恢复证据;缺失时报告恢复未确认,不声称锁超时即释放退款占用 |
| CX-OBSERVE-01 | K3不变,行状态取自RA确认前,capture状态取自确认后 | 缺少共同切面证明时不能发布“当前还能退”的确定金额;已证实矛盾另报CONFLICT,不将独立读取直接判作事实冲突 |
| CX-COUPON-01 | 只完成L2退款,或L1已退款83.33但取消未最终成立 | 均不能触发L1券权益退回;同原核销权益重复任务不重复退券 |
| CX-SUBORDER-01 | S1完成退款,S2继续履约 | 可说明S1对应权益状态,不能称整个O2退款或补偿完成 |
金额判分同时核对币种、分摊版本、capture、权益对象、确认/占用状态与观察范围。若这些条件不一致,即使偶然算出53.33也不算正确。并发夹具应至少改变请求交错、回执顺序、重复次数和中断点;固定单一顺序通过不能证明业务实现不存在竞争。
入口卡片与服务画像
入口卡片展示触发条件、动作和结果;服务画像展示应用职责、入口和交接。两种视图都引用已发布的规则、契约和证据。
1 读取与版本
工作台通过 POST /internal/knowledge/views/read 读取视图。请求包含 request_id、snapshot_id、view_kind、target_ref,view_kind为ENTRY_CARD或SERVICE_PROFILE;target_ref使用现有实现三元组。snapshot_id可在首次查询时省略,由查询服务固定并返回;后续读取沿用该发布。应用有多个实现时分别返回可选择的实现,不默认合并灰度版本。
接口复用查询服务的身份、授权、预算和错误约定,属于工作台内部读取接口,不增加七工具枚举。返回为 snapshot_id、status、items、unresolved。status为OK、PARTIAL或EMPTY;OK要求存在完整可用项,EMPTY只表示当前可见范围无命中。某项含缺口时整体为PARTIAL。视图暂未生成时返回PARTIAL与VIEW_NOT_READY,保留已可读取的正式对象入口;读取旧发布不会临时混入新生成的其他版本。
单项结构见阅读视图Schema,完整例子见入口卡片和服务画像。样例描述O1设计场景,不代表已接入的应用。
2 共用字段
| 字段 | 内容与约束 |
|---|---|
| view_id、revision_id、view_kind | 视图身份与不可变修订;类型区分入口卡片和服务画像 |
| snapshot_id、target_ref | 发布清单及目标实现;目标和下列所有对象引用都要核对发布成员 |
| source_refs | 构成本视图的实体、能力、规则、契约、证据及确认记录,逐项保存ref_id、kind、stable_id、implementation_scope、revision_id |
| input_digest、generator_revision | 规范化的源修订、分组确认、生成策略和模型修订的摘要,以及生成器修订 |
| statements | 每项含statement_id、role、text、source_ref_ids;叙述必须能回查具体来源 |
| coverage | 绑定入口清单修订、目录是否完整、全部发现的入口、已归集入口、未归属入口及排除记录 |
| unresolved | 具体缺口代码、影响对象与原因;不能只写“可能不完整” |
statements的role为TRIGGER、INPUT、CONDITION、ACTION、RESULT、FAILURE、RESPONSIBILITY、BOUNDARY或DEPENDENCY。入口卡片不使用RESPONSIBILITY,服务画像必须至少有RESPONSIBILITY和BOUNDARY。text用于阅读,语义条件仍从source_refs指向的规则读取。不能只引用服务名称来支持职责,也不能以这张视图作为自己的证据。
source_refs不是权限凭据。服务端在生成、发布及返回时检查其成员和读取权限;任何必要来源不可见时,不返回原来的综合叙述,返回PARTIAL及不暴露来源身份的权限缺口,可继续列出有权读取的正式对象。不能在读取时删改statements或source_refs后沿用原revision_id。确需面向更大授权范围提供局部说明时,按派生内容权限生成并审阅独立脱敏修订,重新固定来源、input_digest及授权范围,再随发布读取;不透露隐藏入口的名称或数量。
3 入口卡片怎样组装
入口任务以声明入口及实现范围为目标。先取得它可达的规则、调用参数和外层条件,再按触发、输入、条件、动作、结果及失败分组。公共方法可被多张卡片引用,但每次调用带入的参数与守卫分别保留。同一策略下互斥的规则不能压成一个同时成立的动作列表。
卡片额外保存 entry_ref_id、rule_ref_ids、contract_ref_ids、branch_mapping_refs。entry_ref_id指向目标入口;rule_ref_ids必须指向同一发布中的原BusinessRule修订,不能另造一条“生命周期规则”代替多条原规则;branch_mapping_refs绑定分析阶段的分支核对记录。记录逐项关联需要说明的条件、动作、失败及结果与statement_id,并定位原规则的predicate、effect或原证据片段。缺少一句关键条件、引用错分支或分支检查未完成时,卡片保留具体缺口,只能部分发布。卡片不承载另一份predicate/effects正文。
O1履约拒绝卡直接引用原六条规则中的退款、退券和汇合三条修订:rr:scenario:refund-original-cash:1、rr:scenario:coupon-return-once:1、rr:scenario:compensation-join:1。它说明支付未确认时等待核验、退款沿用原实付、已核销退券与仅预占释放分别处理,以及结果未知、回执核对和完成判断。报价与核销规则仍属于各自入口。每句话能回到原规则或原证据,不凭“补偿”二字补齐实现。
该样例的原规则仍为候选、未审阅且适用范围未确认,退券条件还是OPAQUE表达式。卡片沿用这些状态,coverage.complete=false,读取结果为PARTIAL;分支叙述齐全也不能替代规则核验。原证据在本例中直接使用既有evidence_id定位不可变登记,并由夹具核对内容摘要,不另造一组看似真实的源码证据。
4 服务画像怎样组装
画像额外保存 service_id、service_version_refs、capability_ref_ids、entry_ref_ids、owned_object_ref_ids、state_ref_ids、dependency_ref_ids、grouping_ref_ids。按可部署应用和实现范围读取入口清单,再用经确认的能力分组关联入口、对象和状态职责;没有确认的分组保留为候选,进入unresolved,不自动形成确定职责。
JoyAI将已定位的对象关系写成职责、边界和依赖说明。检查器核对每项叙述的对象引用、服务实现范围及证据,并检查每个发现的入口是否进入entry_ref_ids、未归属清单或有依据的排除记录。目录未拉完时,即使已发现的入口全部归集,也不能称入口完整。
支付服务样例的职责是确认实收、受理退款和确认退款结果;订单关闭由订单服务按退款、退券及终态写入条件判断。画像对“订单关闭”的说明以BOUNDARY记录,并引用对应交接和订单能力。跨服务流程可据此帮助读者定位,但建立流程边仍读取L1关系和L2规则。
支付画像修订2在source_refs中保留本次读取的原退款规则。规则仍待审阅、适用范围及是否需要刷新未确认,对应SOURCE_RULE_UNRESOLVED写入画像unresolved。虽然三个入口均已归集,coverage.complete仍为false,读取信封为PARTIAL。入口清单、规则核验与构建任务完成分别显示,不用其中一个状态替代另外两个。
5 检查、更新与发布
inventory_revision指向固定的全局入口清单,检查器按target_ref及实现范围取得本视图应包含的入口:入口卡片对应一个入口,服务画像对应该应用实现的入口集合。服务端用这份独立清单核对discovered_entry_ref_ids,不能仅验证返回内容内部自洽。
入口覆盖检查满足:已归集、未归属、排除三组互不重叠,合并后等于本范围应发现的入口。排除项必须有适用于当前清单与范围的确认记录。complete为true还要求目录完整、无未归属、无阻断缺口,并且该声明没有超出当前授权范围。覆盖这里只说明入口归集,不能代替L4业务覆盖。
源规则、入口、契约、状态、分组确认或入口清单变化时,按直接依赖重建受影响视图。只改生成策略也产生新修订。证据撤权或禁用时按现有派生内容机制立即停止返回受影响叙述,不等下一次构建。旧视图继续属于原发布,不能原地替换正文。
生成器把任务结果inherited_unresolved中的缺项传入视图unresolved,保留缺口类型、目标及原因;只在任务日志中保留不足以满足读取要求。发布检查核对两者对应关系,并从规则修订复核候选、范围和解析状态。视图丢失任一继承缺口时拒收;必要来源不可见时继续按第2节权限处理,不直接返回缺口中的隐藏目标标识。SERVICE_PROFILE和ENTRY_CARD执行同一项交接检查。
视图生成失败不删除正式规则和契约。检查通过的视图与引用对象进入同一候选发布;原子切换仍使用发布提交。正式对象已更新而视图失败时,候选发布记录该视图不可用;页面显示尚未生成,并允许读取有权限的正式对象。
验收覆盖原规则与证据的定位、关键条件和结果遗漏、候选及OPAQUE状态传播,以及无来源职责、混用灰度实现、遗漏入口、未完成目录、重复归集、过期分组确认及来源撤权,见四层与维护合同检查。检查器读取原O1夹具并核对指定条件和动作位置;自然语言是否准确仍需要语义复核。
6 业务目录怎样浏览
工作台通过 POST /internal/knowledge/catalog/query 枚举目录,不用空字符串调用search_knowledge。根目录按有权读取的业务域列出对象和场景;选择父节点后,沿已发布的归属关系展开。一个对象可以出现在多个业务场景中,页面保存当前位置,数据不复制成多份知识。
| 请求字段 | 含义 |
|---|---|
| request_id、snapshot_id | 请求标识及固定发布;首次可省略snapshot_id并由服务返回 |
| scope | 可选的业务域、环境筛选,只能收窄授权范围 |
| parent_ref | 根目录为null;非根固定父对象的类型、标识、实现范围与修订 |
| types | 要列出的ENTITY、CAPABILITY、FLOW、RULE或SERVICE;不填时读取本目录允许的类型 |
| page_size、cursor | page_size为1至100,默认20;cursor为空开始查询,否则原筛选、父节点、发布与身份保持一致 |
返回snapshot_id、status、items、unresolved及next_cursor。每个item包含object_ref、name、description、children_state;object_ref保存kind及现有实现三元组,children_state为VISIBLE、EMPTY或UNKNOWN。只在当前权限下确有可见子项时用VISIBLE;确认本范围无子项才用EMPTY;目录资料尚未完整时用UNKNOWN并带可见缺口。返回不包含隐藏总量。
例如在K1下选择“订单补偿”场景,会列出有归属依据的退款规则、券恢复规则及参与服务;点击支付服务再读取其SERVICE_PROFILE。搜索同义词使用已确认的领域别名,用户从目录直接浏览则不依赖关键词召回或相似度排名。
游标固定排序、成员清单与过滤条件。新发布不会插入旧分页;权限变化使原游标失效。服务端核对parent_ref属于指定发布且有权读取,再解析归属边。末页只说明当前目录枚举完毕,不改变场景覆盖结论。目录源不完整时status为PARTIAL,即使当前没有items;仅在已声明范围内无命中且无缺口时返回EMPTY。
目录中每种对象的详情继续读取正式对象;入口卡片和服务画像使用第1节的视图接口。规则与流程细节沿用get_business_rule与get_business_flow对应的查询服务,内部适配不复制第二套业务判定。缺少服务画像时仍可列出有权读取的入口,明确画像尚未生成。
7 从详情继续提问
网页从规则、流程或服务详情发起问答时,调用 POST /internal/knowledge/answers/from-selection。请求封装原AnswerRequest 0.1与selection_refs,成功返回原AnswerResult 0.2。公共问答接口与七个工具不变。
| 字段 | 约束 |
|---|---|
| answer_request | 沿用问题、范围、预算、假设和请求标识;snapshot_id在此接口中必填且非空 |
| selection_refs | 1至20个选中对象;每项为kind、stable_id、implementation_scope、revision_id;kind允许RULE、FLOW、SERVICE、ENTITY、CAPABILITY,重复引用拒绝 |
网页从详情响应取得对象引用和知识版本。提交前显示选中对象;用户切换版本时重新读取详情并生成新的请求标识。服务端先核对每项引用属于指定发布、位于请求范围且当前有权读取,再将它们加入查询计划的起始对象。问“这条补偿为什么没结束”时,所选流程确定调查对象;退款和退券状态仍需另读O1归档。选中对象不转成assumptions,也不自动成为答案中的已证实结论。
相同主体、客户端与request_id沿用现有去重键;输入摘要覆盖整个封装,不能只计算answer_request。selection_refs按类型和实现三元组排序后计算摘要,调整选择顺序不产生新输入;增加、删除或更换对象修订则属于新输入。复用相同去重键时,输入变化返回REQUEST_CONFLICT,调用方用新request_id重新提交。
版本已回收返回VERSION_UNAVAILABLE;引用未属于该发布或超出请求范围返回INVALID_ARGUMENT;不可见对象返回NOT_FOUND,不能暴露隐藏名称和数量。资料读取和最终结果交付前重新授权。上述失败均不回退到名称检索或最新版,页面保留问题供用户重新选择。没有选中对象时使用普通问答接口。内部异步任务如承接此操作,须保存完整封装并按同一规则去重,不能只保存其中的answer_request。
详情问答样例沿用O1在K2的完成规则;衔接检查核对输入、版本、范围、权限和重放。
8 结果导出
工作台导出已经结束的一次问答或影响分析。导出内容保留问题或需求、范围、知识版本、已取得的结果、证据引用和未查范围,不在下载时继续搜索,也不使用当前新版替换原依据。预算不足而结束的部分结果可以导出,文件须显示未完成范围;运行中、失败或取消的调查不能导出临时片段。
页面从哪里取得导出身份
问答沿用答案结果身份。影响分析由工作台查询服务在组装结束时保存不可变结果,包括原需求、范围、快照、实际采用的trace_impact或build_context结果、支撑来源清单及未查范围。登记和内容保存一起提交后,内部阅读响应增加export_source,字段为kind=IMPACT、query_id和result_revision。query_id标识这次工作台分析,不把某个工具请求的query_id冒充整次分析身份。
一个query_id只对应一份最终结果。继续读取更多路径或重新选择目标后,形成另一份工作台分析结果及新query_id,旧结果保留原范围。尚未登记结果时export_source为空,页面禁用导出。七个工具的请求、返回和枚举不变。
请求与返回
页面调用 POST /internal/knowledge/results/export。请求包含schema_version=0.1、request_id、source_ref和format。source_ref使用页面取得的kind、query_id、result_revision;kind为ANSWER或IMPACT,format为JSON或HTML。不接受客户端上传结果正文、证据内容或任意下载地址。
服务按当前主体和客户端读取登记结果,检查修订相符、结果已经结束且仍保留。随后检查原结果与全部支撑来源的当前权限、删除状态,以及工作区或归档证据租约。任一必要来源不可读就拒绝整份导出,不删除几个字段后继续使用原result_revision。检查期间撤权或授权服务不可用时,不返回文件。
导出前按现有更正提示接口读取答案各结论或结果所引用知识的可见提示,保留checked_at和提示状态。提示接口不可用则返回DEPENDENCY_UNAVAILABLE,不以缓存的NONE代替。提示是导出时的检查结果,不改写历史答案或原分析内容。
成功返回HTTP 200及schema_version、request_id、source_ref、checked_at和artifact。artifact包含file_name、media_type、content、sha256;content是UTF-8文本,sha256按其原始字节计算。JSON保存完整导出文档;HTML由同一文档生成,附带可解析的同份JSON,正文、表格和证据均由它生成,不另写一份摘要。HTML转义源码与用户文本,不含脚本、外链资源、下载令牌或生产操作链接。页面核对摘要后将文本保存为本地文件,服务不返回无需鉴权即可访问的共享下载链接。
request_id用于追踪这次导出读取,不创建后台任务,也不作为永久下载凭据。每次请求都重新检查权限和更正状态,checked_at及文件摘要因此可能变化,source_ref始终固定原结果。导出不得扩大原范围或把PARTIAL、truncated、next_cursor、未决项改成已完成。HTML中的“本次结果未查完”由同一文档的incomplete字段确定,不能因导出成功而隐藏。
| 情况 | 返回与页面处理 |
|---|---|
| 查询不存在或不属于当前主体与客户端 | NOT_FOUND,不透露结果存在性 |
| 修订与登记结果不符 | REVISION_CONFLICT,重新读取结果身份 |
| 运行中、失败或取消 | RESULT_NOT_FINAL,页面继续显示原任务状态 |
| 原结果已回收,或所需临时证据租约已过期 | RESULT_UNAVAILABLE,重新查询后再导出 |
| 必需来源撤权、删除,或检查期间权限变化 | ACCESS_DENIED,不返回部分文件 |
| 授权或更正提示服务不可用 | DEPENDENCY_UNAVAILABLE,可重新发起导出 |
| 文档超过服务公布的同步导出上限 | EXPORT_TOO_LARGE,保留页面结果,缩小调查范围后重新查询;不截断文件 |
错误沿用内部错误对象code、message、retryable,不携带artifact。NOT_FOUND对应404,参数错误对应400,权限错误对应403,修订及未完成状态对应409,结果回收对应410,文件超限对应413,依赖不可用对应503。文件下载完成后的本地副本无法远程收回;其中的证据编号和页面链接不授予持有者查询权限。
导出合同定义字段与文件内容,O1导出样例固定既有恢复入口调查的部分结果。导出检查检查修订、调用身份、撤权、租约、更正状态、截断保留及HTML与JSON内容一致。它验证离线设计样例,不执行导出服务。
9 从上一轮继续追问
工作台调用 POST /internal/knowledge/answers/follow-up 继续上一轮调查。先用结果身份接口取得父查询的固定结果修订,再提交新问题。此接口同步返回原AnswerResult 0.2,不增加Agent工具,也不把新字段加入公共AnswerRequest。
| 请求字段 | 含义 |
|---|---|
| request_id | 本轮请求标识;重新发送同一次请求时保持不变 |
| parent_query_id | 要继续的上一轮查询 |
| parent_result_revision | 上一轮已登记的最终结果修订,不接受“最新”别名 |
| question | 本轮问题;不能把前次答案正文作为取证材料上传 |
| assumptions | 可选的用户条件完整列表,每项为assumption_id与text。省略表示继承;空数组清除;非空列表完整替换,不与旧列表追加合并 |
输入结构见内部追问请求Schema。除表内字段外不接收scope、snapshot_id、对象选择、证据身份或身份凭证。主体和客户端来自已验证的调用上下文。
哪些内容沿用上一轮
服务端读取父查询保存的原问题、已选对象、scope、知识快照及实例查询区间。例如O1原调查固定K2和09:00至10:00的归档区间,追问“恢复任务怎样找到对应方法”仍查这一组资料,不把最近归档水位换成当前时间。原查询涉及多个已核对历史知识分支时,也保留各分支的版本和用途。
仅保存起止时间不足以固定实例资料。父查询在首次归档检索时保存内部archive_read_context,包含candidate_manifest_revision、read_watermark、expires_at和候选清单;每个候选固定observation_id、source_revision及证据引用。候选清单包括已找到但尚未读取的记录,已读证据另行登记。追问沿原清单继续读取,并核对当前权限与删除状态,不重新按相同时间区间搜索当前归档索引。
O1样例固定退款ledger:refund:3、券coupon:return:2和订单order:state:8三条候选。父查询已读前两条,第三条仍可在追问中取得。同一09:00至10:00区间后来补入券修订3时,原追问继续读修订2。要读取新记录,用户新建普通查询;归档读取租约到期返回VERSION_UNAVAILABLE,不能在原query_id或原追问上下文里换水位、换候选。归档候选集与证据租约沿用按订单查已归档的观察。
引用是后续取证的起点。每轮重新检查来源、固定修订和当前权限,重新规划待证明项;上一轮答案正文、临时生成片段和已推导结论都不能作为新证据。被清除或改写的假设不能继续支持新结论。页面提交前列出本轮新增、删除和改写的条件,显示继承的对象、版本及观察区间,不能把用户条件写成归档事实。
请求文本或假设要求更换已固定的订单、环境、知识版本或观察区间时,返回NEW_QUERY_REQUIRED,页面保留新问题并带用户进入普通查询的范围选择。不能根据名称相似自动换对象。已登记为PARTIAL的NEEDS_CLARIFICATION结果可以作为父结果;补充信息仍须在原授权范围内核对,需要改变对象或实例区间时同样新建普通查询。
检查与保存顺序
- 核对原查询属于当前主体和客户端。不存在或不属于调用方时统一返回NOT_FOUND,不返回原问题或目标名称。
- 读取父结果及保存的查询上下文。尚在生成、已失败或已取消的任务不能作为父结果,返回RESULT_NOT_FINAL。已登记的部分回答可以继续;父结果被回收返回RESULT_UNAVAILABLE,上下文租约已到期返回CONTEXT_EXPIRED,页面提示重新查询。
- 核对parent_result_revision与原登记一致。不一致返回REVISION_CONFLICT,不读取较新的替代答案。旧答案有纠错或更正时,仍按原修订读取其可见提示;用户要从更正后的答案追问,需显式选择该答案作为新的父查询。
- 对继承的范围、对象和来源重新授权。授权服务不可用返回DEPENDENCY_UNAVAILABLE;来源撤权返回ACCESS_DENIED;旧知识不可读取返回VERSION_UNAVAILABLE。不得删除受限引用后继续使用含受限内容的旧上下文。
- 固定本轮有效假设与新查询计划。每轮使用新query_id及result_revision,保存parent_query_id、parent_result_revision和实际继承的上下文。原查询、原答案和原假设保持不变。调查预算由服务端当前策略和调用配额控制,不因提交追问无限延续原预算。
- 完成取证后再次授权,将本轮最终结果、结果身份和本轮查询上下文一并登记,再交付AnswerResult。结果修订仍通过结果身份接口取得。超出本轮预算时按原问答语义返回PARTIAL,不静默切换为异步任务。
重发同一次追问
去重键使用主体、客户端和request_id,摘要覆盖操作类型、上述完整请求及字段的省略状态。assumptions按assumption_id排序,文本不改写;同一请求内重复assumption_id返回INVALID_ARGUMENT。未传assumptions与传空数组具有不同含义,不能算成同一输入。凭证不进入摘要,但每次请求均重新授权。
首次接收时原子登记去重键、输入摘要、固定父上下文和新一轮query_id。相同键及相同输入返回同一轮结果,不重复启动;仍在处理时返回RESULT_NOT_READY及可追溯query_id,调用方保持原请求重试。相同键修改问题、父结果或假设返回REQUEST_CONFLICT。并发提交相同输入只能登记一个新查询;不同请求标识允许从同一父结果分别发起调查,彼此不覆盖。
去重记录至少保留到父上下文与本轮结果的可重放租约均到期,避免父上下文仍有效时丢失请求身份。保留期内返回原轮次;结果或上下文已过期时明确返回不可用,不重新执行成另一轮。需要重新调查时使用新请求标识,并在父上下文不可用时走普通查询。重放结果前再次核对当前权限,不能从缓存跳过授权。
O1追问样例复用已有规则、归档区间和证据引用。追问合同检查覆盖假设继承、清除与替换,固定版本与对象、未读归档候选、同区间晚到修订、父结果状态、身份、过期和重复请求;自然语言中的范围变化识别仍需单独评测。
场景维护、审阅与发布操作
维护操作只改变知识服务中的范围、确认记录和构建发布状态。执行退款、退券或修改业务订单不属于这些接口。Agent的七个读取工具不承载维护写入。
1 角色与操作权限
| 操作身份 | 可执行的操作 | 仍需满足的条件 |
|---|---|---|
| 业务使用者 | 提交纠错、为自己提交的问题补充材料、查看可见处理结果 | 有权读取目标修订和补充材料 |
| 领域维护者 | 修订场景要求、确认业务范围与能力分组、处理纠错、核对领域别名 | 获授对应业务域和操作权限;不获得源码或交易数据的额外权限 |
| 技术审阅者 | 关联入口、确认实现依据与技术分项 | 有权读取入口、实现和对应证据 |
| 平台维护者 | 登记来源、开始构建、重试或取消构建、重试纠错重答、请求发布或回滚 | 获授来源或发布范围;发布检查和领域确认不能由角色权限替代 |
上述身份表示操作分工,内部权限系统可以将多项分工授予同一人。业务确认和技术确认分别保存,设计不假设内部组织已经采用某种审批层级。调用方身份从服务端验证的凭证取得。
2 命令与查询
维护命令使用 POST /internal/knowledge/maintenance/commands。公共字段为schema_version、command_id、action、target、expected_revision、payload。target包含kind与id;新建时使用调用方生成的资源ID并要求expected_revision为null,已存在时冲突。修改现有资源必须提供expected_revision。
服务端以主体、客户端和command_id去重。相同键与相同规范化完整输入返回原命令结果;相同键改变action、target、expected_revision或payload,返回COMMAND_CONFLICT。每次重放仍重新授权,凭证本身不进入业务摘要。去重记录过期后返回COMMAND_EXPIRED,调用方查询原资源状态后使用新命令ID;不重新执行未知的旧写入。
GET /internal/knowledge/maintenance/commands/{command_id}查询命令,GET /internal/knowledge/maintenance/resources/{kind}/{id}读取资源当前状态和修订。列表入口 GET /internal/knowledge/maintenance/resources按kind、可见业务域、状态和不透明cursor分页;游标固定筛选、授权和读取水位。用户只能看到有权读取的资源和活动,不显示隐藏数量。
结果包含command_id、status、resource_ref及可选task_id、release_id、error。status为ACCEPTED、APPLIED或REJECTED。ACCEPTED表示已持久接收并创建后续任务;APPLIED表示本次知识管理状态变更已提交。它们都不能代替构建任务或发布状态。拒绝时error.code、message、retryable说明原因,message不能暴露隐藏资料。
请求结构见维护命令Schema和维护请求例。资源查询保留当前修订、业务状态、关联任务/发布、可见活动记录与allowed_actions;allowed_actions只提示当前可选操作,提交时仍检查权限。
审阅参数从资源详情取得
SCENARIO、GROUPING和CAPABILITY详情为有对应审阅权限的调用方返回review_context,包含content_revision、evidence_digest、scope_digest、policy_revision。服务端从当前内容、固定证据及适用范围计算这些值;页面展示对应内容和来源,审阅者确认后原样提交,不在浏览器拼接摘要。GET还返回资源revision;命令expected_revision取这个值。
0.2的REVIEW_SCOPE、REVIEW_GROUPING、REVIEW_CAPABILITY将review_context四个字段原样放入payload,再增加dimension、decision和reason。服务端重新计算并校验:资源revision已变返回REVISION_CONFLICT;内容、证据、范围或策略不再对应返回REVIEW_STALE。客户端重新读取后再确认,不能自动改成新摘要重发。
业务确认会增加资源revision,但不改变未编辑的content_revision;技术审阅者重新GET取得最新resource revision后,仍可核对同一内容。无审阅权限或无法取得必需来源时review_context为null,allowed_actions不包含对应审阅;缺少上下文时不能提交一组手填摘要。REVIEW_CORRECTION按已有目标与证据合同处理,不使用这组分项确认摘要。
返回结构见维护资源详情Schema;首次构建与维护样例给出能力保存后GET、业务确认后再次GET与技术确认的对应值。
维护列表与下一步
资源列表增加view筛选:ALL为授权范围内的资源,SUBMITTED_BY_ME为当前主体创建的资源,BUSINESS_PENDING与TECHNICAL_PENDING分别表示当前内容修订仍缺该项确认。创建主体由服务端登记,客户端不能传任意subject_id代替“我”。待核对视图仅返回当前主体拥有相应审阅权限的资源;它不是个人派单系统。
列表单项含resource_ref、content_revision、state、pending_dimensions、next_action、required_role及allowed_actions;纠错另含followup_task和replacement_ref,缺少可读结果时为空。next_action与required_role由状态和权限计算,例如“核对恢复要求/领域维护者”“核对恢复入口/技术审阅者”“等待候选生成/平台维护者”。某项同时缺业务和技术确认,可以出现在两个待核对视图中。
分页固定view、kind、domain_id、state、授权和读取水位;修改筛选重新查询。权限变化后旧游标失效,返回CURSOR_INVALID,不复用原待办计数。提交人可从“我提交的”读取自己的可见状态,创建者身份不自动授予关联证据权限。
3 资源与命令目录
| action | target.kind | payload与处理 |
|---|---|---|
| REGISTER_SOURCE | SOURCE | source_ref、domain_id、capabilities;登记来源,不自动启动构建 |
| START_BUILD | BUILD | source_bindings、baseline_snapshot_id、strategy_revision、scope;固定已登记来源及实际分析输入,检查通过后新建构建 |
| SAVE_CAPABILITY | CAPABILITY | domain_id、name、definition、input_object_refs、output_object_refs、boundary、evidence_refs;保存能力定义候选,不直接发布 |
| REVIEW_CAPABILITY | CAPABILITY | 与REVIEW_SCOPE相同的分项确认字段;确认当前能力定义、来源与边界 |
| SAVE_SCENARIO | SCENARIO | title、domain_id、material_refs、trigger、object_refs、completion、obligations;新增或形成新的场景修订 |
| MAP_ENTRY | SCENARIO | entry_ref、obligation_ref、evidence_refs;关联入口及待核对义务,不自动判为已覆盖 |
| REQUEST_EXCLUSION | SCENARIO | obligation_ref、reason、evidence_refs;形成排除建议,待业务与技术确认 |
| REVIEW_SCOPE | SCENARIO | dimension、decision、evidence_digest、scope_digest、policy_revision、reason;dimension为BUSINESS或TECHNICAL,decision为ACCEPT或REJECT |
| SAVE_GROUPING | GROUPING | grouping_kind、domain_id、target_ref、member_refs、alias、evidence_refs;保存能力入口分组或领域别名候选 |
| REVIEW_GROUPING | GROUPING | 与REVIEW_SCOPE相同的分项确认字段;绑定当前分组内容修订,不自动合并对象 |
| SUBMIT_CORRECTION | CORRECTION | target_type、target_revision_ref、description、evidence_refs;答案纠错另带answer_ref;再次提交可带supersedes_correction_ref关联旧单 |
| SUPPLEMENT_CORRECTION | CORRECTION | description、evidence_refs;为待补充问题增加资料,回到待处理 |
| REVIEW_CORRECTION | CORRECTION | decision、reason、evidence_refs;接受时另给resolution,说明改知识还是重新回答;改知识必须指定knowledge_target_ref |
| RETRY_BUILD / CANCEL_BUILD | BUILD | reason;重试从失败阶段新建attempt,取消后拒收迟到结果 |
| RETRY_ANSWER_REGENERATION | CORRECTION | failed_task_ref、expected_task_revision、reason;重试此纠错关联的失败重答,输入从服务端原任务读取 |
| REQUEST_PUBLICATION | RELEASE | candidate_revision、expected_active_release、reason;核对候选清单、审阅、索引及授权,再尝试激活 |
| ROLLBACK_PUBLICATION | RELEASE | retained_release_id、expected_active_release、reason;建立新的回滚请求,检查目标仍可读取后切换 |
对象引用在读取时逐项解析,场景和纠错不能引用不可见的材料。保存场景允许义务尚无实现,缺口交给覆盖核对;未确认的场景只产生候选流程,不使业务覆盖闭合。MAP_ENTRY和排除建议改变场景修订,原范围确认随之失效。REVIEW_SCOPE提交的摘要必须与服务器重新计算结果相同,不能由客户端自报“已确认”。
登记后的首次构建
REGISTER_SOURCE提交来源登记,返回SOURCE资源修订及APPLIED。它不执行仓库程序、不接收凭证正文,也不自动创建构建。来源详情读取包含readiness(UNCHECKED、READY或WAITING_INPUT)、missing_inputs、checked_at和可选择的固定输入引用。准备检查只调用已授权适配器读取应用映射、Commit、制品清单和资料修订元数据,登记这些不可变引用;不做Java分析,也不执行构建。首次打开尚未检查时为UNCHECKED,检查结束再返回可选输入;失败保留WAITING_INPUT及可见缺项。页面显示的准备结果不能代表已经分析完成。
维护者选择已登记来源、实际Commit/制品/配置与部署资料、分析策略和范围,调用START_BUILD。source_bindings逐项包含source_resource_ref、source_resource_revision和input_revision_refs;后者指向可读且已登记的不可变资料修订,不接受任意URL或未解析分支。scope包含domain_ids、application_ids和environment,必须属于来源登记与调用方授权的交集。首次构建的baseline_snapshot_id为null;有基线时检查它仍可读取。
输入准备分为两类,页面分别列出:
| 输入情况 | 是否阻止开始构建 | 后续处理 |
|---|---|---|
| 无法固定源码Commit或实际制品、无法识别应用、没有必要读取授权、策略修订不存在 | 阻止;分别返回INPUT_NOT_READY或授权错误 | 补齐身份和固定资料后重新提交 |
| 已有固定源码但缺某依赖方法体、部分治理绑定或当前配置值 | 按所选策略允许的局部分析启动 | 在计划中登记缺项,相关调用或规则保持未解析;策略明确要求这些资料时才阻断 |
| 尚未发现恢复入口、业务能力待确认、场景尚无实现映射 | 不阻止源码扫描 | 它们是分析和业务核对的待解决项;L3/L4保留对应缺口,不能要求先找到扫描结果再启动扫描 |
策略在服务端固定启动必需项与允许缺项;客户端不能把必需项自行降级。首次扫描不要求已经生成入口、业务规则或已确认能力。输入检查不得把“恢复入口尚未找到”当成缺少源码身份。
服务端按下面顺序处理:
- 核对来源资源修订、资料归属与权限,确认策略要求的必需输入已固定。可局部分析的资料按策略列为缺口;缺少Commit、应用映射等必需身份时返回INPUT_NOT_READY及可见的missing_inputs,不创建BUILD、plan或Worker任务。准备状态按读取时实际资料计算,不能由客户端声明READY。
- 检查通过后,在同一知识事务保存BUILD的CREATED修订、固定计划、首个采集任务和outbox,再返回ACCEPTED、resource_ref及task_id。后台按既有COLLECTING等阶段运行。
- 同一主体与客户端重发相同command_id、相同完整输入,返回原构建;换输入返回COMMAND_CONFLICT。不同command_id也受target.id唯一约束,相同BUILD不能建两次。输入补齐后使用新command_id,重新检查;因输入改变重算时使用新build_id。
界面从来源记录的build_refs进入已创建构建;来源readiness变为READY不等于构建完成。构建启动后某项依赖不可访问,转入既有失败或部分结果处理,不能回写计划替换资料。登记引用发生变化时先形成新的来源登记,原登记及构建继续可追溯。样例与拒绝分支见首次构建与维护样例。
维护命令0.2新增START_BUILD、SAVE_CAPABILITY、REVIEW_CAPABILITY、RETRY_ANSWER_REGENERATION、分项确认的content_revision,以及纠错旧单关联字段。原0.1命令继续按原字段校验;新动作和新字段不得以0.1发送。公共问答和七个工具的协议版本不变。
4 场景核对与确认
场景保存材料、触发条件、业务对象、完成条件及正常/异常/恢复义务。业务确认核对“需要完成什么”,技术确认核对入口、实现及证据。两项确认均绑定目标内容修订、材料摘要、范围摘要和确认策略;相同内容修订可以分别追加两类确认,资源revision随操作增加。
场景内容有新修订时,旧确认留在旧修订中。新的入口映射、排除要求或材料变化必须重新核对相应内容。排除只有在两类确认均接受当前提案后才进入有效排除列表;拒绝保留理由和原缺口。确认场景不等于发布,覆盖结果仍按流程与覆盖计算。
能力对象的创建与确认
能力对象使用CAPABILITY资源。维护者先按业务域、名称及已确认别名查找已有对象;可复用对象必须定义、边界及适用范围一致。同名结果供选择,不自动合并。新概念通过SAVE_CAPABILITY保存名称、定义、输入输出对象、交接边界及来源证据,创建DRAFT内容修订。提取任务的entity_candidates只供填入候选,不能自动变成已确认能力。
服务端校验所有对象和证据可读、有固定修订,按领域与定义摘要检查重复候选。定义冲突保留CONFLICT及可见差异,不能进入确认状态;资料缺失时保留DRAFT及缺项。能力内容变化使旧确认失效。
REVIEW_CAPABILITY分别记录BUSINESS和TECHNICAL确认,使用当前内容、证据、范围摘要和确认策略。两项均ACCEPT且没有未解决冲突,能力成为CONFIRMED;任一REJECT保留DRAFT及原因。返回正式对象引用(kind=CAPABILITY、stable_id、implementation_scope=GLOBAL、revision_id)和确认记录;该修订尚未随知识发布,不向普通查询暴露。候选构建可按授权的固定修订读取它。
SAVE_GROUPING的CAPABILITY_ENTRIES目标必须是上述CONFIRMED能力修订,再核对入口成员并提交两类分组确认。能力定义更改后,引用旧定义的分组不能用于新画像,需重新确认。画像产物与能力、分组、入口规则进入同一候选发布,发布检查逐项核对来源;旧发布的能力与画像保持原修订。
能力分组与领域别名使用GROUPING资源。grouping_kind为CAPABILITY_ENTRIES时,target_ref定位能力修订,member_refs列出入口修订,alias为null;为TERM_ALIAS时,target_ref定位业务对象修订,alias填写领域内别名,member_refs为空。target_ref与member_refs必须可读且类型符合,不能把同名方法直接归为同一能力。
领域维护者核对业务含义,技术审阅者核对对象与入口依据。两项确认都绑定当前内容、证据及范围摘要;内容修改后重新核对。确认通过的分组记录随候选发布供L3读取,别名随发布供目录和检索使用。相同领域的同一别名指向不同对象时保留冲突候选,返回GROUPING_CONFLICT,不形成已确认映射;不同领域的同名词各自保留。分组和别名确认不执行实体合并,也不改变已发布对象身份。
5 纠错状态与后续发布
纠错单状态为OPEN、NEEDS_INFO、ACCEPTED或REJECTED。提交后为OPEN;审阅要求补充转NEEDS_INFO;提交补充后转OPEN;接受或驳回成为终态。终态不原地重新开启,新的问题另建纠错单并关联旧单。处理理由与有权限的材料可供提交者回看。
target_type为KNOWLEDGE时,target_revision_ref定位知识修订,不填写answer_ref。为ANSWER时,target_revision_ref定位已完成问答的result_revision,answer_ref包含query_id与claim_id。服务端读取原结果,核对该结论属于该查询和修订,保留当时的问题、资料范围及可读取证据;尚未完成的流式内容可写入问题描述,不能填入最终结论标识。
审阅时先区分回答生成错误和知识错误。resolution为ANSWER_REGENERATION时,仅用于答案纠错,创建独立的重新回答任务,不改写原答案或知识;新任务固定其实际使用的资料及版本。resolution为KNOWLEDGE_CHANGE时,处理者必须给出已经核对的knowledge_target_ref,核对它仍是此次处理对象的当前修订,随后创建知识候选任务。答案引用了错误规则时,可以选择这条路径;原问答不会因新知识发布被重写。REJECT和REQUEST_INFO不填写resolution。
接受决定、对应任务和outbox事件在同一知识事务提交。生成失败时,纠错单保留已接受的处理决定和失败原因。界面分别显示“纠错已接受”和后续任务结果;知识纠错显示候选检查与发布状态,回答纠错显示新的回答链接。原可查询知识直到新发布生效才改变。新的知识断言仍按审阅与纠错追加修订。
被质疑对象已有新修订时返回TARGET_CHANGED,附当前可见修订及差异入口。处理者核对后重新提交新的命令;不把针对旧实现的确认自动用于新实现。人工补充与源码矛盾时保存冲突,接受纠错也不能消除没有解决的证据分歧。
纠错重答失败后怎样重试
纠错单已ACCEPTED、resolution为ANSWER_REGENERATION且当前关联重答任务为FAILED时,有本业务域RETRY_ANSWER_REGENERATION权限的平台维护者可以重试。普通提交者看到“重新回答失败,等待平台处理”及可见原因,不获得该动作。构建任务的RETRY_BUILD不处理回答任务。
命令target定位原纠错单,expected_revision取其当前资源修订;payload只带failed_task_ref、expected_task_revision和reason。服务端核对该任务确为当前followup_task、状态FAILED且仍属于此单。它读取原任务冻结的完整问答输入、所选对象、知识版本与输入摘要,不接受客户端替换问题、假设或资料范围。
执行前重新核对操作人重试权限、原查询主体与客户端的当前授权、Worker服务身份及有效委托。原主体失去必要权限、原知识版本已回收或原输入资料不能合法读取时,拒绝重试并保留失败原因;不得借维护者权限扩大结果范围,也不静默改成最新资料。需要改变输入时,由原使用者重新查询或发起新的核对,不复用这次重试。
同一事务保存新重答任务、retry_of原失败任务、相同input_digest、纠错单的新followup_task及outbox。旧任务保持FAILED,新任务有独立task_id/query_id;原纠错单仍是ACCEPTED,原答案及更正提示不被覆盖。相同command_id与输入只返回同一新任务;并发点击由纠错单与失败任务修订检查阻止重复创建。新任务成功后按原授权关系交付结果,并更新该结论的更正入口。
驳回后带新证据再次提交
旧单为REJECTED且提交者取得新依据时,页面创建新CORRECTION,SUBMIT_CORRECTION携带supersedes_correction_ref。服务核对旧单可读、已终结,以及新单目标与原目标存在可核验的同一业务对象或修订继承关系;新单仍使用本次确认的target_revision_ref。资料无关、目标关系不明或旧单尚未结束时返回INVALID_ARGUMENT。旧单保持终态,新单独立进入OPEN,不能覆盖旧决定。
原结果上的纠错提示
网页每次打开原答案或规则详情时,调用 POST /internal/knowledge/corrections/status。请求包含target_type、target_revision_ref;ANSWER还带query_id和本次要显示的claim_ids。服务先按现有结果读取权限核对原目标、主体和来源,再逐项返回该目标或结论上的提示;不能用此接口绕过原答案只对原主体与客户端可读的约束。
响应包含checked_at、status_revision和items。每项为target_revision_ref、claim_id(知识对象为null)、state、message、replacement_ref;state为NONE、UNDER_REVIEW、ACCEPTED_PENDING或CORRECTED。UNDER_REVIEW只表示有待核对问题,不判定结论错误;ACCEPTED_PENDING表示该项已接受纠错但替代内容尚未可用,生成失败仍保留此状态与可见的失败提示;CORRECTED要求替代回答已完成或替代知识已发布。知识尚未发布时不能提前给出“已修正”。
同一目标或claim有多个可见纠错时,服务按处理记录合并提示:仍有已接受但未完成的修正时为ACCEPTED_PENDING;否则还有待核对问题时为UNDER_REVIEW;其余存在已完成更正时为CORRECTED;仅有驳回或没有可见问题时为NONE。未完成修正不会被另一条已完成记录掩盖。存在互不相容的替代内容时保留待核对状态,不自行选择一个版本;只有唯一、已核验且可读的替代才返回replacement_ref。
接受决定与按目标修订/claim索引的提示事件一起提交;新结果完成或发布后追加replacement_ref,原正文不改。提示只作用于具体目标和claim,不扩大到答案其他结论。业务人员接受了一条知识纠错,也不能仅因其他答案引用同一证据就把它们全部判错;需要已核对的依赖与结论映射。
处理单及其材料可能比原答案更敏感。服务只返回查看者可读的提示,隐藏处理人的身份、纠错材料和不可读替代对象;替代内容不可见时replacement_ref为null,显示“已有更正,当前无法读取”。没有可见提示返回NONE,不泄漏隐藏纠错数量。提示接口不可用时显示“更正状态暂未取得”,不把旧的NONE缓存当成当前判断。答案导出同时保存本次查到的提示与checked_at,不修改历史导出件。查询结果、缓存和替代跳转每次重新授权。
维护读取样例覆盖待办筛选、接受后生成失败、已更正但替代结果不可见及无关claim不受影响。提示结构见纠错提示合同。
答案怎样取得可纠错的结果身份
网页通过 POST /internal/knowledge/answers/resolve-result 提交 query_id,取得 query_id、result_revision、snapshot_id、claim_ids。请求只接受query_id;主体及客户端来自已验证的调用上下文,不接受客户端自报用户、结果修订或结论列表。此内部接口不改变AnswerResult,也不增加Agent七工具。
同步问答在返回AnswerResult前,原子保存最终答案、查询归属、不可变result_revision及其结论索引;异步问答在发出completed前做相同登记。一个query_id只绑定一份最终结果,部分回答在完成生成后也可登记。不得先登记身份再补写正文,也不从客户端上传的答案反建结果身份。
网页拿到答案后,用其中的query_id解析身份,再用返回的result_revision和所选claim_id提交纠错。即使异步结果已经带出修订,提交时仍由服务端核对原结果。解析接口只允许原查询所属的主体与客户端读取;其他用户的query_id不形成访问资格。授权审阅者通过已受理纠错的权限检查读取原结果,不以此接口冒用原用户身份。
服务端在查找前核对身份,返回前再次检查结果及支撑来源的当前权限。查询不存在或不属于当前调用上下文时均返回NOT_FOUND,不披露它是否存在。查询仍在生成、已取消或失败时返回RESULT_NOT_FINAL;结果已回收时返回RESULT_UNAVAILABLE。返回这些结果时不提供修订或结论标识,页面保留问题描述但不能伪造一个可提交的最终答案目标。来源已经撤权时返回ACCESS_DENIED;无法核对当前授权时返回DEPENDENCY_UNAVAILABLE,不从旧缓存取身份。
结果身份用于定位,不是访问凭证。后续提交纠错和读取原答案仍重新授权,核对query_id、result_revision和claim_id属于同一条最终记录。同步答案能解析后提交、未完成查询、外部query_id、登记失败、正文与结论索引不一致,以及解析期间撤权的检查见交叉审阅检查。
6 并发、失败与发布
资源更新使用expected_revision条件写入。两人同时处理同一纠错单,只有一个基于原修订的决定能够提交;另一个收到REVISION_CONFLICT和可见的当前修订。命令去重记录、资源新修订、活动记录与后续任务/outbox在同一JED事务中提交。事务提交后响应丢失,重试返回同一命令;Worker恢复继续执行持久任务。
构建重试仅用于FAILED任务,产生新attempt并沿用或显式重新确定输入;输入变化时新建构建任务。取消与完成竞争按资源修订提交,先到达终态的结果保留。平台管理员重试构建不会让非法Schema或缺证据的对象跳过检查。
发布与回滚都核对expected_active_release。当前生效版本已经改变时返回ACTIVE_RELEASE_CHANGED,不覆盖他人的发布。REQUEST_PUBLICATION目标必须READY;回滚目标必须仍保留完整对象、索引与合法来源。删除标记和当前授权独立检查,回滚不能恢复已撤权内容。发布CAS与旧版保留沿用存储更新。
| 错误 | 调用方处理 |
|---|---|
| INVALID_ARGUMENT | 修改输入,使用新的command_id |
| INPUT_NOT_READY | 按可见missing_inputs补齐资料,核对来源后用新命令开始构建 |
| CURSOR_INVALID | 重新按当前筛选和授权查询列表 |
| ACCESS_DENIED / NOT_FOUND | 转交权限流程或重新定位,不推断隐藏对象 |
| COMMAND_CONFLICT / COMMAND_EXPIRED | 查询命令和资源;核对后用新command_id |
| REVISION_CONFLICT / TARGET_CHANGED | 读取可见的新修订,重新确认本次操作 |
| INVALID_STATE | 当前状态不允许操作,按allowed_actions继续 |
| GROUPING_CONFLICT | 核对同域别名的对象与依据,保留候选,冲突未解决时不确认映射 |
| REVIEW_STALE / ACTIVE_RELEASE_CHANGED | 重新核对内容或发布基线,不盲目重试 |
| DEPENDENCY_UNAVAILABLE | 按retryable与退避建议查询或重试同一命令 |
HTTP中的参数错误为400,身份与授权错误为401/403,目标不可见为404,命令、修订及状态冲突为409,可重试依赖故障为503。异步接收返回202,已完成或重放已完成结果返回200。实际身份委托、事务能力与权限数据仍按内部样本核验。
7 操作验收
检查不同命令ID同时处理旧修订、同ID修改参数、提交成功后响应丢失、证据撤权后重放、接受纠错但生成失败、排除建议缺一类确认、发布时生效版本改变、取消后旧Worker返回及回滚遇到删除标记。验收以资源修订、候选任务和生效发布分别判断,不以一个“成功”字段代替三者。样例检查见四层与维护合同检查。
场景推演
完整场景与复杂情况
在京东实际生产环境中,业务规则从来不是简单的单机单表逻辑,而是由跨越 100 多个微服务的分布式系统协同实现。本文档通过 4 个最具代表性的复杂电商生产场景,深度剖析跨服务结算、拆单分摊、分布式异常补偿与高并发幂等防护。
下单、支付与履约失败
在典型的京东正向交易全链路中,从用户点击“立即下单”到实物仓库发货,涉及 7 个核心微服务的分布式协同。系统必须保障高并发下的数据一致性与资源防超卖。
1.1 跨服务 JSF RPC 与 JMQ 协议交互时序
sequenceDiagram
autonumber
participant GW as [API 网关 / Edge]
participant Order as [trade-order / 订单核心]
participant Promo as [promo-engine / 促销算价]
participant Stock as [stock-center / 库存中心]
participant Pay as [trade-pay / 支付结算]
participant Fulfill as [fulfillment / 仓储履约]
rect rgb(239, 246, 255)
Note over GW,Order: 阶段一:正向下单与资源预占
GW->>Order: 1. 提交订单 (order_id, pin, items, coupon_ids)
activate Order
Order->>Promo: 2. JSF: 锁定优惠券并计算满减金额
Promo-->>Order: 2.1 返回最终应付价格及优惠锁定凭据
Order->>Stock: 3. JSF: JimDB Redis 分布式原子预占库存
Stock-->>Order: 3.1 返回预占成功锁标识 (lock_token)
Order->>Order: 4. 本地事务: JED 分库分表写入 order_info (WAIT_PAY) 及 outbox_event 本地消息表
Order-->>GW: 5. 下单成功,拉起收银台
deactivate Order
end
rect rgb(240, 253, 244)
Note over Order,Pay: 阶段二:用户支付核销与仓储派发
Pay->>Order: 6. JMQ: pay_success_notify (支付实收成功)
activate Order
Order->>Order: 7. 状态机推进: WAIT_PAY -> PAID (版本号乐观锁)
Order->>Fulfill: 8. JMQ / JSF: 派发仓储履约下发请求 (order_dispatch)
deactivate Order
end
rect rgb(254, 242, 242)
Note over Order,Fulfill: 阶段三:履约拒绝与 Saga 全链路逆向自动补偿
Fulfill-->>Order: 9. 履约拒绝: fulfillment_rejected (仓库缺货/地址超区/风控拦截)
activate Order
Order->>Order: 10. 状态机跃迁: PAID -> CANCELING
Order->>Pay: 11. JSF: 原路全额退款 (退回银行卡/微信/京豆)
Order->>Promo: 12. JSF: 解冻并返还优惠券资产
Order->>Stock: 13. JMQ: 释放 JimDB 预占库存与仓库配额
Order->>Order: 14. 终态核验: 全部成功推进至 CLOSED;若遇银行卡注销等不可逆重试耗尽,推进至 MANUAL_ARBITRATION (待财务人工仲裁)
deactivate Order
end
关键异常与分布式防护策略
- 未支付超时自动关单:
- 订单创建时,向 JMQ 投递 30 分钟延迟消息(Delay Topic)。超时未支付时,订单状态机从
WAIT_PAY跃迁为CLOSED,同时异步驱动促销解冻优惠券、库存中心释放 JimDB 预占库存。
- 订单创建时,向 JMQ 投递 30 分钟延迟消息(Delay Topic)。超时未支付时,订单状态机从
- 履约拒绝与支付通知乱序到达:
- 若履约永久拒绝事件先于支付成功事件到达,订单中心将状态标记为
WAIT_VERIFY(待核验挂起);待支付成功回执补齐后,系统识别已处于履约拒绝态,直接触发逆向退款,绝不再向仓储派发发货指令。
- 若履约永久拒绝事件先于支付成功事件到达,订单中心将状态标记为
- 部分节点超时补偿:
- 退款、退券或释库存若发生网络超时,本地事务表记录待补偿事件,由后台定时扫表 Worker(
OrderCancelCompensationWorker)执行带指数退避的幂等重试。
- 退款、退券或释库存若发生网络超时,本地事务表记录待补偿事件,由后台定时扫表 Worker(
- Transactional Outbox 本地事务表与异步消息的血缘缝合:
- 订单中心更新订单主表与发送 JMQ 补偿事件采用 Transactional Outbox 模式。业务写操作与
outbox_event表的写入包裹在同一个 JED MySQL 本地事务中,杜绝分布式裂脑。独立 Worker 轮询outbox_event投递 JMQ,知识库系统在 AST 静态分析中通过双跳血缘将“业务写表 → Outbox 事件 → 下游消费端”缝合成完整业务拓扑。
- 订单中心更新订单主表与发送 JMQ 补偿事件采用 Transactional Outbox 模式。业务写操作与
- 不可逆失败的终态仲裁与平账闭环 (
MANUAL_ARBITRATION):- 当退款遇到银行卡注销、原支付通道单边账彻底冻结、或营销券模板已物理下线无法补发等永久性不可逆失败时,扫表 Worker 在重试耗尽(默认 10 次)后,将订单分布式状态推进至终态
MANUAL_ARBITRATION(待财务人工仲裁),杜绝状态机无限卡死在COMPENSATING中间态;知识库系统自动挂载财务/客服人工平账工单入口,确立“自动重试 → 幂等防重 → 人工平账”的 100% 终态闭环。
- 当退款遇到银行卡注销、原支付通道单边账彻底冻结、或营销券模板已物理下线无法补发等永久性不可逆失败时,扫表 Worker 在重试耗尽(默认 10 次)后,将订单分布式状态推进至终态
同一笔订单怎样查到恢复代码
在线上运维或业务咨询中,产品经理与技术支持经常提出复杂排障问题,例如:“订单 O1 已发生履约拒绝,用户收到了退款,但订单状态为什么一直停留在‘处理中’,且用户账户未收到返还的优惠券?”
业务知识库通过四层资产拓扑与跨工具协同,在 3 分钟内完成全链路归因:
flowchart TB
User["<b>【排障发起 · 业务提问】</b><br/>研发/运营:订单 O1 停滞在处理中且未退券,根因是什么?"]
Step1["<b>【第 1 步 · Web 工作台】</b><br/>检索 L4 全局流程 ➔ 快速定位 promo-engine 节点挂起在 COMPENSATING 状态"]
Step2["<b>【第 2 步 · 智能问答 Q&A】</b><br/>追问退券失败原因 ➔ 召回 CouponRefundServiceImpl 规则卡片(L2 规则)"]
Step3["<b>【第 3 步 · JoyCoder Agent】</b><br/>调用 get_evidence 与 trace_impact ➔ 追查发现后台重试 Job 达到 10 次上限熔断"]
Step4["<b>【第 4 步 · 事实与配置锁定】</b><br/>代码行定位至 CouponRefundServiceImpl.java:128 ➔ 锁定 Ducc 开关 promo.auto.delay=false"]
Step5["<b>【第 5 步 · JoyCoder IDE 研发修复】</b><br/>本地打开补丁 ➔ 实时预警下游 3 个结算系统财务时间窗口约束 ➔ 零资损安全发布"]
User ==>|1. 发起排障| Step1
Step1 ==>|2. 深入定位| Step2
Step2 ==>|3. MCP 探针深入| Step3
Step3 ==>|4. 源码行锚定| Step4
Step4 ==>|5. 编码与影响评估| Step5
classDef qStyle fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a;
classDef stepStyle fill:#f8fafc,stroke:#475569,stroke-width:1.5px,color:#0f172a;
classDef endStyle fill:#ecfdf5,stroke:#059669,stroke-width:2px,color:#064e3b;
class User qStyle;
class Step1,Step2,Step3,Step4 stepStyle;
class Step5 endStyle;
四端协同排障实录
| 调查环节 | 研发执行操作 | 知识库输出的技术事实依据与代码行引用 |
|---|---|---|
| 1. 业务工作台 (Web) | 输入订单号 O1 或查询“履约拒绝后未关单原因” |
系统展示 L4 流程拓扑,标出:支付退款已在 T2 时点确认(金额 70.00 CNY),但优惠券退还任务返回 FAILED,导致整单停滞在 COMPENSATING 中间态。 |
| 2. 智能问答 (Q&A) | 追问:“券服务退券失败的代码条件是什么?” | 系统返回 L2 规则卡片引用:CouponRefundServiceImpl.java:128,券状态为 EXPIRED(已过期)且系统配置未开启自动延期。 |
| 3. Agent 深度排查 (MCP) | Agent 调用 get_evidence 与 trace_impact 追查下游 |
定位到后台重试 Worker CouponCompensateScanJob.java,发现该 Worker 连续重试 10 次失败后,触发了熔断拦截进入人工对账池。 |
| 4. IDE 研发修复 (JoyCoder IDE) | 研发在 IDE 中打开配置或增加补偿延期逻辑 | IDE 实时计算改动爆炸半径:检测到该修改影响下游 3 个结算系统,并提示前置约束:“修改券延期逻辑必须遵守财务核销对账时间窗口”。 |
逐次调用、两个版本的读取方式及错误输入见订单补偿的四条使用链路。
三行商品与两笔实收
在大型电商交易中,一笔购物车结算往往包含多个不同商户(SOP vs 自营 FBP)或不同仓储温层(常温 vs 冷链)的商品行,系统必须执行父单拆子单(Split Order)与跨商品满减优惠按比例高精度分摊。
2.1 拆单分摊与退款上限锁定凭据 (Allocation Ledger)
| 商品行 ID | 商品类型与履约形态 | 原价 | 满减分摊 (跨店满 ¥300 减 ¥20) | 专享券分摊 (L1 专享东券 ¥10) | 实付现金权益上限 (凭据 AL1) | 逆向退款在途与核销锁定规则 |
|---|---|---|---|---|---|---|
| L1 | 自营手机壳 (FBP 常温仓) | ¥100.00 | ¥6.67 | ¥10.00 | ¥83.33 | 发生退款时优先扣减此限额;在途受理期间余额锁定 |
| L2 | POP 数据线 (SOP 商家直发) | ¥100.00 | ¥6.67 | ¥0.00 (未享专享券) | ¥93.33 | 独立子单结算,退款不影响其余两行原分摊比例 |
| L3 | 自营钢化膜 (FBP 仓配) | ¥100.00 | ¥6.66 (分钱配平) | ¥0.00 (未享专享券) | ¥93.34 | 尾数分钱配平吸收,确保各行实付之和严格等于实收 ¥270.00 |
| 合计 / 闭环强校验 | 父订单汇总 (3行单品) | ¥300.00 | ¥20.00 | ¥10.00 | ¥270.00 | 与支付结算实收 ¥270.00 严格吻合,杜绝资金敞口 (误差 0.00 元) |
多支付渠道与部分退款金额约束
- 分摊凭据不可变性(Allocation Record):
- 下单成功时生成分摊凭据
AL1,记录每个商品行的原价、优惠分摊值及现金退款上限(现金权益)。后续发生部分退款时,严格按凭据AL1扣减,绝不允许在部分退款时根据剩余商品动态重新计算分摊比例。
- 下单成功时生成分摊凭据
- 多支付渠道记账与退款(Multi-Channel Pay):
- 270 元实收若由
微信支付 200元与京豆抵扣 70元组合支付,退款时严格按各渠道出资比例或业务规则优先原路退回京豆,再退回微信零钱,并在 JED 数据库pay_record_00~31写入渠道级退款流水。
- 270 元实收若由
- 在途占用(Pending Allocation):
- 当商品行 L1 申请退款 53.33 元处于“银行受理中”时,该 53.33 元进入“在途占用”状态;整单可用退款余额立即扣除在途占用,防止并发申请超额退款。
同一退款意图的并发请求
在高并发与多渠道接入场景下,同一笔订单可能同时收到多方发起的逆向退款请求(例如:用户在手机 App 端自主点击取消申请,同时客服在运营后台发起人工拦截退款)。
3.1 三级并发防重与状态机协调协议时序
sequenceDiagram
autonumber
participant UserApp as [手机 App / 用户端]
participant CSR as [客服工作台 / 运营端]
participant JimDB as [JimDB Redis 集群]
participant OrderDB as [JED MySQL (order_info)]
participant Pay as [trade-pay-service / 支付中心]
rect rgb(239, 246, 255)
Note over UserApp,OrderDB: 关卡一:JimDB 分布式防重互斥锁 (SetNX)
UserApp->>OrderDB: 1. 并发请求 A: 发起退款申请 (request_id_A, order_id)
CSR->>OrderDB: 2. 并发请求 B: 发起退款申请 (request_id_B, order_id)
OrderDB->>JimDB: 3. SETNX lock:order:cancel:${order_id} (TTL=30s)
JimDB-->>OrderDB: 3.1 请求 A 获取分布式锁成功
OrderDB->>JimDB: 4. SETNX lock:order:cancel:${order_id} (TTL=30s)
JimDB-->>OrderDB: 4.1 请求 B 获取锁失败 (排队重试或直接幂等返回处理中)
end
rect rgb(254, 243, 199)
Note over OrderDB,Pay: 关卡二:JED 状态机乐观锁版本控制与退款发起
OrderDB->>OrderDB: 5. UPDATE order_info SET status='CANCELING', version=version+1<br/>WHERE order_id=O1 AND status='PAID' AND version=1
Note over OrderDB: 状态机通过 version 乐观锁原子跃迁为 CANCELING
OrderDB->>Pay: 6. 调用退款接口: refund(order_id, refund_seq_A, amount=270.00)
Pay-->>OrderDB: 6.1 支付中心受理成功,生成退款凭据
OrderDB->>JimDB: 7. 释放分布式锁
end
rect rgb(240, 253, 244)
Note over CSR,OrderDB: 关卡三:请求 B 唤醒重试并触发幂等拦截
CSR->>OrderDB: 8. 请求 B 再次读取 order_info
Note over OrderDB: 发现当前状态已为 CANCELING,且退款流水已存在
OrderDB-->>CSR: 9. 幂等拦截平稳响应: 提示“该订单退款已在处理中,无需重复提交”
end
并发与防重核心防御规则
- 分布式互斥锁(JimDB Distributed Lock):
- 任何涉及资金与状态跃迁的关键入口,均基于
JimClient.setNX("lock:order:cancel:" + orderId, token, 30, TimeUnit.SECONDS)加锁,确保多节点并发请求串行化。
- 任何涉及资金与状态跃迁的关键入口,均基于
- 唯一约束与幂等流水(Idempotency Key):
- 退款记录表建立唯一索引
uk_order_req(order_id, refund_request_id);支付服务根据业务键order_id生成确定性外部退款流水号,银联/微信支付网关以此保证单次扣划绝对幂等。
- 退款记录表建立唯一索引
- 状态机乐观锁(Optimistic Locking):
- 更新数据库状态时使用
WHERE status = 'PAID' AND version = #{version};并发竞争落败方因更新影响行数为 0,自动退出执行分支,杜绝状态机回退或乱序覆盖。
- 更新数据库状态时使用
金融级超时幽灵交易 (Phantom Request) 防御机制
在微服务 RPC 调用中,客户端最忌讳将“网络超时(ReadTimeoutException)”直接等同于“下游执行失败”:
- 幽灵交易隐患:若支付服务实际已在银行渠道扣款/退款成功,但因网络抖动返回给订单中心时超时,订单中心若盲目发起重试或标记失败,将产生巨额资金单边账。
- 确定性防重流水:客户端在发起退款前,生成确定性防重序列号
refund_seq = SHA256(orderId + "_" + itemSku + "_" + refundAttempt); - 前置落库占位:在调用下游前,事务内先向
order_refund_flow插入处于PROCESSING状态的凭据记录,命中uk_order_req唯一索引; - 超时对账闭环:若 RPC 遭遇超时,状态机严禁回退,而是将状态置为
REFUND_SUSPENDED(挂起对账),由后台 Worker 携带原refund_seq调用下游“退款状态正向查询接口”,直到下游明确返回成功或失败后,方可推进状态机终态。
JimDB 分布式锁原子释放与 Watchdog 自动续期:JimDbLockManager.java
package com.jd.trade.concurrency.lock;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.*;
/**
* JimDB (Redis) 生产级分布式锁管理器
* 支持唯一 Token 防误删、Lua 脚本原子释放与后台 Watchdog 自动延期
*/
@Component
public class JimDbLockManager {
private final StringRedisTemplate redisTemplate;
private final ScheduledExecutorService watchdogExecutor = Executors.newScheduledThreadPool(2);
private final ConcurrentMap<String, WatchdogTask> activeLocks = new ConcurrentHashMap<>();
// 释放锁原子 Lua 脚本:核验 value 是否为加锁持有者,防止超时后误删他人已获取的锁
private static final String RELEASE_LOCK_LUA = """
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
""";
private final DefaultRedisScript<Long> releaseScript =
new DefaultRedisScript<>(RELEASE_LOCK_LUA, Long.class);
public JimDbLockManager(StringRedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public record LockHandle(String key, String token, boolean acquired) {}
public LockHandle tryAcquire(String lockKey, long timeoutSeconds) {
String token = UUID.randomUUID().toString();
Boolean success = redisTemplate.opsForValue()
.setIfAbsent(lockKey, token, Duration.ofSeconds(timeoutSeconds));
if (Boolean.TRUE.equals(success)) {
// 启动后台 Watchdog 守护线程:每隔 1/3 TTL 进行自动续期
WatchdogTask task = new WatchdogTask(lockKey, token, timeoutSeconds);
activeLocks.put(lockKey, task);
task.scheduleRenewal();
return new LockHandle(lockKey, token, true);
}
return new LockHandle(lockKey, null, false);
}
public boolean release(LockHandle handle) {
if (!handle.acquired() || handle.token() == null) {
return false;
}
// 停止 Watchdog 续期
WatchdogTask task = activeLocks.remove(handle.key());
if (task != null) {
task.cancel();
}
// 执行原子 Lua 脚本安全释放
Long result = redisTemplate.execute(releaseScript, Collections.singletonList(handle.key()), handle.token());
return Long.valueOf(1L).equals(result);
}
private class WatchdogTask {
private final String key;
private final String token;
private final long timeoutSeconds;
private volatile ScheduledFuture<?> future;
WatchdogTask(String key, String token, long timeoutSeconds) {
this.key = key;
this.token = token;
this.timeoutSeconds = timeoutSeconds;
}
void scheduleRenewal() {
long renewalDelay = Math.max(1, timeoutSeconds / 3);
future = watchdogExecutor.scheduleAtFixedRate(() -> {
try {
String currentVal = redisTemplate.opsForValue().get(key);
if (token.equals(currentVal)) {
redisTemplate.expire(key, Duration.ofSeconds(timeoutSeconds));
} else {
cancel();
}
} catch (Exception ignored) {
// 续期容错
}
}, renewalDelay, renewalDelay, TimeUnit.SECONDS);
}
void cancel() {
if (future != null && !future.isDone()) {
future.cancel(true);
}
}
}
}
Spring 事务消息外发保全:Transactional Outbox 模式
在微服务更新本地数据表并外发 JMQ 消息时,坚决杜绝在 @Transactional 方法体内直接同步调用 producer.send()(若发消息成功后本地事务回滚,会导致下游收到“幽灵消息”消费脏数据):
package com.jd.trade.order.service;
import com.jd.trade.order.domain.OrderRefundEvent;
import com.jd.trade.order.repository.OrderRefundMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* 生产级事务一致性外发模式
*/
@Service
public class OrderRefundService {
private final OrderRefundMapper refundMapper;
private final JmqMessageProducer jmqProducer;
public OrderRefundService(OrderRefundMapper refundMapper, JmqMessageProducer jmqProducer) {
this.refundMapper = refundMapper;
this.jmqProducer = jmqProducer;
}
@Transactional(rollbackFor = Exception.class)
public void processOrderRefund(String orderId, String refundSeq, long amount) {
// 1. 本地数据库写操作:落退款流水与状态机变更
refundMapper.insertRefundFlow(orderId, refundSeq, amount, "REFUNDING");
// 2. 注册事务提交钩子:确保数据库事务物理 COMMIT 成功后再投递远程 JMQ
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
// 事务成功提交后异步投递消息,彻底杜绝脏事务幽灵消息
OrderRefundEvent event = new OrderRefundEvent(orderId, refundSeq, amount);
jmqProducer.sendAsync("jmq.trade.refund.completed", orderId, event);
}
});
}
}
详细定义见分摊、支付实收与退款权益、乱序与补偿完成条件、部分退款与并发约束。检查样例见复杂退款与并发补偿验收。
订单优惠与失败补偿:业务还原推演
本推演使用场景基线。服务、订单O1、源码片段和事件均为合成夹具。下面描述知识系统应如何分析这些输入,不执行下单、扣券或退款,也不声称存在真实运行记录。
1 固定输入与可回答范围
知识快照K1包括order、coupon、payment、fulfillment的版本1,以及promotion版本1和版本2。各技术对象以stable_id、implementation_scope、revision_id定位,两个promotion实现不共用一个符号修订。正常路径指定sv:promotion:1;未指定渠道及配置时,两个实现都保留为候选。
订单O1的100.00原价、20.00满减、10.00券优惠、70.00实付属于设计输入,不是交易查询结果。源码可以支持“此分支按原实付退款”;要回答“O1已退70.00”,还需要与O1、原支付及RF1匹配、金额与币种核验通过的退款完成证据。此处没有真实订单运行记录。
| 输入包 | 样例内容 | 缺失时的结果 |
|---|---|---|
| 源码包 | 五个服务、promotion两实现、构建依赖和固定Commit | 对应方法与关系保留未知,不用另一版本补齐 |
| 绑定包 | JSF契约、环境与alias;JMQ事件、消费组和过滤表达式 | 只建立可能调用或订阅关系 |
| 配置包 | allow_stack引用、默认值、渠道与灰度范围 | 代码条件可解释,当前取值未知 |
| 事件结构包 | PaymentSucceeded、FulfillmentRejected、RefundConfirmed | 只知道消息入口,无法确认字段映射与兼容 |
| 业务样例包 | O1金额、关联键及故障F1至F9 | 作为条件化推演输入,不升级为生产证据 |
初次推演发现基线缺少履约派发和核销调用绑定,现已补成合成设计输入:order在支付确认后调用coupon核销,核销确认后通过JSF派发履约。来源为本次设计夹具,不是扫描真实源码所得;完整性检查仍验证相应声明、控制关系及绑定,不从下游失败事件反推上游执行。
2 证据登记
下表的Java路径是解释用的虚拟定位,不是工程中存在的源码文件。机器夹具使用design-fixture下的合成语义文档定位,校验文档片段的字节哈希;它不提供或校验真实Java文件。业务提取结果是人工期望值,后续真实分析器须用对应仓库样本另行验收。
| evidence_id | 样例定位 | 需要保留的原文含义 |
|---|---|---|
| ev:scenario:promo-quote | promotion/QuoteService.java | 活动、券种、渠道和allow_stack;返回quote_id、规则版本、金额分摊、有效期 |
| ev:scenario:promo-quote-v2 | promotion/QuoteService.java,版本2 | 灰度变更条件;不得替换版本1的分支 |
| ev:scenario:order-create | order/CreateOrder.java | 校验quote_id、金额、渠道、有效期并持久化报价及reservation_id;创建失败触发释放预占 |
| ev:scenario:order-payment | order/PaymentHandler.java | 核对支付事实与预占引用,重复成功通知不重复发起核销 |
| ev:scenario:coupon-commit | coupon/CommitReservation.java | 以reservation_id及支付关联核验预占,核销状态与去重记录原子提交 |
| ev:scenario:order-dispatch | order/DispatchFulfillment.java | 核销确认后通过JSF派发履约,保存接单关联 |
| ev:scenario:order-reject | order/FulfillmentRejectHandler.java | 永久拒绝且支付事实已确认时创建或读取compensation_id |
| ev:scenario:payment-refund | payment/RefundService.java | 按原支付流水与实付申请退款;相同业务请求重试复用退款操作 |
| ev:scenario:payment-confirm | payment/RefundConfirmation.java | 退款完成事件的状态、金额、原支付及补偿关联 |
| ev:scenario:order-recovery | order/CompensationRecovery.java | 持久pending_reject、支付后重评、原幂等键退款重试、CP1+RS1券恢复任务与MANUAL_REQUIRED出口 |
| ev:scenario:recovery-coordination | 合成并发协调条件 | 同订单事实写入、状态修订与持久重评待办共同提交;修订变化重算,扫描任务补取待办 |
| ev:scenario:refund-receipt-validation | 合成回执核验条件 | RF1、P1、CP1、70.00 CNY及最终确认状态均相符,才能确认原操作 |
| ev:scenario:order-refund-result | order/RefundHandler.java | 回执通过上述核验后写退款子状态;字段缺失或不符不写CONFIRMED |
| ev:scenario:coupon-return | coupon/ReturnReservation.java | 预占未核销时release,已核销时核验本次核销关联后return;重复业务操作不重复退回 |
| ev:scenario:order-join | order/CompensationCompletion.java | 退款完成、券退回完成后,订单状态更新成功才闭合补偿 |
| ev:scenario:fulfillment-reject | fulfillment/RejectOrder.java | 永久拒绝原因、order_id与履约单关联,发布FulfillmentRejected |
| ev:scenario:payment-event-v1 | export/PaymentSucceeded.java | 旧消息字段集合,缺少stack_policy |
| ev:scenario:bindings | integration/bindings.json | 契约版本、alias、Topic、事件类型、消费组与过滤规则 |
| ev:scenario:config | config/stack-context.json | 样例渠道与配置上下文;F1中故意移除此项的有效值 |
ev:scenario:payment-consumer-default是待补证据ID,不写入已有证据集合。引用它的结论必须进入取证需求,不能通过创建空片段满足引用检查。
3 从源码到IR
分析器先解析符号及控制上下文,再提取业务断言。以下为需要在夹具中出现的控制结构,不是可运行实现:
报价进入条件:活动命中 AND 选择券
渠道不允许 OR allow_stack不为true → 拒绝叠加
其余路径 → 返回报价凭据与100.00/20.00/10.00/70.00分摊
报价接受:预占券成功 → 创建订单并保存quote_id与reservation_id
订单创建失败:释放预占;释放失败保留待处理,不发起退款
订单创建:凭据存在、未过期、渠道和金额匹配 → 保存报价引用
支付成功:核验支付归属和成功事实 → 关联reservation_id → 核销操作
履约拒绝:永久拒绝 AND 支付已确认 → 取得compensation_id
退款申请:compensation_id + 原payment_id + 70.00 → 请求退款
退款超时:保存结果未知;同业务键重试取原接收记录,等待RefundConfirmed
拒绝先到:持久pending_reject;支付事实确认后重评,进补偿而不再派发
事实并发:同订单事实与重评待办共同提交;重评提交前核对状态修订,竞争后重新读取
退款回执:核对RF1/P1/CP1、70.00 CNY和最终确认;已接收、金额不符或字段缺失均不确认退款完成
退券失败:按CP1+RS1恢复任务重试;预算耗尽写MANUAL_REQUIRED,不写完成
补偿闭合:refund=CONFIRMED AND coupon=RETURNED
订单状态更新成功 → compensation=COMPLETED
每个“核验”“保存”“操作”都必须进一步关联到调用或数据读写证据。只看到方法名refund或finishCompensation时,分析器不能推断上述语义。
| branch_id | 技术关系或出口 | 规则映射 |
|---|---|---|
| branch:scenario:stack-deny | 活动、券、渠道及配置共同控制REJECT | rule:scenario:stack的拒绝条件 |
| branch:scenario:create-failed-release | 订单创建失败,释放reservation;释放失败保持待处理 | 预占释放支路,不触发退款 |
| branch:scenario:quote-invalid | quote_id、有效期、渠道或金额不匹配时提前退出 | rule:scenario:quote-binding |
| branch:scenario:payment-duplicate | 已处理业务支付操作时返回既有结果 | rule:scenario:coupon-commit-once |
| branch:scenario:reject-before-payment | 永久拒绝已到但支付事实未知,保存待核验 | rule:scenario:refund-original-cash的前置条件 |
| branch:scenario:reevaluate-revision-changed | 重评期间订单事实修订改变,保留待办并重算 | 不提交基于旧事实的派发或补偿决定 |
| branch:scenario:refund-receipt-mismatch | 回执关联、金额、币种或终态不符合原RF1 | 不将差异回执纳入退款完成条件 |
| branch:scenario:refund-timeout | 调用结果未知,保存原业务幂等键 | 退款操作的未知结果出口 |
| branch:scenario:coupon-return-failed | 退券未确认,持久恢复任务并重试,不满足join | rule:scenario:compensation-join |
| branch:scenario:recovery-budget-exhausted | 恢复预算耗尽,写MANUAL_REQUIRED | 恢复终点,不等同业务失败或完成 |
| branch:scenario:join-satisfied | 两子状态完成且订单更新成功 | rule:scenario:compensation-join的完成动作 |
字段传播单独记录:quote.paid_amount → order.quoted_paid_amount是COPY;payment.actual_paid_amount → refund.request_amount是COPY;金额参与“是否相等”只产生INFLUENCES。字段名相同不构成复制证据。order_id、payment_id、reservation_id、compensation_id各自有映射路径,不能仅靠共同order_id把两个支付尝试或两次补偿合并。
跨服务边记录调用点、两端implementation_ref、参数映射与绑定证据。消息边额外记录事件结构版本、消费过滤及关联键。发送版本和消费版本可处在不同部署窗口,旧消息回放单独检查,不能简单要求同时部署。
4 业务规则产物
| rule_id | 条件与动作 | 证据及限制 |
|---|---|---|
| rule:scenario:stack | 活动命中且选择券时,渠道允许与allow_stack共同决定是否接受叠加 | ev:scenario:promo-quote;F1下不判断生产开关 |
| rule:scenario:quote-binding | 下单使用指定报价凭据,核验金额、渠道和有效期 | ev:scenario:order-create;不以当前优惠配置重算历史报价 |
| rule:scenario:coupon-commit-once | 支付事实确认且预占关联有效时核销;重复业务支付操作返回已处理结果 | ev:scenario:order-payment、coupon-commit及bindings;核销确认后才进入派发 |
| rule:scenario:refund-original-cash | 永久履约拒绝且支付确认后,按原支付实付申请现金退款 | ev:scenario:order-reject、payment-refund;O1条件下为70.00,不包含30.00优惠 |
| rule:scenario:coupon-return-once | 本次核销与补偿关联匹配后退券,相同补偿请求不重复退回 | ev:scenario:coupon-return;券是否可恢复为可用态取决于明示政策 |
| rule:scenario:compensation-join | 退款确认、券退回确认与订单终态更新全部成立才完成 | ev:scenario:order-refund-result、coupon-return、order-join |
每条规则使用独立revision_id和输入摘要,核验状态保留四个维度。合成样例中的代码逻辑可以设计为已解析,但仍没有专家生产审阅,也没有当前生产配置。rule:scenario:stack在本夹具只绑定v1。v2技术证据独立保存但尚无完整规则产物,查询报告这一覆盖缺口;不同实现条件不因业务名称相同而合并。
退款与退券是两个补偿动作,不描述为“把事务回滚”。退款超时是UNKNOWN_RESULT;退款确认只更新退款维度;退券是否退回到AVAILABLE、EXPIRED或其他状态,需要实际政策证据。基线只要求“退回动作确认”,不擅自扩展为“用户一定能再次使用”。
5 流程组装与完成判定
流程标识为flow:scenario:order-compensation。状态不是一个总开关,而是订单、支付、券与补偿子状态的组合。知识中保存状态维度及join条件,查询按证据解释,不驱动业务状态变更。
| step_id | 进入条件 | 完成证据 | 后续与缺口 |
|---|---|---|---|
| step:scenario:quote | 报价请求进入指定promotion实现 | 报价返回值和规则版本 | 进入reserve,灰度范围必须相容 |
| step:scenario:reserve | 报价通过后的coupon预占申请 | reservation_id及预占结果 | 成功后进入create,失败不创建有效订单 |
| step:scenario:create | 预占成功、报价有效,金额与渠道一致 | 订单持久化及quote_id、reservation_id引用 | 失败进入释放预占;释放失败保持待处理 |
| step:scenario:payment-confirm | 收到PaymentSucceeded或授权支付事实证据 | 原支付归属、金额及成功状态核验 | 无pending_reject进入核销;有pending_reject进入补偿,不再派发 |
| step:scenario:coupon-commit | 支付确认且预占匹配 | 核销写入及幂等记录 | JSF绑定与确认控制边指向履约派发 |
| step:scenario:fulfillment-dispatch | 支付及核销均确认 | ev:scenario:order-dispatch及派发契约、接单关联 | 履约处理后可能正常完成或永久拒绝 |
| step:scenario:fulfillment-reject | 单履约单永久拒绝 | FulfillmentRejected生产与消费绑定 | 支付未确认时等待核验 |
| step:scenario:compensation-open | 永久拒绝且支付事实确认 | 唯一补偿身份及状态记录 | 使用同一compensation_id驱动各子动作 |
| step:scenario:refund-request | 原支付及可退金额核验完成 | 申请接收只证明请求阶段 | 超时为UNKNOWN_RESULT,复用原幂等键重试取得原接收记录;等待RefundConfirmed |
| step:scenario:refund-confirm | RefundConfirmed关联原RF1/P1/CP1,金额70.00 CNY及终态通过核验 | 原操作的退款完成事实与回执核验依据 | 只更新退款维度;缺字段或不符不纳入完成汇合 |
| step:scenario:coupon-return | 补偿关联匹配,核销记录可退;仍预占则走release | 券恢复操作确认,区分release/return | 按CP1+RS1恢复任务重试;失败不join,预算耗尽MANUAL_REQUIRED |
| step:scenario:compensation-close | refund确认且coupon退回确认 | 订单终态更新成功及补偿完成记录 | 任一条件未知都不能标COMPLETED |
本样例固定quote→reserve→create,创建失败释放预占;支付成功后coupon-commit确认,再派发履约。这些顺序由补充的合成控制证据表达。流程图可以展示能力依赖,不能为画成一条直线而编造顺序。ev:scenario:order-recovery补齐本例F2、F3、F4恢复边;删除该证据的负例则将恢复边降为UNRESOLVED。主路径与指定恢复路径闭合不代表其他未建模支路都已覆盖。
6 故障逐项推演
| 故障 | 业务对象状态推演 | 知识系统应返回 | 禁止结论 |
|---|---|---|---|
| 创建订单失败 | 券处于预占态且尚无支付确认 | release预占及失败待处理支路,不启动退款 | “下单失败所以退回70元” |
| F1 配置缺失 | 代码中的条件仍存在,当前allow_stack未知 | rule:scenario:stack及CONFIG_SCOPE_UNKNOWN | “当前渠道一定允许/禁止叠加” |
| F2 重复支付 | 相同业务支付事实可能有不同message_id | 业务幂等依据、已处理分支及重复路径 | 仅因message_id不同就认为应再次核销 |
| F2 拒绝先到 | 持久pending_reject,支付未确认时不退款;PaymentSucceeded核验后重评 | 直接进入补偿且不再派发;券按预占/核销状态走release/return | “拒绝到达即已满足退款前提” |
| F3 退款超时 | 请求可能已接收,结果未知 | 同业务键重试取原接收记录,最终RefundConfirmed推进;恢复预算耗尽MANUAL_REQUIRED | “退款失败,生成新退款申请” |
| F4 退款确认、退券失败 | refund=CONFIRMED,coupon未完成 | CP1+RS1恢复任务重试;本例恢复确认后join,预算耗尽MANUAL_REQUIRED | “退款成功所以订单已补偿完成” |
| F5 旧消息回放 | v1事件缺stack_policy | 字段缺失及消费方缺省行为取证需求 | 默认false或套用当前配置 |
| F6 分叉工作区 | K1规则只覆盖K1实现,祖先只有源码 | 分离已发布规则、祖先源码与工作区推导 | 把祖先源码称为祖先已发布规则 |
| F7 券证据撤权 | 原回答依据失去访问许可 | 废弃未交付生成,按可见证据重建 | 只删除券引用却保留受其影响的结论 |
| F8 等待标记后写 | 支付与拒绝处理交错,后续不再有支付消息 | 根据同订单协调和持久待办继续重评;缺协调依据则恢复未知 | 仅因存在支付通知处理器就认定一定唤醒 |
| F9 差异退款回执 | 原RF1要求70.00 CNY;回执却为30.00、错误币种或错误操作 | 核对原操作并记录差异;缺核验依据时保留未知 | 仅凭Confirmed事件名称或相同P1/CP1确认全额退款 |
F2、F3、F4正例共用ev:scenario:order-recovery的合成控制和调度证据。F3不假定另有退款查询API;原幂等请求返回原接收记录只能证明已受理,最终由RefundConfirmed确认结果。MANUAL_REQUIRED是业务恢复停止自动处理的状态;有明确人工任务入口时映射知识流程的MANUAL_HANDOFF,没有该入口时仍列人工接管证据不足。
负例N_RECOVERY_REMOVED删除ev:scenario:order-recovery并重建。预期仍能还原退款、券恢复和join条件,但不能推断重复、乱序及超时后一定可恢复;对应边标UNRESOLVED并保留缺失证据项。禁止从正例缓存继承已确认的恢复边。
并发交错与回执反例
F8先按旧描述安排三个动作:拒绝处理器读支付未知,支付处理器写确认并检查无等待项,拒绝处理器最后写等待项。此时两项事实均存在,却没有待执行重评,也没有下一条支付通知。新增正例改用场景基线中的同订单协调和持久待办,检查支付提交、拒绝提交、重评读取、重评提交的不同交错。重评读取后事实变化时,旧决定不提交;进程退出后从持久待办继续。删除ev:scenario:recovery-coordination后,不运行假定存在的协调器,直接返回RECOVERY_WAKEUP_UNPROVEN。
F9分别输入有效70.00 CNY终态回执、30.00回执、错误币种、其他退款操作、只有接收状态、缺少币种和重复有效回执。只有有效终态匹配原RF1才确认,重复确认不再累计。删除ev:scenario:refund-receipt-validation后,即使回执字段碰巧正确,也只能说核验依据未取得。检查程序验证的是这些合成输入和设计判断,不验证实际服务具备相同事务或回执防护。
7 本轮暴露的设计缺口
| 缺口 | 主方案修订 | 本场景结果 |
|---|---|---|
| 总流程终点掩盖子动作未完成 | 02补业务操作与多维状态、04补join闭合 | 退款完成和退券完成分别判断 |
| 投递去重被误当业务幂等 | 03补操作键、参数摘要及提交边界提取 | message_id不证明退款/核销只执行一次 |
| 超时被错误写成失败 | 02补UNKNOWN_RESULT,04补取证和恢复边 | 退款超时保留结果未知 |
| 历史交易被当前规则重算 | 02补决策凭据与有效范围,03补字段来源 | 退款金额回到原支付事实,优惠回到quote_id |
| 拥有静态完成分支被当实例完成 | 04区分静态可完成与运行实例已完成 | O1只能按样例金额作条件化解释 |
| 核销与履约派发绑定未给出 | 补充合成绑定和控制证据 | 核销确认后派发,不靠常识连接 |
| F2/F3/F4恢复依据未给出 | 增加order-recovery合成证据及删证据负例 | 正例闭合,删除证据后恢复边降为未知 |
本推演的通过条件是每条规则、确定关系和完成判断都能回到相应输入;缺失输入必须使对应结论降为未知或部分结果。业务还原结果不是一个无缺口的流程故事。
订单补偿:问答与Agent取证推演
本篇使用场景基线与业务还原推演。O1及所有版本、金额和事件均为合成输入。工具调用是合同推演,没有连接订单、支付或优惠系统。
1 统一查询范围
知识快照为K1。调用身份允许读取订单、优惠、券、支付和履约的样例源码;不假定有生产交易流水权限。以下完整请求使用同一scope,后续取证固定snapshot_id=K1,各独立工具请求返回各自query_id,由Agent在本地调查记录中串联。
{
"schema_version": "0.1",
"request_id": "req:scenario:refund-search",
"scope": {
"repo_ids": [],
"domain_ids": ["domain:scenario:order-compensation"],
"environment": null,
"purpose": "DESIGN_REVIEW"
},
"snapshot_id": "K1",
"arguments": {
"query": "订单履约失败后退款金额和补偿完成条件",
"types": ["BUSINESS_RULE", "BUSINESS_FLOW"],
"page_size": 20
}
}
search_knowledge应定位rule:scenario:refund-original-cash、rule:scenario:compensation-join及对应流程。返回命中只支持下一步定位,不能直接把summary送给用户作为完整答案。page_size=20是这个夹具的请求参数,不是全库召回保证。
2 问题一:为什么O1只能退70元
先把问题拆成四项:退款范围是否为整单撤销、原支付金额是多少、是否已有退款或在途占用、规则是否按原实付退款。基线仅给出了整单样例及原实付70.00,没有真实订单查询结果。
| 待证明项 | 调查动作 | 样例证据及判定 |
|---|---|---|
| 退款金额规则 | get_business_rule读取refund-original-cash,再get_evidence | ev:scenario:payment-refund支持以原支付流水为依据,优惠不作为现金退款 |
| 原报价及支付绑定 | 读取quote-binding及其证据 | ev:scenario:order-create支持quote_id绑定;ev:scenario:order-payment支持支付关联,不代表真实O1流水已存在 |
| O1原实付70.00 | 检查已归档实例证据 | 本夹具只提供用户假设,无真实支付流水,记INSTANCE_EVIDENCE_MISSING |
| 无已退及在途占用且本次整单退款 | 检查退款范围、历史退款及在途占用证据 | 基线将整单撤销作为推演条件,不能外推到部分退款或真实订单 |
后续调用的arguments如下,公共身份、scope及snapshot_id仍沿用上面的合同;每次request_id另取唯一值。
{
"rule_id": "rule:scenario:refund-original-cash"
}
{
"evidence_id": "ev:scenario:payment-refund"
}
可交付结论为:“本场景给定原实付70元。若本次整单撤销,且没有已退或仍可能成功的在途退款,现金退款上限为70元;优惠不转成现金退款。O1的真实支付、已退和在途记录尚未取得。”
这是一条规则结论和一条带假设的金额解释。对“真实O1为什么只能退70元”的回答状态为PARTIALLY_ANSWERABLE,未决项为INSTANCE_EVIDENCE_MISSING;不能把合成金额生成运行证据ID,也不能宣称已审核退款账目。若问题改为“这条规则如何计算”,读取完整代码规则后可以ANSWERABLE。
3 问题二:退款成功是否代表补偿完成
get_business_flow读取完整流程,再通过get_business_rule读取rule:scenario:compensation-join。退款确认、退券确认和订单终态三个条件分别取证。
| 判断 | 来源 | 允许的结论 |
|---|---|---|
| 退款请求被受理 | ev:scenario:payment-refund | 已提交退款请求;未证明资金结果 |
| 已收到关联正确的退款确认 | ev:scenario:payment-confirm、order-refund-result | 退款子状态可以更新;仍需券和订单状态 |
| 券退回成功 | ev:scenario:coupon-return | 券子状态可更新;须与本次核销和补偿关联 |
| 两子状态成功并完成订单更新 | ev:scenario:order-join | 满足该版本补偿完成条件 |
F4提供“退款确认成功、退券失败”的样例状态。按合成状态推演,结论是“退款子步骤成功,补偿尚未完成,退券仍需处理”。规则解释可以ANSWERABLE;真实订单完成状态仍需实例证据。不能因接收RefundConfirmed而跳过coupon-return或order-join。
F2中履约拒绝先到且支付事实未确认时,问答列出“已观察履约拒绝、支付状态待核验”,不得建议按事件到达先后直接退款。F3中退款申请超时,答案必须保留结果未知,并说明后续应复用业务幂等键查询或重试;知识服务本身不执行退款动作。
4 问题三:当前渠道能否叠券
R_STACK的代码判定需要活动命中、券已选择、渠道允许及allow_stack=true。K1同时包含promotion:1与promotion:2,查询不能因为知识快照只有一个就认为生产只有一个实现。
- search_knowledge定位
rule:scenario:stack,get_business_rule读取已存在的规则修订及service_version_refs;本夹具只有v1完整规则,v2继续读取技术证据并保留规则覆盖缺口。不得返回合同未定义的“实现集合”字段或把v1条件复制给v2。 - get_evidence读取ev:scenario:promo-quote与可见的v2实现证据,保留各自适用渠道与版本。
- 若没有提供渠道且两个实现结论不同,返回NEEDS_CLARIFICATION,不自选v1。
- 已指定渠道但没有生产配置快照时,返回PARTIALLY_ANSWERABLE:解释代码条件,记录CONFIG_SCOPE_UNKNOWN,不把默认值当生效值。
- 如果连实现绑定都无法确认,记录IMPLEMENTATION_AMBIGUOUS;不把同名规则合并成无条件允许。
本场景F1缺少当前生产allow_stack快照,因此不能回答“当前允许叠加”。已固定历史quote_id的订单使用报价当时的规则和金额;配置后来关闭不意味着旧单应退款80元或100元。
5 Agent连续调用:stack_policy字段变更
任务为“PaymentSucceeded增加stack_policy字段,检查旧消费者及历史消息回放”。新增字段尚不在K1中,target应定位既有消息契约,变更由Diff或工作区覆盖层描述,不构造一个不存在的字段ID。
| 顺序 | 工具与输入 | 必须得到的结果 | 停止或降级条件 |
|---|---|---|---|
| A1 | search_knowledge:PaymentSucceeded,types=[CONTRACT] | 逻辑contract_id及每个可见revision_id | 只找到Topic时继续查绑定,不能直接确定契约 |
| A2 | get_contract:contract_id及A1返回的revision_id | 旧消息字段、序列化及bindings | 修订不属于K1则VERSION_UNAVAILABLE |
| A3 | get_evidence:旧事件定义 | ev:scenario:payment-event-v1支持旧消息不含stack_policy | 证据未归档则PARTIAL,不凭摘要假定 |
| A4 | trace_impact:消息契约、FIELD、workspace_revision | 消费绑定、反序列化点、缺省值及分支使用点 | 不可解析映射保留POTENTIAL |
| A5 | get_evidence:各使用点引用 | 核验具体缺省和未知字段处理 | 未找到缺省实现时UNKNOWN,不填false |
| A6 | 汇总 | 按版本、消费组、使用点和回放场景输出 | 仍有未展开前沿时PARTIAL |
A2的精确读取参数为:
{
"contract_id": "contract:scenario:payment-succeeded",
"revision_id": "revision:scenario:payment-succeeded:1"
}
该revision_id必须由K1中的搜索命中提供。调用方不能把任意制品版本放进隐藏参数。未指定修订且多实现字段不同,工具先返回IMPLEMENTATION_AMBIGUOUS;增加revision_id后才解除这个死路。
A4使用已登记的工作区覆盖层,参数为:
{
"target": {
"id": "contract:scenario:payment-succeeded",
"kind": "CONTRACT"
},
"change_type": "FIELD",
"workspace_revision": "workspace:scenario:stack-policy-change"
}
在本基线下可确认旧消息没有新字段,但未提供消费方对缺字段的实现证据。最终影响报告必须把ev:scenario:payment-consumer-default列为缺失需求,不能把它放进evidence_refs假装已经读取。
| 影响类别 | 本场景判定依据 |
|---|---|
| DEPENDENCY_ONLY | 确认订阅PaymentSucceeded,但未找到与字段变化有关的读取或反序列化行为 |
| POTENTIAL | 已定位反序列化边界,缺省策略或字段转换尚未解析 |
| SUPPORTED | 取得具体读取、校验、拒绝未知字段或缺省分支证据,并说明与变更的关系 |
“旧消费者不读新字段”不足以认定兼容;“新消费者把缺失字段当false”也不能凭Java类型推断,因为反序列化器、构造器和显式校验可能改变行为。回放分析分别检查旧生产者→新消费者、新生产者→旧消费者,不能只检查当前部署组合。
6 权限撤销、过期与重放
F7中coupon证据在退款与退券联合解释生成期间被撤权。服务废弃这次未交付生成,重新取得授权范围。若只剩支付证据,可以重新生成退款子步骤的解释,并明确无法核验补偿全貌;不能复用原文中的退券规则后删去引用。
get_evidence返回NOT_FOUND或ACCESS_DENIED遵守统一不可见策略,不通过“隐藏消费方数量”或候选名称泄露来源。原query_id或分享链接只定位记录,不授予权限;同request_id重放也重新授权。
工作区或共同祖先临时证据的租约到期时,返回VERSION_UNAVAILABLE。Agent可以建立新调查上下文,但不得把新拉取内容悄悄换到旧evidence_id之下继续引用。
7 推演发现及主方案修订
| 缺口 | 导致的问题 | 已修改位置 |
|---|---|---|
| 订单实例问题与规则问题混在同一“证据充分”判断中 | 仅靠源码即可声称真实支付和补偿结果 | 05§11区分RULE、INSTANCE_FACT、USER_ASSUMPTION |
| 契约搜索返回修订但读取不能选择修订 | 多实现场景永久卡在PARTIAL | 06§10、§13增加get_contract.revision_id及快照归属校验 |
| 新增字段还未入库却要求已解析字段target | Agent可能虚构字段ID | 06§15以既有契约为target,Diff/覆盖层描述新增字段 |
| 共同祖先源码无已发布知识时无法标明来源 | 祖先被错标为发布证据或dirty代码 | 06§10增加COMMIT_SOURCE及source_context_id |
| 临时证据无法跨调用取回 | Agent拿到片段引用后无法继续核验 | 06§15规定服务登记、主体绑定及租约失效 |
| 同仓库多灰度实现只有一个版本关系 | IDE和Agent误用“整个仓库EXACT” | 06§9逐implementation_scope返回版本关系 |
主方案修订完成不代表上述服务已实现。本篇以合同调用和证据依赖检查推演;机器示例由统一Schema检查负责,真实兼容性依照各内部平台样本验收。
订单补偿:IDE与版本推演
本推演沿用场景基线的O1订单,分别检查优惠规则改动、券仓库新增恢复方法和配置更新。代码、记录与Commit均为合成输入。
本章用“配置基线”“配置更新版”区分两份知识:前者读取原配置,后者只更新配置知识,对应订单补偿夹具中的K1、K2。首次使用另演示订单仓库的恢复方法,其K2含订单恢复实现;两组推演独立,不能按版本编号拼成一次发布。
1 版本与证据准备
promotion仓库有共同祖先A。配置基线收录P1和P2两个部署实现,P2属于灰度范围;工作区W从A分叉,又包含未提交Diff D。A可以从授权源码归档读取,但没有已发布业务知识。
P1 ── P2 配置基线中的两个实现:sv:promotion:1、sv:promotion:2
/
A ────┤
\
W + D IDE工作区;D不属于任何已发布Commit
| 标识 | 本次含义 | 获取方式与权限 |
|---|---|---|
| 配置基线 | 查询参考知识发布,含五服务和promotion两实现 | 发布清单与成员授权 |
| ev:promo:p1:stack | P1中的叠加条件 | 配置基线固定实现的源码证据 |
| ev:promo:p2:stack | P2中的灰度叠加条件 | 配置基线另一实现的源码证据 |
| ev:promo:a:stack | A中的原始条件 | 固定Commit源码登记,不声明已有规则修订 |
| wr:promo:w:d1 | W与Diff D1组成的覆盖层 | 本次查询身份与临时证据租约 |
| ev:promo:wr1:stack | D1修改后的条件 | wr:promo:w:d1来源,不能标为配置基线成员 |
| cfg:stack:1 | 配置基线所用配置上下文 | 配置快照范围与读取授权 |
| cfg:stack:2 | 后续配置更新 | 新采集输入,不覆盖cfg:stack:1 |
实际实现使用40位或64位Commit摘要,不将P1、P2、A、W作为协议中的commit_sha。以上别名只用于解释版本关系。
2 IDE请求到上下文包
IDE任务为“调整渠道叠加条件,并新增stack_policy传递,检查支付回放与退款补偿是否受影响”。客户端上传promotion工作区及选定文件Diff,声明SELECTED_FILES;没有上传order、payment和coupon本地仓库,不能声称它们的开发分支已检查。
| 步骤 | 输入及服务端动作 | 必须返回的结果 |
|---|---|---|
| I1 固定查询 | 认证身份、限制域与仓库、解析配置基线,登记query_id | 后续调用固定配置基线;客户端不可伪造授权范围 |
| I2 定位实现 | 根据业务渠道与已知绑定找promotion实现;配置基线同时含P1/P2 | 没有唯一依据时返回两项比较或未决项,不选择日期较新的P2 |
| I3 比较版本 | 分别比较W与P1、P2,读取Commit图 | 两项DIVERGED,各自必填implementation_scope并记录共同祖先A |
| I4 读取祖先 | 在授权源码服务读取A相关片段并登记证据 | 来源为COMMIT_SOURCE,带source_context_id;没有rule_revision:A就不生成该引用 |
| I5 校验Diff | 核对D1基线W与文件原始字节SHA256、路径和补丁 | 补丁可应用后,连同实际构建与依赖输入、上传完整性固定wr:promo:w:d1;缺文件或补丁不匹配进入未决项 |
| I6 解析覆盖层 | 解析变更条件、字段写入及已知调用点,保留选择文件范围 | 覆盖层事实为本次候选;依赖未取得时,相关规则适用性为UNKNOWN;未改文件是否完整取决于输入声明 |
| I7 取跨服务依据 | 在配置基线读取报价凭据、旧支付事件、退款金额与退券完成条件 | 所有跨仓库内容注明配置基线实现;不假设与W共同部署 |
| I8 组装上下文 | 按直接规则、契约、影响路径、证据排序,完整片段装入预算 | snapshot_id=K1(配置基线)、workspace_revision=wr:promo:w:d1、逐实现版本关系及未包含范围 |
上下文中至少保留以下约束:退款依据原支付实付70.00,不因新的allow_stack改变;历史quote_id保留当时规则版本和金额分摊;旧消息没有stack_policy,必须检查消费者缺省行为;RefundConfirmed只推进退款子状态,不能跳过coupon退回确认。
规则适用性不是全包一个布尔值。原R_STACK对D1修改符号的依据可能INVALIDATED;退款金额规则若未受字段路径改变且依赖已核对,可作为配置基线侧约束返回。跨分支业务相容性尚未证明时仍用UNKNOWN,不能因为某文件未改就认定整条业务规则适用。
3 覆盖层证据连续读取
build_context返回ev:promo:wr1:stack之后,Agent可能调用get_evidence展开原文。服务端必须解析到wr:promo:w:d1的查询证据登记,而不是只在配置基线成员中搜索。同一身份、客户端、基线快照和有效租约下重新授权后可读;同evidence_id换用户不授予权限;覆盖层已过期返回VERSION_UNAVAILABLE。读取接口无需增加参数,不透明ID只用于定位授权登记。
祖先ev:promo:a:stack也需要独立来源。若将其标成PUBLISHED,就会伪造祖先已有知识;若标成WORKSPACE,又无法区分A与W+D。COMMIT_SOURCE表达固定Commit原文,并在locator中保存仓库与A,临时登记保留授权、内容哈希和租约。
IDE打开证据时,按locator.file_content_hash比较当前整文件;P1、P2和A取各自固定Commit的文件,wr1取应用D1后的文件。证据片段的content_hash不能完成这项比较。缺少整文件哈希或比较不一致时,只打开该证据固定的文件或片段视图。即使片段文字仍相同,前面插入了其他代码,也不能继续沿用旧行号跳转。
4 未提交Diff再次改变
IDE继续编辑,D1变为D2。客户端重新提交基线、完整的当前Diff、文件哈希和上传范围,得到wr:promo:w:d2。wr1仍能在原租约内用于回看,但不能与wr2的规则适用性、证据行号或影响路径混用。服务端校验行号对应内容;代码移动后跳转到已固定来源,不能直接在新文件同一行打开。
如果D2新增了接口字段但没提供相应序列化文件,结果包含DIFF_INCOMPLETE,并保留“消费者是否会收到该字段”未决项。服务不得根据字段声明自行补造序列化路径。
若D2未变,但依赖的券SDK制品或构建profile改变,分析输入摘要仍会变化。服务重新建立工作区分析修订,检查SDK对退券参数、异常与重试的处理。新制品尚未取得时,返回缺失依赖;旧版本SDK的摘要不能证明新工作区行为。相同Diff从SELECTED_FILES改为FULL_WORKTREE,也重新登记完整性,不能直接沿用原来的适用性结果。
新增退券恢复方法
在本章的券仓库变体中,研发提交coupon仓库的基线和实际Diff,新增 retryFailedCoupons() 调用原退券接口。服务生成 wr:coupon:w:d1。promotion的覆盖层不能代替这份coupon输入。
| 路径引用 | kind | origin及版本 | 核对内容 |
|---|---|---|---|
| 新增恢复方法 | NODE | WORKSPACE,wr:coupon:w:d1 | 确认方法存在于该覆盖层,以及筛选条件、原退券操作关联和失败出口 |
| 恢复方法到退券接口的新调用 | EDGE | WORKSPACE,wr:coupon:w:d1 | 确认补丁后的调用点、参数映射与条件;不能复用已删除的旧调用边 |
| 原退券接口的确定实现 | NODE | PUBLISHED,配置基线 | 确认实现属于配置基线,并核对输入、幂等和返回状态 |
上述引用全部进入该ImpactItem的reference_sources,按接入合同登记ref_id与来源版本。省略工作区来源、将新方法写成配置基线成员、或引用另一个工作区的同名方法,都不能通过语义检查。客户端继续读取时仍要重新授权。
这次修改需要同时检查重试原操作、退券最终确认和订单关闭条件。退款已确认不等于可跳过退券;工作区已补上恢复方法也不证明O1已经执行恢复。该订单的最终结果仍须按实际记录核对。
5 配置更新与K2发布
这次发布只改变配置知识,不包含上面尚未提交的coupon恢复方法。后台收到cfg:stack:2,源码P1/P2没有改变。更新器复用方法体解析,重新计算配置绑定、适用范围、R_STACK实现集合、相关流程边及索引内容。配置更新版以配置基线为父,保留未变化的退款与退券规则修订,发布前核对所有成员及证据闭包。
配置更新版的变化只说明新查询可看到新的配置知识,不证明O1当时使用该配置。O1的quote_id对应cfg:stack:1和原报价版本,实付仍是70.00。将“当前配置不允许叠加”用于重算O1退款为80或100,属于错误版本与错误金额规则。
配置更新版在索引核对完成后以CAS切换生效指针。I1产生的query_id继续配置基线,wr1/wr2与配置基线组合不被原地修改。IDE显式开新查询使用配置更新版时,重新生成上下文包及适用性结果;不能仅把旧包snapshot_id替换为配置更新版。
6 旧消息回放的影响判断
旧PaymentSucceeded不含stack_policy。推演必须分开保存旧生产者事件结构、新消费者实现和消费时配置。查询先检查消费者如何处理缺失字段:能否反序列化、是否填默认值、默认值是否改变分支、是否错误触发重报价。
如果只拿到最新事件Schema,结论是“历史回放兼容性未确认”;不能用新Schema的默认值补齐旧消息后宣称兼容。若找到消费者从缺失字段进入重报价的分支,则标记SUPPORTED使用点,并引用该分支和旧消息契约。具体业务处理修改仍由需求设计决定,知识服务不执行回放或退款。
7 补偿完成、权限与回收
F4下退款已确认,coupon退回失败。问答和IDE均需保留两个子状态,结果不能写“补偿已完成”。状态结论需要实例证据;本夹具只证明在给定输入下,设计应保留未完成条件。
F7在coupon证据进入模型后撤权。废弃未交付生成,以剩余授权证据重新构造答案;无法确认退券条件时返回缺口。配置基线租约和旧上下文不能绕过撤权。已发送到客户端的内容无法追回,因此每次片段交付都先授权。
当配置基线不再生效时,只要原查询租约有效就不得清理其成员与索引。wr1、wr2单独按临时证据租约回收。回收后同一evidence_id不能映射到另一个覆盖层,也不能回退到仓库最新内容。
8 本次推演发现的设计缺口
| 缺口 | 影响 | 修订 |
|---|---|---|
| version_matches按repo_id只比较一个Commit | 灰度双实现时IDE不知道参考哪份逻辑 | 按implementation_scope或service_version_ref返回比较 |
| 来源只有发布与工作区 | 共同祖先无知识时无法返回诚实来源 | 增加固定Commit源码来源与授权登记 |
| get_evidence只有快照读取语义 | build_context返回的覆盖层引用无法继续取证 | 按证据归属登记解析并检查租约与权限 |
| 配置更新版生效后上下文如何更新未明确 | 旧证据与新快照可能混合 | 固定配置基线查询;配置更新版显式新查询并重算上下文 |
| 配置增量可能覆盖历史报价 | O1退款金额被当前优惠规则污染 | 分开交易规则依据和当前配置知识 |
| 旧事件用最新Schema解释 | 回放缺省行为被隐藏 | 保留生产者契约、消费者实现与消费配置三方范围 |
07新增历史交易范围、临时证据与覆盖层存储规则;08补充对应验收断言。06与Schema由接入组和主方案统一修订,避免只在本推演中定义不同协议。
复杂退款:金额、权益与业务还原
本篇沿用复杂场景基线。金额、支付和退款状态均为合成输入;计算只核对设计样例,不代表真实账户可退额度,也不执行退款或额度占用。
1 分单不改变原分摊凭据
AL1将20.00满减按三行等权分摊。以分计,2000除以3,各行先取得666分,剩余2分按line_id升序分给L1、L2。券10.00只适用于L1,不能随子单金额比例再分给L2或L3。
| 行 | 子单 | 原价 | 满减 | 券优惠 | 现金权益 |
|---|---|---|---|---|---|
| L1 | S1 | 100.00 | 6.67 | 10.00 | 83.33 |
| L2 | S1 | 100.00 | 6.67 | 0.00 | 93.33 |
| L3 | S2 | 100.00 | 6.66 | 0.00 | 93.34 |
| 合计 | O2 | 300.00 | 20.00 | 10.00 | 270.00 |
S1现金权益176.66,S2为93.34。退款继续引用AL1,不对“当前剩余两行”重新分配20.00满减。否则原价同为100.00的L2和L3被错误认为可退同额,或者一次退款后剩余权益凭空改变。
知识提取必须找到分摊方法中的参与行、适用过滤、整数精度、余分循环及稳定排序。只有最终270.00汇总证据时,最多确认总额,不足以确认L1的83.33。
2 两次支付尝试不是两份商品权益
| 顺序 | 支付观察 | 应保留的对象与结论 |
|---|---|---|
| P1 | A1超时 | 尝试结果未知,不能删除可能的实收 |
| P2 | A2确认C2=270.00 | C2被订单采纳,与AL1商品权益关联 |
| P3 | A1迟到成功C1=270.00 | C1独立保存,属于重复实收处置;不覆盖C2 |
| P4 | C1需要返还 | 另建重复实收返还意图,退款指向C1,不消耗L1/L2商品退款额度 |
PI2只有一份订单商品权益270.00,资金侧存在两笔实收合计540.00。若C1返还完成、C2的L1/L2全部退回,资金净额为540.00 - 270.00 - 176.66 = 93.34,与仍履约L3现金权益相符。该关系是本夹具的核对式,不证明实际两笔扣款或退款已发生。
用“订单最后一条成功支付”选择退款capture,会把商品退款指向C1;用“payment_id金额覆盖原值”保存回调,又会丢失重复实收。分析器需保留attempt到capture、capture到订单采纳以及退款到capture三段独立关系。
3 部分退款与在途占用
先固定L1原权益83.33及此前确认R0=30.00。在没有其他占用的观察点,剩余53.33。RA占用这53.33后,新的可申请余额是0.00;RA尚未确认不意味着53.33仍可再次申请。
| 观察点 | L1确认退款 | L1占用 | L1新可申请 | C2确认退款 | C2占用 | C2新可申请 |
|---|---|---|---|---|---|---|
| T0:仅R0完成 | 30.00 | 0.00 | 53.33 | 30.00 | 0.00 | 240.00 |
| T1:RA占用 | 30.00 | 53.33 | 0.00 | 30.00 | 53.33 | 186.67 |
| T2:RB也占用L2 | 30.00 | 53.33 | 0.00 | 30.00 | 146.66 | 93.34 |
| T3:RA确认,RB在途 | 83.33 | 0.00 | 0.00 | 83.33 | 93.33 | 93.34 |
| T4:RA、RB均确认 | 83.33 | 0.00 | 0.00 | 176.66 | 0.00 | 93.34 |
T3是把RA的53.33从占用转为确认,不能同时留在两栏。RA超时保持T1/T2的占用;只有可验证终结且不再可能成功的拒绝或撤销才能释放。源系统若不提供这样的终结保证,知识服务只能报告结果未知和占用处理未确认。
这一组数值只对应所声明的观察点。K3不变,T0至T4的可退金额仍会变化;问答不能缓存“可退53.33”并把它当作K3整个有效期的事实。
4 并发协调方与业务意图
RA与RC针对同一L1取消,属于同一业务退款意图;两个compensation_id只是不同协调记录,不产生两份53.33退款权。RC应找到已有RA并复用其状态。若RA与另一申请确实属于两个合法的部分退款意图,也必须竞争同一L1剩余权益与C2退款限额。
| 层次 | 本例对象 | 能防止什么 | 不能单独证明什么 |
|---|---|---|---|
| 投递 | message_id | 同一消息重复消费 | 两协调方不同消息表达同一取消 |
| 业务意图 | L1本次取消对应refund_intent_id | 同一诉求重复创建 | 两个合法退款意图合计不超额 |
| 执行操作 | refund_operation_id与渠道键 | 超时重试重复付款 | 其他操作是否已经占用余额 |
| 权益限额 | AL1/L1与capture C2 | 多合法意图并发总额受约束 | 缺少原子提交时的读写竞争 |
提取器需要找到意图来源与唯一范围、同键不同参数冲突、余额检查和占用提交位置。只看到一把业务锁或一个幂等注解时,结果仍为局部防护候选。这里描述的是被分析交易系统的正确性条件,知识服务不会创建这些锁或执行额度扣减。
5 券权益与完成层级
本例券只适用于L1,退回要求L1现金权益全部退款确认,且L1取消最终成立。T1中RA已受理不足以退券;RB/L2退款完成也不触发退券。重复实收C1的返还不取消商品或原核销,更不触发第二次券恢复。
退券去重范围是原核销与退券权益。RA重试、RC协调和券重试均指向同一份权益;不能用各自compensation_id生成新的退券权。券退回后是否仍在有效期、能否再次使用不在本基线中,答案保留该政策边界。
| 已确认条件 | 可以声称完成 | 不可以声称完成 |
|---|---|---|
| RA退款确认 | RA操作;R0+RA覆盖L1现金83.33 | 券已退、S1已关闭、O2已关闭 |
| L1取消最终成立且券恢复确认 | 本例L1退款及券补偿 | L2退款、S2履约或O2整体 |
| L1/L2各自终态满足S1关闭条件 | S1对应范围 | S2仍履约时的O2整体 |
| C1重复实收返还确认 | C1资金处置 | 任何商品取消或券退回 |
实例终态必须来自对应对象证据。本夹具没有实际订单状态记录,不把表中条件化判断写成线上状态。
6 证据与IR检查清单
| 提取目标 | 必须取得的证据 | 缺失时 |
|---|---|---|
| AL1分摊 | 适用行、金额尺度、舍入及余分顺序 | ALLOCATION_ORDER_UNKNOWN或分摊未确认 |
| 支付采纳 | attempt/capture映射、订单采纳记录、迟到实收分支 | 不推断哪笔实收用于商品退款 |
| 部分退款权益 | 原分摊、确认退款及在途占用,聚合键与观察范围 | 只能解释公式,不给当前可退额度 |
| 并发防护 | 意图唯一性、额度检查与占用提交、冲突分支 | REFUND_CAPACITY_ATOMICITY_UNKNOWN |
| 超时释放 | 远端终结事实、原操作关联及释放条件 | 保留UNKNOWN_RESULT与占用未知 |
| 券恢复 | 原核销、政策修订、L1终态及执行幂等 | 不推断退款即退券 |
| 总体完成 | 目标集合、各目标终态及汇合条件 | 子范围完成不能上推订单整体 |
7 正反例
正例保留AL1三个现金权益合计270.00;C1/C2分别核算退款;RA受理后占用53.33;RC复用同一意图;RA确认时占用转确认;L1取消且退款退尽后按政策恢复一次券。
反例分别注入:将余分给L3造成分摊变化、用C1覆盖C2、把RA超时当可释放、为RC生成新意图绕过RA、同时把RA计入确认和占用、用RB退款触发L1券恢复、把S1完成输出为O2完成。知识还原应指出相应证据冲突或未知,不能靠重新汇总金额掩盖身份与状态错误。
复杂退款:问答、Agent与IDE接入推演
使用统一基线。O2、AL1、C1/C2、RA/RB/RC及所有状态均为合成输入。下列金额结论是条件化计算,未读取真实订单或资金流水。
1 先确定问的是什么金额
同一句“这单还能退多少”可能指不同对象,不能返回一个无范围的数字。
| 对象与时点 | 计算 | 可以说明的内容 |
|---|---|---|
| L1在R0确认后、RA占用前 | 83.33 − 30.00 = 53.33 | 本例L1尚未退款的现金权益上限 |
| L1在RA占用53.33后 | 83.33 − 30.00 − 53.33 = 0.00 | 本例剩余未占用上限为零;不代表RA已退款成功 |
| C2在R0确认、RA/RB都占用后 | 270.00 − 30.00 − 53.33 − 93.33 = 93.34 | 本例C2尚未退款且未占用的现金容量;不能据此批准继续履约的S2退款 |
| C1迟到成功后的重复实收 | 独立capture金额270.00 | 进入C1重复实收处置,不增加C2商品退款权益 |
L1的53.33与C2的240.00不是可相加额度。前者是行权益边界,后者是在RA/RB占用前的capture剩余资金边界;一次申请需要同时满足两者。把行剩余与capture剩余相加会制造不存在的退款权益。
未给出capture、行范围或观察时点且这些信息会改变答案时,回答NEEDS_CLARIFICATION。已给出本夹具全部条件时,可以给出CONDITIONAL计算;用户询问真实当前额度而没有实例证据时,保留INSTANCE_EVIDENCE_MISSING,不能把计算结果展示为可执行退款额度。
2 分单与尾差问答
问题为“S2为什么分到93.34,而不是93.33”。取证顺序是分摊政策、AL1适用行、币种精度、余分规则和落库结果。
在本夹具中,20.00满减的理想等分为6.666…;先到分保留6.66后剩2分,按稳定line_id顺序补给L1和L2。三个满减份额为6.67、6.67、6.66;券10.00只归L1。因此现金份额为83.33、93.33、93.34,总和270.00。
这条解释必须保留AL1。后来拆单顺序改变、列表排序改变或当前活动规则变更,不重新决定历史那一分钱归属。如果只有最终付款270.00,没有AL1的适用行及尾差政策,只能说明订单总额,不能倒推唯一的行退款金额。
若IDE把分摊改为每行独立四舍五入,例中三个满减会变成6.67,总和20.01。知识服务返回“破坏该夹具的分摊守恒”,并引用对应分摊及汇总使用点;不能只因每个单行金额都合法而放过总额差异。
3 多次支付尝试的解释
问题为“A1超时,A2成功,为什么后来又有270元返还”。先定位支付意图PI2、尝试A1/A2、实收C1/C2,以及订单采纳哪笔实收的证据。
| 输入事实或假设 | 能得出的结论 | 不能得出的结论 |
|---|---|---|
| A1超时 | A1结果未知,可能需后续核验 | A1已经失败,不会再成功 |
| A2对应C2被订单采纳 | 商品支付依据为C2及AL1 | PI2下其他成功实收不存在 |
| A1迟到成功对应C1 | 另有独立capture待重复实收处置 | 商品权益或可退款行金额翻倍 |
| C1返还完成 | C1对应重复实收资金得到处置 | C2上的RA/RB已完成,或S1已补偿完成 |
C1与C2的退款记录分别回到各自capture。即便退款用途不同,两者都要检查对应capture的已确认与在途金额;不能把C1退款计入C2已退总额,再使C2少退或误报超退。
本例的“订单采纳C2”是明确基线条件。真实数据没有采纳依据时,返回PAYMENT_SELECTION_UNKNOWN,不按回执时间较晚、金额相同或支付尝试序号选择capture。
4 并发补偿的问答边界
问题为“另一个协调方可以给L1再退53.33吗”。本例RA已占用53.33,RC与RA对应同一L1撤销意图。因此RC应复用既有进行中业务操作,不能因compensation_id不同新增一次退款。
Agent需要找到意图相等判定、业务操作唯一约束或条件更新、金额占用写入、退款请求与确认,以及回执匹配的证据。只有一个分布式锁调用、一次重复message_id拦截或一个方法名idempotentRefund,不能证明上述约束成立。
退款超时仍可能成功,不能释放53.33后允许另一个申请重新占用。只有可验证拒绝或撤销证明原操作不再可能成功,才讨论释放。若服务只取到“任务超时”日志,没有支付渠道终止证据,问答返回结果未知,不能给出“重试时换一个退款ID”的操作建议。
RA与RB属于不同目标行,可以在各自行权益内并行;两者仍共用C2资金上限。一次申请通过行上限不意味着它已经通过capture上限。仅靠查询时分别读到两笔余额不足以证明并发安全,必须核对业务系统实际提交约束。知识服务只解释约束,不为业务服务锁额度。
5 券与父子状态完成条件
问题为“L1已退30元,现在能退券吗”。本例政策要求L1全部现金退款确认且取消最终成立,所以仅R0=30.00不满足;RA仅受理也不满足。R0与RA确认合计83.33且L1取消成立后,才具备本例券退回条件。券操作还需按原核销和退券权益核验,另起补偿任务不能重复恢复同一权益。
RB=93.33属于L2,本例没有L2券权益,因此RB成功不触发L1券退回。S1可以在其目标行及券恢复条件全部满足后闭合,S2仍在履约;不能把S1完成写成O2全部完成,也不能因为O2未完成就声称S1退款失败。
Agent的完成调查需明确目标集合和成员版本。查询订单级、子单级、行级状态时分别读取相应条件;任何父状态都不能靠收到某一个子状态事件直接推断。
6 Agent工具链与金额依据
| 步骤 | 工具与目标 | 保留结果 |
|---|---|---|
| A1 | search_knowledge查分摊、退款上限、支付采纳及券恢复规则 | 规则与契约ID、修订和适用范围 |
| A2 | get_business_rule按命中修订读取 | 行权益上限、capture上限、在途占用和确认条件 |
| A3 | get_contract定位已实收及退款消息的具体修订 | attempt、capture、intent、operation的字段语义;不只查amount |
| A4 | get_evidence核对原文 | 关联键、金额来源、幂等和状态转移证据 |
| A5 | get_business_flow查看部分退款及父子完成分支 | 目标范围、并行约束、失败及恢复条件 |
| A6 | 根据已有归档观察或假设组装解释 | RULE、CONDITIONAL或INSTANCE_OBSERVATION,保留观察来源与时点 |
同一K3内各工具请求固定知识版本,各次query_id独立。K3只冻结规则和实现,不能冻结退款流水。假设组、观察组和计算分项都随最终AnswerResult返回,七工具仍不直接查询或改变交易账户。
若先读到C2在途占用,再从另一服务读到旧的L1可退权益,这两条观察可能都正确,却不能拼成同一原子时点。observations分别保留observed_at、source_revision和subject_refs,observation_sets标记INDEPENDENT_READS。没有共同切面证明时,不返回OBSERVED_AVAILABLE;可以列出两条历史观察及未知项。
7 IDE变更推演
IDE任务包含两个候选改动:把占用释放从“可证明终止”改为“请求超时”,以及改动分摊舍入方法。请求以工作区真实解析到的符号或已存在规则为target,change_type=LOGIC;本篇不虚构仓库中一定存在的技术ID。
| 改动 | 必须调查的路径 | 本夹具要求 |
|---|---|---|
| 超时即释放占用 | 原退款操作、迟到成功回执、重新申请、行与capture两个上限 | 保留A1/RA结果未知反例;不能只检查单线程方法返回 |
| 每行独立四舍五入 | 分摊生成、持久化、子单读取、退款计算与总额核对 | 20.01对20.00的守恒反例,历史AL1不得重算 |
| 更换退款幂等键 | refund_intent识别、业务操作唯一性、参数冲突、补偿协调者 | 不同compensation_id不能绕过同意图处理 |
| 以支付意图代替capture | 原支付选择、重复实收处置、退款关联和额度汇总 | C1返还与C2商品退款分开,不跨capture扣减 |
上下文包返回规则、原分摊与消息契约的版本依据;实例观察如已过期,不能作为当前并发余额前提。分析器只识别普通调用关系而未找到金额或状态使用点时,影响为POTENTIAL,不将全部上下游标为SUPPORTED。实际修改、付款或退款不在知识服务工具权限内。
8 本轮接口漏洞与修订
| 漏洞 | 修订 |
|---|---|
| AnswerResult不能区分条件化金额与实例结论 | claim增加basis_type、assumption_refs和observation_refs |
| 知识版本被误当资金快照 | observations独立记录来源修订与时间,observation_sets显式表达一致性依据 |
| 合法数字掩盖跨capture或跨行计算 | calculation记录目标范围、capture、AL1、币种和逐项来源 |
| 资金容量被误当退款权限 | ARITHMETIC_BOUND与OBSERVED_AVAILABLE分开,两个上限和业务适用条件分别核验 |
| 重复协调任务被当成新退款权益 | 调查退款意图、业务操作和原核销权益,不只看message_id或compensation_id |
| 子单完成被提升为整单完成 | 父子目标范围与完成成员独立判断 |
这些合同描述查询与解释,不是交易批准。Schema可拒绝缺少必要字段的结果,跨对象来源、共同切面及金额守恒还需要服务端语义检查与实际业务样本。
复杂退款:并发补偿与观察一致性
本篇按统一基线推演人工期望。金额、操作与时序均为合成输入;知识服务只还原业务约束,不创建支付、退款或额度锁。
1 身份不能合并
| 身份 | 本场景对象 | 不能替代的对象 |
|---|---|---|
| 支付意图 | PI2 | 不等于一笔成功实收 |
| 支付尝试 | A1、A2 | A1超时不等于未扣款 |
| 成功实收 | C1、C2,各270.00 | 不能按同一order_id覆盖成一个capture |
| 被订单采纳的支付 | C2 | 不使迟到C1增加商品权益 |
| 退款意图 | L1本次取消权益对应的意图IA | 不等于协调任务compensation_id |
| 退款操作 | RA及其远端操作标识 | 重试、回执重复和另一个协调方不能产生第二笔现金退款 |
| 券恢复权益 | 原L1核销与相应退券权益 | 不因每个子单或新补偿任务重建 |
知识还原时应从实际字段和唯一约束找到这些身份。如果现有服务只存order_id而无法区分capture,结果是身份缺口,不能由模型给C1/C2补造数据库关联。
2 先区分两个额度池
AL1将商品现金权益固定为L1=83.33、L2=93.33、L3=93.34。C2提供正常商品退款资金;C1属于迟到重复实收。两个capture各有270.00的原始资金上限,但O2商品权益只有270.00。
行权益约束为:已确认商品退款加在途商品退款占用,不超过AL1中该行可退现金。capture约束为:该capture全部已确认返还加全部在途返还,不超过它的实收。重复实收返还也计入capture层,不能为不同purpose分别复制出270.00额度。
本场景所有正常退款都绑定C2。真实多支付来源分摊若不同,必须另有“行权益→capture”分配证据;不能从PI2相同推断任意选择一个capture。
3 RA、RC与RB交错执行
R0已在L1/C2确认30.00。此时L1现金权益剩余53.33;C2总体剩余240.00。
| 检查点 | 事件 | L1确认 / 占用 | L2确认 / 占用 | C2确认 / 占用 / 剩余 |
|---|---|---|---|---|
| T0 | R0已确认 | 30.00 / 0.00 | 0.00 / 0.00 | 30.00 / 0.00 / 240.00 |
| T1 | RA取得IA并占用L1剩余 | 30.00 / 53.33 | 0.00 / 0.00 | 30.00 / 53.33 / 186.67 |
| T2 | RC使用另一个协调任务请求同IA | 不变 | 不变 | 不变;RC关联RA,不另占用 |
| T3 | RB为L2独立意图占用93.33 | 30.00 / 53.33 | 0.00 / 93.33 | 30.00 / 146.66 / 93.34 |
| T4 | RA请求超时,远端结果未知 | 不变 | 不变 | 不变;超时不释放53.33 |
| T5 | RA成功确认 | 83.33 / 0.00 | 0.00 / 93.33 | 83.33 / 93.33 / 93.34 |
| T6 | RA同一回执重投 | 不变 | 不变 | 不变 |
| T7 | RB成功确认 | 83.33 / 0.00 | 93.33 / 0.00 | 176.66 / 0.00 / 93.34 |
T5将53.33从在途转为确认,不改变C2剩余。若实现先减占用、后加确认,中间状态可被别的退款请求利用;需要原子迁移或足够保守的权威状态。知识系统只在找到提交边界与竞争守卫后才确认该保障。
RC若不携带与RA可对齐的IA,只能作为待判断候选。不能仅凭“都退款53.33”将两个合法分次退款合并,也不能仅凭两个compensation_id就认定它们是独立权益。应核对原取消/退货申请、行或数量范围及业务版本。
4 原子性与死锁检查
危险时序是RA、RC同时读取L1剩余53.33,各自独立写入53.33申请。最终仅一个RPC成功并不能证明设计安全,另一个可能稍后成功。应在产生远端副作用之前找到意图唯一性、行权益占用和capture占用的可靠守卫。
若同一权威数据库事务覆盖这些记录,提取实际条件更新或锁定范围、唯一约束以及提交顺序。跨服务独立数据库不能由一处@Transactional推定为同一事务;需保存两个占用阶段和补偿状态,未确认两层占用前不认定允许发起退款。一个阶段崩溃后如何发现和恢复残留占用,也须有任务或对账证据。
多个资源的锁定顺序必须可检查。例如按固定资源类型及稳定ID排序,而不是RA先锁行再锁capture、RB先锁capture再锁行。缺少顺序并不自动证明会死锁,但须保留恢复未确认。数据库锁释放只结束本地互斥,不能据此释放远端可能已受理退款的业务占用。
5 迟到支付与退款归属
A1超时后A2成功并形成C2;A1稍后成功形成C1。订单采纳C2的事实不应改成“最后成功的C1”。C1进入重复实收处置,返还操作绑定C1,不能扣减L1/L2权益,也不能把RA误关联到C1。
商品退款C2与重复实收返还C1可以并行,但回执必须校验各自capture、操作ID、金额和币种。若只按PI2或order_id处理回执,可能将C1的270.00回执误写成O2商品已全退。知识还原应将此问题标为关联键不足,而不是用汇总金额判断完成。
6 未知、释放与晚到回执
RA超时后保持在途。协调进程退出、租约到期或人工关闭页面都不改变远端事实。只有可验证的终局拒绝或撤销,才能支撑额度释放;“未查到”可能只是查询延迟,不证明退款没有发生。
若同一操作先出现终局拒绝、后又收到成功,先核对来源、操作ID、响应版本和拒绝的真实语义。无法消解时保留冲突、停止新的额度确定性结论,不能将成功改挂到新操作上。已获资金观察不一致时,问答返回部分解释与冲突,不建议用户再次退款。
业务状态UNKNOWN_RESULT与知识查询超预算分别记录。知识查询预算耗尽只使结果PARTIAL,不取消业务退款;知识任务inbox去重也不能证明RA在支付服务中不会执行两次。
7 分单与券恢复的完成边界
T7说明S1的L1、L2现金权益均已退款确认,S2的L3仍可履约。订单O2不能因此标为全部退款或全部补偿完成。父流程按目标权益集合判断,而不是按已结束子单数量推断。
本例券仅属于L1。R0的30.00不足以触发退券;RA确认后L1累计83.33且L1取消最终成立,才具备该券恢复前提。若L1取消仍有争议,即使现金已退83.33也不自动退券。原核销与退券权益只能确认一次,RA、RC或父单协调任务不能各退一次。
此政策是本样例输入,不是通用业务规则。业务政策不同则以独立规则修订与证据解释,不能让金额公式决定券是否恢复可用。
8 K3与实例观察混读
K3固定分析代码与规则,不能冻结T0至T7的资金状态。假如L1使用T0数据而C2使用T5数据,问答可能算出“L1还能退53.33”;这个数值来自过期行观察,不能因K3相同就视为一致。
实例观察集合需要来源版本、水位、关联键和观察时间,并说明是否取得共同一致性依据。没有共同屏障时可以分别列出“来源甲在时点一观察到……、来源乙在时点二观察到……”,不能合成一个当前可退金额。授权仅允许读取部分资金来源时,同样保留缺口,不能将不可见capture当零。
对本篇合成输入,问答可以说“若T3的确认与占用同时成立,L1无剩余可占用额度,C2剩余93.34”。它不能说“真实O2现在可退93.34”。Agent与IDE读取的规则保持K3;实例解释另带观察集合,不把变化的交易状态写入稳定源码知识。
9 主方案修订与核验范围
07新增资金观察、两层限额、业务意图、占用释放和并发证据约束;08新增相应故障与判分样本。本篇只给出应核对的业务保障,不假定京东现有服务采用某种锁、账本或分片事务。
机器夹具可核对金额守恒、状态迁移预期和重复事件不改变期望状态;真实实现是否具有原子性、终局拒绝语义与恢复保障,仍需对应源码、约束和运行样本。未取得证据时输出RACE_WINDOW、关联不明或观察不一致,不把人工正确时序当成实际系统证明。
订单补偿的四条使用链路
沿用O1场景基线:原价100元,满减20元,券优惠10元,原支付确认70元。券已核销,履约永久拒绝;退款随后确认,券退回失败。以下归档记录与代码均为设计样例。
1 从服务目录找到这笔业务
先核对订单、营销、券、支付和履约五个服务的应用、仓库、制品及部署。其余服务继续留在服务清单中,不能因为这一笔订单只涉及五个服务,就把全工程范围缩成五个。
从订单补偿场景反查入口:下单接口、支付通知、履约拒绝、退款回执、退券恢复任务,以及订单完成检查。每个入口要有固定版本和源码位置。订单号连接同一订单;原支付、退款操作、券预占与核销分别定位各自对象。相同Topic或相同表名只能提供查找线索。
| 业务步骤 | 要找到的实现和资料 | 缺少时保留什么 |
|---|---|---|
| 原报价与支付 | 原报价凭据、优惠规则、支付确认记录 | 有报价只能解释应付,实付仍未知 |
| 券核销与履约拒绝 | 核销确认、派发条件、拒绝事件结构及消费绑定 | 不把未核销券走入退券分支 |
| 退款确认 | 原支付、RF1退款操作、70.00 CNY金额及终态核验 | 操作或金额不符不能记整笔退款完成 |
| 退券恢复 | 原核销关联、失败记录、任务筛选、重试与结果回写 | 找到任务名不足以证明该订单会被处理 |
| 订单完成 | 退款、退券条件与订单终态持久化 | 退款已确认不代表退券或订单已完成 |
乱序还要按处理器内部步骤推演。拒绝处理器读到“未支付”,支付处理器先结束,拒绝处理器才写等待标记,单靠下一条支付消息就可能停住。本例补充的合成条件使用同订单修订检查和持久重评待办;进程中断后,扫描器仍能发现未完成项。若实际源码没有这些安排,还原结果应指出缺口,不能把合成条件套到真实服务。
2 回答“为什么还没关闭”
问答先定位业务系统中的O1及观察时间。归档入口按命名空间、对象类型、对象ID和半开时间区间查询,返回固定来源修订。只给“O1”且不能区分所属系统时,先确认对象,不能全库拼接同名订单。
在时点T2,样例观察包括原支付70元、RF1退款确认70元、券退回失败和订单仍在补偿。回答为:
T2归档记录显示,70元退款已确认,当时退券失败,订单仍在补偿中。查到的完成条件要求退券成功并写入订单终态,这条条件尚未核对。
这里沿用原夹具的检查点:T1为退款结果未知、退券待处理;T2为退款已确认、退券失败;T3才表示两项补偿确认并写入订单终态。各条归档仍保存实际观察时间,检查点名称不能代替时间或证明资金状态来自同一次一致观察。
接口样例中的instance_identity_witness固定归档标识与原对象的关联:capture:O1对应P1的实收,refund:O1对应RF1,compensation:O1对应CP1,return:O1在页面显示为CR1。核销redemption:O1关联原预占RS1,两者是不同对象。关联见证绑定归档命名空间、关联记录修订和三条观察的确切来源修订,保留关联记录摘要。退款、退券及订单记录均保留相应关联,检查器再与原O1夹具核对;只有同一订单号和70元金额,仍不足以认定是同一次操作。
问答页面把这些记录和规则整理为可读结论,不是归档接口的原样输出。本次完成条件读取K2的汇合规则;原报价读取K1。归档记录使用各自来源修订,既不属于K1或K2发布成员,也不因页面切换知识版本而变成新的观察。
样例登记了K2完成规则的引用,没有提供该修订的审阅通过记录。页面因此标明完成条件待核对。归档中的退款、退券和订单状态单独解释,不为这条规则补造审阅结果。
每句话分别引用相应观察与完成规则。归档只说明记录所覆盖的时点;没有更晚记录,不等于当前仍未恢复。回答中的“退款已确认”不等于银行到账。移除退券观察后,只能说明退券结果未知;移除原支付记录后,不能再断言实际支付70元;把退款回执改成30元时,不能把它当成RF1整笔70元退款完成。
若问“还能退多少”,还需取得同一资金观察范围中的实收、已退和在途占用。上述状态记录不足以自动证明一个一致余额。没有这组依据时,回答列出缺少的记录,不把未知占用算成零。
3 Agent从订单记录追到代码
Agent使用同一有效身份,先读业务规则,再查订单归档。二者分别授权。接口样例见四链路请求与结果。
| 调用 | 使用的定位信息 | 继续调查的依据 |
|---|---|---|
| search_knowledge查询规则 | 订单补偿、业务域、固定参考快照 | 规则、流程的对象与修订 |
| search_knowledge查询INSTANCE_OBSERVATION | O1的精确选择器与观察区间 | 观察ID、归档修订、证据ID及已核对的历史知识引用 |
| get_evidence读取归档 | 返回的证据ID | 原支付、退款操作、金额、币种及券处理状态 |
| get_business_rule / get_business_flow | 已选对象、修订及其所属快照 | 完成条件、失败分支和恢复入口 |
| trace_impact调查恢复入口 | 具体方法与变更类型 | 调用方、退券接口、状态写入及逐条证据 |
从任务标签取得影响查询目标
退券原文的recovery_entry=task:coupon-return-retry只是检索线索,不能直接填入trace_impact.target并声明它是方法。调用过程如下;源码与登记均为合成设计输入。
| 样例调用 | 参数来自哪里 | 返回与下一步 |
|---|---|---|
| find-recovery-symbol | read-coupon原文中的任务标签作为query;types为TECHNICAL_ENTITY,沿用本分支K2和scope | 返回symbol:scenario:coupon-return-retry、确定实现修订及证据引用;命中仍是CANDIDATE |
| read-recovery-binding | 搜索结果的evidence_refs | 固定源码显示任务标签对应CouponReturnRetryTask#retry(OrderState),以及原补偿、核销和退券操作的传参;不证明任务会选中O1 |
| trace-recovery-entry | 搜索返回且证据核对过的符号ID,kind=SYMBOL、change_type=LOGIC | 当前只定位到方法;调度筛选、券接口确定实现和结果回写缺证据,返回PARTIAL与POTENTIAL |
未命中时保留“恢复入口未解析”,多个实现时按合同分别调查或收窄范围,不取第一个名称匹配项。接下来进入IDE时,开发者打开自己的订单仓库;IDE重新按本地文件、基线及选区定位。此处K2的调查符号不是下一节K1工作区新方法的身份,两者不能互换。
归档记录可以晚于参考知识K1。它以INSTANCE_ARCHIVE返回,不冒充K1发布成员,也不改写K1。分页固定查询开始时的归档候选范围;后来写入的成功记录要用新查询取得,不能让正在翻页的结果自行变化。
O1的原报价若采用K1,而实际恢复已经运行K2,Agent沿归档返回的knowledge_refs分别读取两份版本。K1下读取原报价,K2下读取恢复规则,各自保留游标、修订与权限检查。问答汇总列出knowledge_contexts,说明每份版本用于解释哪个动作。没有执行版本关联时,不能因K2发布时间较晚就认定O1使用K2。
长任务重试还要保留原输入。相同request_id、相同问题及假设返回原任务;把“退款未知”改成“退款已确认”属于新输入,用同一request_id提交应返回REQUEST_CONFLICT。一个请求中两条假设不能复用同一assumption_id表达不同内容。
4 IDE检查退券恢复改动
研发根据调查结果,准备新增一个退券恢复方法。IDE提交实际仓库基线、目标符号、完整Diff和文件哈希,并声明上传范围。服务先核对补丁,再产生工作区修订。
影响路径可以是“工作区新增恢复方法 → 已发布退券接口 → 已发布订单完成检查”。每个节点和关系分别标明来自哪个快照或工作区。第一条关系是新增方法调用退券接口;第二条关系表示退券返回值决定是否继续调用订单检查,不表示券服务直接调用订单服务。工作区新增的边不需要先进入正式发布;它也不能被标成K1已有的实现。删除的旧边不会因为仍在K1中就重新进入工作区执行路径。
接口样例保存两组独立的IDE输入:
| 样例 | 基线与改动 | 检查内容 |
|---|---|---|
| workspace-new-recovery-impact / workspace-new-recovery-context | K1基线上新增退券恢复方法 | 新方法调用原退券接口,返回确认后进入已有订单检查;三个节点和两条关系逐项保留来源 |
| workspace-impact / workspace-context | K2基线上删除couponReturned条件 | 另一项有风险的改动,用于检查工作区关系与订单关闭条件;不作为新增恢复方法的验收输入 |
新增方法正例同时保存原文件、完整Diff、修改后文件及独立的发布和工作区成员见证。只提供这个文件时,调度和持久待办等资料仍缺失,返回PARTIAL。设计检查从保存的请求、结果和见证核对版本、补丁、文件哈希、路径端点及来源,不执行Java,也不据此判断O1已经恢复。
新增恢复上下文同时返回基线已有的“券退回业务幂等”和“补偿汇合条件”完整规则、原证据及逐条rule_applicability。两条规则继续保持UNREVIEWED/UNRESOLVED;工作区适用性与规则审阅状态分别展示。
当前样例两条适用性均为UNKNOWN:局部方法虽然传递原补偿、核销和退券操作标识,但券接口中的原预占映射及幂等判断尚未取得,不能将原OPAQUE条件判为完全适用;退券确认后的调用也不能证明完成检查仍核对退款、退券及终态持久化。IDE先展示这些候选约束和具体缺项,再显示已解析的调用路径。调度、持久待办及其他未上传实现继续列入省略范围。
IDE取得规则及路径后,先检查:退款已确认时是否还会重复提交;退券是否仍关联原核销;失败项是否能再次被扫描;完成检查是否仍同时要求退款、退券和订单终态。只有未提交代码,不能回答“O1现在已恢复”。
跳转前核对整文件原始字节哈希。片段的UTF-8内容哈希只验证这段证据,不能拿来比较本地整文件。整文件哈希缺失或不匹配时,打开固定证据视图。继续编辑、修改依赖、切换构建profile或改变上传范围后,重新计算工作区分析输入,旧结论只用于回看。
5 恢复成功以后怎样更新回答
检查点T3另给退券确认和订单终态写入的归档记录,两者必须关联同一O1、补偿与原核销。新查询才能回答“T3时该订单补偿已完成”。原T2答案继续保留T2依据;代码变更、知识K2发布和实际业务完成是三个独立事件。
| 故意改变的输入 | 必须出现的结果 |
|---|---|
| 无交易归档权限,只有源码权限 | 返回规则解释及实例资料缺口,不返回流水、隐藏数量或订单名称 |
| 归档记录属于另一命名空间的同号订单 | 不参与O1结论 |
| 原报价版本已回收 | 返回历史版本缺口,不用K2重算原金额 |
| RF1回执只有30元或币种不符 | 不将70元退款标为确认完成 |
| 没有持久重评待办或扫描依据 | 保留并发停滞风险与缺失实现,不把恢复路径标为已查清 |
| 影响路径引用另一工作区的节点 | 拒绝该路径,不按节点名称合并 |
| 本地文件已继续编辑 | 固定证据视图仍可读,原行号不直接跳到当前文件 |
| 权限在模型读入证据后撤销 | 废弃尚未交付结果,按当前权限重新取证 |
从首次输入到继续调查
以下是离线设计样例。订单查阅与IDE沿用四条使用链路的O1归档和订单仓库恢复方法;异步任务沿用跨版本问答:K1用于原报价,K2含订单恢复实现。三组调用各自固定资料和观察时间。
IDE与版本推演使用另一组输入:恢复方法位于券仓库,知识更新只涉及配置。其“配置基线”“配置更新版”与本章K1、K2不属于同一条发布线。完整请求、响应与交接对象见接口样例,结构见客户端入口合同。
从订单号开始
用户知道O1,并想看最近可取得的退款、退券及订单记录。客户端此时还没有namespace、知识版本或证据ID。
| 顺序 | 用户或客户端做什么 | 服务返回什么 | 下一步使用哪些值 |
|---|---|---|---|
| 1 | 初始化读取session/options | 当前身份可读的“订单业务归档”,以及选项修订和租约 | 页面显示名称,内部保存source-option:trade |
| 2 | 用户选择订单业务归档,输入O1,选“最近可用记录” | 准备接口按已完成归档水位取回看窗口 | 返回区间09:00至10:00、scope和K2 |
| 3 | search_knowledge按返回选择器查实例归档 | 退款、退券、订单记录的观察与证据引用 | 用返回的evidence_refs读取原文 |
| 4 | 打开退款原文 | 原支付与退款操作、70元、币种、最终结果及原记录时间 | 再读退券和订单依据,分别说明已知与未知 |
本例的归档水位为2026年10月30日10:00(UTC+08:00),回看窗口为一小时;水位是排他上界。默认窗口属于接入配置,不能在客户端硬编码成业务规则。没有命中时显示查过的区间,用户可以改选历史范围,不直接返回“订单不存在”。
准备请求:
{
"request_id": "req:first:prepare",
"options_revision": "options:scenario:1",
"source_option_ref": "source-option:trade",
"object_kind": "ORDER",
"object_id": "O1",
"time": {"mode": "RECENT"}
}
准备结果中的选择器:
{
"namespace": "archive:scenario:trade",
"object_kind": "ORDER",
"object_id": "O1",
"observed_from": "2026-10-30T09:00:00+08:00",
"observed_to": "2026-10-30T10:00:00+08:00"
}
宿主把选择器放入search_knowledge.arguments.instance_selector,types只填INSTANCE_OBSERVATION,同时带入返回的scope与snapshot_id。完整请求见接口样例的handoffs.archive_search;它与既有归档搜索使用相同范围。
两个系统都存在O1时,先让用户选择可见业务系统;没有访问资格的系统不出现在候选中。请求已经成功而响应丢失时重试原request_id,仍使用原时间窗口;想取得后续记录时新建请求。
从当前文件开始
开发者在订单仓库的src/OrderRecovery.java中新增退券恢复方法,选中第2至8行,点击查看业务约束。方法沿用原补偿、原核销与原退券操作,不再次申请已经确认的退款。
| IDE拿到的本地信息 | 适配器处理 | 形成的请求信息 |
|---|---|---|
| Git远端 | 与初始化返回的已登记别名匹配 | repo:scenario:order;多候选须选择 |
| 知识版本 | 初始化的knowledge_versions列出K1和K2;工作区基线唯一对应K1,IDE显示并带入 | resolve-targets的snapshot_id=K1,不要求开发者填写编号 |
| 当前Commit及未提交改动 | 保留原始Diff、文件内容哈希和上传完整性 | 原O1恢复方法workspace,基线为K1对应源码 |
| src/OrderRecovery.java,第2至8行 | resolve-targets核对补丁和当前整文件哈希,再解析选区 | OrderRecovery#retryCouponReturn(OrderState)及工作区符号引用 |
| 用户任务“补齐退券恢复” | 与选定目标一起提交 | build_context的task与symbols |
本例的远端别名为ssh://git@scm.example.invalid/scenario/order.git,仅用于演示匹配形态,服务不访问这个地址。仓库标识来自服务返回的已登记选项,不由客户端截取URL最后一段猜出。
定位后返回工作区符号symbol:workspace:retry-coupon-return。这是服务已登记的临时引用,绑定本次输入摘要、快照、身份与租约,不是让调用方手工拼接的命名模板。完整resolve-targets请求与返回见接口样例的resolve_targets项;随后调用见handoffs.build_context,使用相同workspace和返回的目标符号。
选区涵盖多个方法时显示完整签名供选择;代码还未解析成功时显示缺少的文件或依赖。开发者继续编辑后,原符号定位与上下文均不能直接用于新代码,重新定位、重新分析。只有需求描述时symbols可以为空,返回候选和未核对范围,不能冒充已经精确找到改动目标。
问答断线后继续
这个样例调查“O1的70元实付采用哪版依据,后来的退券恢复用了哪版实现”,沿用跨版本问答的原结论和观察记录。客户端拥有该历史样例所需的domain:trade范围;它与前一小节的归档选项分别授权。
服务端任务只接收问答,外部Agent自有工具链由客户端保存和续接。客户端提交到POST /kb/v1/tasks的正文直接是AnswerRequest:
{
"schema_version": "0.1",
"request_id": "req:first:task",
"question": "O1的70元实付采用哪版依据,后来的退券恢复用了哪版实现?",
"scope": {
"repo_ids": [],
"domain_ids": ["domain:trade"],
"environment": null,
"purpose": "BUSINESS_EXPLANATION"
},
"snapshot_id": "K2",
"assumptions": []
}
| 操作 | 请求或返回要点 | 客户端处理 |
|---|---|---|
| 创建任务 | 202;task:O1:1、修订1、QUEUED、query:first:task、K2 | 保存任务标识;断线不重复创建另一任务 |
| 重新连接 | GET任务状态,得到修订3、SUCCEEDED、answer-result:O1:1 | 使用返回的结果修订读取最终结果 |
| 读取第一页 | result_revision固定,cursor为空,page_size=1 | 收到完整AnswerResult和下一页游标 |
| 读取第二页 | 原结果修订、原页大小及服务返回游标 | 收到该答案的结论—证据索引,next_cursor为空 |
| 完成后请求取消 | expected_task_revision=3 | 返回原SUCCEEDED状态,不改写终态 |
| 另一个运行中任务取消成功 | 条件写入成功,状态转CANCELLED | 不显示未完成结果;迟到模型返回不发布 |
结果分页不是将一句结论拆成多段,也不在第二页追加新的推断。第一页保持完整AnswerResult;后续索引只整理已有结论的证据引用。没有索引附件时第一页直接结束。每次读取重新检查答案及必要来源的当前权限;授权变化停止旧结果回放,不能只删引用继续显示原答案。
接口样例的create_task、read_task、read_results、cancel_task给出完整请求与返回,包括两种取消结果。字段定义见异步问答合同,有限正反例见首次使用检查。
部分退款、分单与并发补偿:统一基线
合成设计场景,不是京东实际交易规则。所有金额为CNY十进制字符串,原支付与分摊版本固定在凭据AL1,不用当前营销配置重算。
订单O2包含三行:L1原价100.00、L2原价100.00、L3原价100.00,分别归属子单S1、S1、S2。满减20.00按三行原价等权分配,采用最大余数法,金额到分,余分按稳定line_id升序分配:L1=6.67、L2=6.67、L3=6.66。券10.00仅适用L1,故现金分摊L1=83.33、L2=93.33、L3=93.34,合计270.00。
支付意图PI2下:尝试A1超时并保持结果未知;尝试A2确认支付C2=270.00且被订单采纳。之后A1收到迟到成功,形成独立capture C1=270.00,进入重复实收处置,不覆盖C2,也不将订单可消费权益变成540.00。此例的重复实收返还与商品退款分开关联,但都消耗对应capture退款额度。
正常退款用C2:此前L1已成功部分退款R0=30.00。本次L1撤销申请RA最多还可退53.33;L2另一申请RB=93.33。RA请求已接收但尚无最终退款结果,53.33须计入在途占用。另一协调方针对同一L1取消发起RC,不同compensation_id不能绕过已占用额度或重复退款。RC与RA语义重复,需识别业务取消/退款意图,不能只靠message_id或compensation_id去重。
S2履约继续,S1内L1/L2可分别退款。L1撤销是否退券由独立政策决定:本例设定券退回须券所对应的L1全额现金退款确认且L1取消最终成立;其他行取消不触发该券退回。该政策只为场景输入,不能当作京东通用规则。券退回动作按原核销+退券权益去重,不能因新补偿任务再退一次。
并发采用人工期望时序:RA占用L1剩余额度53.33后,RC发现同一退款意图已有进行中操作并复用;RB可独立占用L2额度。退款超时保留在途占用;只有可验证拒绝或撤销使该操作不可能再成功时释放额度。晚到成功必须与原退款操作关联,禁止先释放后另退造成超退。
必须区分:knowledge snapshot K3固定规则/代码/契约;实例资金状态observed_at固定某次观察,不能因K3不变就认为退款额度不变。只掌握静态源码和本合成输入时,问答给条件化计算,不宣称真实账户可退额度。
推演输入覆盖金额舍入、分摊版本、业务权益、capture、refund_intent、refund_operation、退款占用、确认与拒绝。分析对象是业务系统;知识服务只还原并解释,不提供扣款、退款、锁额度等写接口。
订单优惠与失败补偿:场景基线
本场景为设计夹具,不描述京东线上实际业务。所有服务名、版本、事件和规则标识均为合成数据。各专项推演共用本基线,不自行改变金额与状态语义;需要调整时记录冲突后统一修订。
服务与版本
| service_id | 职责 | service_version_ref |
|---|---|---|
| svc:order | 订单入口、订单状态与补偿协调 | sv:order:1 |
| svc:promotion | 优惠报价、优惠资格及报价凭据 | sv:promotion:1;灰度sv:promotion:2 |
| svc:coupon | 券预占、核销及退回 | sv:coupon:1 |
| svc:payment | 支付确认与退款 | sv:payment:1 |
| svc:fulfillment | 履约接单与失败事件 | sv:fulfillment:1 |
知识快照K1包含上述实现,promotion两个版本并存,以渠道与配置范围绑定。完整代码Commit在机器夹具中用确定的合成40位hex表示。正常例使用promotion:1;版本2用于灰度差异和IDE变更。K1包含v2技术证据,但本夹具没有完整的v2业务规则产物;不得把v1条件当成两个实现的共同规则。
订单与规则
- 订单O1为单履约单,原价100.00 CNY,满减20.00,券优惠10.00,实际支付70.00。金额均为十进制字符串。
- 规则R_STACK:活动命中且选择券时,渠道允许并且配置allow_stack=true才允许叠加;报价返回quote_id、规则版本、金额分摊与有效期。
- 创建顺序为报价→券预占→订单创建。创建失败释放原reservation_id;释放失败保留待处理,不走退款(尚未确认支付)。
- order按quote_id核验金额、渠道与有效期,不在支付回调时用当前配置重算历史报价。
- coupon以reservation_id记录预占;支付确认后核销。重复支付事件不重复扣券。
- 履约永久拒绝发生在支付成功之后,order创建compensation_id。退款以原支付流水和实付金额70.00申请,优惠不是现金退款。
- 退款确认、券退回分别是独立子状态;只有两个动作都确认且订单状态更新后,补偿才完成。退款请求被接收不等于退款到账。
- coupon退券需要核验当前券状态及本次核销关联,不以相同coupon_id作为所有退款事件的去重键。
事件与关联
JSF边界为order→promotion报价、order→coupon预占及核销、order→fulfillment派发、order→payment退款申请、order→coupon退回。JMQ承载PaymentSucceeded、FulfillmentRejected、RefundConfirmed;消费组分别保留绑定。Topic相同不自动合并事件。
正常控制关系为支付事实确认→券核销确认→履约派发,派发永久拒绝才进入本例补偿。核销失败也进入补偿调查,但券未核销时执行释放预占而不是退回已核销券;两种操作保留不同状态守卫。本例F4以券已核销为前提。上述关系作为合成声明与控制证据提供,不从服务名称猜测。
业务键包括order_id、payment_id、quote_id、reservation_id、compensation_id。message_id只用于一次投递的标识,重试或重放可能改变;业务操作幂等键须独立于message_id。
故障输入
F1 缺生产allow_stack快照:只能解释代码条件,不能回答当前是否允许。 F2 PaymentSucceeded重复和乱序;FulfillmentRejected先到但支付事实尚未确认:记录待核验状态,不能直接退款。 F3 退款申请超时但支付侧已接收;重试必须复用业务幂等键。 F4 退款确认成功、退券失败:保持部分补偿,禁止宣称全流程完成。 F5 旧版PaymentSucceeded消息被新版消费端回放;消息不含新增stack_policy字段。 F6 需求拟修改promotion叠加条件并增加stack_policy,由报价传入订单与PaymentSucceeded。当前只提供promotion未提交Diff,order/payment字段映射与消费缺省尚未补齐;影响分析必须报告未确定传递路径。工作区与K1分叉,共同祖先源码可用但没有已发布知识。 F7 查询途中coupon证据被撤权;已进入模型上下文的结果废弃。 F8 拒绝处理器已读到支付未知,支付处理器随后完成确认并检查无等待标记,拒绝处理器最后才写入pending_reject;不能依赖再次收到支付消息恢复。 F9 原退款操作为70.00 CNY,但收到同P1、CP1下30.00回执,或币种、退款操作标识不符;不得仅凭Confirmed事件名称推进退款完成。
消费端任务
问答:为什么O1只能退70元;退款成功是否代表订单补偿完成;当前渠道能否叠券。 Agent:从业务规则搜索到完整流程、契约与证据,追查新增stack_policy字段对旧消费方和历史回放的影响。 IDE:对promotion规则修改生成任务上下文,区分历史已发布知识、祖先源码和工作区覆盖层;输出规则约束、契约使用点、未确定影响,不写代码。
恢复路径的合成证据
完整正例另提供ev:scenario:order-recovery:拒绝先到时持久化pending_reject,后续PaymentSucceeded核验支付后重新评估;已有永久拒绝则进入补偿,不再派发履约。退款申请超时后复用相同业务键重试,支付侧返回原接收记录;最终以RefundConfirmed推进退款状态。恢复预算耗尽进入MANUAL_REQUIRED,不把未知结果改为失败,也不新建退款操作。
券退回失败由绑定compensation_id与reservation_id的恢复任务再次尝试;本例随后确认退回并完成join。预算耗尽时保留MANUAL_REQUIRED,不宣称补偿完成。删去order-recovery构成独立反例,应返回恢复入口未知;不能仅凭主路径成功推断恢复机制。
并发重评与退款回执的补充条件
以下为本次补充的合成场景条件,用于检查设计,不表示已发现或验证相同的线上实现。
订单O1的支付事实和永久拒绝事实按同一订单协调。每次事实写入与状态修订递增、重评待办写入在同一提交边界完成。重评任务读取这份状态修订,提交决定前再次核对修订;修订变化时保留待办并重算。待办由扫描任务补取,唤醒消息丢失或执行进程退出不会删除它。两项事实均成立后创建或读取原补偿,重复重评不新建补偿,也不再创建该履约操作的正常派发。该条件由新增合成证据ev:scenario:recovery-coordination提供;删除它时,F8返回恢复唤醒机制未证实,不沿用串行正例的完整结论。
O1的原退款操作标识为RF1,关联P1、CP1,要求单次全额退款70.00 CNY。回执须匹配RF1、原支付、补偿关联、金额、币种及最终确认状态,才可确认该操作;已接收仍需等待最终结果。新增合成证据ev:scenario:refund-receipt-validation明确这项约束。F9的30.00、错误币种和错误操作回执进入差异核对;缺少币种或该核验证据时保留未知,不推动补偿完成。重复的有效回执只确认同一RF1一次。
协议与示例
字段定义和请求、返回示例。业务语义见接入合同与对应技术章节。
answer-coverage.example.json
{
"schema_version": "0.2",
"request_id": "r-example",
"query_id": "q-example",
"snapshot_id": "release:coverage:1",
"status": "PARTIAL",
"answer_state": "INSUFFICIENT_EVIDENCE",
"claims": [],
"clarifications": [],
"coverage": {
"scope_basis": "CODE_ONLY",
"queried_repo_ids": [],
"unresolved": [
{
"code": "RECOVERY_UNRESOLVED",
"target": "obligation:reconcile"
},
{
"code": "HANDOFF_CONTRACT_MISSING",
"target": "obligation:manual"
}
],
"truncated": false,
"business_assessment": {
"ledger_revision": "coverage:synthetic:1",
"snapshot_id": "release:coverage:1",
"closure": "PARTIAL",
"required_for_answer": true
}
},
"policy_epoch": "policy-example",
"assumptions": [],
"observations": [],
"observation_sets": []
}
answer-followup-request.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:answer-followup-request:0.1",
"title": "工作台内部追问请求",
"type": "object",
"additionalProperties": false,
"properties": {
"request_id": {
"type": "string",
"minLength": 1
},
"parent_query_id": {
"type": "string",
"minLength": 1
},
"parent_result_revision": {
"type": "string",
"minLength": 1
},
"question": {
"type": "string",
"minLength": 1
},
"assumptions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"assumption_id": {
"type": "string",
"minLength": 1
},
"text": {
"type": "string",
"minLength": 1
}
},
"required": [
"assumption_id",
"text"
]
},
"uniqueItems": true
}
},
"required": [
"request_id",
"parent_query_id",
"parent_result_revision",
"question"
]
}
answer-request.example.json
{
"schema_version": "0.1",
"request_id": "req:synthetic:question:1",
"question": "在给定条件下,L1已有退款后还剩多少现金权益?",
"scope": {
"repo_ids": [],
"domain_ids": [
"domain:trade"
],
"environment": null,
"purpose": "BUSINESS_EXPLANATION"
},
"snapshot_id": null,
"assumptions": [
{
"assumption_id": "assumption:amount",
"text": "合成条件:原现金权益83.33元,已确认退款30.00元;本问题只算差额,不核定实际可退额度。"
}
]
}
answer-request.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:answer-request:0.1",
"title": "同步问答请求",
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"question": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"environment": {
"type": [
"string",
"null"
]
},
"purpose": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_ids",
"domain_ids",
"environment",
"purpose"
],
"anyOf": [
{
"properties": {
"repo_ids": {
"minItems": 1
}
}
},
{
"properties": {
"domain_ids": {
"minItems": 1
}
}
}
]
},
"snapshot_id": {
"type": [
"string",
"null"
]
},
"budget": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_tool_calls": {
"type": "integer",
"minimum": 0
},
"max_source_bytes": {
"type": "integer",
"minimum": 0
},
"max_graph_nodes": {
"type": "integer",
"minimum": 0
},
"max_depth": {
"type": "integer",
"minimum": 0
},
"max_input_tokens": {
"type": "integer",
"minimum": 0
},
"max_output_tokens": {
"type": "integer",
"minimum": 0
},
"deadline_ms": {
"type": "integer",
"minimum": 1
}
},
"required": []
},
"assumptions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"assumption_id": {
"type": "string",
"minLength": 1
},
"text": {
"type": "string",
"minLength": 1
}
},
"required": [
"assumption_id",
"text"
]
},
"uniqueItems": true
}
},
"required": [
"schema_version",
"request_id",
"question",
"scope",
"assumptions"
]
}
answer.example.json
{
"schema_version": "0.2",
"request_id": "r-example",
"query_id": "q-example",
"snapshot_id": "release-example",
"status": "PARTIAL",
"answer_state": "NEEDS_CLARIFICATION",
"claims": [],
"clarifications": [
{
"field": "entity_id",
"question": "指订单主单还是履约单?",
"candidates": [
"订单主单",
"履约单"
]
}
],
"coverage": {
"scope_basis": "CODE_ONLY",
"queried_repo_ids": [
"repo:example:order"
],
"unresolved": [
{
"code": "ENTITY_AMBIGUOUS",
"target": "订单"
}
],
"truncated": false
},
"policy_epoch": "policy-example",
"assumptions": [],
"observations": [],
"observation_sets": []
}
answer.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:answer:0.2",
"title": "问答结果",
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.2"
},
"request_id": {
"type": "string",
"minLength": 1
},
"query_id": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"status": {
"enum": [
"OK",
"PARTIAL",
"EMPTY"
]
},
"answer_state": {
"enum": [
"ANSWERABLE",
"PARTIALLY_ANSWERABLE",
"NEEDS_CLARIFICATION",
"CONFLICT",
"NOT_FOUND",
"INSUFFICIENT_EVIDENCE"
]
},
"claims": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"claim_id": {
"type": "string",
"minLength": 1
},
"text": {
"type": "string",
"minLength": 1
},
"rule_revision_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"scope": {
"$ref": "urn:jd-kb:business-rule:0.2#/properties/scope"
},
"verification_status": {
"enum": [
"CANDIDATE",
"REVIEWED",
"CONFLICTED",
"STALE"
]
},
"basis_type": {
"enum": [
"RULE",
"CONDITIONAL",
"INSTANCE_OBSERVATION"
]
},
"assumption_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"observation_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"calculation": {
"type": "object",
"additionalProperties": false,
"properties": {
"target_kind": {
"enum": [
"ORDER",
"SUBORDER",
"LINE",
"REFUND_OPERATION",
"CAPTURE",
"DUPLICATE_CAPTURE",
"COUPON_ENTITLEMENT"
]
},
"target_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"currency": {
"type": "string",
"pattern": "^[A-Z]{3}$"
},
"allocation_revision_ref": {
"type": [
"string",
"null"
]
},
"capture_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"formula": {
"enum": [
"ALLOCATION_MINUS_CONFIRMED_MINUS_HELD",
"CAPTURE_MINUS_CONFIRMED_MINUS_HELD",
"MIN_OF_SCOPED_BALANCES",
"ALLOCATION_TOTAL"
]
},
"components": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"amount": {
"type": "string",
"pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$"
},
"source_ref": {
"type": "string",
"minLength": 1
}
},
"required": [
"name",
"amount",
"source_ref"
]
},
"minItems": 1
},
"result": {
"type": "string",
"pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$"
},
"result_kind": {
"enum": [
"ARITHMETIC_BOUND",
"OBSERVED_AVAILABLE"
]
},
"observation_set_ref": {
"type": [
"string",
"null"
]
}
},
"required": [
"target_kind",
"target_refs",
"currency",
"allocation_revision_ref",
"capture_refs",
"formula",
"components",
"result",
"result_kind",
"observation_set_ref"
],
"allOf": [
{
"if": {
"properties": {
"result_kind": {
"const": "OBSERVED_AVAILABLE"
}
}
},
"then": {
"properties": {
"observation_set_ref": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"target_kind": {
"enum": [
"ORDER",
"SUBORDER",
"LINE"
]
}
}
},
"then": {
"properties": {
"allocation_revision_ref": {
"type": "string",
"minLength": 1
}
}
}
}
]
}
},
"required": [
"claim_id",
"text",
"rule_revision_refs",
"evidence_refs",
"scope",
"verification_status",
"basis_type",
"assumption_refs",
"observation_refs"
],
"allOf": [
{
"if": {
"properties": {
"basis_type": {
"const": "CONDITIONAL"
}
}
},
"then": {
"properties": {
"assumption_refs": {
"minItems": 1
},
"calculation": {
"properties": {
"result_kind": {
"const": "ARITHMETIC_BOUND"
},
"observation_set_ref": {
"type": "null"
}
}
}
}
}
},
{
"if": {
"properties": {
"basis_type": {
"const": "INSTANCE_OBSERVATION"
}
}
},
"then": {
"properties": {
"observation_refs": {
"minItems": 1
},
"assumption_refs": {
"maxItems": 0
},
"evidence_refs": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"basis_type": {
"const": "RULE"
}
}
},
"then": {
"properties": {
"assumption_refs": {
"maxItems": 0
},
"observation_refs": {
"maxItems": 0
},
"evidence_refs": {
"minItems": 1
}
},
"not": {
"required": [
"calculation"
]
}
}
}
]
},
"minItems": 0
},
"clarifications": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"field": {
"type": "string",
"minLength": 1
},
"question": {
"type": "string",
"minLength": 1
},
"candidates": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
}
},
"required": [
"field",
"question",
"candidates"
]
},
"minItems": 0
},
"coverage": {
"type": "object",
"additionalProperties": false,
"properties": {
"scope_basis": {
"enum": [
"CODE_ONLY",
"DEPLOYMENT_AND_CONFIG",
"OBSERVED"
]
},
"queried_repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"unresolved": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"code": {
"type": "string",
"minLength": 1
},
"target": {
"type": "string",
"minLength": 1
},
"detail": {
"type": "string",
"minLength": 1
}
},
"required": [
"code",
"target"
]
},
"minItems": 0
},
"truncated": {
"type": "boolean"
},
"business_assessment": {
"type": "object",
"additionalProperties": false,
"required": [
"ledger_revision",
"snapshot_id",
"closure",
"required_for_answer"
],
"properties": {
"ledger_revision": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"closure": {
"enum": [
"DECLARED_SCOPE_COMPLETE",
"PARTIAL"
]
},
"required_for_answer": {
"type": "boolean"
}
}
}
},
"required": [
"scope_basis",
"queried_repo_ids",
"unresolved",
"truncated"
]
},
"policy_epoch": {
"type": "string",
"minLength": 1
},
"assumptions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"assumption_id": {
"type": "string",
"minLength": 1
},
"text": {
"type": "string",
"minLength": 1
}
},
"required": [
"assumption_id",
"text"
]
},
"minItems": 0
},
"observations": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"observation_id": {
"type": "string",
"minLength": 1
},
"observed_at": {
"type": "string",
"format": "date-time"
},
"subject_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"source_revision": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"observation_id",
"observed_at",
"subject_refs",
"source_revision",
"evidence_refs"
]
},
"minItems": 0
},
"observation_sets": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"observation_set_id": {
"type": "string",
"minLength": 1
},
"observation_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"consistency_status": {
"enum": [
"VERIFIED_COMMON_CUT",
"INDEPENDENT_READS",
"UNKNOWN"
]
},
"proof_evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
}
},
"required": [
"observation_set_id",
"observation_refs",
"consistency_status",
"proof_evidence_refs"
],
"allOf": [
{
"if": {
"properties": {
"consistency_status": {
"const": "VERIFIED_COMMON_CUT"
}
}
},
"then": {
"properties": {
"proof_evidence_refs": {
"minItems": 1
}
}
}
}
]
},
"minItems": 0
},
"knowledge_contexts": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"snapshot_id",
"reason",
"rule_revision_refs",
"evidence_refs"
],
"properties": {
"snapshot_id": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
},
"rule_revision_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
}
}
}
}
},
"required": [
"schema_version",
"request_id",
"query_id",
"snapshot_id",
"status",
"answer_state",
"claims",
"clarifications",
"coverage",
"policy_epoch",
"assumptions",
"observations",
"observation_sets"
],
"allOf": [
{
"if": {
"properties": {
"answer_state": {
"const": "ANSWERABLE"
}
}
},
"then": {
"properties": {
"status": {
"const": "OK"
},
"claims": {
"minItems": 1
},
"clarifications": {
"maxItems": 0
},
"coverage": {
"properties": {
"unresolved": {
"maxItems": 0
},
"truncated": {
"const": false
}
}
}
}
}
},
{
"if": {
"properties": {
"answer_state": {
"const": "NOT_FOUND"
}
}
},
"then": {
"properties": {
"status": {
"const": "EMPTY"
},
"claims": {
"maxItems": 0
},
"clarifications": {
"maxItems": 0
},
"coverage": {
"properties": {
"unresolved": {
"maxItems": 0
},
"truncated": {
"const": false
}
}
}
}
}
},
{
"if": {
"properties": {
"answer_state": {
"enum": [
"PARTIALLY_ANSWERABLE",
"NEEDS_CLARIFICATION",
"CONFLICT"
]
}
}
},
"then": {
"properties": {
"status": {
"const": "PARTIAL"
}
}
}
},
{
"if": {
"properties": {
"answer_state": {
"const": "NEEDS_CLARIFICATION"
}
}
},
"then": {
"properties": {
"claims": {
"maxItems": 0
},
"clarifications": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"answer_state": {
"const": "CONFLICT"
}
}
},
"then": {
"properties": {
"coverage": {
"properties": {
"unresolved": {
"contains": {
"properties": {
"code": {
"const": "EVIDENCE_CONFLICT"
}
},
"required": [
"code"
]
}
}
}
}
}
}
},
{
"if": {
"properties": {
"answer_state": {
"const": "PARTIALLY_ANSWERABLE"
}
}
},
"then": {
"properties": {
"claims": {
"minItems": 1
},
"coverage": {
"anyOf": [
{
"properties": {
"unresolved": {
"minItems": 1
}
}
},
{
"properties": {
"truncated": {
"const": true
}
}
}
]
}
}
}
},
{
"if": {
"properties": {
"answer_state": {
"const": "INSUFFICIENT_EVIDENCE"
}
}
},
"then": {
"properties": {
"status": {
"const": "PARTIAL"
},
"claims": {
"maxItems": 0
},
"clarifications": {
"maxItems": 0
},
"coverage": {
"anyOf": [
{
"properties": {
"unresolved": {
"minItems": 1
}
}
},
{
"properties": {
"truncated": {
"const": true
}
}
}
]
}
}
}
},
{
"if": {
"properties": {
"coverage": {
"required": [
"business_assessment"
],
"properties": {
"business_assessment": {
"properties": {
"closure": {
"const": "PARTIAL"
},
"required_for_answer": {
"const": true
}
}
}
}
}
}
},
"then": {
"properties": {
"status": {
"const": "PARTIAL"
},
"answer_state": {
"not": {
"enum": [
"ANSWERABLE",
"NOT_FOUND"
]
}
},
"coverage": {
"properties": {
"unresolved": {
"minItems": 1
}
}
}
}
}
}
]
}
business-rule.example.json
{
"schema_version": "0.2",
"rule_id": "rule:example:dong-tiered-stack",
"revision_id": "revision:example:1",
"subject": "东券与跨店阶梯满减的叠加限制",
"scope": {
"resolution": "UNKNOWN",
"environment": null,
"service_version_refs": [
"service-version:example:promo"
],
"channels": [],
"audiences": [],
"business_time": {
"resolution": "UNKNOWN",
"valid_from": null,
"valid_to": null
},
"config_context_refs": [],
"deployment_refs": []
},
"predicate": {
"op": "AND",
"args": [
{
"op": "EQ",
"ref": "field:hitCrossShopTieredPromo",
"value": true,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
},
{
"op": "CONTAINS",
"ref": "field:selectedCouponTypes",
"value": "DONG_COUPON",
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "ENUM"
},
{
"op": "EQ",
"ref": "config:allowDongCouponStackTiered",
"value": false,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
}
],
"evaluation_order": "SHORT_CIRCUIT_LEFT_TO_RIGHT"
},
"effects": [
{
"kind": "REJECT",
"description": "拒绝本次优惠叠加",
"error_code": "PROMO_DONG_STACK_FORBIDDEN",
"evidence_ids": [
"evidence:example:branch"
],
"effect_id": "effect:example:reject",
"target_ref": null,
"expression": null,
"guard": {
"op": "AND",
"args": [
{
"op": "EQ",
"ref": "field:hitCrossShopTieredPromo",
"value": true,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
},
{
"op": "CONTAINS",
"ref": "field:selectedCouponTypes",
"value": "DONG_COUPON",
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "ENUM"
},
{
"op": "EQ",
"ref": "config:allowDongCouponStackTiered",
"value": false,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
}
],
"evaluation_order": "SHORT_CIRCUIT_LEFT_TO_RIGHT"
},
"sequence": 0,
"outcome": "THROW",
"control_ref": "control:example:reject-block",
"exception_region_ref": null
}
],
"exceptions": {
"resolution": "UNKNOWN",
"conditions": []
},
"config_dependencies": [
"config:allowDongCouponStackTiered"
],
"evidence_ids": [
"evidence:example:branch"
],
"lifecycle": "CANDIDATE",
"unresolved": [
"仅为协议示例,证据引用未连接真实仓库",
"生产取值、人群、渠道与例外尚未核验"
],
"derivation_kind": "MODEL_INTERPRETATION",
"review_status": "UNREVIEWED",
"freshness": "UNKNOWN",
"resolution_status": "UNRESOLVED",
"entity_refs": [
"entity:example:promotion"
]
}
business-rule.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:business-rule:0.2",
"title": "业务规则修订",
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"rule_id",
"revision_id",
"subject",
"scope",
"predicate",
"effects",
"exceptions",
"evidence_ids",
"derivation_kind",
"review_status",
"freshness",
"resolution_status",
"config_dependencies",
"entity_refs"
],
"properties": {
"schema_version": {
"const": "0.2"
},
"rule_id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
},
"subject": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"resolution": {
"enum": [
"KNOWN",
"PARTIAL",
"UNKNOWN"
]
},
"environment": {
"type": [
"string",
"null"
]
},
"service_version_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"channels": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"audiences": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"business_time": {
"type": "object",
"additionalProperties": false,
"properties": {
"resolution": {
"enum": [
"KNOWN",
"PARTIAL",
"UNKNOWN"
]
},
"valid_from": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"valid_to": {
"type": [
"string",
"null"
],
"format": "date-time"
}
},
"required": [
"resolution",
"valid_from",
"valid_to"
],
"allOf": [
{
"if": {
"properties": {
"resolution": {
"const": "KNOWN"
}
}
},
"then": {
"properties": {
"valid_from": {
"type": "string",
"format": "date-time"
},
"valid_to": {
"type": "string",
"format": "date-time"
}
}
}
}
]
},
"config_context_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"deployment_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
}
},
"required": [
"resolution",
"environment",
"service_version_refs",
"channels",
"audiences",
"business_time",
"config_context_refs",
"deployment_refs"
]
},
"predicate": {
"$ref": "#/$defs/condition"
},
"effects": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"effect_id": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"REJECT",
"COMPUTE",
"ROUTE",
"TRANSITION",
"READ",
"WRITE",
"PUBLISH",
"OTHER"
]
},
"description": {
"type": "string",
"minLength": 1
},
"target_ref": {
"type": [
"string",
"null"
]
},
"expression": {
"oneOf": [
{
"$ref": "#/$defs/expression"
},
{
"type": "null"
}
]
},
"guard": {
"$ref": "#/$defs/condition"
},
"sequence": {
"type": "integer",
"minimum": 0
},
"outcome": {
"enum": [
"CONTINUE",
"RETURN",
"THROW",
"ASYNC_SUBMIT"
]
},
"error_code": {
"type": [
"string",
"null"
]
},
"evidence_ids": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
},
"control_ref": {
"type": "string",
"minLength": 1
},
"exception_region_ref": {
"type": [
"string",
"null"
]
}
},
"required": [
"effect_id",
"kind",
"description",
"target_ref",
"expression",
"guard",
"sequence",
"outcome",
"evidence_ids",
"control_ref",
"exception_region_ref"
],
"allOf": [
{
"if": {
"properties": {
"kind": {
"const": "COMPUTE"
}
}
},
"then": {
"properties": {
"expression": {
"$ref": "#/$defs/expression"
}
}
}
}
]
},
"minItems": 1
},
"exceptions": {
"type": "object",
"additionalProperties": false,
"required": [
"resolution",
"conditions"
],
"properties": {
"resolution": {
"enum": [
"CONFIRMED_NONE",
"KNOWN",
"UNKNOWN"
]
},
"conditions": {
"type": "array",
"items": {
"$ref": "#/$defs/condition"
}
}
},
"allOf": [
{
"if": {
"properties": {
"resolution": {
"const": "CONFIRMED_NONE"
}
}
},
"then": {
"properties": {
"conditions": {
"maxItems": 0
}
}
}
},
{
"if": {
"properties": {
"resolution": {
"const": "KNOWN"
}
}
},
"then": {
"properties": {
"conditions": {
"minItems": 1
}
}
}
}
]
},
"config_dependencies": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"evidence_ids": {
"$ref": "#/$defs/evidenceRefs"
},
"lifecycle": {
"enum": [
"CANDIDATE",
"REVIEWED",
"CONFLICTED",
"STALE",
"RETIRED"
]
},
"unresolved": {
"type": "array",
"items": {
"type": "string"
}
},
"derivation_kind": {
"enum": [
"STATIC_DERIVATION",
"MODEL_INTERPRETATION",
"HUMAN_ENTRY"
]
},
"review_status": {
"enum": [
"UNREVIEWED",
"ACCEPTED",
"REJECTED"
]
},
"freshness": {
"enum": [
"CURRENT",
"STALE",
"UNKNOWN"
]
},
"resolution_status": {
"enum": [
"RESOLVED",
"AMBIGUOUS",
"UNRESOLVED",
"CONFLICT"
]
},
"entity_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
}
},
"$defs": {
"evidenceRefs": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
},
"condition": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"AND",
"OR"
]
},
"args": {
"type": "array",
"items": {
"$ref": "#/$defs/condition"
},
"minItems": 2
},
"evaluation_order": {
"enum": [
"SHORT_CIRCUIT_LEFT_TO_RIGHT",
"EAGER_LEFT_TO_RIGHT",
"UNKNOWN"
]
}
},
"required": [
"op",
"args",
"evaluation_order"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"op": {
"const": "NOT"
},
"arg": {
"$ref": "#/$defs/condition"
}
},
"required": [
"op",
"arg"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"IS_NULL",
"IS_MISSING"
]
},
"ref": {
"type": "string",
"minLength": 1
},
"evidence_ids": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
}
},
"required": [
"op",
"ref",
"evidence_ids"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"EQ",
"NE",
"GT",
"GE",
"LT",
"LE",
"IN",
"CONTAINS"
]
},
"ref": {
"type": "string",
"minLength": 1
},
"value_type": {
"enum": [
"STRING",
"BOOLEAN",
"INTEGER",
"DECIMAL",
"ENUM"
]
},
"value": {
"type": [
"string",
"integer",
"boolean",
"array"
]
},
"unit": {
"type": [
"string",
"null"
]
},
"evidence_ids": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
}
},
"required": [
"op",
"ref",
"value_type",
"value",
"evidence_ids"
],
"allOf": [
{
"if": {
"properties": {
"value_type": {
"const": "STRING"
}
}
},
"then": {
"if": {
"properties": {
"op": {
"const": "IN"
}
}
},
"then": {
"properties": {
"value": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
}
},
"else": {
"properties": {
"value": {
"type": "string"
}
}
}
}
},
{
"if": {
"properties": {
"value_type": {
"const": "ENUM"
}
}
},
"then": {
"if": {
"properties": {
"op": {
"const": "IN"
}
}
},
"then": {
"properties": {
"value": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
}
},
"else": {
"properties": {
"value": {
"type": "string"
}
}
}
}
},
{
"if": {
"properties": {
"value_type": {
"const": "BOOLEAN"
}
}
},
"then": {
"if": {
"properties": {
"op": {
"const": "IN"
}
}
},
"then": {
"properties": {
"value": {
"type": "array",
"items": {
"type": "boolean"
},
"minItems": 1
}
}
},
"else": {
"properties": {
"value": {
"type": "boolean"
}
}
}
}
},
{
"if": {
"properties": {
"value_type": {
"const": "INTEGER"
}
}
},
"then": {
"if": {
"properties": {
"op": {
"const": "IN"
}
}
},
"then": {
"properties": {
"value": {
"type": "array",
"items": {
"type": "integer"
},
"minItems": 1
}
}
},
"else": {
"properties": {
"value": {
"type": "integer"
}
}
}
}
},
{
"if": {
"properties": {
"value_type": {
"const": "DECIMAL"
}
}
},
"then": {
"if": {
"properties": {
"op": {
"const": "IN"
}
}
},
"then": {
"properties": {
"value": {
"type": "array",
"items": {
"type": "string",
"pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$"
},
"minItems": 1
}
}
},
"else": {
"properties": {
"value": {
"type": "string",
"pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$"
}
}
}
}
},
{
"if": {
"properties": {
"op": {
"enum": [
"GT",
"GE",
"LT",
"LE"
]
}
}
},
"then": {
"properties": {
"value_type": {
"enum": [
"INTEGER",
"DECIMAL"
]
}
}
}
}
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"op": {
"const": "OPAQUE"
},
"expression": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
},
"evidence_ids": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
}
},
"required": [
"op",
"expression",
"reason",
"evidence_ids"
]
},
{
"type": "object",
"additionalProperties": false,
"required": [
"op",
"value",
"evidence_ids"
],
"properties": {
"op": {
"const": "CONST"
},
"value": {
"type": "boolean"
},
"evidence_ids": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
}
}
}
]
},
"expression": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"const": "REF"
},
"ref": {
"type": "string",
"minLength": 1
}
},
"required": [
"kind",
"ref"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"const": "LITERAL"
},
"value_type": {
"enum": [
"STRING",
"BOOLEAN",
"INTEGER",
"DECIMAL",
"ENUM"
]
},
"value": {
"type": [
"string",
"boolean",
"integer"
]
},
"unit": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"value_type",
"value"
],
"allOf": [
{
"if": {
"properties": {
"value_type": {
"const": "STRING"
}
}
},
"then": {
"properties": {
"value": {
"type": "string"
}
}
}
},
{
"if": {
"properties": {
"value_type": {
"const": "ENUM"
}
}
},
"then": {
"properties": {
"value": {
"type": "string"
}
}
}
},
{
"if": {
"properties": {
"value_type": {
"const": "BOOLEAN"
}
}
},
"then": {
"properties": {
"value": {
"type": "boolean"
}
}
}
},
{
"if": {
"properties": {
"value_type": {
"const": "INTEGER"
}
}
},
"then": {
"properties": {
"value": {
"type": "integer"
}
}
}
},
{
"if": {
"properties": {
"value_type": {
"const": "DECIMAL"
}
}
},
"then": {
"properties": {
"value": {
"type": "string",
"pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$"
}
}
}
}
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"const": "CALL"
},
"operator": {
"type": "string",
"minLength": 1
},
"args": {
"type": "array",
"items": {
"$ref": "#/$defs/expression"
},
"minItems": 0
},
"unit": {
"type": [
"string",
"null"
]
},
"rounding": {
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"operator",
"args"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"const": "OPAQUE"
},
"source": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"kind",
"source",
"reason"
]
}
]
}
}
}
client-entry.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:client-entry:0.1",
"title": "客户端首次查询、目标定位及问答任务合同",
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"operation": {
"const": "options"
},
"response": {
"$ref": "#/$defs/OptionsResult"
},
"request": {
"$ref": "#/$defs/OptionsRequest"
}
},
"required": [
"operation",
"response",
"request"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"operation": {
"const": "prepare_instance"
},
"response": {
"$ref": "#/$defs/PrepareResult"
},
"request": {
"$ref": "#/$defs/PrepareRequest"
}
},
"required": [
"operation",
"response",
"request"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"operation": {
"const": "resolve_targets"
},
"response": {
"$ref": "#/$defs/ResolveResult"
},
"request": {
"$ref": "#/$defs/ResolveRequest"
}
},
"required": [
"operation",
"response",
"request"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"operation": {
"const": "create_task"
},
"response": {
"$ref": "#/$defs/TaskCreated"
},
"request": {
"$ref": "#/$defs/TaskCreate"
}
},
"required": [
"operation",
"response",
"request"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"operation": {
"const": "read_task"
},
"response": {
"$ref": "#/$defs/TaskStatus"
}
},
"required": [
"operation",
"response"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"operation": {
"const": "read_results"
},
"response": {
"$ref": "#/$defs/ResultPage"
},
"request": {
"$ref": "#/$defs/ResultRequest"
}
},
"required": [
"operation",
"response",
"request"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"operation": {
"const": "cancel_task"
},
"response": {
"$ref": "#/$defs/TaskStatus"
},
"request": {
"$ref": "#/$defs/CancelRequest"
}
},
"required": [
"operation",
"response",
"request"
]
}
],
"$defs": {
"Scope": {
"$ref": "urn:jd-kb:answer-request:0.1#/properties/scope"
},
"Selector": {
"$ref": "urn:jd-kb:tool-contracts:0.1#/$defs/InstanceSelector"
},
"OptionsRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"cursor": {
"type": [
"string",
"null"
]
},
"page_size": {
"type": "integer",
"minimum": 1,
"maximum": 100
}
},
"required": [
"cursor",
"page_size"
]
},
"ArchiveOption": {
"type": "object",
"additionalProperties": false,
"properties": {
"option_ref": {
"type": "string",
"minLength": 1
},
"label": {
"type": "string",
"minLength": 1
},
"namespace": {
"type": "string",
"minLength": 1
},
"object_kinds": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"scope": {
"$ref": "#/$defs/Scope"
},
"retention_start": {
"type": "string",
"format": "date-time"
},
"watermark": {
"type": "string",
"format": "date-time"
},
"default_lookback_seconds": {
"type": "integer",
"minimum": 1
},
"max_window_seconds": {
"type": "integer",
"minimum": 1
}
},
"required": [
"option_ref",
"label",
"namespace",
"object_kinds",
"scope",
"retention_start",
"watermark",
"default_lookback_seconds",
"max_window_seconds"
]
},
"RepoOption": {
"type": "object",
"additionalProperties": false,
"properties": {
"option_ref": {
"type": "string",
"minLength": 1
},
"repo_id": {
"type": "string",
"minLength": 1
},
"label": {
"type": "string",
"minLength": 1
},
"remote_aliases": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"scope": {
"$ref": "#/$defs/Scope"
},
"knowledge_versions": {
"type": "array",
"items": {
"$ref": "#/$defs/KnowledgeVersion"
}
}
},
"required": [
"option_ref",
"repo_id",
"label",
"remote_aliases",
"scope",
"knowledge_versions"
]
},
"OptionsResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"options_revision": {
"type": "string",
"minLength": 1
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"archive_sources": {
"type": "array",
"items": {
"$ref": "#/$defs/ArchiveOption"
},
"minItems": 0
},
"repositories": {
"type": "array",
"items": {
"$ref": "#/$defs/RepoOption"
},
"minItems": 0
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"options_revision",
"expires_at",
"archive_sources",
"repositories",
"next_cursor"
]
},
"TimeSelection": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"const": "RECENT"
}
},
"required": [
"mode"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"const": "RANGE"
},
"from": {
"type": "string",
"format": "date-time"
},
"to": {
"type": "string",
"format": "date-time"
}
},
"required": [
"mode",
"from",
"to"
]
}
]
},
"PrepareRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"request_id": {
"type": "string",
"minLength": 1
},
"options_revision": {
"type": "string",
"minLength": 1
},
"source_option_ref": {
"type": "string",
"minLength": 1
},
"object_kind": {
"type": "string",
"minLength": 1
},
"object_id": {
"type": "string",
"minLength": 1
},
"time": {
"$ref": "#/$defs/TimeSelection"
}
},
"required": [
"request_id",
"options_revision",
"source_option_ref",
"object_kind",
"object_id",
"time"
]
},
"PrepareResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"preparation_id": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"scope": {
"$ref": "#/$defs/Scope"
},
"instance_selector": {
"$ref": "#/$defs/Selector"
},
"resolved_at": {
"type": "string",
"format": "date-time"
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"limited_to_retention": {
"type": "boolean"
}
},
"required": [
"preparation_id",
"snapshot_id",
"scope",
"instance_selector",
"resolved_at",
"expires_at",
"limited_to_retention"
]
},
"Selection": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_id": {
"type": "string",
"minLength": 1
},
"path": {
"type": "string",
"pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"
},
"file_content_hash": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"line_start": {
"type": "integer",
"minimum": 1
},
"line_end": {
"type": "integer",
"minimum": 1
}
},
"required": [
"repo_id",
"path",
"file_content_hash",
"line_start",
"line_end"
]
},
"ResolveRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"request_id": {
"type": "string",
"minLength": 1
},
"options_revision": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"scope": {
"$ref": "#/$defs/Scope"
},
"task": {
"type": "string",
"minLength": 1
},
"workspace": {
"$ref": "urn:jd-kb:workspace:0.1"
},
"selections": {
"type": "array",
"items": {
"$ref": "#/$defs/Selection"
},
"minItems": 0
}
},
"required": [
"request_id",
"options_revision",
"snapshot_id",
"scope",
"task",
"workspace",
"selections"
]
},
"ResolvedTarget": {
"type": "object",
"additionalProperties": false,
"properties": {
"symbol_ref": {
"type": "string",
"minLength": 1
},
"repo_id": {
"type": "string",
"minLength": 1
},
"path": {
"type": "string",
"minLength": 1
},
"signature": {
"type": "string",
"minLength": 1
},
"origin": {
"enum": [
"PUBLISHED",
"WORKSPACE"
]
},
"selection_index": {
"type": "integer",
"minimum": 0
}
},
"required": [
"symbol_ref",
"repo_id",
"path",
"signature",
"origin",
"selection_index"
]
},
"ResolveResult": {
"type": "object",
"additionalProperties": false,
"properties": {
"resolution_id": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"workspace_input_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"status": {
"enum": [
"RESOLVED",
"NEEDS_SELECTION",
"UNRESOLVED"
]
},
"targets": {
"type": "array",
"items": {
"$ref": "#/$defs/ResolvedTarget"
},
"minItems": 0
},
"unresolved": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
}
},
"required": [
"resolution_id",
"snapshot_id",
"workspace_input_digest",
"expires_at",
"status",
"targets",
"unresolved"
],
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "RESOLVED"
}
}
},
"then": {
"properties": {
"targets": {
"minItems": 1
},
"unresolved": {
"maxItems": 0
}
}
}
},
{
"if": {
"properties": {
"status": {
"const": "UNRESOLVED"
}
}
},
"then": {
"properties": {
"targets": {
"maxItems": 0
},
"unresolved": {
"minItems": 1
}
}
}
},
{
"if": {
"properties": {
"status": {
"const": "NEEDS_SELECTION"
}
}
},
"then": {
"properties": {
"targets": {
"minItems": 2
}
}
}
}
]
},
"TaskCreate": {
"$ref": "urn:jd-kb:answer-request:0.1"
},
"TaskCreated": {
"type": "object",
"additionalProperties": false,
"properties": {
"task_id": {
"type": "string",
"minLength": 1
},
"task_revision": {
"type": "integer",
"minimum": 1
},
"state": {
"const": "QUEUED"
},
"query_id": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"task_id",
"task_revision",
"state",
"query_id",
"snapshot_id"
]
},
"TaskStatus": {
"type": "object",
"additionalProperties": false,
"properties": {
"task_id": {
"type": "string",
"minLength": 1
},
"task_revision": {
"type": "integer",
"minimum": 1
},
"task_type": {
"const": "ANSWER"
},
"state": {
"enum": [
"QUEUED",
"RUNNING",
"SUCCEEDED",
"PARTIAL",
"FAILED",
"CANCELLED"
]
},
"query_id": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"result_revision": {
"type": [
"string",
"null"
]
},
"next_poll_after_ms": {
"type": [
"integer",
"null"
],
"minimum": 1
},
"error": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"code": {
"type": "string",
"minLength": 1
},
"message": {
"type": "string",
"minLength": 1
},
"retryable": {
"type": "boolean"
}
},
"required": [
"code",
"message",
"retryable"
]
}
]
}
},
"required": [
"task_id",
"task_revision",
"task_type",
"state",
"query_id",
"snapshot_id",
"result_revision",
"next_poll_after_ms",
"error"
],
"allOf": [
{
"if": {
"properties": {
"state": {
"enum": [
"SUCCEEDED",
"PARTIAL"
]
}
}
},
"then": {
"properties": {
"result_revision": {
"type": "string",
"minLength": 1
},
"next_poll_after_ms": {
"type": "null"
},
"error": {
"type": "null"
}
}
}
},
{
"if": {
"properties": {
"state": {
"enum": [
"QUEUED",
"RUNNING"
]
}
}
},
"then": {
"properties": {
"result_revision": {
"type": "null"
},
"next_poll_after_ms": {
"type": "integer",
"minimum": 1
},
"error": {
"type": "null"
}
}
}
},
{
"if": {
"properties": {
"state": {
"enum": [
"FAILED",
"CANCELLED"
]
}
}
},
"then": {
"properties": {
"result_revision": {
"type": "null"
},
"next_poll_after_ms": {
"type": "null"
}
}
}
},
{
"if": {
"properties": {
"state": {
"const": "FAILED"
}
}
},
"then": {
"properties": {
"error": {
"type": "object"
}
}
}
}
]
},
"ResultRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"result_revision": {
"type": "string",
"minLength": 1
},
"cursor": {
"type": [
"string",
"null"
]
},
"page_size": {
"type": "integer",
"minimum": 1,
"maximum": 100
}
},
"required": [
"result_revision",
"cursor",
"page_size"
]
},
"ResultItem": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"const": "ANSWER"
},
"answer": {
"$ref": "urn:jd-kb:answer:0.2"
}
},
"required": [
"kind",
"answer"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"const": "SOURCE_INDEX"
},
"entries": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"claim_id": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"claim_id",
"evidence_refs"
]
},
"minItems": 1
}
},
"required": [
"kind",
"entries"
]
}
]
},
"ResultPage": {
"type": "object",
"additionalProperties": false,
"properties": {
"task_id": {
"type": "string",
"minLength": 1
},
"result_revision": {
"type": "string",
"minLength": 1
},
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/ResultItem"
},
"minItems": 1
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"task_id",
"result_revision",
"items",
"next_cursor"
]
},
"CancelRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"request_id": {
"type": "string",
"minLength": 1
},
"expected_task_revision": {
"type": "integer",
"minimum": 1
}
},
"required": [
"request_id",
"expected_task_revision"
]
},
"KnowledgeVersion": {
"type": "object",
"additionalProperties": false,
"properties": {
"snapshot_id": {
"type": "string",
"minLength": 1
},
"label": {
"type": "string",
"minLength": 1
},
"commit_sha": {
"type": "string",
"pattern": "^[a-f0-9]{40}$"
},
"is_active": {
"type": "boolean"
}
},
"required": [
"snapshot_id",
"label",
"commit_sha",
"is_active"
]
}
}
}
correction-status.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:correction-status:0.1",
"title": "原答案或知识修订的更正提示",
"type": "object",
"additionalProperties": false,
"properties": {
"request": {
"type": "object",
"additionalProperties": false,
"properties": {
"target_type": {
"enum": [
"ANSWER",
"KNOWLEDGE"
]
},
"target_revision_ref": {
"type": "string",
"minLength": 1
},
"query_id": {
"type": "string",
"minLength": 1
},
"claim_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
}
},
"required": [
"target_type",
"target_revision_ref"
],
"allOf": [
{
"if": {
"properties": {
"target_type": {
"const": "ANSWER"
}
}
},
"then": {
"required": [
"query_id",
"claim_ids"
]
},
"else": {
"not": {
"anyOf": [
{
"required": [
"query_id"
]
},
{
"required": [
"claim_ids"
]
}
]
}
}
}
]
},
"response": {
"type": "object",
"additionalProperties": false,
"properties": {
"checked_at": {
"type": "string",
"format": "date-time"
},
"status_revision": {
"type": "string",
"minLength": 1
},
"items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"target_revision_ref": {
"type": "string",
"minLength": 1
},
"claim_id": {
"type": [
"string",
"null"
],
"minLength": 1
},
"state": {
"enum": [
"NONE",
"UNDER_REVIEW",
"ACCEPTED_PENDING",
"CORRECTED"
]
},
"message": {
"type": "string",
"minLength": 1
},
"replacement_ref": {
"type": [
"string",
"null"
],
"minLength": 1
}
},
"required": [
"target_revision_ref",
"claim_id",
"state",
"message",
"replacement_ref"
],
"allOf": [
{
"if": {
"properties": {
"state": {
"enum": [
"NONE",
"UNDER_REVIEW",
"ACCEPTED_PENDING"
]
}
}
},
"then": {
"properties": {
"replacement_ref": {
"type": "null"
}
}
}
}
]
}
}
},
"required": [
"checked_at",
"status_revision",
"items"
]
}
},
"anyOf": [
{
"required": [
"request"
]
},
{
"required": [
"response"
]
}
]
}
coverage-ledger.example.json
{
"schema_version": "0.1",
"ledger_revision": "coverage:synthetic:1",
"snapshot_id": "release:coverage:1",
"inventory_revision": "inventory:coverage:1",
"inventory_reconciled": true,
"scope": {
"domain_refs": [
"domain:trade"
],
"scenario_refs": [
"scenario:order-recovery"
],
"environment": "SYNTHETIC",
"source_scope_refs": [
"source:catalog:1"
]
},
"obligations": [
{
"obligation_id": "obligation:submit",
"scenario_ref": "scenario:order-recovery",
"kind": "ENTRY",
"expected_source_refs": [
"expected:submit"
],
"status": "COVERED",
"entry_refs": [
"entry:order-http"
],
"flow_refs": [
"flow:recovery:1"
],
"evidence_refs": [
"evidence:submit"
],
"reason": null,
"review_ref": null
},
{
"obligation_id": "obligation:reject",
"scenario_ref": "scenario:order-recovery",
"kind": "BRANCH",
"expected_source_refs": [
"expected:reject"
],
"status": "COVERED",
"entry_refs": [
"entry:fulfillment-event"
],
"flow_refs": [
"flow:recovery:1"
],
"evidence_refs": [
"evidence:reject"
],
"reason": null,
"review_ref": null
},
{
"obligation_id": "obligation:reconcile",
"scenario_ref": "scenario:order-recovery",
"kind": "RECOVERY",
"expected_source_refs": [
"expected:reconcile"
],
"status": "BLOCKED",
"entry_refs": [
"entry:refund-job"
],
"flow_refs": [],
"evidence_refs": [],
"reason": "缺少恢复或交接合同证据",
"review_ref": null
},
{
"obligation_id": "obligation:manual",
"scenario_ref": "scenario:order-recovery",
"kind": "EXTERNAL_BOUNDARY",
"expected_source_refs": [
"expected:manual"
],
"status": "BLOCKED",
"entry_refs": [
"entry:manual-case"
],
"flow_refs": [],
"evidence_refs": [],
"reason": "缺少恢复或交接合同证据",
"review_ref": null
},
{
"obligation_id": "obligation:finish",
"scenario_ref": "scenario:order-recovery",
"kind": "COMPLETION",
"expected_source_refs": [
"expected:finish"
],
"status": "COVERED",
"entry_refs": [
"entry:order-terminal"
],
"flow_refs": [
"flow:recovery:1"
],
"evidence_refs": [
"evidence:finish"
],
"reason": null,
"review_ref": null
},
{
"obligation_id": "obligation:orphan",
"scenario_ref": "scenario:order-recovery",
"kind": "ENTRY",
"expected_source_refs": [
"expected:orphan"
],
"status": "BLOCKED",
"entry_refs": [],
"flow_refs": [],
"evidence_refs": [],
"reason": "已发现批任务,尚未确认场景归属",
"review_ref": null
}
],
"unassigned_entry_refs": [
"entry:orphan-batch"
],
"unresolved": [
{
"code": "RECOVERY_UNRESOLVED",
"target": "obligation:reconcile"
},
{
"code": "HANDOFF_CONTRACT_MISSING",
"target": "obligation:manual"
}
],
"closure": "PARTIAL"
}
coverage-ledger.schema.json
{
"type": "object",
"properties": {
"schema_version": {
"const": "0.1"
},
"ledger_revision": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"inventory_revision": {
"type": "string",
"minLength": 1
},
"inventory_reconciled": {
"type": "boolean"
},
"scope": {
"type": "object",
"properties": {
"domain_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"uniqueItems": true
},
"scenario_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"uniqueItems": true
},
"environment": {
"type": "string",
"minLength": 1
},
"source_scope_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"uniqueItems": true
}
},
"required": [
"domain_refs",
"scenario_refs",
"environment",
"source_scope_refs"
],
"additionalProperties": false
},
"obligations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"obligation_id": {
"type": "string",
"minLength": 1
},
"scenario_ref": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"ENTRY",
"BRANCH",
"RECOVERY",
"EXTERNAL_BOUNDARY",
"COMPLETION"
]
},
"expected_source_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"uniqueItems": true
},
"status": {
"enum": [
"COVERED",
"BLOCKED",
"EXCLUDED"
]
},
"entry_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0,
"uniqueItems": true
},
"flow_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0,
"uniqueItems": true
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0,
"uniqueItems": true
},
"reason": {
"type": [
"string",
"null"
]
},
"review_ref": {
"type": [
"string",
"null"
]
}
},
"required": [
"obligation_id",
"scenario_ref",
"kind",
"expected_source_refs",
"status",
"entry_refs",
"flow_refs",
"evidence_refs",
"reason",
"review_ref"
],
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "COVERED"
}
}
},
"then": {
"properties": {
"flow_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"uniqueItems": true
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"uniqueItems": true
}
}
}
},
{
"if": {
"properties": {
"status": {
"enum": [
"BLOCKED",
"EXCLUDED"
]
}
}
},
"then": {
"properties": {
"reason": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"status": {
"const": "EXCLUDED"
}
}
},
"then": {
"properties": {
"review_ref": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"uniqueItems": true
}
}
}
}
]
},
"minItems": 1,
"uniqueItems": true
},
"unassigned_entry_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0,
"uniqueItems": true
},
"unresolved": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": {
"type": "string",
"minLength": 1
},
"target": {
"type": "string",
"minLength": 1
}
},
"required": [
"code",
"target"
],
"additionalProperties": false
},
"minItems": 0,
"uniqueItems": true
},
"closure": {
"enum": [
"DECLARED_SCOPE_COMPLETE",
"PARTIAL"
]
}
},
"required": [
"schema_version",
"ledger_revision",
"snapshot_id",
"inventory_revision",
"inventory_reconciled",
"scope",
"obligations",
"unassigned_entry_refs",
"unresolved",
"closure"
],
"additionalProperties": false,
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:coverage-ledger:0.1",
"title": "声明范围内的业务覆盖台账",
"allOf": [
{
"if": {
"properties": {
"closure": {
"const": "DECLARED_SCOPE_COMPLETE"
}
}
},
"then": {
"properties": {
"inventory_reconciled": {
"const": true
},
"unassigned_entry_refs": {
"maxItems": 0
},
"unresolved": {
"maxItems": 0
},
"obligations": {
"items": {
"properties": {
"status": {
"enum": [
"COVERED",
"EXCLUDED"
]
}
}
}
}
}
}
}
]
}
entry-card.example.json
{
"schema_version": "0.1",
"view_id": "view:entry_card:O1",
"revision_id": "viewrev:entry_card:2",
"view_kind": "ENTRY_CARD",
"snapshot_id": "K1",
"target_ref": {
"stable_id": "entry:order:fulfillment-rejected",
"implementation_scope": "sv:order:1",
"revision_id": "entry:order:fulfillment-rejected:r1"
},
"source_refs": [
{
"ref_id": "e-reject",
"kind": "ENTRY",
"stable_id": "entry:order:fulfillment-rejected",
"implementation_scope": "sv:order:1",
"revision_id": "entry:order:fulfillment-rejected:r1"
},
{
"ref_id": "r-refund",
"stable_id": "rule:scenario:refund-original-cash",
"implementation_scope": "GLOBAL",
"kind": "RULE",
"revision_id": "rr:scenario:refund-original-cash:1"
},
{
"ref_id": "r-coupon",
"stable_id": "rule:scenario:coupon-return-once",
"implementation_scope": "GLOBAL",
"kind": "RULE",
"revision_id": "rr:scenario:coupon-return-once:1"
},
{
"ref_id": "r-join",
"stable_id": "rule:scenario:compensation-join",
"implementation_scope": "GLOBAL",
"kind": "RULE",
"revision_id": "rr:scenario:compensation-join:1"
},
{
"ref_id": "c-refund",
"kind": "CONTRACT",
"stable_id": "contract:payment:refund",
"implementation_scope": "sv:payment:1",
"revision_id": "contract:payment:refund:r1"
},
{
"ref_id": "b-reject",
"kind": "BRANCH_MAPPING",
"stable_id": "branches:order:reject",
"implementation_scope": "sv:order:1",
"revision_id": "branches:order:reject:r1"
},
{
"ref_id": "ev-reject",
"stable_id": "ev:scenario:order-reject",
"implementation_scope": "sv:order:1",
"kind": "EVIDENCE",
"revision_id": "ev:scenario:order-reject"
},
{
"ref_id": "ev-refund",
"stable_id": "ev:scenario:payment-refund",
"implementation_scope": "sv:payment:1",
"kind": "EVIDENCE",
"revision_id": "ev:scenario:payment-refund"
},
{
"ref_id": "ev-coupon",
"stable_id": "ev:scenario:coupon-return",
"implementation_scope": "sv:coupon:1",
"kind": "EVIDENCE",
"revision_id": "ev:scenario:coupon-return"
},
{
"ref_id": "ev-join",
"stable_id": "ev:scenario:order-join",
"implementation_scope": "sv:order:1",
"kind": "EVIDENCE",
"revision_id": "ev:scenario:order-join"
},
{
"ref_id": "ev-recovery",
"stable_id": "ev:scenario:order-recovery",
"implementation_scope": "sv:order:1",
"kind": "EVIDENCE",
"revision_id": "ev:scenario:order-recovery"
},
{
"ref_id": "ev-receipt",
"stable_id": "ev:scenario:order-refund-result",
"implementation_scope": "sv:order:1",
"kind": "EVIDENCE",
"revision_id": "ev:scenario:order-refund-result"
},
{
"ref_id": "ev-coordination",
"stable_id": "ev:scenario:recovery-coordination",
"implementation_scope": "sv:order:1",
"kind": "EVIDENCE",
"revision_id": "ev:scenario:recovery-coordination"
},
{
"ref_id": "ev-receipt-check",
"stable_id": "ev:scenario:refund-receipt-validation",
"implementation_scope": "sv:order:1",
"kind": "EVIDENCE",
"revision_id": "ev:scenario:refund-receipt-validation"
}
],
"input_digest": "a9cfd0aeb1412abd6670e74fed5e4268f49420ae7425df14dcc078283bf7ce95",
"generator_revision": "view-generator:design:2",
"statements": [
{
"statement_id": "st-trigger",
"role": "TRIGGER",
"text": "收到与订单及履约单关联的永久拒绝后,读取原支付事实。",
"source_ref_ids": [
"e-reject",
"r-refund",
"ev-reject"
]
},
{
"statement_id": "st-paid",
"role": "CONDITION",
"text": "支付已确认且履约永久拒绝时启动补偿;支付未确认则保存待核验,支付事实到达后重新判断。",
"source_ref_ids": [
"r-refund",
"ev-reject",
"ev-recovery"
]
},
{
"statement_id": "st-identity",
"role": "INPUT",
"text": "沿用订单关联的原支付;创建或读取同一次补偿CP1。退款复用P1 + CP1,退券复用CP1 + RS1。",
"source_ref_ids": [
"r-refund",
"r-coupon",
"ev-refund",
"ev-coupon",
"ev-coordination"
]
},
{
"statement_id": "st-cash",
"role": "ACTION",
"text": "退款金额取原支付的实付现金;O1单次全额退款为70.00 CNY,不按当前优惠配置重算。",
"source_ref_ids": [
"r-refund",
"c-refund",
"ev-refund"
]
},
{
"statement_id": "st-coupon",
"role": "ACTION",
"text": "券已核销且核销关联匹配时退回原核销;仅预占时释放原预占。该条件在原规则中仍是待核对的OPAQUE表达式。",
"source_ref_ids": [
"r-coupon",
"ev-coupon"
]
},
{
"statement_id": "st-unknown",
"role": "FAILURE",
"text": "退款被接收仍待确认,超时保留结果未知;按原P1 + CP1重试并等待RefundConfirmed,不新建另一退款。退券恢复沿用CP1 + RS1;恢复预算耗尽后转人工处理。",
"source_ref_ids": [
"r-refund",
"r-coupon",
"ev-receipt",
"ev-recovery"
]
},
{
"statement_id": "st-receipt",
"role": "CONDITION",
"text": "回执的退款操作RF1、支付P1、补偿CP1、金额70.00 CNY及最终状态都与原操作匹配才确认;缺字段继续保留未知,不匹配进入差异核对,重复有效回执只确认一次。",
"source_ref_ids": [
"r-refund",
"ev-receipt",
"ev-receipt-check"
]
},
{
"statement_id": "st-completion",
"role": "RESULT",
"text": "退款已确认、券补偿已确认且订单终态写入成功,三项同时成立才结束补偿。收到拒绝消息或退款受理都不表示完成。",
"source_ref_ids": [
"r-join",
"ev-join"
]
}
],
"coverage": {
"inventory_revision": "inventory:O1:entries:1",
"inventory_complete": true,
"discovered_entry_ref_ids": [
"e-reject"
],
"assigned_entry_ref_ids": [
"e-reject"
],
"unassigned_entry_ref_ids": [],
"exclusions": [],
"complete": false
},
"unresolved": [
{
"code": "SOURCE_RULE_UNRESOLVED",
"target": "rr:scenario:refund-original-cash:1",
"reason": "原O1规则仍为候选、未审阅且适用范围未确认;卡片沿用原状态。"
},
{
"code": "SOURCE_RULE_UNRESOLVED",
"target": "rr:scenario:coupon-return-once:1",
"reason": "原O1规则仍为候选、未审阅且适用范围未确认;卡片沿用原状态。"
},
{
"code": "SOURCE_RULE_UNRESOLVED",
"target": "rr:scenario:compensation-join:1",
"reason": "原O1规则仍为候选、未审阅且适用范围未确认;卡片沿用原状态。"
},
{
"code": "OPAQUE_RULE",
"target": "rr:scenario:coupon-return-once:1",
"reason": "退券条件保留人工期望语义,尚未解析为可检查的条件节点。"
}
],
"entry_ref_id": "e-reject",
"rule_ref_ids": [
"r-refund",
"r-coupon",
"r-join"
],
"contract_ref_ids": [
"c-refund"
],
"branch_mapping_refs": [
"b-reject"
]
}
ir-manifest.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:ir-manifest:0.1",
"title": "静态分析IR包清单",
"type": "object", "additionalProperties": false,
"required": ["schema_version", "scan_id", "service_id", "repo_id", "commit_sha", "analyzer_version", "input_digest", "status", "files", "coverage_ref"],
"properties": {
"schema_version": {"const": "0.1"},
"scan_id": {"type": "string", "minLength": 1},
"service_id": {"type": "string", "minLength": 1},
"repo_id": {"type": "string", "minLength": 1},
"commit_sha": {"type": "string", "pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"},
"analyzer_version": {"type": "string", "minLength": 1},
"input_digest": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"status": {"enum": ["COMPLETE", "PARTIAL", "FAILED"]},
"dependency_artifacts": {"type": "array", "items": {"type": "object", "required": ["coordinate", "sha256"], "properties": {"coordinate": {"type": "string"}, "sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"}}}},
"files": {
"type": "array", "minItems": 1,
"items": {
"type": "object", "additionalProperties": false, "required": ["path", "sha256", "record_count"],
"properties": {
"path": {"type": "string", "pattern": "^[A-Za-z0-9_-]+\\.jsonl?$"},
"sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"record_count": {"type": "integer", "minimum": 0}
}
}
},
"coverage_ref": {"const": "coverage.json"},
"config_snapshot_refs": {"type": "array", "items": {"type": "string"}},
"deployment_refs": {"type": "array", "items": {"type": "string"}}
}
}
knowledge-view.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://jd-kb.example/schemas/knowledge-view.schema.json",
"title": "内部阅读视图",
"description": "入口卡片与服务画像的派生视图;跨字段和授权由语义检查约束。",
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"view_id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
},
"view_kind": {
"enum": [
"ENTRY_CARD",
"SERVICE_PROFILE"
]
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"target_ref": {
"type": "object",
"additionalProperties": false,
"properties": {
"stable_id": {
"type": "string",
"minLength": 1
},
"implementation_scope": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"stable_id",
"implementation_scope",
"revision_id"
]
},
"source_refs": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"ref_id": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"ENTRY",
"RULE",
"CAPABILITY",
"CONTRACT",
"ENTITY",
"STATE",
"EVIDENCE",
"REVIEW",
"SERVICE",
"BRANCH_MAPPING"
]
},
"stable_id": {
"type": "string",
"minLength": 1
},
"implementation_scope": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"ref_id",
"kind",
"stable_id",
"implementation_scope",
"revision_id"
]
}
},
"input_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"generator_revision": {
"type": "string",
"minLength": 1
},
"statements": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"statement_id": {
"type": "string",
"minLength": 1
},
"role": {
"enum": [
"TRIGGER",
"INPUT",
"CONDITION",
"ACTION",
"RESULT",
"FAILURE",
"RESPONSIBILITY",
"BOUNDARY",
"DEPENDENCY"
]
},
"text": {
"type": "string",
"minLength": 1
},
"source_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
}
},
"required": [
"statement_id",
"role",
"text",
"source_ref_ids"
]
}
},
"coverage": {
"type": "object",
"additionalProperties": false,
"properties": {
"inventory_revision": {
"type": "string",
"minLength": 1
},
"inventory_complete": {
"type": "boolean"
},
"discovered_entry_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"assigned_entry_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"unassigned_entry_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"exclusions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"entry_ref_id": {
"type": "string",
"minLength": 1
},
"review_ref_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"entry_ref_id",
"review_ref_id"
]
}
},
"complete": {
"type": "boolean"
}
},
"required": [
"inventory_revision",
"inventory_complete",
"discovered_entry_ref_ids",
"assigned_entry_ref_ids",
"unassigned_entry_ref_ids",
"exclusions",
"complete"
]
},
"unresolved": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"code": {
"type": "string",
"minLength": 1
},
"target": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"code",
"target",
"reason"
]
}
},
"entry_ref_id": {
"type": "string",
"minLength": 1
},
"rule_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"contract_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"branch_mapping_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"service_id": {
"type": "string",
"minLength": 1
},
"service_version_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"capability_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"entry_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"owned_object_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"state_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"dependency_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"grouping_ref_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
}
},
"required": [
"schema_version",
"view_id",
"revision_id",
"view_kind",
"snapshot_id",
"target_ref",
"source_refs",
"input_digest",
"generator_revision",
"statements",
"coverage",
"unresolved"
],
"allOf": [
{
"if": {
"properties": {
"view_kind": {
"const": "ENTRY_CARD"
}
}
},
"then": {
"required": [
"entry_ref_id",
"rule_ref_ids",
"contract_ref_ids",
"branch_mapping_refs"
],
"not": {
"anyOf": [
{
"required": [
"service_id"
]
},
{
"required": [
"service_version_refs"
]
},
{
"required": [
"capability_ref_ids"
]
},
{
"required": [
"entry_ref_ids"
]
},
{
"required": [
"owned_object_ref_ids"
]
},
{
"required": [
"state_ref_ids"
]
},
{
"required": [
"dependency_ref_ids"
]
},
{
"required": [
"grouping_ref_ids"
]
}
]
}
},
"else": {
"required": [
"service_id",
"service_version_refs",
"capability_ref_ids",
"entry_ref_ids",
"owned_object_ref_ids",
"state_ref_ids",
"dependency_ref_ids",
"grouping_ref_ids"
],
"not": {
"anyOf": [
{
"required": [
"entry_ref_id"
]
},
{
"required": [
"rule_ref_ids"
]
},
{
"required": [
"contract_ref_ids"
]
},
{
"required": [
"branch_mapping_refs"
]
}
]
}
}
}
]
}
maintenance-command.examples.json
[
{
"schema_version": "0.1",
"command_id": "cmd:design:1",
"action": "REGISTER_SOURCE",
"target": {
"kind": "SOURCE",
"id": "source:O1"
},
"expected_revision": null,
"payload": {
"source_ref": "source:order-repo",
"domain_id": "domain:order",
"capabilities": [
"JAVA",
"JSF",
"JMQ"
]
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:2",
"action": "SAVE_SCENARIO",
"target": {
"kind": "SCENARIO",
"id": "scenario:O1"
},
"expected_revision": null,
"payload": {
"title": "履约失败后的订单补偿",
"domain_id": "domain:order",
"material_refs": [
"material:order:compensation:r1"
],
"trigger": "永久履约拒绝",
"object_refs": [
"entity:order"
],
"completion": "退款确认、退券确认和订单终态写入均成立",
"obligations": [
{
"obligation_id": "obl:refund",
"kind": "RECOVERY",
"description": "按原幂等操作重试并等待退款确认"
}
]
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:3",
"action": "MAP_ENTRY",
"target": {
"kind": "SCENARIO",
"id": "scenario:O1"
},
"expected_revision": "scenario:O1:r1",
"payload": {
"entry_ref": "entry:order:fulfillment-rejected:r1",
"obligation_ref": "obl:refund",
"evidence_refs": [
"ev:order:refund-source:r1"
]
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:4",
"action": "REQUEST_EXCLUSION",
"target": {
"kind": "SCENARIO",
"id": "scenario:O1"
},
"expected_revision": "scenario:O1:r1",
"payload": {
"obligation_ref": "obl:external",
"reason": "本次只核对外部交接合同",
"evidence_refs": [
"ev:boundary:r1"
]
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:5",
"action": "REVIEW_SCOPE",
"target": {
"kind": "SCENARIO",
"id": "scenario:O1"
},
"expected_revision": "scenario:O1:r1",
"payload": {
"dimension": "BUSINESS",
"decision": "ACCEPT",
"evidence_digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"scope_digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"policy_revision": "review-policy:1",
"reason": "已核对原支付及退券的完成条件"
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:6",
"action": "SUBMIT_CORRECTION",
"target": {
"kind": "CORRECTION",
"id": "correction:O1"
},
"expected_revision": null,
"payload": {
"target_revision_ref": "rule:order:lifecycle:r1",
"description": "退款确认被误写成订单已经关闭",
"evidence_refs": [
"ev:order:close:r1"
],
"target_type": "KNOWLEDGE"
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:7",
"action": "SUPPLEMENT_CORRECTION",
"target": {
"kind": "CORRECTION",
"id": "correction:O1"
},
"expected_revision": "correction:O1:r1",
"payload": {
"description": "补充退券失败及订单状态来源",
"evidence_refs": [
"ev:coupon:failed:r1"
]
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:8",
"action": "REVIEW_CORRECTION",
"target": {
"kind": "CORRECTION",
"id": "correction:O1"
},
"expected_revision": "correction:O1:r1",
"payload": {
"decision": "ACCEPT",
"reason": "原文还要求券退回和订单终态",
"evidence_refs": [
"ev:order:close:r1"
],
"resolution": "KNOWLEDGE_CHANGE",
"knowledge_target_ref": "rule:order:lifecycle:r1"
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:9",
"action": "RETRY_BUILD",
"target": {
"kind": "BUILD",
"id": "build:O1"
},
"expected_revision": "build:O1:r1",
"payload": {
"reason": "已恢复受限依赖访问"
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:10",
"action": "CANCEL_BUILD",
"target": {
"kind": "BUILD",
"id": "build:O1"
},
"expected_revision": "build:O1:r1",
"payload": {
"reason": "该批输入已被新修订替代"
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:11",
"action": "REQUEST_PUBLICATION",
"target": {
"kind": "RELEASE",
"id": "release:O1"
},
"expected_revision": "release:O1:r1",
"payload": {
"candidate_revision": "candidate:K2:r1",
"expected_active_release": "K1",
"reason": "入口与覆盖检查通过"
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:12",
"action": "ROLLBACK_PUBLICATION",
"target": {
"kind": "RELEASE",
"id": "release:O1"
},
"expected_revision": null,
"payload": {
"retained_release_id": "K1",
"expected_active_release": "K2",
"reason": "恢复仍可读取的旧知识"
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:13",
"action": "SAVE_GROUPING",
"target": {
"kind": "GROUPING",
"id": "group:payment:cash"
},
"expected_revision": null,
"payload": {
"grouping_kind": "CAPABILITY_ENTRIES",
"domain_id": "domain:payment",
"target_ref": "cap:payment:cash:r1",
"member_refs": [
"entry:payment:confirm:r1",
"entry:payment:refund:r1",
"entry:payment:refund-confirmed:r1"
],
"alias": null,
"evidence_refs": [
"ev:payment:refund-source:r1"
]
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:14",
"action": "REVIEW_GROUPING",
"target": {
"kind": "GROUPING",
"id": "group:payment:cash"
},
"expected_revision": "group:payment:cash:r1",
"payload": {
"dimension": "BUSINESS",
"decision": "ACCEPT",
"evidence_digest": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"scope_digest": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"policy_revision": "review-policy:1",
"reason": "收退款职责及入口分组相符"
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:15",
"action": "SAVE_GROUPING",
"target": {
"kind": "GROUPING",
"id": "alias:payment:cash"
},
"expected_revision": null,
"payload": {
"grouping_kind": "TERM_ALIAS",
"domain_id": "domain:payment",
"target_ref": "entity:payment:r1",
"member_refs": [],
"alias": "原支付",
"evidence_refs": [
"ev:payment:refund-source:r1"
]
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:16",
"action": "SUBMIT_CORRECTION",
"target": {
"kind": "CORRECTION",
"id": "correction:answer:O1"
},
"expected_revision": null,
"payload": {
"target_type": "ANSWER",
"target_revision_ref": "result:O1:T1:1",
"answer_ref": {
"query_id": "query:O1:T1",
"claim_id": "claim:O1:completion"
},
"description": "答案把退款确认误写成整单补偿完成",
"evidence_refs": [
"ev:order:close:r1"
]
}
},
{
"schema_version": "0.1",
"command_id": "cmd:design:17",
"action": "REVIEW_CORRECTION",
"target": {
"kind": "CORRECTION",
"id": "correction:answer:O1"
},
"expected_revision": "correction:answer:O1:r1",
"payload": {
"decision": "ACCEPT",
"reason": "完成规则正确,答案遗漏退券失败记录",
"evidence_refs": [
"ev:order:close:r1"
],
"resolution": "ANSWER_REGENERATION"
}
}
]
maintenance-command.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://jd-kb.example/schemas/maintenance-command.schema.json",
"title": "知识维护命令",
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"enum": [
"0.1",
"0.2"
]
},
"command_id": {
"type": "string",
"minLength": 1
},
"action": {
"enum": [
"REGISTER_SOURCE",
"SAVE_SCENARIO",
"MAP_ENTRY",
"REQUEST_EXCLUSION",
"REVIEW_SCOPE",
"SUBMIT_CORRECTION",
"SUPPLEMENT_CORRECTION",
"REVIEW_CORRECTION",
"RETRY_BUILD",
"CANCEL_BUILD",
"REQUEST_PUBLICATION",
"ROLLBACK_PUBLICATION",
"SAVE_GROUPING",
"REVIEW_GROUPING",
"START_BUILD",
"SAVE_CAPABILITY",
"REVIEW_CAPABILITY",
"RETRY_ANSWER_REGENERATION"
]
},
"target": {
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"enum": [
"SOURCE",
"SCENARIO",
"CORRECTION",
"BUILD",
"RELEASE",
"GROUPING",
"CAPABILITY"
]
},
"id": {
"type": "string",
"minLength": 1
}
},
"required": [
"kind",
"id"
]
},
"expected_revision": {
"type": [
"string",
"null"
],
"minLength": 1
},
"payload": {
"type": "object"
}
},
"required": [
"schema_version",
"command_id",
"action",
"target",
"expected_revision",
"payload"
],
"allOf": [
{
"if": {
"properties": {
"action": {
"const": "REGISTER_SOURCE"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "SOURCE"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"source_ref": {
"type": "string",
"minLength": 1
},
"domain_id": {
"type": "string",
"minLength": 1
},
"capabilities": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
}
},
"required": [
"source_ref",
"domain_id",
"capabilities"
]
},
"expected_revision": {
"type": "null"
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "SAVE_SCENARIO"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "SCENARIO"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"title": {
"type": "string",
"minLength": 1
},
"domain_id": {
"type": "string",
"minLength": 1
},
"material_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"trigger": {
"type": "string",
"minLength": 1
},
"object_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"completion": {
"type": "string",
"minLength": 1
},
"obligations": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"obligation_id": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"ENTRY",
"BRANCH",
"RECOVERY",
"EXTERNAL_BOUNDARY",
"COMPLETION"
]
},
"description": {
"type": "string",
"minLength": 1
}
},
"required": [
"obligation_id",
"kind",
"description"
]
}
}
},
"required": [
"title",
"domain_id",
"material_refs",
"trigger",
"object_refs",
"completion",
"obligations"
]
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "MAP_ENTRY"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "SCENARIO"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"entry_ref": {
"type": "string",
"minLength": 1
},
"obligation_ref": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
}
},
"required": [
"entry_ref",
"obligation_ref",
"evidence_refs"
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "REQUEST_EXCLUSION"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "SCENARIO"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"obligation_ref": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
}
},
"required": [
"obligation_ref",
"reason",
"evidence_refs"
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "REVIEW_SCOPE"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "SCENARIO"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"dimension": {
"enum": [
"BUSINESS",
"TECHNICAL"
]
},
"decision": {
"enum": [
"ACCEPT",
"REJECT"
]
},
"evidence_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"scope_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"policy_revision": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
},
"content_revision": {
"type": "string",
"minLength": 1
}
},
"required": [
"dimension",
"decision",
"evidence_digest",
"scope_digest",
"policy_revision",
"reason"
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "SUBMIT_CORRECTION"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "CORRECTION"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"target_revision_ref": {
"type": "string",
"minLength": 1
},
"description": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"target_type": {
"enum": [
"KNOWLEDGE",
"ANSWER"
]
},
"answer_ref": {
"type": "object",
"additionalProperties": false,
"properties": {
"query_id": {
"type": "string",
"minLength": 1
},
"claim_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"query_id",
"claim_id"
]
},
"supersedes_correction_ref": {
"type": "string",
"minLength": 1
}
},
"required": [
"target_revision_ref",
"description",
"evidence_refs",
"target_type"
],
"allOf": [
{
"if": {
"properties": {
"target_type": {
"const": "ANSWER"
}
}
},
"then": {
"required": [
"answer_ref"
]
},
"else": {
"not": {
"required": [
"answer_ref"
]
}
}
}
]
},
"expected_revision": {
"type": "null"
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "SUPPLEMENT_CORRECTION"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "CORRECTION"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"description": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
}
},
"required": [
"description",
"evidence_refs"
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "REVIEW_CORRECTION"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "CORRECTION"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"decision": {
"enum": [
"ACCEPT",
"REJECT",
"REQUEST_INFO"
]
},
"reason": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"resolution": {
"enum": [
"KNOWLEDGE_CHANGE",
"ANSWER_REGENERATION"
]
},
"knowledge_target_ref": {
"type": "string",
"minLength": 1
}
},
"required": [
"decision",
"reason",
"evidence_refs"
],
"allOf": [
{
"if": {
"properties": {
"decision": {
"const": "ACCEPT"
}
}
},
"then": {
"required": [
"resolution"
],
"allOf": [
{
"if": {
"properties": {
"resolution": {
"const": "KNOWLEDGE_CHANGE"
}
}
},
"then": {
"required": [
"knowledge_target_ref"
]
},
"else": {
"not": {
"required": [
"knowledge_target_ref"
]
}
}
}
]
},
"else": {
"not": {
"anyOf": [
{
"required": [
"resolution"
]
},
{
"required": [
"knowledge_target_ref"
]
}
]
}
}
}
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "RETRY_BUILD"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "BUILD"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"reason"
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "CANCEL_BUILD"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "BUILD"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"reason"
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "REQUEST_PUBLICATION"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "RELEASE"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"candidate_revision": {
"type": "string",
"minLength": 1
},
"expected_active_release": {
"type": [
"string",
"null"
],
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"candidate_revision",
"expected_active_release",
"reason"
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "ROLLBACK_PUBLICATION"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "RELEASE"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"retained_release_id": {
"type": "string",
"minLength": 1
},
"expected_active_release": {
"type": [
"string",
"null"
],
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"retained_release_id",
"expected_active_release",
"reason"
]
},
"expected_revision": {
"type": "null"
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "SAVE_GROUPING"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "GROUPING"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"grouping_kind": {
"enum": [
"CAPABILITY_ENTRIES",
"TERM_ALIAS"
]
},
"domain_id": {
"type": "string",
"minLength": 1
},
"target_ref": {
"type": "string",
"minLength": 1
},
"member_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true
},
"alias": {
"type": [
"string",
"null"
],
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
}
},
"required": [
"grouping_kind",
"domain_id",
"target_ref",
"member_refs",
"alias",
"evidence_refs"
],
"allOf": [
{
"if": {
"properties": {
"grouping_kind": {
"const": "CAPABILITY_ENTRIES"
}
}
},
"then": {
"properties": {
"member_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"alias": {
"type": "null"
}
}
},
"else": {
"properties": {
"member_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"maxItems": 0
},
"alias": {
"type": "string",
"minLength": 1
}
}
}
}
]
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "REVIEW_GROUPING"
}
}
},
"then": {
"properties": {
"target": {
"properties": {
"kind": {
"const": "GROUPING"
}
}
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"dimension": {
"enum": [
"BUSINESS",
"TECHNICAL"
]
},
"decision": {
"enum": [
"ACCEPT",
"REJECT"
]
},
"evidence_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"scope_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"policy_revision": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
},
"content_revision": {
"type": "string",
"minLength": 1
}
},
"required": [
"dimension",
"decision",
"evidence_digest",
"scope_digest",
"policy_revision",
"reason"
]
},
"expected_revision": {
"type": "string",
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "START_BUILD"
}
}
},
"then": {
"properties": {
"schema_version": {
"const": "0.2"
},
"target": {
"properties": {
"kind": {
"const": "BUILD"
}
}
},
"expected_revision": {
"type": "null"
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"source_bindings": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"source_resource_ref": {
"type": "string",
"minLength": 1
},
"source_resource_revision": {
"type": "string",
"minLength": 1
},
"input_revision_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
}
},
"required": [
"source_resource_ref",
"source_resource_revision",
"input_revision_refs"
]
}
},
"baseline_snapshot_id": {
"type": [
"string",
"null"
],
"minLength": 1
},
"strategy_revision": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"application_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"environment": {
"type": "string",
"minLength": 1
}
},
"required": [
"domain_ids",
"application_ids",
"environment"
]
}
},
"required": [
"source_bindings",
"baseline_snapshot_id",
"strategy_revision",
"scope"
]
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "SAVE_CAPABILITY"
}
}
},
"then": {
"properties": {
"schema_version": {
"const": "0.2"
},
"target": {
"properties": {
"kind": {
"const": "CAPABILITY"
}
}
},
"expected_revision": {
"type": [
"string",
"null"
],
"minLength": 1
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"domain_id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"definition": {
"type": "string",
"minLength": 1
},
"input_object_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"output_object_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
},
"boundary": {
"type": "string",
"minLength": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": true,
"minItems": 1
}
},
"required": [
"domain_id",
"name",
"definition",
"input_object_refs",
"output_object_refs",
"boundary",
"evidence_refs"
]
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "REVIEW_CAPABILITY"
}
}
},
"then": {
"properties": {
"schema_version": {
"const": "0.2"
},
"target": {
"properties": {
"kind": {
"const": "CAPABILITY"
}
}
},
"expected_revision": {
"type": "string",
"minLength": 1
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"dimension": {
"enum": [
"BUSINESS",
"TECHNICAL"
]
},
"decision": {
"enum": [
"ACCEPT",
"REJECT"
]
},
"evidence_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"scope_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"policy_revision": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
},
"content_revision": {
"type": "string",
"minLength": 1
}
},
"required": [
"dimension",
"decision",
"evidence_digest",
"scope_digest",
"policy_revision",
"reason"
]
}
}
}
},
{
"if": {
"properties": {
"schema_version": {
"const": "0.1"
}
}
},
"then": {
"properties": {
"action": {
"not": {
"enum": [
"START_BUILD",
"SAVE_CAPABILITY",
"REVIEW_CAPABILITY",
"RETRY_ANSWER_REGENERATION"
]
}
},
"payload": {
"not": {
"anyOf": [
{
"required": [
"supersedes_correction_ref"
]
},
{
"required": [
"content_revision"
]
}
]
}
}
}
}
},
{
"if": {
"properties": {
"schema_version": {
"const": "0.2"
},
"action": {
"enum": [
"REVIEW_SCOPE",
"REVIEW_GROUPING",
"REVIEW_CAPABILITY"
]
}
}
},
"then": {
"properties": {
"payload": {
"required": [
"content_revision"
]
}
}
}
},
{
"if": {
"properties": {
"action": {
"const": "RETRY_ANSWER_REGENERATION"
}
}
},
"then": {
"properties": {
"schema_version": {
"const": "0.2"
},
"target": {
"properties": {
"kind": {
"const": "CORRECTION"
}
}
},
"expected_revision": {
"type": "string",
"minLength": 1
},
"payload": {
"type": "object",
"additionalProperties": false,
"properties": {
"failed_task_ref": {
"type": "string",
"minLength": 1
},
"expected_task_revision": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"failed_task_ref",
"expected_task_revision",
"reason"
]
}
}
}
}
]
}
maintenance-resource.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:maintenance-resource:0.1",
"title": "知识维护资源详情共用字段",
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"enum": [
"SOURCE",
"SCENARIO",
"GROUPING",
"CAPABILITY",
"CORRECTION",
"BUILD",
"RELEASE"
]
},
"resource_id": {
"type": "string",
"minLength": 1
},
"resource_ref": {
"type": "string",
"minLength": 1
},
"revision": {
"type": "string",
"minLength": 1
},
"content_revision": {
"type": [
"string",
"null"
],
"minLength": 1
},
"state": {
"type": "string",
"minLength": 1
},
"allowed_actions": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
},
"review_context": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"content_revision": {
"type": "string",
"minLength": 1
},
"evidence_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"scope_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"policy_revision": {
"type": "string",
"minLength": 1
}
},
"required": [
"content_revision",
"evidence_digest",
"scope_digest",
"policy_revision"
]
}
]
},
"pending_dimensions": {
"type": "array",
"uniqueItems": true,
"items": {
"enum": [
"BUSINESS",
"TECHNICAL"
]
}
},
"next_action": {
"type": "string",
"minLength": 1
},
"required_role": {
"type": "string",
"minLength": 1
},
"followup_task": {
"type": [
"string",
"null"
],
"minLength": 1
},
"replacement_ref": {
"type": [
"string",
"null"
],
"minLength": 1
},
"data": {
"type": "object"
}
},
"required": [
"kind",
"resource_id",
"resource_ref",
"revision",
"content_revision",
"state",
"allowed_actions",
"review_context"
]
}
result-export.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:result-export:0.1",
"title": "工作台结果导出",
"type": "object",
"additionalProperties": false,
"properties": {
"request": {
"$ref": "#/$defs/request"
},
"response": {
"$ref": "#/$defs/response"
}
},
"required": [
"request",
"response"
],
"$defs": {
"source_ref": {
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"enum": [
"ANSWER",
"IMPACT"
]
},
"query_id": {
"type": "string",
"minLength": 1
},
"result_revision": {
"type": "string",
"minLength": 1
}
},
"required": [
"kind",
"query_id",
"result_revision"
]
},
"request": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"source_ref": {
"$ref": "#/$defs/source_ref"
},
"format": {
"enum": [
"JSON",
"HTML"
]
}
},
"required": [
"schema_version",
"request_id",
"source_ref",
"format"
]
},
"response": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"source_ref": {
"$ref": "#/$defs/source_ref"
},
"checked_at": {
"type": "string",
"format": "date-time"
},
"artifact": {
"type": "object",
"additionalProperties": false,
"properties": {
"file_name": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]+\\.(json|html)$"
},
"media_type": {
"enum": [
"application/json; charset=utf-8",
"text/html; charset=utf-8"
]
},
"content": {
"type": "string",
"minLength": 1
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"required": [
"file_name",
"media_type",
"content",
"sha256"
]
}
},
"required": [
"schema_version",
"request_id",
"source_ref",
"checked_at",
"artifact"
]
},
"document": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"source_ref": {
"$ref": "#/$defs/source_ref"
},
"title": {
"type": "string",
"minLength": 1
},
"task_text": {
"type": "string",
"minLength": 1
},
"scope": {
"$ref": "urn:jd-kb:answer-request:0.1#/properties/scope"
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"payload": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"const": "ANSWER"
},
"answer": {
"$ref": "urn:jd-kb:answer:0.2"
}
},
"required": [
"kind",
"answer"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"const": "IMPACT"
},
"results": {
"type": "array",
"minItems": 1,
"items": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "trace_impact"
},
"result": {
"$ref": "urn:jd-kb:tool-contracts:0.1#/$defs/trace_impactResult"
}
},
"required": [
"tool",
"result"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "build_context"
},
"result": {
"$ref": "urn:jd-kb:tool-contracts:0.1#/$defs/build_contextResult"
}
},
"required": [
"tool",
"result"
]
}
]
}
}
},
"required": [
"kind",
"results"
]
}
]
},
"incomplete": {
"type": "boolean"
},
"correction_checks": {
"type": "array",
"items": {
"$ref": "urn:jd-kb:correction-status:0.1"
}
},
"exported_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"schema_version",
"source_ref",
"title",
"task_text",
"scope",
"snapshot_id",
"payload",
"incomplete",
"correction_checks",
"exported_at"
]
},
"view_identity": {
"type": "object",
"additionalProperties": false,
"required": [
"state",
"export_source"
],
"properties": {
"state": {
"enum": [
"RUNNING",
"SUCCEEDED",
"PARTIAL",
"FAILED",
"CANCELLED"
]
},
"export_source": {
"oneOf": [
{
"$ref": "#/$defs/source_ref"
},
{
"type": "null"
}
]
}
},
"allOf": [
{
"if": {
"properties": {
"state": {
"enum": [
"SUCCEEDED",
"PARTIAL"
]
}
}
},
"then": {
"properties": {
"export_source": {
"$ref": "#/$defs/source_ref"
}
}
},
"else": {
"properties": {
"export_source": {
"type": "null"
}
}
}
}
]
}
}
}
service-profile.example.json
{
"schema_version": "0.1",
"view_id": "view:service_profile:O1",
"revision_id": "viewrev:service_profile:2",
"view_kind": "SERVICE_PROFILE",
"snapshot_id": "K1",
"target_ref": {
"stable_id": "svc:payment",
"implementation_scope": "sv:payment:1",
"revision_id": "svc:payment:r1"
},
"source_refs": [
{
"ref_id": "svc-pay",
"kind": "SERVICE",
"stable_id": "svc:payment",
"implementation_scope": "sv:payment:1",
"revision_id": "svc:payment:r1"
},
{
"ref_id": "e-confirm",
"kind": "ENTRY",
"stable_id": "entry:payment:confirm",
"implementation_scope": "sv:payment:1",
"revision_id": "entry:payment:confirm:r1"
},
{
"ref_id": "e-refund",
"kind": "ENTRY",
"stable_id": "entry:payment:refund",
"implementation_scope": "sv:payment:1",
"revision_id": "entry:payment:refund:r1"
},
{
"ref_id": "e-refund-confirm",
"kind": "ENTRY",
"stable_id": "entry:payment:refund-confirmed",
"implementation_scope": "sv:payment:1",
"revision_id": "entry:payment:refund-confirmed:r1"
},
{
"ref_id": "cap-cash",
"kind": "CAPABILITY",
"stable_id": "cap:payment:cash",
"implementation_scope": "GLOBAL",
"revision_id": "cap:payment:cash:r1"
},
{
"ref_id": "cap-close",
"kind": "CAPABILITY",
"stable_id": "cap:order:close",
"implementation_scope": "GLOBAL",
"revision_id": "cap:order:close:r1"
},
{
"ref_id": "obj-pay",
"kind": "ENTITY",
"stable_id": "entity:payment",
"implementation_scope": "GLOBAL",
"revision_id": "entity:payment:r1"
},
{
"ref_id": "obj-refund",
"kind": "ENTITY",
"stable_id": "entity:refund",
"implementation_scope": "GLOBAL",
"revision_id": "entity:refund:r1"
},
{
"ref_id": "state-refund",
"kind": "STATE",
"stable_id": "state:refund:confirmed",
"implementation_scope": "GLOBAL",
"revision_id": "state:refund:confirmed:r1"
},
{
"ref_id": "c-order",
"kind": "CONTRACT",
"stable_id": "contract:order:refund-confirmed",
"implementation_scope": "sv:order:1",
"revision_id": "contract:order:refund-confirmed:r1"
},
{
"ref_id": "group-pay",
"kind": "REVIEW",
"stable_id": "review:payment:capability-grouping",
"implementation_scope": "GLOBAL",
"revision_id": "review:payment:capability-grouping:r1"
},
{
"ref_id": "ev-pay",
"kind": "EVIDENCE",
"stable_id": "ev:payment:refund-source",
"implementation_scope": "sv:payment:1",
"revision_id": "ev:payment:refund-source:r1"
},
{
"ref_id": "r-refund",
"kind": "RULE",
"stable_id": "rule:scenario:refund-original-cash",
"implementation_scope": "GLOBAL",
"revision_id": "rr:scenario:refund-original-cash:1"
}
],
"input_digest": "517402cda0ce46cb907c8eca46411662329a98eec4baa9e5a54234c73970b0e4",
"generator_revision": "view-generator:design:2",
"statements": [
{
"statement_id": "st-responsibility",
"role": "RESPONSIBILITY",
"text": "支付服务确认实收、受理退款并确认退款结果。",
"source_ref_ids": [
"e-confirm",
"e-refund",
"e-refund-confirm",
"cap-cash",
"ev-pay",
"r-refund"
]
},
{
"statement_id": "st-boundary",
"role": "BOUNDARY",
"text": "订单服务收到退款确认后,继续核对退券及订单终态。",
"source_ref_ids": [
"cap-close",
"c-order"
]
}
],
"coverage": {
"inventory_revision": "inventory:O1:entries:1",
"inventory_complete": true,
"discovered_entry_ref_ids": [
"e-confirm",
"e-refund",
"e-refund-confirm"
],
"assigned_entry_ref_ids": [
"e-confirm",
"e-refund",
"e-refund-confirm"
],
"unassigned_entry_ref_ids": [],
"exclusions": [],
"complete": false
},
"unresolved": [
{
"code": "SOURCE_RULE_UNRESOLVED",
"target": "rr:scenario:refund-original-cash:1",
"reason": "O1原规则尚未审阅,范围与新鲜度未确认"
}
],
"service_id": "svc:payment",
"service_version_refs": [
"sv:payment:1"
],
"capability_ref_ids": [
"cap-cash"
],
"entry_ref_ids": [
"e-confirm",
"e-refund",
"e-refund-confirm"
],
"owned_object_ref_ids": [
"obj-pay",
"obj-refund"
],
"state_ref_ids": [
"state-refund"
],
"dependency_ref_ids": [
"c-order",
"cap-close"
],
"grouping_ref_ids": [
"group-pay"
]
}
tool-contracts.examples.json
[
{
"tool": "search_knowledge",
"request": {
"schema_version": "0.1",
"request_id": "request:example:search_knowledge",
"scope": {
"repo_ids": [
"repo:example:order"
],
"domain_ids": [
"domain:example:promo"
],
"environment": null,
"purpose": "DESIGN_REVIEW"
},
"budget": {
"max_graph_nodes": 100,
"max_depth": 5
},
"arguments": {
"query": "叠券规则",
"types": [
"BUSINESS_RULE"
],
"page_size": 10
}
}
},
{
"tool": "get_business_rule",
"request": {
"schema_version": "0.1",
"request_id": "request:example:get_business_rule",
"scope": {
"repo_ids": [
"repo:example:order"
],
"domain_ids": [
"domain:example:promo"
],
"environment": null,
"purpose": "DESIGN_REVIEW"
},
"budget": {
"max_graph_nodes": 100,
"max_depth": 5
},
"arguments": {
"rule_id": "rule:example:dong-tiered-stack"
}
}
},
{
"tool": "get_business_flow",
"request": {
"schema_version": "0.1",
"request_id": "request:example:get_business_flow",
"scope": {
"repo_ids": [
"repo:example:order"
],
"domain_ids": [
"domain:example:promo"
],
"environment": null,
"purpose": "DESIGN_REVIEW"
},
"budget": {
"max_graph_nodes": 100,
"max_depth": 5
},
"arguments": {
"entity_id": "entity:example:order",
"event_id": "event:example:created"
}
}
},
{
"tool": "get_contract",
"request": {
"schema_version": "0.1",
"request_id": "request:example:get_contract",
"scope": {
"repo_ids": [
"repo:example:order"
],
"domain_ids": [
"domain:example:promo"
],
"environment": null,
"purpose": "DESIGN_REVIEW"
},
"budget": {
"max_graph_nodes": 100,
"max_depth": 5
},
"arguments": {
"contract_id": "contract:example:order"
}
}
},
{
"tool": "trace_impact",
"request": {
"schema_version": "0.1",
"request_id": "request:example:trace_impact",
"scope": {
"repo_ids": [
"repo:example:order"
],
"domain_ids": [
"domain:example:promo"
],
"environment": null,
"purpose": "DESIGN_REVIEW"
},
"budget": {
"max_graph_nodes": 100,
"max_depth": 5
},
"arguments": {
"target": {
"id": "field:example:stack",
"kind": "FIELD"
},
"change_type": "FIELD"
}
}
},
{
"tool": "get_evidence",
"request": {
"schema_version": "0.1",
"request_id": "request:example:get_evidence",
"scope": {
"repo_ids": [
"repo:example:order"
],
"domain_ids": [
"domain:example:promo"
],
"environment": null,
"purpose": "DESIGN_REVIEW"
},
"budget": {
"max_graph_nodes": 100,
"max_depth": 5
},
"arguments": {
"evidence_id": "evidence:example:branch",
"line_range": {
"start": 1,
"end": 10
}
}
}
},
{
"tool": "build_context",
"request": {
"schema_version": "0.1",
"request_id": "request:example:build_context",
"scope": {
"repo_ids": [
"repo:example:order"
],
"domain_ids": [
"domain:example:promo"
],
"environment": null,
"purpose": "DESIGN_REVIEW"
},
"budget": {
"max_graph_nodes": 100,
"max_depth": 5
},
"arguments": {
"task": "检查叠券条件变化",
"workspace": {
"repos": [
{
"repo_id": "repo:example:order",
"commit_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"dirty": true,
"diff_completeness": "SELECTED_FILES",
"omitted_categories": [
"SELECTED_OUT"
],
"diffs": [
{
"repo_id": "repo:example:order",
"base_commit": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"path": "src/Rule.java",
"change_kind": "MODIFY",
"base_blob_hash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"untracked": false,
"patch": "@@ -1 +1 @@\n-old\n+new"
}
]
}
]
},
"symbols": [
"symbol:example:rule"
],
"context_budget_tokens": 4096
}
}
}
]
tool-contracts.result-examples.json
[
{
"tool": "search_knowledge",
"result": {
"schema_version": "0.1",
"request_id": "request:example:search_knowledge",
"query_id": "query-example",
"snapshot_id": "release-example",
"status": "OK",
"items": [
{
"id": "rule:example:dong-tiered-stack",
"revision_id": "revision:example:1",
"type": "BUSINESS_RULE",
"summary": "叠券规则候选",
"matched_fields": [
"subject"
],
"evidence_refs": [
"evidence:example:branch"
],
"verification_status": "CANDIDATE"
}
],
"unresolved": [],
"truncated": false,
"next_cursor": null
}
},
{
"tool": "get_business_rule",
"result": {
"schema_version": "0.1",
"request_id": "request:example:get_business_rule",
"query_id": "query-example",
"snapshot_id": "release-example",
"status": "PARTIAL",
"items": [
{
"schema_version": "0.2",
"rule_id": "rule:example:dong-tiered-stack",
"revision_id": "revision:example:1",
"subject": "东券与跨店阶梯满减的叠加限制",
"scope": {
"resolution": "UNKNOWN",
"environment": null,
"service_version_refs": [
"service-version:example:promo"
],
"channels": [],
"audiences": [],
"business_time": {
"resolution": "UNKNOWN",
"valid_from": null,
"valid_to": null
},
"config_context_refs": [],
"deployment_refs": []
},
"predicate": {
"op": "AND",
"args": [
{
"op": "EQ",
"ref": "field:hitCrossShopTieredPromo",
"value": true,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
},
{
"op": "CONTAINS",
"ref": "field:selectedCouponTypes",
"value": "DONG_COUPON",
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "ENUM"
},
{
"op": "EQ",
"ref": "config:allowDongCouponStackTiered",
"value": false,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
}
],
"evaluation_order": "SHORT_CIRCUIT_LEFT_TO_RIGHT"
},
"effects": [
{
"kind": "REJECT",
"description": "拒绝本次优惠叠加",
"error_code": "PROMO_DONG_STACK_FORBIDDEN",
"evidence_ids": [
"evidence:example:branch"
],
"effect_id": "effect:example:reject",
"target_ref": null,
"expression": null,
"guard": {
"op": "AND",
"args": [
{
"op": "EQ",
"ref": "field:hitCrossShopTieredPromo",
"value": true,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
},
{
"op": "CONTAINS",
"ref": "field:selectedCouponTypes",
"value": "DONG_COUPON",
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "ENUM"
},
{
"op": "EQ",
"ref": "config:allowDongCouponStackTiered",
"value": false,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
}
],
"evaluation_order": "SHORT_CIRCUIT_LEFT_TO_RIGHT"
},
"sequence": 0,
"outcome": "THROW",
"control_ref": "control:example:reject-block",
"exception_region_ref": null
}
],
"exceptions": {
"resolution": "UNKNOWN",
"conditions": []
},
"config_dependencies": [
"config:allowDongCouponStackTiered"
],
"evidence_ids": [
"evidence:example:branch"
],
"lifecycle": "CANDIDATE",
"unresolved": [
"仅为协议示例,证据引用未连接真实仓库",
"生产取值、人群、渠道与例外尚未核验"
],
"derivation_kind": "MODEL_INTERPRETATION",
"review_status": "UNREVIEWED",
"freshness": "UNKNOWN",
"resolution_status": "UNRESOLVED",
"entity_refs": [
"entity:example:promotion"
]
}
],
"unresolved": [
{
"code": "EVIDENCE_INSUFFICIENT",
"target": "example"
}
],
"truncated": false,
"next_cursor": null
}
},
{
"tool": "get_business_flow",
"result": {
"schema_version": "0.1",
"request_id": "request:example:get_business_flow",
"query_id": "query-example",
"snapshot_id": "release-example",
"status": "PARTIAL",
"items": [
{
"flow_id": "flow:example:order",
"revision_id": "revision:example:flow",
"trigger": "订单提交请求",
"completion": "履约单创建回执(本例缺少证据)",
"steps": [
{
"step_id": "step:example:submit",
"capability_ref": "capability:example:order",
"guard": {
"op": "CONST",
"value": true,
"evidence_ids": [
"evidence:example:entry"
]
},
"input_bindings": [],
"outputs": [
"event:example:created"
],
"completion": "提交订单事件",
"evidence_ids": [
"evidence:example:entry"
]
}
],
"edges": [],
"coverage": {
"state": "PARTIAL",
"unresolved": [
"FULFILLMENT_EVIDENCE_MISSING"
],
"truncated": false
},
"evidence_refs": [
"evidence:example:entry"
]
}
],
"unresolved": [
{
"code": "EVIDENCE_INSUFFICIENT",
"target": "example"
}
],
"truncated": false,
"next_cursor": null
}
},
{
"tool": "get_contract",
"result": {
"schema_version": "0.1",
"request_id": "request:example:get_contract",
"query_id": "query-example",
"snapshot_id": "release-example",
"status": "PARTIAL",
"items": [
{
"contract_id": "contract:example:order",
"revision_id": "revision:example:contract",
"kind": "EVENT",
"signature": "OrderCreated",
"fields": [
{
"path": "stackAllowed",
"type": "boolean",
"default_resolution": "UNKNOWN",
"serialization_name": "stackAllowed",
"evidence_refs": [
"evidence:example:branch"
]
}
],
"bindings": [
{
"binding_id": "binding:example:consumer",
"environment": null,
"alias": null,
"resolution_status": "UNRESOLVED",
"evidence_refs": [
"evidence:example:branch"
]
}
],
"evidence_refs": [
"evidence:example:branch"
]
}
],
"unresolved": [
{
"code": "EVIDENCE_INSUFFICIENT",
"target": "example"
}
],
"truncated": false,
"next_cursor": null
}
},
{
"tool": "trace_impact",
"result": {
"schema_version": "0.1",
"request_id": "request:example:trace_impact",
"query_id": "query-example",
"snapshot_id": "release-example",
"status": "OK",
"items": [
{
"target": {
"id": "field:example:stack",
"kind": "FIELD"
},
"impact_type": "SUPPORTED",
"change_ref": "change:example:stack",
"paths": [
{
"node_refs": [
"field:example:stack",
"symbol:example:consumer"
],
"edge_refs": [
"edge:example:read"
],
"evidence_refs": [
"evidence:example:branch"
]
}
],
"usage_points": [
{
"symbol_id": "symbol:example:consumer",
"field_path": "stackAllowed",
"evidence_refs": [
"evidence:example:branch"
]
}
],
"version_scope": [
"service-version:example:consumer"
],
"evidence_refs": [
"evidence:example:branch"
]
}
],
"unresolved": [],
"truncated": false,
"next_cursor": null
}
},
{
"tool": "get_evidence",
"result": {
"schema_version": "0.1",
"request_id": "request:example:get_evidence",
"query_id": "query-example",
"snapshot_id": "release-example",
"status": "OK",
"items": [
{
"evidence_id": "evidence:example:branch",
"segment_id": "segment:example:branch",
"source_type": "CODE",
"locator": {
"repo_id": "repo:example:order",
"commit_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"path": "src/Rule.java",
"start_line": 1,
"end_line": 1,
"source_version": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
},
"content": "// synthetic evidence fixture",
"content_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"source_content_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"redactions": [],
"origin": "PUBLISHED",
"snapshot_id": "release-example"
}
],
"unresolved": [],
"truncated": false,
"next_cursor": null
}
},
{
"tool": "build_context",
"result": {
"schema_version": "0.1",
"request_id": "request:example:build_context",
"query_id": "query-example",
"snapshot_id": "release-example",
"status": "PARTIAL",
"items": [
{
"workspace_revision": "workspace:example:dirty",
"snapshot_id": "release-example",
"policy_epoch": "policy-example",
"context_policy_version": "context-policy:example:1",
"version_matches": [
{
"repo_id": "repo:example:order",
"workspace_commit": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"knowledge_commit": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"relationship": "EXACT",
"merge_bases": [
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
],
"unresolved": [],
"implementation_scope": "service-version:example:order"
}
],
"rules": [
{
"schema_version": "0.2",
"rule_id": "rule:example:dong-tiered-stack",
"revision_id": "revision:example:1",
"subject": "东券与跨店阶梯满减的叠加限制",
"scope": {
"resolution": "UNKNOWN",
"environment": null,
"service_version_refs": [
"service-version:example:promo"
],
"channels": [],
"audiences": [],
"business_time": {
"resolution": "UNKNOWN",
"valid_from": null,
"valid_to": null
},
"config_context_refs": [],
"deployment_refs": []
},
"predicate": {
"op": "AND",
"args": [
{
"op": "EQ",
"ref": "field:hitCrossShopTieredPromo",
"value": true,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
},
{
"op": "CONTAINS",
"ref": "field:selectedCouponTypes",
"value": "DONG_COUPON",
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "ENUM"
},
{
"op": "EQ",
"ref": "config:allowDongCouponStackTiered",
"value": false,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
}
],
"evaluation_order": "SHORT_CIRCUIT_LEFT_TO_RIGHT"
},
"effects": [
{
"kind": "REJECT",
"description": "拒绝本次优惠叠加",
"error_code": "PROMO_DONG_STACK_FORBIDDEN",
"evidence_ids": [
"evidence:example:branch"
],
"effect_id": "effect:example:reject",
"target_ref": null,
"expression": null,
"guard": {
"op": "AND",
"args": [
{
"op": "EQ",
"ref": "field:hitCrossShopTieredPromo",
"value": true,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
},
{
"op": "CONTAINS",
"ref": "field:selectedCouponTypes",
"value": "DONG_COUPON",
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "ENUM"
},
{
"op": "EQ",
"ref": "config:allowDongCouponStackTiered",
"value": false,
"evidence_ids": [
"evidence:example:branch"
],
"value_type": "BOOLEAN"
}
],
"evaluation_order": "SHORT_CIRCUIT_LEFT_TO_RIGHT"
},
"sequence": 0,
"outcome": "THROW",
"control_ref": "control:example:reject-block",
"exception_region_ref": null
}
],
"exceptions": {
"resolution": "UNKNOWN",
"conditions": []
},
"config_dependencies": [
"config:allowDongCouponStackTiered"
],
"evidence_ids": [
"evidence:example:branch"
],
"lifecycle": "CANDIDATE",
"unresolved": [
"仅为协议示例,证据引用未连接真实仓库",
"生产取值、人群、渠道与例外尚未核验"
],
"derivation_kind": "MODEL_INTERPRETATION",
"review_status": "UNREVIEWED",
"freshness": "UNKNOWN",
"resolution_status": "UNRESOLVED",
"entity_refs": [
"entity:example:promotion"
]
}
],
"contracts": [
{
"contract_id": "contract:example:order",
"revision_id": "revision:example:contract",
"kind": "EVENT",
"signature": "OrderCreated",
"fields": [
{
"path": "stackAllowed",
"type": "boolean",
"default_resolution": "UNKNOWN",
"serialization_name": "stackAllowed",
"evidence_refs": [
"evidence:example:branch"
]
}
],
"bindings": [
{
"binding_id": "binding:example:consumer",
"environment": null,
"alias": null,
"resolution_status": "UNRESOLVED",
"evidence_refs": [
"evidence:example:branch"
]
}
],
"evidence_refs": [
"evidence:example:branch"
]
}
],
"impact_paths": [
{
"target": {
"id": "field:example:stack",
"kind": "FIELD"
},
"impact_type": "SUPPORTED",
"change_ref": "change:example:stack",
"paths": [
{
"node_refs": [
"field:example:stack",
"symbol:example:consumer"
],
"edge_refs": [
"edge:example:read"
],
"evidence_refs": [
"evidence:example:branch"
]
}
],
"usage_points": [
{
"symbol_id": "symbol:example:consumer",
"field_path": "stackAllowed",
"evidence_refs": [
"evidence:example:branch"
]
}
],
"version_scope": [
"service-version:example:consumer"
],
"evidence_refs": [
"evidence:example:branch"
]
}
],
"evidence_segments": [
{
"evidence_id": "evidence:example:branch",
"segment_id": "segment:example:branch",
"source_type": "CODE",
"locator": {
"repo_id": "repo:example:order",
"commit_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"path": "src/Rule.java",
"start_line": 1,
"end_line": 1,
"source_version": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
},
"content": "// synthetic evidence fixture",
"content_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"source_content_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"redactions": [],
"origin": "PUBLISHED",
"snapshot_id": "release-example"
}
],
"omitted": [
{
"target": "workspace:untracked",
"reason": "DIFF_INCOMPLETE"
}
],
"budget_usage": {
"input_tokens": 2000,
"output_tokens": 500,
"source_bytes": 1000,
"graph_nodes": 3
},
"rule_applicability": [
{
"rule_revision_id": "revision:example:1",
"symbol_refs": [
"symbol:example:consumer"
],
"state": "UNKNOWN",
"reasons": [
"DIFF_INCOMPLETE"
]
}
]
}
],
"unresolved": [
{
"code": "EVIDENCE_INSUFFICIENT",
"target": "example"
}
],
"truncated": false,
"next_cursor": null
}
}
]
tool-contracts.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:tool-contracts:0.1",
"title": "七工具请求与返回合同",
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "search_knowledge"
},
"request": {
"$ref": "#/$defs/search_knowledgeRequest"
},
"result": {
"$ref": "#/$defs/search_knowledgeResult"
}
},
"required": [
"tool"
],
"anyOf": [
{
"required": [
"request"
]
},
{
"required": [
"result"
]
}
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "get_business_rule"
},
"request": {
"$ref": "#/$defs/get_business_ruleRequest"
},
"result": {
"$ref": "#/$defs/get_business_ruleResult"
}
},
"required": [
"tool"
],
"anyOf": [
{
"required": [
"request"
]
},
{
"required": [
"result"
]
}
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "get_business_flow"
},
"request": {
"$ref": "#/$defs/get_business_flowRequest"
},
"result": {
"$ref": "#/$defs/get_business_flowResult"
}
},
"required": [
"tool"
],
"anyOf": [
{
"required": [
"request"
]
},
{
"required": [
"result"
]
}
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "get_contract"
},
"request": {
"$ref": "#/$defs/get_contractRequest"
},
"result": {
"$ref": "#/$defs/get_contractResult"
}
},
"required": [
"tool"
],
"anyOf": [
{
"required": [
"request"
]
},
{
"required": [
"result"
]
}
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "trace_impact"
},
"request": {
"$ref": "#/$defs/trace_impactRequest"
},
"result": {
"$ref": "#/$defs/trace_impactResult"
}
},
"required": [
"tool"
],
"anyOf": [
{
"required": [
"request"
]
},
{
"required": [
"result"
]
}
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "get_evidence"
},
"request": {
"$ref": "#/$defs/get_evidenceRequest"
},
"result": {
"$ref": "#/$defs/get_evidenceResult"
}
},
"required": [
"tool"
],
"anyOf": [
{
"required": [
"request"
]
},
{
"required": [
"result"
]
}
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"tool": {
"const": "build_context"
},
"request": {
"$ref": "#/$defs/build_contextRequest"
},
"result": {
"$ref": "#/$defs/build_contextResult"
}
},
"required": [
"tool"
],
"anyOf": [
{
"required": [
"request"
]
},
{
"required": [
"result"
]
}
]
}
],
"$defs": {
"search_knowledgeRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"environment": {
"type": [
"string",
"null"
]
},
"purpose": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_ids",
"domain_ids",
"environment",
"purpose"
],
"anyOf": [
{
"properties": {
"repo_ids": {
"minItems": 1
}
}
},
{
"properties": {
"domain_ids": {
"minItems": 1
}
}
}
]
},
"snapshot_id": {
"type": [
"string",
"null"
]
},
"budget": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_tool_calls": {
"type": "integer",
"minimum": 0
},
"max_source_bytes": {
"type": "integer",
"minimum": 0
},
"max_graph_nodes": {
"type": "integer",
"minimum": 0
},
"max_depth": {
"type": "integer",
"minimum": 0
},
"max_input_tokens": {
"type": "integer",
"minimum": 0
},
"max_output_tokens": {
"type": "integer",
"minimum": 0
},
"deadline_ms": {
"type": "integer",
"minimum": 1
}
},
"required": []
},
"arguments": {
"type": "object",
"additionalProperties": false,
"properties": {
"query": {
"type": "string",
"minLength": 1
},
"types": {
"type": "array",
"items": {
"enum": [
"BUSINESS_RULE",
"BUSINESS_FLOW",
"CAPABILITY",
"BUSINESS_ENTITY",
"CONTRACT",
"TECHNICAL_ENTITY",
"INSTANCE_OBSERVATION"
]
},
"minItems": 1
},
"page_size": {
"type": "integer",
"minimum": 1
},
"cursor": {
"type": [
"string",
"null"
]
},
"instance_selector": {
"$ref": "#/$defs/InstanceSelector"
}
},
"required": [
"query",
"types",
"page_size"
],
"allOf": [
{
"if": {
"properties": {
"types": {
"contains": {
"const": "INSTANCE_OBSERVATION"
}
}
}
},
"then": {
"required": [
"instance_selector"
],
"properties": {
"types": {
"const": [
"INSTANCE_OBSERVATION"
]
}
}
},
"else": {
"not": {
"required": [
"instance_selector"
]
}
}
}
]
}
},
"required": [
"schema_version",
"request_id",
"scope",
"arguments"
]
},
"search_knowledgeResult": {
"allOf": [
{
"$ref": "urn:jd-kb:tool-result:0.1"
},
{
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
},
"type": {
"enum": [
"BUSINESS_RULE",
"BUSINESS_FLOW",
"CAPABILITY",
"BUSINESS_ENTITY",
"CONTRACT",
"TECHNICAL_ENTITY",
"INSTANCE_OBSERVATION"
]
},
"summary": {
"type": "string",
"minLength": 1
},
"matched_fields": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"verification_status": {
"enum": [
"CANDIDATE",
"REVIEWED",
"CONFLICTED",
"STALE"
]
},
"observation": {
"$ref": "urn:jd-kb:answer:0.2#/properties/observations/items"
},
"knowledge_refs": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"$ref": "#/$defs/KnowledgeRef"
}
}
},
"required": [
"id",
"revision_id",
"type",
"summary",
"matched_fields",
"evidence_refs",
"verification_status"
],
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "INSTANCE_OBSERVATION"
}
}
},
"then": {
"required": [
"observation"
]
},
"else": {
"not": {
"anyOf": [
{
"required": [
"observation"
]
},
{
"required": [
"knowledge_refs"
]
}
]
}
}
}
]
},
"minItems": 0
}
}
}
]
},
"get_business_ruleRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"environment": {
"type": [
"string",
"null"
]
},
"purpose": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_ids",
"domain_ids",
"environment",
"purpose"
],
"anyOf": [
{
"properties": {
"repo_ids": {
"minItems": 1
}
}
},
{
"properties": {
"domain_ids": {
"minItems": 1
}
}
}
]
},
"snapshot_id": {
"type": [
"string",
"null"
]
},
"budget": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_tool_calls": {
"type": "integer",
"minimum": 0
},
"max_source_bytes": {
"type": "integer",
"minimum": 0
},
"max_graph_nodes": {
"type": "integer",
"minimum": 0
},
"max_depth": {
"type": "integer",
"minimum": 0
},
"max_input_tokens": {
"type": "integer",
"minimum": 0
},
"max_output_tokens": {
"type": "integer",
"minimum": 0
},
"deadline_ms": {
"type": "integer",
"minimum": 1
}
},
"required": []
},
"arguments": {
"type": "object",
"additionalProperties": false,
"properties": {
"rule_id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"rule_id"
]
}
},
"required": [
"schema_version",
"request_id",
"scope",
"arguments"
]
},
"get_business_ruleResult": {
"allOf": [
{
"$ref": "urn:jd-kb:tool-result:0.1"
},
{
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "urn:jd-kb:business-rule:0.2"
},
"minItems": 0,
"maxItems": 1
}
}
}
]
},
"get_business_flowRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"environment": {
"type": [
"string",
"null"
]
},
"purpose": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_ids",
"domain_ids",
"environment",
"purpose"
],
"anyOf": [
{
"properties": {
"repo_ids": {
"minItems": 1
}
}
},
{
"properties": {
"domain_ids": {
"minItems": 1
}
}
}
]
},
"snapshot_id": {
"type": [
"string",
"null"
]
},
"budget": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_tool_calls": {
"type": "integer",
"minimum": 0
},
"max_source_bytes": {
"type": "integer",
"minimum": 0
},
"max_graph_nodes": {
"type": "integer",
"minimum": 0
},
"max_depth": {
"type": "integer",
"minimum": 0
},
"max_input_tokens": {
"type": "integer",
"minimum": 0
},
"max_output_tokens": {
"type": "integer",
"minimum": 0
},
"deadline_ms": {
"type": "integer",
"minimum": 1
}
},
"required": []
},
"arguments": {
"type": "object",
"additionalProperties": false,
"properties": {
"flow_id": {
"type": "string",
"minLength": 1
},
"entity_id": {
"type": "string",
"minLength": 1
},
"event_id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
},
"cursor": {
"type": [
"string",
"null"
],
"minLength": 1
},
"page_size": {
"type": "integer",
"minimum": 1
}
},
"required": [],
"oneOf": [
{
"required": [
"flow_id"
],
"not": {
"anyOf": [
{
"required": [
"entity_id"
]
},
{
"required": [
"event_id"
]
}
]
}
},
{
"required": [
"entity_id",
"event_id"
],
"not": {
"required": [
"flow_id"
]
}
}
],
"allOf": [
{
"if": {
"required": [
"revision_id"
]
},
"then": {
"required": [
"flow_id"
]
}
}
]
}
},
"required": [
"schema_version",
"request_id",
"scope",
"arguments"
]
},
"get_business_flowResult": {
"allOf": [
{
"$ref": "urn:jd-kb:tool-result:0.1"
},
{
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"flow_id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
},
"trigger": {
"type": "string",
"minLength": 1
},
"completion": {
"type": "string",
"minLength": 1
},
"steps": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"step_id": {
"type": "string",
"minLength": 1
},
"capability_ref": {
"type": "string",
"minLength": 1
},
"guard": {
"$ref": "urn:jd-kb:business-rule:0.2#/$defs/condition"
},
"input_bindings": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"source_ref": {
"type": "string",
"minLength": 1
},
"target_ref": {
"type": "string",
"minLength": 1
},
"transform": {
"type": [
"string",
"null"
]
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"source_ref",
"target_ref",
"transform",
"evidence_refs"
]
},
"minItems": 0
},
"outputs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"completion": {
"type": "string",
"minLength": 1
},
"evidence_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"step_id",
"capability_ref",
"guard",
"input_bindings",
"outputs",
"completion",
"evidence_ids"
]
},
"minItems": 1
},
"edges": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"from_step": {
"type": "string",
"minLength": 1
},
"to_step": {
"type": "string",
"minLength": 1
},
"edge_type": {
"enum": [
"SEQUENCE",
"PARALLEL",
"EVENT_TRIGGER",
"RETRY",
"COMPENSATE"
]
},
"guard": {
"$ref": "urn:jd-kb:business-rule:0.2#/$defs/condition"
},
"correlation_mapping": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"source_field": {
"type": "string",
"minLength": 1
},
"target_field": {
"type": "string",
"minLength": 1
},
"transform": {
"type": [
"string",
"null"
]
},
"evidence_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"source_field",
"target_field",
"transform",
"evidence_ids"
]
},
"minItems": 0
},
"version_scope": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"evidence_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"resolution_status": {
"enum": [
"RESOLVED",
"AMBIGUOUS",
"UNRESOLVED",
"CONFLICT"
]
}
},
"required": [
"from_step",
"to_step",
"edge_type",
"guard",
"correlation_mapping",
"version_scope",
"evidence_ids",
"resolution_status"
]
},
"minItems": 0
},
"coverage": {
"type": "object",
"additionalProperties": false,
"properties": {
"state": {
"enum": [
"COMPLETE",
"PARTIAL",
"UNKNOWN"
]
},
"unresolved": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"truncated": {
"type": "boolean"
},
"business_assessment": {
"type": "object",
"additionalProperties": false,
"required": [
"ledger_revision",
"snapshot_id",
"closure",
"required_for_answer"
],
"properties": {
"ledger_revision": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"closure": {
"enum": [
"DECLARED_SCOPE_COMPLETE",
"PARTIAL"
]
},
"required_for_answer": {
"type": "boolean"
}
}
}
},
"required": [
"state",
"unresolved",
"truncated"
]
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"completion_predicate": {
"$ref": "urn:jd-kb:business-rule:0.2#/$defs/condition"
},
"state_dimensions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"correlation_refs",
"state_ref",
"evidence_refs"
],
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"correlation_refs": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"state_ref": {
"type": "string"
},
"evidence_refs": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
}
}
}
},
"completion_target": {
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"enum": [
"ORDER",
"SUBORDER",
"LINE",
"REFUND_OPERATION",
"COUPON_ENTITLEMENT",
"DUPLICATE_CAPTURE"
]
},
"target_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"kind",
"target_refs"
]
}
},
"required": [
"flow_id",
"revision_id",
"trigger",
"completion",
"steps",
"edges",
"coverage",
"evidence_refs"
],
"allOf": [
{
"if": {
"required": [
"state_dimensions"
],
"properties": {
"state_dimensions": {
"minItems": 2
}
}
},
"then": {
"required": [
"completion_predicate"
]
}
},
{
"if": {
"properties": {
"coverage": {
"required": [
"business_assessment"
],
"properties": {
"business_assessment": {
"properties": {
"closure": {
"const": "PARTIAL"
}
}
}
}
}
}
},
"then": {
"properties": {
"coverage": {
"properties": {
"state": {
"const": "PARTIAL"
},
"unresolved": {
"minItems": 1
}
}
}
}
}
}
]
},
"minItems": 0
}
}
},
{
"if": {
"properties": {
"status": {
"const": "OK"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"properties": {
"coverage": {
"properties": {
"state": {
"const": "COMPLETE"
},
"unresolved": {
"maxItems": 0
},
"truncated": {
"const": false
}
}
}
}
}
}
}
}
}
]
},
"get_contractRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"environment": {
"type": [
"string",
"null"
]
},
"purpose": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_ids",
"domain_ids",
"environment",
"purpose"
],
"anyOf": [
{
"properties": {
"repo_ids": {
"minItems": 1
}
}
},
{
"properties": {
"domain_ids": {
"minItems": 1
}
}
}
]
},
"snapshot_id": {
"type": [
"string",
"null"
]
},
"budget": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_tool_calls": {
"type": "integer",
"minimum": 0
},
"max_source_bytes": {
"type": "integer",
"minimum": 0
},
"max_graph_nodes": {
"type": "integer",
"minimum": 0
},
"max_depth": {
"type": "integer",
"minimum": 0
},
"max_input_tokens": {
"type": "integer",
"minimum": 0
},
"max_output_tokens": {
"type": "integer",
"minimum": 0
},
"deadline_ms": {
"type": "integer",
"minimum": 1
}
},
"required": []
},
"arguments": {
"type": "object",
"additionalProperties": false,
"properties": {
"contract_id": {
"type": "string",
"minLength": 1
},
"binding_filters": {
"type": "object",
"additionalProperties": false,
"properties": {
"environment": {
"type": "string",
"minLength": 1
},
"alias": {
"type": "string",
"minLength": 1
}
},
"required": []
},
"revision_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"contract_id"
]
}
},
"required": [
"schema_version",
"request_id",
"scope",
"arguments"
]
},
"get_contractResult": {
"allOf": [
{
"$ref": "urn:jd-kb:tool-result:0.1"
},
{
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"contract_id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"JSF",
"HTTP",
"EVENT"
]
},
"signature": {
"type": "string",
"minLength": 1
},
"fields": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"minLength": 1
},
"type": {
"type": "string",
"minLength": 1
},
"default_value": {},
"serialization_name": {
"type": [
"string",
"null"
]
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"default_resolution": {
"enum": [
"KNOWN",
"ABSENT",
"UNKNOWN"
]
}
},
"required": [
"path",
"type",
"serialization_name",
"evidence_refs",
"default_resolution"
],
"allOf": [
{
"if": {
"properties": {
"default_resolution": {
"const": "KNOWN"
}
}
},
"then": {
"required": [
"default_value"
]
},
"else": {
"not": {
"required": [
"default_value"
]
}
}
}
]
},
"minItems": 0
},
"bindings": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"binding_id": {
"type": "string",
"minLength": 1
},
"environment": {
"type": [
"string",
"null"
]
},
"alias": {
"type": [
"string",
"null"
]
},
"resolution_status": {
"enum": [
"RESOLVED",
"AMBIGUOUS",
"UNRESOLVED"
]
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"binding_id",
"environment",
"alias",
"resolution_status",
"evidence_refs"
]
},
"minItems": 0
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"contract_id",
"revision_id",
"kind",
"signature",
"fields",
"bindings",
"evidence_refs"
]
},
"minItems": 0,
"maxItems": 1
}
}
}
]
},
"trace_impactRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"environment": {
"type": [
"string",
"null"
]
},
"purpose": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_ids",
"domain_ids",
"environment",
"purpose"
],
"anyOf": [
{
"properties": {
"repo_ids": {
"minItems": 1
}
}
},
{
"properties": {
"domain_ids": {
"minItems": 1
}
}
}
]
},
"snapshot_id": {
"type": [
"string",
"null"
]
},
"budget": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_tool_calls": {
"type": "integer",
"minimum": 0
},
"max_source_bytes": {
"type": "integer",
"minimum": 0
},
"max_graph_nodes": {
"type": "integer",
"minimum": 0
},
"max_depth": {
"type": "integer",
"minimum": 0
},
"max_input_tokens": {
"type": "integer",
"minimum": 0
},
"max_output_tokens": {
"type": "integer",
"minimum": 0
},
"deadline_ms": {
"type": "integer",
"minimum": 1
}
},
"required": []
},
"arguments": {
"type": "object",
"additionalProperties": false,
"properties": {
"target": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"ENTITY",
"SYMBOL",
"FIELD",
"CONTRACT",
"EVENT",
"CONFIG"
]
}
},
"required": [
"id",
"kind"
]
},
"change_type": {
"enum": [
"LOGIC",
"FIELD",
"STATE",
"TABLE_FIELD",
"CONFIG"
]
},
"diff": {
"type": "array",
"items": {
"$ref": "urn:jd-kb:workspace:0.1#/$defs/diff"
},
"minItems": 1
},
"workspace_revision": {
"type": "string",
"minLength": 1
},
"cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"target",
"change_type"
],
"not": {
"required": [
"diff",
"workspace_revision"
]
}
}
},
"required": [
"schema_version",
"request_id",
"scope",
"arguments"
]
},
"trace_impactResult": {
"allOf": [
{
"$ref": "urn:jd-kb:tool-result:0.1"
},
{
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/ImpactItem"
},
"minItems": 0
}
}
}
]
},
"get_evidenceRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"environment": {
"type": [
"string",
"null"
]
},
"purpose": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_ids",
"domain_ids",
"environment",
"purpose"
],
"anyOf": [
{
"properties": {
"repo_ids": {
"minItems": 1
}
}
},
{
"properties": {
"domain_ids": {
"minItems": 1
}
}
}
]
},
"snapshot_id": {
"type": [
"string",
"null"
]
},
"budget": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_tool_calls": {
"type": "integer",
"minimum": 0
},
"max_source_bytes": {
"type": "integer",
"minimum": 0
},
"max_graph_nodes": {
"type": "integer",
"minimum": 0
},
"max_depth": {
"type": "integer",
"minimum": 0
},
"max_input_tokens": {
"type": "integer",
"minimum": 0
},
"max_output_tokens": {
"type": "integer",
"minimum": 0
},
"deadline_ms": {
"type": "integer",
"minimum": 1
}
},
"required": []
},
"arguments": {
"type": "object",
"additionalProperties": false,
"properties": {
"evidence_id": {
"type": "string",
"minLength": 1
},
"segment_id": {
"type": "string",
"minLength": 1
},
"line_range": {
"type": "object",
"additionalProperties": false,
"properties": {
"start": {
"type": "integer",
"minimum": 1
},
"end": {
"type": "integer",
"minimum": 1
}
},
"required": [
"start",
"end"
]
}
},
"required": [
"evidence_id"
],
"not": {
"required": [
"segment_id",
"line_range"
]
}
}
},
"required": [
"schema_version",
"request_id",
"scope",
"arguments"
]
},
"get_evidenceResult": {
"allOf": [
{
"$ref": "urn:jd-kb:tool-result:0.1"
},
{
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/EvidenceSegment"
},
"minItems": 0,
"maxItems": 1
}
}
}
]
},
"build_contextRequest": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"scope": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"domain_ids": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"environment": {
"type": [
"string",
"null"
]
},
"purpose": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_ids",
"domain_ids",
"environment",
"purpose"
],
"anyOf": [
{
"properties": {
"repo_ids": {
"minItems": 1
}
}
},
{
"properties": {
"domain_ids": {
"minItems": 1
}
}
}
]
},
"snapshot_id": {
"type": [
"string",
"null"
]
},
"budget": {
"type": "object",
"additionalProperties": false,
"properties": {
"max_tool_calls": {
"type": "integer",
"minimum": 0
},
"max_source_bytes": {
"type": "integer",
"minimum": 0
},
"max_graph_nodes": {
"type": "integer",
"minimum": 0
},
"max_depth": {
"type": "integer",
"minimum": 0
},
"max_input_tokens": {
"type": "integer",
"minimum": 0
},
"max_output_tokens": {
"type": "integer",
"minimum": 0
},
"deadline_ms": {
"type": "integer",
"minimum": 1
}
},
"required": []
},
"arguments": {
"type": "object",
"additionalProperties": false,
"properties": {
"task": {
"type": "string",
"minLength": 1
},
"workspace": {
"$ref": "urn:jd-kb:workspace:0.1"
},
"symbols": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"context_budget_tokens": {
"type": "integer",
"minimum": 1
}
},
"required": [
"task",
"workspace",
"symbols",
"context_budget_tokens"
]
}
},
"required": [
"schema_version",
"request_id",
"scope",
"arguments"
]
},
"build_contextResult": {
"allOf": [
{
"$ref": "urn:jd-kb:tool-result:0.1"
},
{
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"workspace_revision": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"policy_epoch": {
"type": "string",
"minLength": 1
},
"context_policy_version": {
"type": "string",
"minLength": 1
},
"version_matches": {
"type": "array",
"items": {
"$ref": "urn:jd-kb:workspace:0.1#/$defs/versionMatch"
},
"minItems": 1
},
"rules": {
"type": "array",
"items": {
"$ref": "urn:jd-kb:business-rule:0.2"
},
"minItems": 0
},
"contracts": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"contract_id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"JSF",
"HTTP",
"EVENT"
]
},
"signature": {
"type": "string",
"minLength": 1
},
"fields": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"minLength": 1
},
"type": {
"type": "string",
"minLength": 1
},
"default_value": {},
"serialization_name": {
"type": [
"string",
"null"
]
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"default_resolution": {
"enum": [
"KNOWN",
"ABSENT",
"UNKNOWN"
]
}
},
"required": [
"path",
"type",
"serialization_name",
"evidence_refs",
"default_resolution"
],
"allOf": [
{
"if": {
"properties": {
"default_resolution": {
"const": "KNOWN"
}
}
},
"then": {
"required": [
"default_value"
]
},
"else": {
"not": {
"required": [
"default_value"
]
}
}
}
]
},
"minItems": 0
},
"bindings": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"binding_id": {
"type": "string",
"minLength": 1
},
"environment": {
"type": [
"string",
"null"
]
},
"alias": {
"type": [
"string",
"null"
]
},
"resolution_status": {
"enum": [
"RESOLVED",
"AMBIGUOUS",
"UNRESOLVED"
]
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"binding_id",
"environment",
"alias",
"resolution_status",
"evidence_refs"
]
},
"minItems": 0
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"contract_id",
"revision_id",
"kind",
"signature",
"fields",
"bindings",
"evidence_refs"
]
},
"minItems": 0
},
"impact_paths": {
"type": "array",
"items": {
"$ref": "#/$defs/ImpactItem"
},
"minItems": 0
},
"evidence_segments": {
"type": "array",
"items": {
"$ref": "#/$defs/EvidenceSegment"
},
"minItems": 0
},
"omitted": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"target": {
"type": "string",
"minLength": 1
},
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"target",
"reason"
]
},
"minItems": 0
},
"budget_usage": {
"type": "object",
"additionalProperties": false,
"properties": {
"input_tokens": {
"type": "integer",
"minimum": 0
},
"output_tokens": {
"type": "integer",
"minimum": 0
},
"source_bytes": {
"type": "integer",
"minimum": 0
},
"graph_nodes": {
"type": "integer",
"minimum": 0
},
"tokenizer_id": {
"type": "string",
"minLength": 1
},
"context_token_count": {
"type": "integer",
"minimum": 0
},
"effective_context_budget_tokens": {
"type": "integer",
"minimum": 1
}
},
"required": [
"input_tokens",
"output_tokens",
"source_bytes",
"graph_nodes"
],
"dependentRequired": {
"tokenizer_id": [
"context_token_count",
"effective_context_budget_tokens"
],
"context_token_count": [
"tokenizer_id",
"effective_context_budget_tokens"
],
"effective_context_budget_tokens": [
"tokenizer_id",
"context_token_count"
]
}
},
"rule_applicability": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"rule_revision_id",
"symbol_refs",
"state",
"reasons"
],
"properties": {
"rule_revision_id": {
"type": "string",
"minLength": 1
},
"symbol_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"state": {
"enum": [
"APPLIES",
"INVALIDATED",
"UNKNOWN"
]
},
"reasons": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
},
"allOf": [
{
"if": {
"properties": {
"state": {
"enum": [
"UNKNOWN",
"INVALIDATED"
]
}
}
},
"then": {
"properties": {
"reasons": {
"minItems": 1
}
}
}
}
]
}
}
},
"required": [
"workspace_revision",
"snapshot_id",
"policy_epoch",
"context_policy_version",
"version_matches",
"rules",
"contracts",
"impact_paths",
"evidence_segments",
"omitted",
"budget_usage",
"rule_applicability"
]
},
"minItems": 0,
"maxItems": 1
}
}
},
{
"if": {
"properties": {
"status": {
"const": "OK"
}
}
},
"then": {
"properties": {
"items": {
"items": {
"properties": {
"omitted": {
"maxItems": 0
}
}
}
}
}
}
}
]
},
"InstanceSelector": {
"type": "object",
"additionalProperties": false,
"properties": {
"namespace": {
"type": "string",
"minLength": 1
},
"object_kind": {
"enum": [
"ORDER",
"SUBORDER",
"LINE",
"CAPTURE",
"REFUND_OPERATION",
"COUPON_ENTITLEMENT"
]
},
"object_id": {
"type": "string",
"minLength": 1
},
"observed_from": {
"type": "string",
"format": "date-time"
},
"observed_to": {
"type": "string",
"format": "date-time"
}
},
"required": [
"namespace",
"object_kind",
"object_id",
"observed_from",
"observed_to"
]
},
"KnowledgeRef": {
"type": "object",
"additionalProperties": false,
"properties": {
"snapshot_id": {
"type": "string",
"minLength": 1
},
"object_type": {
"enum": [
"BUSINESS_RULE",
"BUSINESS_FLOW",
"CONTRACT",
"TECHNICAL_ENTITY"
]
},
"object_id": {
"type": "string",
"minLength": 1
},
"revision_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"snapshot_id",
"object_type",
"object_id",
"revision_id"
]
},
"EvidenceSegment": {
"type": "object",
"additionalProperties": false,
"properties": {
"evidence_id": {
"type": "string",
"minLength": 1
},
"segment_id": {
"type": "string",
"minLength": 1
},
"source_type": {
"enum": [
"CODE",
"CONFIG",
"DEPLOYMENT",
"GOVERNANCE",
"RUNTIME",
"DOCUMENT",
"HUMAN"
]
},
"locator": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_id": {
"type": [
"string",
"null"
]
},
"commit_sha": {
"oneOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
{
"type": "null"
}
]
},
"path": {
"type": [
"string",
"null"
]
},
"start_line": {
"type": [
"integer",
"null"
],
"minimum": 1
},
"end_line": {
"type": [
"integer",
"null"
],
"minimum": 1
},
"source_version": {
"type": "string",
"minLength": 1
},
"source_ref": {
"type": "string",
"minLength": 1
},
"file_content_hash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"required": [
"repo_id",
"commit_sha",
"path",
"start_line",
"end_line",
"source_version"
]
},
"content": {
"type": "string"
},
"content_hash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"source_content_hash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"redactions": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"start_offset": {
"type": "integer",
"minimum": 0
},
"end_offset": {
"type": "integer",
"minimum": 0
},
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"start_offset",
"end_offset",
"reason"
]
},
"minItems": 0
},
"origin": {
"enum": [
"PUBLISHED",
"WORKSPACE",
"COMMIT_SOURCE",
"INSTANCE_ARCHIVE"
]
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"workspace_revision": {
"type": "string",
"minLength": 1
},
"source_context_id": {
"type": "string",
"minLength": 1
}
},
"required": [
"evidence_id",
"segment_id",
"source_type",
"locator",
"content",
"content_hash",
"source_content_hash",
"redactions",
"origin"
],
"allOf": [
{
"if": {
"properties": {
"origin": {
"const": "PUBLISHED"
}
}
},
"then": {
"required": [
"snapshot_id"
],
"not": {
"anyOf": [
{
"required": [
"workspace_revision"
]
},
{
"required": [
"source_context_id"
]
}
]
}
}
},
{
"if": {
"properties": {
"origin": {
"const": "WORKSPACE"
}
}
},
"then": {
"required": [
"workspace_revision",
"source_context_id"
],
"not": {
"required": [
"snapshot_id"
]
}
}
},
{
"if": {
"properties": {
"origin": {
"const": "COMMIT_SOURCE"
}
}
},
"then": {
"required": [
"source_context_id"
],
"not": {
"anyOf": [
{
"required": [
"snapshot_id"
]
},
{
"required": [
"workspace_revision"
]
}
]
},
"properties": {
"locator": {
"properties": {
"repo_id": {
"type": "string",
"minLength": 1
},
"commit_sha": {
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
"path": {
"type": "string",
"minLength": 1
}
}
}
}
}
},
{
"if": {
"properties": {
"source_type": {
"const": "CODE"
}
}
},
"then": {
"properties": {
"locator": {
"properties": {
"repo_id": {
"type": "string",
"minLength": 1
},
"commit_sha": {
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
"path": {
"type": "string",
"minLength": 1
},
"start_line": {
"type": "integer",
"minimum": 1
},
"end_line": {
"type": "integer",
"minimum": 1
}
}
}
}
},
"else": {
"properties": {
"locator": {
"anyOf": [
{
"required": [
"source_ref"
]
},
{
"properties": {
"repo_id": {
"type": "string",
"minLength": 1
},
"commit_sha": {
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
"path": {
"type": "string",
"minLength": 1
}
}
}
]
}
}
}
},
{
"if": {
"properties": {
"origin": {
"const": "INSTANCE_ARCHIVE"
}
}
},
"then": {
"required": [
"source_context_id"
],
"not": {
"anyOf": [
{
"required": [
"snapshot_id"
]
},
{
"required": [
"workspace_revision"
]
}
]
},
"properties": {
"source_type": {
"enum": [
"RUNTIME",
"DOCUMENT"
]
},
"locator": {
"required": [
"source_ref",
"source_version"
]
}
}
}
}
]
},
"ReferenceSource": {
"type": "object",
"additionalProperties": false,
"properties": {
"ref_id": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"NODE",
"EDGE"
]
},
"origin": {
"enum": [
"PUBLISHED",
"WORKSPACE"
]
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"workspace_revision": {
"type": "string",
"minLength": 1
}
},
"required": [
"ref_id",
"kind",
"origin"
],
"allOf": [
{
"if": {
"properties": {
"origin": {
"const": "PUBLISHED"
}
}
},
"then": {
"required": [
"snapshot_id"
],
"not": {
"required": [
"workspace_revision"
]
}
}
},
{
"if": {
"properties": {
"origin": {
"const": "WORKSPACE"
}
}
},
"then": {
"required": [
"workspace_revision"
],
"not": {
"required": [
"snapshot_id"
]
}
}
}
]
},
"ImpactItem": {
"type": "object",
"additionalProperties": false,
"properties": {
"target": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"kind": {
"enum": [
"ENTITY",
"SYMBOL",
"FIELD",
"CONTRACT",
"EVENT",
"CONFIG"
]
}
},
"required": [
"id",
"kind"
]
},
"impact_type": {
"enum": [
"DEPENDENCY_ONLY",
"POTENTIAL",
"SUPPORTED"
]
},
"change_ref": {
"type": "string",
"minLength": 1
},
"paths": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"node_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"edge_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
}
},
"required": [
"node_refs",
"edge_refs",
"evidence_refs"
]
},
"minItems": 0
},
"usage_points": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"symbol_id": {
"type": "string",
"minLength": 1
},
"field_path": {
"type": [
"string",
"null"
]
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
},
"required": [
"symbol_id",
"field_path",
"evidence_refs"
]
},
"minItems": 0
},
"version_scope": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
},
"reference_sources": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"$ref": "#/$defs/ReferenceSource"
}
}
},
"required": [
"target",
"impact_type",
"change_ref",
"paths",
"usage_points",
"version_scope",
"evidence_refs"
],
"allOf": [
{
"if": {
"properties": {
"impact_type": {
"const": "SUPPORTED"
}
}
},
"then": {
"properties": {
"usage_points": {
"minItems": 1
}
}
}
}
]
}
}
}
tool-result.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:tool-result:0.1",
"title": "查询工具成功与部分结果",
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"request_id",
"query_id",
"snapshot_id",
"status",
"items",
"unresolved",
"truncated",
"next_cursor"
],
"properties": {
"schema_version": {
"const": "0.1"
},
"request_id": {
"type": "string",
"minLength": 1
},
"query_id": {
"type": "string",
"minLength": 1
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"status": {
"enum": [
"OK",
"PARTIAL",
"EMPTY"
]
},
"items": {
"type": "array",
"items": {
"type": "object"
}
},
"unresolved": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"code",
"target"
],
"properties": {
"code": {
"type": "string"
},
"target": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
},
"truncated": {
"type": "boolean"
},
"next_cursor": {
"oneOf": [
{
"type": "null"
},
{
"type": "string",
"minLength": 1
}
]
}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "EMPTY"
}
}
},
"then": {
"properties": {
"items": {
"maxItems": 0
},
"truncated": {
"const": false
},
"next_cursor": {
"type": "null"
},
"unresolved": {
"maxItems": 0
}
}
}
},
{
"if": {
"properties": {
"truncated": {
"const": true
}
}
},
"then": {
"properties": {
"status": {
"const": "PARTIAL"
}
}
}
},
{
"if": {
"properties": {
"status": {
"const": "OK"
}
}
},
"then": {
"properties": {
"items": {
"minItems": 1
},
"unresolved": {
"maxItems": 0
},
"truncated": {
"const": false
},
"next_cursor": {
"type": "null"
}
}
}
},
{
"if": {
"properties": {
"next_cursor": {
"type": "string"
}
}
},
"then": {
"properties": {
"truncated": {
"const": true
},
"status": {
"const": "PARTIAL"
}
}
}
}
]
}
workspace.example.json
{
"repos": [
{
"repo_id": "repo:example:order",
"commit_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"dirty": true,
"diff_completeness": "SELECTED_FILES",
"omitted_categories": [
"SELECTED_OUT"
],
"diffs": [
{
"repo_id": "repo:example:order",
"base_commit": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"path": "src/Rule.java",
"change_kind": "MODIFY",
"base_blob_hash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"untracked": false,
"patch": "@@ -1 +1 @@\n-old\n+new"
}
]
}
]
}
workspace.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:jd-kb:workspace:0.1",
"title": "IDE工作区与补丁",
"type": "object",
"additionalProperties": false,
"properties": {
"repos": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_id": {
"type": "string",
"minLength": 1
},
"commit_sha": {
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
"branch": {
"type": [
"string",
"null"
]
},
"dirty": {
"type": "boolean"
},
"diff_completeness": {
"enum": [
"FULL_WORKTREE",
"SELECTED_FILES"
]
},
"omitted_categories": {
"type": "array",
"items": {
"enum": [
"BINARY",
"UNTRACKED",
"IGNORED",
"SELECTED_OUT"
]
},
"minItems": 0
},
"diffs": {
"type": "array",
"items": {
"$ref": "#/$defs/diff"
},
"minItems": 0
}
},
"required": [
"repo_id",
"commit_sha",
"dirty",
"diff_completeness",
"omitted_categories",
"diffs"
]
},
"minItems": 1
}
},
"required": [
"repos"
],
"$defs": {
"diff": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_id": {
"type": "string",
"minLength": 1
},
"base_commit": {
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
"path": {
"type": "string",
"minLength": 1,
"pattern": "^(?!/)(?![A-Za-z]:)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\).+$"
},
"change_kind": {
"enum": [
"MODIFY",
"ADD",
"DELETE",
"RENAME",
"BINARY"
]
},
"base_blob_hash": {
"oneOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
{
"type": "null"
}
]
},
"patch": {
"type": "string",
"minLength": 1
},
"content": {
"type": "string"
},
"content_hash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"old_path": {
"type": "string",
"minLength": 1,
"pattern": "^(?!/)(?![A-Za-z]:)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\).+$"
},
"new_path": {
"type": "string",
"minLength": 1,
"pattern": "^(?!/)(?![A-Za-z]:)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\).+$"
},
"untracked": {
"type": "boolean"
}
},
"required": [
"repo_id",
"base_commit",
"path",
"change_kind",
"base_blob_hash",
"untracked"
],
"allOf": [
{
"if": {
"properties": {
"change_kind": {
"const": "MODIFY"
}
}
},
"then": {
"required": [
"patch"
],
"properties": {
"base_blob_hash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
}
}
},
{
"if": {
"properties": {
"change_kind": {
"const": "ADD"
}
}
},
"then": {
"required": [
"content",
"content_hash"
],
"properties": {
"base_blob_hash": {
"type": "null"
}
}
}
},
{
"if": {
"properties": {
"change_kind": {
"const": "DELETE"
}
}
},
"then": {
"properties": {
"base_blob_hash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
},
"not": {
"anyOf": [
{
"required": [
"patch"
]
},
{
"required": [
"content"
]
}
]
}
}
},
{
"if": {
"properties": {
"change_kind": {
"const": "RENAME"
}
}
},
"then": {
"required": [
"old_path",
"new_path"
],
"properties": {
"base_blob_hash": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
}
}
},
{
"if": {
"properties": {
"change_kind": {
"const": "BINARY"
}
}
},
"then": {
"not": {
"anyOf": [
{
"required": [
"patch"
]
},
{
"required": [
"content"
]
}
]
}
}
}
]
},
"versionMatch": {
"type": "object",
"additionalProperties": false,
"properties": {
"repo_id": {
"type": "string",
"minLength": 1
},
"workspace_commit": {
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
"knowledge_commit": {
"oneOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
{
"type": "null"
}
]
},
"relationship": {
"enum": [
"EXACT",
"ANCESTOR",
"AHEAD",
"DIVERGED",
"UNKNOWN"
]
},
"merge_bases": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
},
"minItems": 0
},
"unresolved": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 0
},
"implementation_scope": {
"type": "string",
"minLength": 1
}
},
"required": [
"repo_id",
"workspace_commit",
"knowledge_commit",
"relationship",
"merge_bases",
"unresolved",
"implementation_scope"
],
"allOf": [
{
"if": {
"properties": {
"relationship": {
"enum": [
"EXACT",
"ANCESTOR",
"AHEAD",
"DIVERGED"
]
}
}
},
"then": {
"properties": {
"knowledge_commit": {
"type": "string",
"pattern": "^[0-9a-f]{40}([0-9a-f]{24})?$"
}
}
}
}
]
}
}
}