# Event Extractor v2

新版提取规则只用于升级后正常提取的新 Event。提取器不会重放旧 L5、改写旧标题或回填分类提示和版本号。已有待处理任务仍按正常重试规则处理。历史重复卡由下述独立的一次性整理任务处理。

## 提取判断

判断独立含义及遗忘成本，而不是以重要性、criticality 或消息角色作为统一门槛。用户事实、评价、审美反馈、明确要求、纠正、改变决定和可复用指导采用较低提取门槛；普通 Agent / Tool 执行步骤采用较高门槛。已确认根因、平台限制、失败条件、可复用经验和重要结果仍可独立保留。Summarizer 的高召回预筛同步提示这些候选。

保守使用现有 scope：单次答复要求保留 session 范围；项目要求使用 project；明确长期指导才可使用 user。重复纠正可以成为经验的证据，但不能把一次局部反馈扩大成永久人格或审美。两个能独立变化、被检索、冲突或替代的事实仍分开；原子化不等于记录每次工具调用。标题保留明确对象、稳定锚点和一个主要变化，详细原因留在 summary。
Extractor 结构化输出必须明确返回合法 scope。工具调用及文本 fallback 都先进行同一 schema 验证；遗漏或非法值触发现有有界重试，重试仍失败时不写入 Event，不再默认扩大为 project。核心旧 Event、手工输入及自定义 Extractor 的兼容类型不变。

## 重复与关系

同一 Block 内的同义表达由模型识别为一条事实，保留直接支持它的目标消息 ID。适配层额外合并同一次输出中 title、summary、scope、criticality 和 temporal 完全相同的卡片，比较截断前的完整模型文本，合并目标来源及检索标签；不同事实、范围或关系不合并。
精确重复卡的 catalogHints 保留第一张卡的归一化结果，包括第一张缺省时继续缺省；不合并或追加后续卡的类别。

纯重复且没有新增长期信息可不提取；明确强化或延续用 sameEventId，替代/纠正用 supersedesEventIds，无法确认替代的矛盾用 conflictsWithEventIds。历史卡保留。相同项目、关键词近似不能单独建立关系。现有 timeline 仍最多提供 8 条相关及 4 条最近 Event，增加每条最多 400 字符的摘要、范围和历史状态以辅助识别；字段对自定义 Extractor 保持可选。timeline / neighbor 只供理解和关系匹配，不能为新事实提供来源。

## 入库去重与一次性历史整理

程序负责从当前命名空间的 passive/agent 两个 Event 池发现候选。同批同来源的重复输出仍确定性消重，写入回执继续处理重放；跨 Block 的相似记录即使文字相同，也交给 AI 判断，不能仅凭文本相似直接丢弃新来源。

专用裁决器读取双方完整卡与来源。KEEP_LEFT/KEEP_RIGHT 选择沿用的主卡，并返回完整标题和正文草稿；只有证据支持同一事实、草稿有效且 confidence 至少为 0.9 时才自动采用。缺失信息、表达精度和分类差异不单独构成冲突；不同发生、后续进展、纠正或真实矛盾应明确 KEEP_BOTH，不确定才 REVIEW。明确 KEEP_BOTH 视为 AI 已完成，不要求用户逐对确认。缺草稿、低把握、失败或证据超限时保留原卡，进入人工队列，不回退到程序拼接。阈值是执行规则，并非经真实模型评测校准的准确率。

整理版本为 3，升级时重审未由人工确认的旧候选，并保留已有撤销记录。扫描包括 active/superseded 卡；自动裁决只处理双方 active 的候选，历史版本直接进入人工队列，不消耗自动裁决调用。初次扫描完成后，新增 Event 会触发新候选发现，已处理候选不反复调用模型。程序检查命名空间/会话范围、指纹、置顶和关系完整性；日期、数值等语义差异交给 AI 或人工结合上下文判断。合并采用完整草稿，双方引语、参与者、标签、来源及安全关联按规则保留；沿用主卡的结构化日期和状态，界面提示有差异的字段。自动合并及普通有效卡合并遇到进展、替代、冲突关系或时间环时拒绝折叠；显式人工历史合并保留原始时间链，不重定向历史关联。权重继承双方真实采用字段最大值，不制造采用回执。

后台保留跨进程租约、调用前预留尝试、每对最多两次、60 秒退避和 30 秒外层超时。人工预览复用当前来源指纹对应的 AI 稿；无缓存时可请求草稿，失败后仍可直接填写完整稿，最终确认本身不调用模型。界面分为“需要你判断 / 等待 AI / 已处理”，支持完整标题/正文编辑、仅保留 A/B、保留两张、来源查看和手动接管。切换候选/队列会在当前页面保留最多 50 份编辑草稿；刷新不保存未提交的人工编辑。自动与人工合并均保存可恢复的逆操作；撤销会恢复原内容、历史状态及关系，有后续编辑、采用或相关投影变化时拒绝覆盖新数据。

