feat: M2 — 写→审(一致性)→裁决→验收(事务);未决冲突禁验收

- 续审 Agent 声明(AgentSpec) + 结构化输出契约(ContinuityReview/Conflict 五类)
- LangGraph 并行审子图(可扩四审) + collect 落 chapter_reviews 留痕 + review SSE(section/conflict)
- 验收-side Repository:章节 accepted 版本晋升 + digest append-only + 审稿留痕/裁决
- API:review(SSE) + reviews 历史 + accept(单原子事务:晋升 version + 终稿 digest + 裁决留痕)
- 冲突 gate:未决裁决拦截(CONFLICT_UNRESOLVED);digest 从终稿提炼(不变量#4)
- 前端:审稿报告页 + 冲突就地标注 + 裁决(采纳/忽略/手改) + 未决禁验收 + 「本次将更新」清单
- M2 E2E:真实 DB + 多档位 mock 网关零 token 走通 写→审→裁决→验收→摘要入库
- 多 agent 协同台账(PROGRESS.md) + 共享记忆(memory/contracts·decisions·gotchas)
This commit is contained in:
Yaojia Wang
2026-06-18 11:38:28 +02:00
parent b523b4fd21
commit 68f194a043
36 changed files with 3881 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
"""续审 Agent 的结构化输出 schemaARCH §5.4 continuity 行 / §6.1 冲突分类)。
snake_casePydantic v2。网关经 instructor 保证产出符合这些 schemaC1/§4.4)。
不变量 #3四审只读——审稿期只产**冲突清单**,不产 digestdigest 在验收时
从终稿另提,见不变量 #4 / ARCH §5.5)。
"""
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field
# ARCH §6.1 五类冲突;受限枚举,便于前端就地裁决分类与统计。
ConflictType = Literal[
"性格漂移",
"能力不符",
"设定违例",
"地理矛盾",
"时间线倒错",
]
class Conflict(BaseModel):
"""单条一致性冲突ARCH §6.1)。"""
type: ConflictType = Field(description="冲突分类(五类之一)")
where: str = Field(description="本章定位:哪一段/哪句触发冲突")
refs: list[str] = Field(
default_factory=list,
description="冲突来源引用:相关章节号、设定项或人物卡条目",
)
suggestion: str = Field(description="改法建议")
class ContinuityReview(BaseModel):
"""续审结构化产出:仅冲突清单(无 digest
digest 不在审稿期产——那是验收时从**终稿**另提(不变量 #4
"""
conflicts: list[Conflict] = Field(
default_factory=list,
description="检出的一致性冲突;无冲突时为空列表",
)