Add interfaces and contracts reference (doc 11)

Consolidates plane-boundary ports, service/event contracts, and the
canonical domain-object table (merged with peer review §12), plus the
TS↔Python strategy: zod as schema source, committed JSON Schema
artifacts, generated pydantic models, golden-fixture contract tests
in both CIs, and cross-language data-representation rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019u5SLNweVio6ozJX7yfxQr

🔮 View transcript: https://logs.lojong.info/s/e8u90k3t33w590r7b5y7yzqh
This commit is contained in:
stewart hu 2026-09-01 20:52:14 -04:00
parent 11f19a661a
commit 9d2ef6e432
2 changed files with 161 additions and 0 deletions

View File

@ -120,3 +120,4 @@ flowchart TB
| 08-implementation | Mastra 映射、LLM 抽象层、部署形态、影子运行 | 2.5 基础条件 | | 08-implementation | Mastra 映射、LLM 抽象层、部署形态、影子运行 | 2.5 基础条件 |
| 09-runtime-implementation | Runtime 实现设计(Mastra 落地细节) | 2.3 建设内容 05 | | 09-runtime-implementation | Runtime 实现设计(Mastra 落地细节) | 2.3 建设内容 05 |
| 10-federation | 省间协同联邦边界 | 3.3 二期推广 | | 10-federation | 省间协同联邦边界 | 3.3 二期推广 |
| 11-contracts | 接口清单、业务对象总表、TS↔Python 契约策略 | 2.3 建设内容 02/05 |

160
docs/11-contracts.md Normal file
View File