界面逐组展示 A/B 卡片及发生日期、引语、参与者和来源。用户先选主卡，再选择“合并双方内容”或“只保留所选卡”，预览保留/归档对象、日期和证据去向后确认。日期或事实存在差异时可由用户核对完整稿后合并，不确定时保留两张。superseded 历史卡可在人工确认后补入当前有效卡：默认推荐当前卡作为主卡，完整标题和正文必须经 AI 起草或人工编辑后提交；旧卡归档且保留原文、来源及时间链，双方证据汇入当前卡，当前卡结构化日期和状态不变，外部关联不改写。旧卡即使指向第三个版本，也可在人工确认的完整稿中作为来源，原后继指针保留；将被归档的卡已置顶或已作为其他合并的原始证据时，拒绝并显示具体原因。用户仍可显式二选一（恢复历史卡前单独提示影响）：所选卡设为 active，另一张归档，内容、采用权重、原始来源和历史引用均不混合、不改写；不额外排入模型投影任务。置顶副卡、已合并来源和过期指纹仍受保护。归档卡已有的 supersededBy 保留，只有原来没有后继时才指向所选卡；显式恢复被选历史卡时将其设为 active 并清除自身后继，这是用户选择恢复的状态转换，不改写第三张卡。中断恢复复用已持久化逆操作核对归档结果，不把后继指针当作人工选择的唯一凭据。人工选择独立记为 selected，不冒充 merged；归档 agent 卡可通过显式来源页面查看证据。撤销后回到“需要你判断”并定位刚恢复的候选，避免跳到无关卡片。

存储 schema 13 通过独立 event_merge_sources 表记录 mergedFromEventIds；普通卡继续采用单来源边界，合并卡的额外消息必须来自可追溯的归档原卡。schema 12 可只读查看并无损升级，旧插件会拒绝打开更高存储版本。撤销外部导入时，若其证据已参与合并则拒绝整批删除，避免破坏其他来源。narrative 是已退役的 Event 字段，现存正文在 summary；合并不生成或改写事实正文。

这套机制减少重复，但不能保证语义改写零漏判。仅共享主题、后续进展或时间不明的重复发生都优先保留；不会为追求去重率抹掉独立事实。存量扫描采用词元候选召回，低词面重合的同义表达仍可能未命中。

## 可选字段与兼容

| 字段 | 语义 | 边界 |
| --- | --- | --- |
| `catalogHints?: string[]` | 长期类别的自由短语，仅供导航 | 最多 2 个，每个最多 64 个 Unicode 字符；可以缺省或为空；不设 enum 或 other/其他兜底，不指定目录 ID/路径，不改写标题来充当类别 |
| `extractorVersion?: number` | 对话提取规则版本 | DSH Extractor 在代码中标记为 `2`，不让模型决定；旧卡、手工卡及其他 Extractor 缺省合法 |

运行时限制提示数量，移除空白、重复、非法类型、明显兜底和目录 ID/路径；类别是否有来源、是否只是标题改写等语义约束由 prompt 负责。Topic Projector 可见 catalogHints 用于路由，但不能据此生成事实或决定章/节。Element 和 Graph 都用字段白名单构造 Event 模型输入，物理排除提示和版本号；Element 保留事实正文、引用、目标来源、时间、范围、criticality 和历史关系。检索的事实字段、provenance、时间、criticality 和 admission 机制不变。

SQLite 用新增的可选 `event_metadata` 附表保存这两个字段，支持 passive / agent 两个 Event 池，随原有事务保存和清理。只为已有字段的卡写元数据行；不 ALTER 旧 Event 表或重建历史数据，存储 schema 仍为 12。旧库没有附表也可以只读打开；普通写入器打开时创建空表。旧 Event 的 API 字段形状保持原样，新字段存在时才输出。

## 验证边界

确定性测试验证 prompt/schema 合约、模型输出归一化、同 Block 及跨 Block 去重、目标来源边界、relation 写入、SQLite 往返、旧库只读/升级、无历史重提取/回填，以及旧卡的检索、Topic、Graph、API 和 UI 路径。去重另覆盖模型失败/低把握时保留、并发变化、跨进程租约、检查点恢复和一次性执行。测试里的模型响应是 mock，并非真实模型语义准确率测量；同义识别、提取敏感度及泛化质量仍取决于实际模型。未新增依赖或目录算法。
