From 9d2ef6e4323cee827da47fc96f50a4c8ef7c3295 Mon Sep 17 00:00:00 2001 From: stewart hu Date: Tue, 1 Sep 2026 20:52:14 -0400 Subject: [PATCH] Add interfaces and contracts reference (doc 11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_019u5SLNweVio6ozJX7yfxQr 🔮 View transcript: https://logs.lojong.info/s/e8u90k3t33w590r7b5y7yzqh --- docs/00-overview.md | 1 + docs/11-contracts.md | 160 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 docs/11-contracts.md diff --git a/docs/00-overview.md b/docs/00-overview.md index 52acfe0..30c41a9 100644 --- a/docs/00-overview.md +++ b/docs/00-overview.md @@ -120,3 +120,4 @@ flowchart TB | 08-implementation | Mastra 映射、LLM 抽象层、部署形态、影子运行 | 2.5 基础条件 | | 09-runtime-implementation | Runtime 实现设计(Mastra 落地细节) | 2.3 建设内容 05 | | 10-federation | 省间协同联邦边界 | 3.3 二期推广 | +| 11-contracts | 接口清单、业务对象总表、TS↔Python 契约策略 | 2.3 建设内容 02/05 | diff --git a/docs/11-contracts.md b/docs/11-contracts.md new file mode 100644 index 0000000..b1110c5 --- /dev/null +++ b/docs/11-contracts.md @@ -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 +} +interface SimulationPort { + simulate(proposal: Proposal): Promise +} +interface EnvelopePort { + match(proposal: Proposal): Promise // 包络命中与边界检查 +} + +// 授权环节:现势复核 + 许可签发(03 篇 §2.2,I4) +interface AuthorityPort { + authorize(p: Proposal, approvals: Approval[]): Promise + revoke(permitId: PermitId, reason: string): Promise +} + +// 网关:只认 (Proposal, Permit) 对 +interface GatewayPort { + dispatch(p: Proposal, permit: ExecutionPermit): Promise +} + +// 共享账本与证据 +interface LedgerPort { + read(scope: LedgerScope): Promise // 带版本号(乐观并发) + append(update: PositionUpdate): Promise +} +interface EvidencePort { + record(evt: DomainEvent): Promise // 事件溯源写入口 +} + +// 运营工单台(02 篇 §5) +interface CaseDeskPort { + open(kind: CaseKind, input: CaseInput): Promise + read(caseId: CaseId): Promise + apply(cmd: CaseCommand): Promise // 审批、叉分情景、关单… + watch(caseId: CaseId): AsyncIterable +} +``` + +### 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 { + 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 仓的任何内部代码——组织边界与代码边界对齐。