--- name: 决定正文候选去留 description: 据用户明确指令接受、合并或丢弃 Shadow 正文候选并更新 Canonical。仅主会话在用户决定后调用;知识卡归 确认知识草稿,规划归 制定作品规划。 disable-model-invocation: true --- # 确认 / 丢弃(Shadow→Canonical 的唯一入口) **只在用户明确说"采纳/确认/丢弃"后执行,主会话与智能体不得自行发起。** **闸口(05 §2)**:产出候选之后,必须经你确认,才能入库为正式正文。`accept` 授权下游 shadow 草稿自动生成(抽卡等);草稿转正式仍须你确认。未确认不得把候选当 Canonical,也不得在未 accept 时自动写下游草稿。 数据权威在 PostgreSQL(领域索引 §2)。正文的 Shadow→Canonical = 写库内正文块,**不是 git commit**;Git 只管代码与文档留痕。 ## 正文候选:接受 / 丢弃(DB 写路径) 两步,顺序不可颠倒: 1. **先过接受前置检查(纯函数,不写库)**:`scripts/check_writer_acceptance.py` - `check_shadow_ready` 校验生产模式、`acceptanceEligible=true`、候选正文 hash、冻结上下文 ID/hash、`writer-production-v1` 策略、来源状态、候选有效期,以及 detector 最终报告(`writer-pipeline-result-v1`,要求最终轨迹同时通过机械门与语义审查)对当前 `attempt/candidateVersion/candidateSha256` 的绑定。 - 实时状态由 `scripts/acceptance_state.py` 从库重读(冻结行、授权快照、已确认细纲、Canonical revision、接受窗口),编排层不得用内存旧快照冒充。 - `accept/merge` 必须实时匹配 `expectedRevision`;冲突返回 `REVISION_CONFLICT`,不得覆盖 Canonical。 - `acceptanceEligible=false` 的诊断/评测候选在第一道门硬拒绝,不能靠改参数、重跑 fake 或用户确认混进接受链。 - 生产链的 detector 终态来自 `run_writer_pipeline` 的真实机械门 + 语义 detector 双报告;LLM 自然语言 PASS 不是裁决依据,只有结构化报告过检才可接受。 2. **前置通过后,经写入层落库(单事务)**:`scripts/write_canonical.py`(复用 `访问数据库` 的 DSN) - 接受: ```bash .venv/bin/python muse/content/work/skills/sovereignty/决定正文候选去留/scripts/write_canonical.py accept \ --expected-revision --rationale "为什么接受" --basis-ref "大纲@日期" --command-id <幂等ID> \ [--approved-deltas <已批准增量JSON数组>] # 先试跑(完整走一遍事务再回滚,校验不落库):加 --dry-run ``` - 丢弃: ```bash .venv/bin/python muse/content/work/skills/sovereignty/决定正文候选去留/scripts/write_canonical.py discard --rationale "为什么丢弃" ``` - 写入层按落库设计 §2.9 单事务执行:写正文块(`content_text`,revision+1,CAS 乐观锁)→ 写来源归因(`muse_content_block_source_attribution`,来源权威落块,架构-02 §3)→ 合并已批准事实增量(`fact_delta.py`,进 `example_fact_ledger` 正典账本)→ 登记投影(`projection_registry.py`,旧 revision 投影翻 stale、新 revision 登记 pending)→ 写命令幂等审计 → 写决策归档(`example_user_decision`)→ 翻候选 `state='accepted'`。**任一失败整体回滚,绝不留无来源指针的正式正文,也绝不产生正文已提交而事实半合并。** - DB 级兜底硬校验(不靠调用方自觉):`run_type` 非 production 拒绝接受(05 §8.4)、`state` 非 passed 拒绝、`semantic_status` 非 passed 拒绝(先审后入)、revision 冲突拒绝。 ## merge(修改后合并) - 用户以编辑前候选为基线编辑,生成严格 `candidateVersion+1` 的新候选,正文 hash 必须变化,重跑完整 detector 与接受前置检查,回到 Shadow 再走上面的 accept 流程。 - 接受时归因 `--source-type user_merge`,记 `writer+用户修订`。**不得修改后不经重检直接合并。** ## 知识卡 / 规划:各自的确认轨 本 Skill 只管正文轨。另外两条轨各有 owner,表集互不相交: - **知识卡**:归 `确认知识草稿`。**采纳正文 ≠ 确认知识**,抽取产出的卡变更要单独确认。 - **规划**(大纲/细纲/设定):归 `制定作品规划`,由 [`制定作品规划/scripts/persist_planning.py`](../../../../../lifecycle/flow/skills/book/制定作品规划/scripts/persist_planning.py) 的 `confirm_section` 在 `example_planning_section` 上做 shadow→confirmed。 ## 红线 - 评测/诊断候选(run_type≠production)任何情况下不得成为正式正文。 - 写正文必带来源归因;不接受绕过归因的直接写块。 - 正文的 Shadow→Canonical 只写库,不做 git 操作;知识卡与规划的确认不在本 Skill 执行。 ## 输入 - 用户明确的采纳 / 丢弃指令、候选 id、`--expected-revision`、rationale、basis-ref、幂等 `command-id`。 - 接受前必须先过 `scripts/check_writer_acceptance.py`(Shadow 就绪、detector 终态、实时 Canonical revision)。 ## 输出 - accept:Canonical 正文块 revision+1、来源归因、已批准事实增量、投影登记、决策归档、候选 `state=accepted`;回执含 `next_steps`(抽卡等下游草稿 `auto=true`;转正式与下一章规划仍须人)。 - discard:候选 `state=discarded` 与决策记录;附 `next_steps`(不自动改正文)。 - `--dry-run`:完整走事务后回滚,不落库。 ## 复利合同 - 接受事务提交后经 `propose_lesson_dedup` 登记 `example_lesson`(绑 run_id / candidate_id);lesson 写在接受事务外。 - 升格仍走人工评审,不把单次采纳自动升为公共范式。 ## 数据边界 - 读写范围限于本 Skill 合同声明的表/文件;失败整体回滚,不留半写入状态。 - 模型调用走统一网关;raw 证据由 `记录运行证据` 归档。