@ -0,0 +1,160 @@
# 11 · 接口与契约总册
> 全系统的边界接口清单 + 规范业务对象契约 + TypeScript↔Python 跨语言契约策略。
> 各篇的 YAML 片段是示意,本篇是接口的**权威索引**;字段级定义在代码仓 `packages/domain` 中。
## 1. 接口清单(按边界分类)
### 1.1 平面间端口(进程内 / 内部服务,TS interface)
借用同行评审(brainstorming.md §6)的端口风格——每个端口是一条信任边界的收口:
```ts
// 认知平面 → 可信执行链:唯一提交入口
interface ProposalSubmissionPort {
submit(proposal: Proposal): Promise<{ caseId: CaseId; lifecycleRunId: RunId }>
}
// 可信执行链内部依赖(确定性服务,不暴露给 LLM)
interface PolicyEnginePort {
check(proposal: Proposal, pack: PolicyPackRef): Promise<ValidationResult>
}
interface SimulationPort {
simulate(proposal: Proposal): Promise<SimulationResult>
}
interface EnvelopePort {
match(proposal: Proposal): Promise<EnvelopeMatch> // 包络命中与边界检查
}
// 授权环节:现势复核 + 许可签发(03 篇 §2.2,I4)
interface AuthorityPort {
authorize(p: Proposal, approvals: Approval[]): Promise<ExecutionPermit | StaleDenial>
revoke(permitId: PermitId, reason: string): Promise<void>
}
// 网关:只认 (Proposal, Permit) 对
interface GatewayPort {
dispatch(p: Proposal, permit: ExecutionPermit): Promise<ExecutionReceipt>
}
// 共享账本与证据
interface LedgerPort {
read(scope: LedgerScope): Promise<LedgerView> // 带版本号(乐观并发)
append(update: PositionUpdate): Promise<LedgerVersion>
}
interface EvidencePort {
record(evt: DomainEvent): Promise<EvidenceRef> // 事件溯源写入口
}
// 运营工单台(02 篇 §5)
interface CaseDeskPort {
open(kind: CaseKind, input: CaseInput): Promise<CaseId>
read(caseId: CaseId): Promise<CaseView>
apply(cmd: CaseCommand): Promise<CommandReceipt> // 审批、叉分情景、关单…
watch(caseId: CaseId): AsyncIterable<CaseEvent>
}
```
### 1.2 服务间接口(跨进程 / 跨语言)
| 接口 | 双方 | 协议 | 契约来源 |
|---|---|---|---|
| Skill 调用 | TS Runtime → Python Skill 服务 | HTTP/JSON(FastAPI) | domain 导出的 JSON Schema(见 §3) |
| 审批/工单 API | 前端/工单台 → Runtime | HTTP/JSON | 同上 |
| 决策案 API(外部系统) | 外部系统 → 平台 | HTTP/JSON,`start/act/observe` 三操作(同行方案 A) | 二期再开放,一期仅内部 |
| 联邦网关 | 省级平台 ↔ 他省 | 签名工件交换(10 篇) | FlexibilityEnvelope 等工件 schema |
| 外部适配器 | 平台 ↔ 交易平台/调度/计量 | 对方规定(文件/WebService/消息) | 防腐层内转换(06 篇),原始报文留痕 |
| 边缘控制链路 | 执行引擎 ↔ 边缘终端 | 国网标准协议栈(IEC 104 / MQTT + 国密等,按现场定) | **不属于** JSON 契约域;计划/包络的语义仍来自 domain 对象 |
### 1.3 事件契约
事件总线上的每类事件 = 一个 domain 对象 + 信封:
```ts
interface EventEnvelope<T> {
eventType: string; schemaVersion: string // 语义化版本
occurredAt: string // ISO8601 UTC
causationId: string; correlationId: string // 因果链(复盘/审计遍历用)
payload: T
}
```
## 2. 规范业务对象总表
合并本文档集与同行评审 §12 的清单,去重后的权威列表(★ = 已在各篇定义):
| 对象 | 篇 | 权威存储 | 说明 |
|---|---|---|---|
| Resource / ResourceProfile ★ | 02 | 关系库(复用既有档案/设备中心主数据) | 画像含可靠性评分 |
| FlexibilityEnvelope ★ | 04/10 | 关系库 | 能力向上;省间交换同 schema |
| PositionLedger / PositionUpdate ★ | 00/04 | 关系库(账本服务) | 约束级联载体 |
| Commitment | 10 | 关系库 | 用户承诺与省间承诺共用基型 |
| ForecastBundle | 05 | 时序库 + 快照 | 预测曲线 + 分位区间 + 模型版本 |
| SituationReport ★ | 02 | 事件日志 + 快照 | |
| Proposal ★(含 digest) | 03 | 关系库 + 事件日志 | 状态机见 03 |
| ConstraintSet | 03/05 | 随 Proposal 快照 | 优化器输入的约束集合 |
| ValidationResult / SimulationResult | 03 | 快照 | 血缘组成部分 |
| Approval ★ / ExecutionPermit ★ | 03 | 关系库 | 绑定 digest |
| DispatchOrder | 04 | 关系库 | 许可放行后的分解指令 |
| ExecutionReceipt / ExecutionReport ★ | 04 | 事件日志 | 幂等回执(I5) |
| Settlement | 06 | 关系库 | 结算事实 |
| DecisionCase ★ | 02 | 关系库 | 工单聚合(引用,不复制) |
| PolicyPack ★ | 05 | 版本库(随代码仓管理) | 可执行规则 + 测试 |
| Envelope ★(授权包络) | 03 | 关系库 | 与 FlexibilityEnvelope 严格区分 |
| ReviewFinding ★ | 02 | 语义记忆库 | |
## 3. TypeScript ↔ Python 契约策略
### 3.1 单一事实来源 + 双向生成
```
packages/domain (zod schemas, TS) ← 唯一手写处
│ 构建时导出
▼
contracts/*.schema.json (JSON Schema) ← 提交入库的中立工件(版本化)
│ datamodel-code-generator
▼
skills-py/.../models.py (pydantic) ← 生成物,禁止手改
```
- **为什么 zod 为源**:对象的产生地与主要校验点在 TS Runtime(工作流步骤 IO、
结构化输出、事件信封都用 zod);JSON Schema 作为中立层,Python 侧不依赖 TS 工具链;
- **双端校验**:TS 侧 `registerSkill` 出站校验(05/09 篇),Python FastAPI 用生成的
pydantic 模型入站校验——同一 schema,两端执行;
- **备选方案**(记录备查):JSON Schema 手写为源、两侧都生成——对 Python 团队更中立,
但失去 zod 的 TS 类型推导与重构联动;除非武大/电科院团队明确要求共管 schema 源文件,
维持 zod 为源。
### 3.2 契约测试(CI 强制)
- `contracts/fixtures/` 存每类对象的**黄金样例**(含边界值与历史真实脱敏样本);
- TS CI 与 Python CI 各自加载全部样例做校验——两端对同一样例结论不一致即构建失败;
- schema 变更走**兼容性检查**:对比上一版 JSON Schema,破坏性变更(删字段、改类型、
收紧约束)必须升主版本并附迁移说明;事件消费者按 `schemaVersion` 路由新旧处理器。
### 3.3 数据表示纪律(跨语言最容易翻车处)
| 项 | 约定 |
|---|---|
| 金额 / 电价 / 电量 | **字符串表示的定点小数**(`"123.45"`),禁止 JSON 浮点直传金额(TS number 与 Python float 的精度差异会在结算对账时爆炸);两侧分别用 decimal 库处理 |
| 单位 | 编进字段名:`power_mw`、`energy_mwh`、`price_yuan_per_mwh`——消灭「这个数是 kW 还是 MW」类事故 |
| 时间戳 | ISO8601 UTC 存储与传输;市场时段语义(96 点、申报截止)统一按 `Asia/Shanghai` 解释,时段用 `{date, interval_index}` 而非裸时间戳 |
| 曲线 | `{interval_minutes: 15, start: ..., values: [...]}` 定长数组,不用稀疏 map |
| 标识 | 全部字符串 ID(防 JS 大整数精度损失);主数据 ID 引用既有档案中心编码 |
| 枚举 | 全大写字符串字面量,两侧生成为枚举类型 |
### 3.4 为什么不用 gRPC / protobuf
当前调用量级(申报级频次,非遥测流)下 HTTP/JSON 足够,且:
血缘快照人类可读(审计员直接看)、合作方接入门槛低、与 FastAPI/OpenAPI 生态顺滑。
遥测流是另一个协议域(边缘侧,国网标准协议栈),本就不在 JSON 契约范围内。
二期若省间联邦工件量大再评估签名 + 二进制序列化。
## 4. 一期落实清单
1. `packages/domain` 建仓:先落 07 篇场景所需对象(Proposal / Approval / Permit /
PositionLedger / ForecastBundle / SituationReport / DecisionCase);
2. JSON Schema 导出与 pydantic 生成接入构建脚本;`contracts/` 目录 + 黄金样例;
3. 双端契约测试进 CI(M1 里程碑的一部分——数据先行包括契约先行);
4. 与武大/电科院约定:Skill 服务只依赖 `contracts/`(JSON Schema + 生成的 pydantic),
不依赖 TS 仓的任何内部代码——组织边界与代码边界对齐。