feat: export core Hermes skills

This commit is contained in:
2026-07-15 02:45:56 +00:00
parent a028b63eda
commit 54711fee2a
308 changed files with 41310 additions and 1 deletions
@@ -0,0 +1,996 @@
---
name: contract-portfolio-analysis
description: 合同组合分析——批量OCR、独立法律审查、模版对比、三角色校对、Excel汇总表制作与台账维护。适用于多校区/多合同的批量梳理与持续维护项目。
version: 1.12.0
tags: [合同, 批量分析, 模版对比, Excel, OCR, 租赁, 法律审查, 三角色校对, 台账维护]
triggers:
- 批量合同梳理/分析
- 多校区合同汇总
- 合同与标准模版对比
- 合同组合风险分析
- 租赁合同汇总表制作
- 汇总表更新/维护
- 租赁台账维护
- 新增租赁合同
- 合同到期更新
- 提前解除/退租更新
---
# 合同组合分析(Contract Portfolio Analysis)
## 适用场景
客户有大量已签署合同需要梳理(如多个校区的租赁+物业合同),要求:
- 逐份提取关键信息
- 与标准模版对比差异
- 提取变更/解除条款
- 汇总为结构化Excel表格
---
## ⚠️ 元规则:workflow 是必经清单,必须逐项严格执行;不得擅自改动(Maggie 2026-06-22 确立)
**这条管的是「怎么对待 workflow 本身」,优先级排在所有内容铁律之前。**
- **每个校区都必须按本 skill 完整逐项执行**——Step 0→7(单校区闭环 Step 0→6 + 全局收尾 Step 7)+ 三角色校对 + H列三件套 + **末尾整体风险分析与建议段** + 需核实标红,**一步都不能跳、不能简化、不能凭「上个校区做过的印象」代替**。Maggie 原话:「以后每个校区都需要按照 workflow 来做。」
- **不得擅自改动 workflow**:流程的任何增删改(跳过校对、省掉整体分析段、改列结构、改 Step 顺序、改交付方式等)都必须**经 Maggie 明确授权**;授权的调整**固化进本 skill 后才算数**,未固化的一律按原 workflow。我不能自行决定「这步这次不用做」。Maggie 原话:「不能擅自改动 workflow。」
- **悦拾光教训(2026-06-22)**:被要求「做好汇总表」后,凭「世茂做过」的印象裸做,擅自跳过了三角色校对、末尾整体风险分析段、H列付款安排标红、需客户核实标红——被 Maggie **连续四次**追问「你有按 workflow 操作么 / 在做了么」。根因:把 workflow 当参考而非必经清单,把「做表」误判成机械画格子活、绕过 skill 直接 openpyxl 裸写。(详见 Pitfall 16)
- **落地**:每个校区开工前,**先把 workflow 步骤列成 todo 逐项打勾**;交付前对照清单确认每一步都做了,**缺一项不交付**。Maggie 验收必查两件事:(a) 标准板块齐全(尤其整体风险分析与建议段);(b) 是否真走了 workflow——两者缺一即返工。
---
## 🔴🔴 开工铁律:每个校区跑「单校区开工闸门」脚本,从头独立做(Maggie 2026-06-23 立,最高优先级之一)
**这条专治「开新校区时凭上个校区的印象乱跑/跳步」。是物理闸门,不是靠记性。**
### ① 开工第一个动作 = 跑闸门脚本(不跑不准动手)
开始任何一个校区(新建/续做/重做)的**第一件事**,先在终端跑:
```bash
python3 ~/.hermes/skills/legal/contract-portfolio-analysis/scripts/campus-workflow-gate.py <校区名>
```
它会打印:单校区独立闭环纪律 + 完整 Step 0→7 workflow + 该校区源文件夹定位 + 汇总表存放路径 + 待打勾 todo。**把它吐出的 todo 贴进 todo 工具逐项打勾**。没跑这个脚本、没建这份 todo,就不算开工,不准开始填表。
### ② 单校区独立闭环纪律(核心)
**每个校区都是「第一次」,从 Step 0 从头到 Step 6 独立完整跑一遍(Step 7 总览是全部校区定稿后的全局收尾),不受任何其他校区影响:**
- **不拿别校区的印象代替本校区的实做**——「世茂/悦拾光是这样做的」「上个校区这么定级」这类印象,**一律不假设适用于本校区**。本校区的逐字通读、八维审查、回 07 原件比对,每一项都要在本校区原文上从头做。
- **别校区的结论/定级/措辞,统统不迁移**。一切回本校区合同原文重新判断。这是「全新合同全面审」,不是「套上一份的模子」。
- **为什么立这条**:批量做时,注意力被格式/效率分散,最容易「这份大概和上一份一样」地跳读跳审——人不会觉得自己跳了,但判断地基已经空了(与「第一铁律·逐字通读」的批量失效模式同源)。开工闸门脚本就是强制把「每个校区从头来」顶在最前面。
### ③ 汇总表存放纪律(Maggie 2026-06-23 立)
**每个校区做完,汇总表存到该校区自己的文件夹下**,与该校区合同放一起,便于客户对照查阅:
- 存放路径:`小Maggie协作区/南通新东方/履约期内非集采合同-综办/房租物业合同/<校区名>/`
- 命名:`<校区名/项目名>-梳理-MJ-YYYYMMDD.xlsx`(当事人/项目名+文件名+修改人+日期)
- **不放公共目录、不放别的校区文件夹、不只留本地 /tmp**。17 个校区各自的汇总表归各自文件夹。
- 总览 sheet 是所有校区定稿后最后整合的产物(见 Step 7),与「各校区表存各校区文件夹」不冲突——单校区表归位在前,总览整合在后。
### ④ 与既有规则的关系
本节是「元规则·workflow 必经清单」的开工落地抓手,与「Pitfall 18·禁止 openpyxl 裸做」「第一铁律·逐字通读」三位一体:元规则定「必须走流程」,本节定「每校区从头独立走 + 开工先跑闸门 + 表归各自文件夹」,Pitfall 18 定「别绕过 skill 裸写」。三条一起堵死「开新校区自己乱跑」。
---
## ⚠️ 第一铁律:每份合同每份文件,亲自逐字逐句通读理解后再判断(Maggie 2026-06-22 确立,刻进骨子的律师基本严谨)
**这是本 skill 所有规则的地基,排在最前面。** Maggie 原话:「你要把每一份合同每一份文件都逐字逐句自己阅读理解并审查,刻在骨子里,这是做一个律师工作最基本的严谨。」
- **铁律本身**:法律审查/填表/下任何结论前,必须**亲自 `read_file` 把该合同整篇 OCR 原文(含全部附件)从头读到尾、读懂每条的语境与语义**。`禁止`用以下任何一种代替通读:① subagent 的提取报告 ② `grep`/`search_files` 命中单行 ③「这套合同我见过、大概是这样」的印象式推断。源头(读原文)必须在自己手里——这与「三角色分工·法律审查动作A不外包」「第0步·审查第一性原则」是同一条骨架,本条把它提到全局第一位。
- **🔴 批量场景是这条铁律最容易失守的地方(必须正视的失效模式)**:一次做 4+ 份合同时,注意力被「填表格式、行高、防 subagent 超时、跨表联动」分散,逐字通读这一步会**悄悄退化**成「提取报告说啥我核个大概」——人不会觉得自己跳读了,但判断的地基已经空了。**越是批量、越要顶住,每一份都亲自从头读完,不因为是第 3 份第 4 份就打折。**
- **自检信号(出现即说明我没真读)**:用户就某条款问一个具体问题(如「这里能不能推算」「这个填空是什么意思」「依据是什么」),我**一回原文、30 秒就核出答案**——这恰好证明答案一直在原文里明摆着,**之前没去逐字读**。凡是「用户一问、回原文秒答」的,根因都是当初没通读,不是题目难。
- **没真读的两类典型产物(2026-06-22 世茂高中物业实证,均在 ⑤b 详述)**:① 因果方向写反(9.1/10.1「物业违约连带触发租赁解除」——原文是单向「租赁终止则物业终止」);② 选填留空 `/` 当真实备选项论证(「填空额取高」)。两个都是「没读懂原文就下笔」的直接产物,逐字读过绝不会发生。
- **逐字通读会主动捞出选择性审查漏掉的真问题(同日世茂物业实证)**:亲自通读两份物业全文后,发现 K列漏审了 ① 高中物业 8.3/8.4/8.5 甲方违约责任(双倍保证金赔偿等,**对乙方有利**)② 6.2/6.3 甲方可转让+「乙方15日内不配合签转让协议视为同意+甲方可解约」(沉默视同意,**对乙方不利**)③ 3.1.3 乙方违约全部保证金作违约金——挑审/靠提取报告时全漏了。**逐字读不是慢,是把本该发现的风险真的发现。**
- **落地**:续做/校对/交付前,凡涉及对某合同下法律结论,先确认「这份我本人逐字读过整篇原文了吗」;没有就先读,OCR 没有就先 OCR(扫描件无文字层走 tesseract,见 Pitfall 4)。读完再走「整合质询三对撞」「⑤b 法律结论核证」收口。
---
## ⚠️ 铁律:模版差异 ≠ 法律风险(Maggie 2026-06-16 确立)
**法律审查 和 模版比对 是两件性质完全不同的事,绝不能混为一谈:**
| | 法律审查(动作A) | 模版比对(动作B) |
|---|------------------|------------------|
| 回答的问题 | 合同**本身**有没有法律风险 | 现实情况 vs **内部合规要求**差多少 |
| 参照系 | 法律 + 司法实践 | 客户的标准范本 |
| 做法 | 当作**一份新合同全面审** | 中性陈述差异 |
| 性质 | 法律风险判断 | 合规差距说明 |
- **不能用"和模版有无差距"代替"有无法律风险"**。模版比对的目的是让客户了解现状与内控标准的差距,**不能作为合同本身法律风险的判断依据**。
- 一份合同可能**完全符合模版却仍有法律风险**(条款歧义、引用失效法规、约定履行不能的义务——模版覆盖不到);也可能**大幅偏离模版却无实质法律风险**(纯商业安排或措辞不同)。
- ❌ 旧做法里隐含的等号"模版有、本合同没有 = 风险"是**错的**,已废止。
- 汇总表中"法律风险"信息(动作A产出)与"模版差异"信息(动作B产出)**分列**,并注明两者性质区别,避免下游把合规差距误读为法律风险。
→ 完整审查框架见 `references/independent-legal-review-framework.md`(八维框架),模版比对方法论见本文「模版对比方法论」节。
---
## ⚠️ 核心工序:填表前的「整合质询」(Maggie 2026-06-17 世茂提成教训确立,对治"信息在手却没整合")
**这是我主审的必经工序,不是可选项。** 病灶诊断(必须正视):提成漏判、违约金摘单句,根因都**不是信息没拿到**——提取报告早标了"提成比例%空缺"、合同里违约金兜底句白纸黑字写着。错在**读到了分散的信息,却没把它们对撞成完整判断**就直接填表了。光靠"记得仔细点"防不住,状态一松就漏。所以把"整合"从脑内一闪念,固化成填表前的强制动作。
### 做法:每个关键字段进表前,先过「三对撞」
对**金额、面积、期限、违约金、解除权、优先权、续租、保证金**等每个要进表的关键字段,填之前必须主动问三句、并在脑中(或主审清单里)确认一遍才能落笔:
1. **空缺对撞**——这个数额/比例/期限,原文对应的**填空位真的填了数额吗**?还是 `/`、空白、"待定"、"另行约定"?
- 空缺 → 该机制实践中不适用,按"实际如何"写,不照搬字面(提成栽点:比例空缺=提成不适用=实际按保底)。
- ⚠️ **反向陷阱:下"留白/未约定"结论前,必须穷尽 正文条款 + 全部附件 + 补充协议 三处出处,别拿"我提取的那一处没写"当"全合同没约定"(2026-06-18 世茂高中租赁2028租金教训)**。世茂栽点:高中租赁(3023双签版)附件三只约定了 2026/1–2027/12 保底租金,提取只读了附件三 → 表里记"2028年度第3年留白";实际**正文第3.1条**已明确约定 2028 年度:不含税 **6,689.17 元/月**、含税 **7,291.2 元/月**(税率9%)、或营业额2%提成两者取高。是 Maggie 截图正文第3.1条才捞回来的。错因:商业Mall合同金额信息**正文与附件双向分布**——附件三按年列租金却漏了第3年,正文3.1条反而把全程(含第3年)写全了。这与本 skill "金额数字常在附件,正文条款只定规则"的经验**互为补充、不可偏废**:附件可能有**时间/范围缺口**由正文补全,正文也可能只定规则把数额甩给附件——两个方向都要查。
- 做法:任何"留白/空白/未约定/第X年缺"落笔前,回 OCR 原文把**正文对应条款 + 每个附件 + 补充协议**都 `grep` 一遍(搜该费用/金额关键词与年度),三处都确认没有,才能记"留白";一处有就照实补,并按 4d 把数字来源标到**真实出处条款号**(如"正文3.1"而非"附件三")。补回的数额仍走金额数学交叉验证锁真值(不含税×(1+税率)=含税、单价×面积=不含税、税金/不含税=税率、对比相邻年度递增率是否合常理)。
2. **跨条款对撞**——这个字段在**别的条款**有没有被限定、修改、加例外、设前提、做衔接?
- 违约金:有没有"守约方/违约方"对等表述?有没有"不足赔偿的赔全部损失"兜底?(万达栽点:摘"2个月"漏了兜底全赔+对等适用)
- 期限:物业期限 vs 租赁期限对不对得上?(世茂青少物业2024/3 vs 新租赁2025/12)
- 解除权/优先权:正文说有,附件/补充协议有没有改掉、放弃掉?
3. **字面 vs 实际对撞**——合同这么"写",**实践中实际怎么执行**?字面机制会不会因某个空缺/前提不成立而落空?
- "两者取高"但提成比例空白→取高落空,实际只有保底。
- "可续租"但通知期已过/条件未成就→续租权实际已丧失。
4a. **跨副本对撞**——同一项目里若有**多份同一套标准格式合同**(如世茂青少+高中都是世茂52+格式、万达各校区同范本),**同一条款号的文本必须逐字相同**。提取后若发现**同一条款在两份副本里数值/表述不一致**,这**几乎必然是 OCR 错误**,不是真实差异——**立即回原图核,绝不把伪差异写进表**。(2026-06-18 世茂6.4装修违约金教训:青少 OCR 读"十倍"、高中 OCR 读"1倍",我把"青少10倍/高中1倍"当真实差异写进 K列还标"青少畸高"——其实两份同款合同6.4逐字相同,青少那行 OCR 是整行乱码,"十"是"1"的误识。同一范本同条款不一致=红灯,不是发现。)"十↔1""〇↔0""日↔目"等也是 OCR 高混淆对,和 ‰↔% 同等警惕。处置同费率符号:双跑交叉→不一致即裁图放大、`MEDIA:` 发 Maggie 肉眼终判,不在两个机器结果里挑一个。
- **🟢 反向建设性用法:同范本逐字相同特性可「补回」某份 OCR 丢失的字段,不止「揪错」(2026-06-22 悦拾光实证)**:当一份合同某关键字段被**页间断裂/污渍/整行乱码**吃掉、双跑裁图都拿不到时,回它的同范本兄弟合同核同一条款号——既逐字相同,兄弟份的值即这份的真值。实证:悦拾光一期租赁30.3逾期付款违约金率正好卡在第12页末「每逾期一日甲方有权按拖」断行处、费率数字消失在页间,各 psm 裁图都补不到;扩租合同(同星展模板)30.3 OCR 完整「按拖欠金额【3】%…逾期超【7】日停水电」——同范本同条款号,一期那缺口即【3】%。**比裁图发 Maggie 更省一步**(自动闭环,不必劳烦用户看像素)。前提同 4a:必须是**确认的同一套范本**(条款号体系、措辞结构逐条对应),补回数额仍走金额数学交叉验证/兄弟份二次确认。「跨副本对撞」完整双向用法:**不一致→揪 OCR 错;一份缺→拿兄弟份补**。
4b. **倍数/比例先换算绝对值再定级(别被大数字唬住)**——违约金"X倍日租金""X%"等,**必须乘出每天/每月的绝对金额,放进合同语境判断高低**,不凭倍数大小拍脑袋。世茂6.4:装修期是免租期,按营业期日租金折算——1倍≈1,100元/天=督促按期开业的常规违约金(**不构成风险点**);若真10倍≈11,000元/天=一天顶三分之一月租金,才叫畸高。**定级看绝对值与语境,不看倍数数字本身大不大。**
4c. **租赁违约金/保证金一律换算成"几个月月租金"进表(Maggie 2026-06-18 世茂确立)**——租赁合同的**保证金、违约金**等金额,进 H列/K列时**必须同时给出"=X个月月租金"**,让违约金是否过高一目了然、便于横向比对。物业合同同理换算成"X个月管理费"。
- 换算基数:租赁用**月(保底)租金**(14.2"平均月租金"则按租期加权平均月租算);物业用**月管理费**。
- 🔴 **分母陷阱:月租金 = 年租÷12(或半年租÷6),别误把半年租/全年租当分母(2026-06-22 人民中路实证,格式校对揪出)**。栽点:押金39,730元,月租金=119,190.75÷6=19,865元,正确换算≈**2个月月租**;我误用半年租金当分母算成"0.33个月月租"(39,730÷119,190.75=0.33,实为"0.33个半年期租金")。做除法前先把分母统一成**月**租金,再除。
- 实例(世茂):青少租赁保证金66,230元≈**1.95个月**月租;14.2违约金(平均月租3倍或等额取高)=101,685元=**3个月**月租。高中租赁保证金13,888元=**2个月**月租;14.2违约金=20,832元=**3个月**月租。青少物业履约保证金12,432.72元≈**3个月**管理费;高中物业6,944元=**2个月**管理费。
- 写法:金额后加括号注换算,如"租赁保证金:66,230元(≈1.95个月平均月租)""根本违约金(14.2):平均月租3倍或等额保证金取高=101,685元(3个月月租)"。这是金额提取的**标准动作**,不是可选。
4d. **金额条款号标"数字真实出处",不标正文"请见附件X"的指引条(Maggie 2026-06-18 世茂物业逐条纠正确立)**——给金额加条款号方便核对时,必须标**数字实际写在合同哪一条**,而不是正文里那句"具体金额请见附件一"的指引条。
- 世茂栽点(被 Maggie 逐条纠正4次):履约保证金我标"3.1.1"(正文指引条)实际数字在**附件一1.1**;管理费标"3.3"实际在**附件一第2条**;装修押金标"3.4.1"实际在**附件一3.1**;水电费标"3.6"实际在**附件一4.1**;租赁保证金标"5.1"实际在**附件三2.1**。世茂这类商业合同的金额数字几乎全在附件(附件一费用表/附件三租金表),正文条款只写"详见附件X"。
- 做法:标条款号前,回原文确认**数字落地在哪一条**——搜到正文"请见附件X"就继续往附件里翻,找到真正写着数字的那一条(如"附件一第2条""附件三2.1")再标。一翻就到,才是方便核对。
- 条款号格式忠于原文编号体系:世茂用阿拉伯数字(附件一1.1、附件三2.1),万达用中文章节(四、五、第四条一款)——不把万达的"四"硬改成"4.1",各合同标各自的原生编号。
4e. **分档条款先判"本租户属哪一档",都不属=该条不适用,不照搬档位数字(Maggie 2026-06-18 世茂质量保证金确立)**——合同按业态/类型分档约定金额时(如质量保证金分"充值类≥8万/零售1万/餐饮留空"),**必须先判断本租户(新东方=教育培训)属于哪一档**。
- 世茂栽点:质量保证金附件一1.2分三档(充值业务为主≥8万、零售商品`/`留空、美容美发餐饮`/`留空),新东方是**教育培训**机构——三档**都不属于**。我却把"≥8万(充值类)/1万(零售)"照搬进 H列,既误导(像是本合同要交8万/1万),其中"1万"还是 OCR 把零售档留空`/`误识成"1"。
- 正解:本租户不属任何档→**该条对本租户不适用,整条不列**(与"提成比例空白→不适用""装修违约金属常规→不列"同理)。绝不照搬不对应的档位数字。
- ⚠️ **业态推理优先于 OCR 字符核对**:当"本租户不属任何档"已能凭业态推理判定时,不必纠结某档的留空符号到底是`/`还是"1万"——那是"零售档"的填值,新东方本就不在零售档,符号是几都不影响"不适用"的结论。先用语境(业态归类)判适用性,再决定要不要核字符。这是"字面 vs 实际对撞"在分档条款上的落地。
4. **单位/量级对撞**——费率、金额、面积的**单位和量级**是否合理?OCR 文本的符号高度不可信,必须做常识量级核验。
- **‰ vs % 是 OCR 重灾区**(2026-06-17 世茂租赁14.1教训):扫描件 OCR 常把千分号 `‰` 误识为百分号 `%`。世茂4份合同 OCR 全部把"千分之2"识别成"2%",被 Maggie 当场抓出。
- **量级常识闸门**:日费率写进表前先口算年化——每日 X% × 365。**年化超过约 100% 就该警觉**(每日2%=年化730%,荒谬;每日千分之2=年化73%,合理)。逾期违约金/滞纳金日费率,正常落在 万分之几~千分之几(年化 18%~73%),**见到"每日1%、每日2%"先疑 OCR 误识,回 PDF 原件核符号**。
- 同理核:折年化标注别算错(0.5%/日=年化182.5%,不是18.25%;万分之5/日才是年化18.25%)。
- **OCR 符号判不准时的处理**:扫描件低质量 OCR 对 ‰/% 这种小符号经常判不清,机器反复试无解→**标注"OCR数值,单位以PDF原件为准",不武断定值**;能看清原件就看(局部裁剪放大),看不清就请 Maggie 核(她看过原件)。绝不拿可疑的 OCR 符号当确定结论填进交付物。
- **主动双跑核符号,不止"怀疑"(2026-06-18 世茂物业9.2实证)**:对存疑费率符号别停在"先疑 OCR"——主动跑**两种方法**交叉验证:①整页 OCR;②把该费率行**裁出来放大 3–4 倍单独重 OCR**(tesseract chi_sim+eng 多 psm)。**两次结果不一致 = 已证明机器判不准,立即升级人工**,绝不在两个机器结果里挑一个填表。世茂实证:青少物业9.2 整页读 `0.5%`、裁图重读 `0.5‰`;高中物业9.2 两次分别读 `1%` 和 `1‰`——三跑三种组合,铁证 OCR 不可信。常见误识:`%` 被读成"吃",`‰` 与 `%` 在不同 psm 间反复横跳。
- **升级人工要带"放大裁图",不甩空问题(2026-06-18 确立)**:机器判不准时,把那一行费率裁出、放大、存 PNG,用 `MEDIA:` 发 Maggie 做肉眼终判(符号就在数字后那一个字符),而不是空口问"是%还是‰"。这是"不把校验责任推给用户"在符号核对上的落地——能做的双跑交叉先做尽,剩下唯一机器解不了的一个像素符号才交人。✅ **vision_analyze 已配好可用(魏玮 2026-06-22 配置,实测能准确读出渲染图的红色标记/文字截断/版面)**:现在符号判不准时**先自己 `vision_analyze` 看裁图终判**,能自核就不必裁图发 Maggie;自核仍拿不准的像素级符号才交人。这是从前"vision provider 未配、只能裁图发人"的升级——主路径变为自核,发人是兜底。命令级配方见 `references/ocr-rate-symbol-verification.md`。
- **金额用数学交叉验证,构成自洽 = 不必看图、不必问人(2026-06-18 世茂高中物业管理费实证)**:当 OCR 的**合计/总额不稳**(同一"合计"两跑读成 1347、8472)但**构成项稳定**(不含税 3275.42 + 税金 196.53、单价 9.43×面积 347.2、税率 6%),用**算术关系反推**就是最硬的裁判——比看像素更可靠,且**全自动无需人工**。三条恒等式当探针:①`不含税 + 税金 = 含税合计`(3275.42+196.53=3471.95,自证"合计1347"是误读)②`单价 × 面积 = 不含税`(9.43×347.2≈3274,与 OCR 不含税吻合)③`税金 / 不含税 = 税率`(196.53/3275.42=6.00%,精确命中)。三式互相咬合且与多数稳定 OCR 值一致 → 锁定真值,OCR 那个不稳的总额直接弃用。**适用面**:凡"分项 + 合计"结构(管理费、租金保底=不含税+税金、押金=N月租金)都先做构成自洽核验,再决定信不信 OCR 的总额。比量级闸门更进一步:量级闸门排除荒谬值,数学交叉验证直接算出真值。
### 铁律
- **三对撞过不了,不填表**。任一对撞发现问题,回原文核实清楚再落笔。
- **优先用提取报告里 subagent 已标的"空缺/待核"信号**——它标了"提成%空缺"我却没用,是整合失职,不是它没干活。subagent 标的每个"待核/空缺/乱码"都必须在三对撞里被显式处理掉,不能晾着。
- **判断过程不写进交付物**(Maggie 2026-06-17):三对撞是我审查时走的内部工序,汇总表/结论里**只写整合后的最终结论**(如"营业期保底租金"),不写"因提成空缺所以不适用"这类推理过程。过程留给主审清单,交付物只留结论。
- **核实痕迹不写进交付物**(Maggie 2026-06-18 世茂确立):我**自己的核实过程**——"经PDF原件核实""经数学交叉核实""关键数字均经PDF原件+数学交叉核实""(目录XX系扫描漏识L)"等——一律**不进交付物**,删除。客户只需看结论,不需要知道我怎么核的。核实是我的内部责任,留痕在工作记录/主审清单即可。这与"判断过程不进交付物"同源。世茂栽点:青少/高中物业K列写"(9.2,经PDF原件核实)"、高中物业末尾整段"〔关键数字均经PDF原件+数学交叉核实…〕"注脚,被 Maggie 要求全删。
- ⚠️ **清理核实痕迹(及任何统一性清理/修正)必须全表扫描,配对合同往往漏一处(2026-06-22 世茂确立)**:青少↔高中、租赁↔物业的同款条款常含同一句痕迹,删一处极易漏掉配对那份。实例:Maggie 手删青少物业 I8 的"经原件核实",却漏了高中物业 I14 的同款痕迹("逾期缴费违约金1‰/日(9.2,经原件核实)"),由小Maggie 补扫全表清掉。续做接手/交付前**用脚本全表 grep 痕迹关键词**(经原件核实/经原件/经PDF/经数学/均经…核实/核实〕)确认 0 残留再发——别只清用户点名的那一处。这是「同口径修正必须扫全表对齐」在清理动作上的同一抓手。
- **需客户核实的内容整条标红**(Maggie 2026-06-18 世茂确立):风险点/备注中**需要客户去核实或确认某个事实**的内容,**整条标红**(红色 FFFF0000),方便客户一眼识别待办。
- **判据(标红 vs 不标红)**:①只标"**需客户去核实/确认事实**"的——如"服务期衔接需核实""2028年度计租标准建议签约时补明或确认";②**提示类不标红**——"提示按时缴费""提示知悉""提示自行投保"等是提醒乙方履约注意,不是要客户核实事实;③**我已核实的不标红**(且核实痕迹要删,见上条)。
- **范围:整条标红**(从该条编号到句末整条,不是只标"需核实"那半句)。Maggie 先要"只标需核实那句"、后改为"整条标红"——以**整条**为准。实例:青少物业第1条(服务期衔接需核实)、高中租赁第9条(2028租金留白需确认)、整体分析第6点(衔接需核实)三条整条红色。
- ✅ **标准做法(2026-06-18 世茂最终验证成功):openpyxl 写富文本红色 → WPS 打开另存为 xlsx → Excel 不报错且红色保留**。这是"单元格内某条标红、其余黑、且 Excel 兼容"目前**唯一跑通**的路径,Maggie 已亲验 Excel 正常打开+红色在。两步缺一不可。
- **技术实现**:openpyxl `CellRichText` + `TextBlock(InlineFont(rFont="微软雅黑", sz=10, color="FFFF0000"), 整条文本)`,黑色段 `color="FF000000"`,按 `\n` 切分逐行判断、整行染色保留换行。务必带 rFont/sz 与全表一致(微软雅黑10),否则富文本丢字体。
- ⚠️ **为什么必须 WPS 另存这一步**:openpyxl 把单元格写成 `inlineStr`+`CellRichText`(`<is><r><rPr>…`),不合 Excel 严格 OOXML 校验 → Excel 报"部分内容有问题/需要修复",点"修复"会**丢弃富文本→红色一并丢失**。试过手改 XML(修 rPr 子元素顺序 rFont→charset→family→sz→color、补 `charset=134`/`family=2`)**都没用**。WPS 容错宽松能正常打开,**且 WPS 另存会把整个文件重写成规范格式(inlineStr→sharedStrings),消除所有不合规处**——这才是 Excel 不再报错的真正原因。验证规范化成功的标志:另存版 xlsx 里 `xl/sharedStrings.xml` 存在(openpyxl 原版没有)。
- 🔴🔴 **富文本红必须是 openpyxl 写入的「最后一步」,中间任何 load_workbook→save 都会把红打回纯文本(2026-06-22 悦拾光实证,多次返工教训)**:openpyxl 的 `CellRichText` 在「`load_workbook` 重新加载→`save`」一个来回后**退化成纯字符串**——哪怕这一轮只改了别的格、甚至只改了行高没碰富文本格,红色照样全丢。悦拾光栽点:H5/H6 写好富文本红(9处)后,又去 `load_workbook` 改 K列定性错误、改行高,每改一轮存一次,红色就被打回纯文本一次(红run 9→0),反复三次。**正解:把所有文本编辑(改错别字、补条款、改措辞、改行高 row_dimensions)全部做完定稿后,在同一个脚本的最后一段一次性写富文本红 + `save`,之后绝不再 `load_workbook`**。写完立即用 `zipfile` 读 `xl/worksheets/sheet1.xml` 数 `FFFF0000` 验证(不要用 openpyxl 读回验证——读回这个动作本身无害,但养成「写完只用 zipfile 验、不 load」的肌肉记忆更稳)。顺序铁律:①所有纯文本编辑→②设行高→③最后写富文本红→④save→⑤zipfile验红run→⑥WPS另存/x2t渲染。
- 🔴🔴 **二次编辑已标红(WPS规范化)的 xlsx:绝不用 openpyxl 重存——它会把红色全毁掉(2026-06-18 世茂实证)**。WPS 另存后的好文件存储用 `sharedStrings.xml` + 富文本红 `<r>` run;一旦 `openpyxl.load_workbook → 改 → save`,openpyxl 把整表打回 `inlineStr`、**3 处红色 run 直接归零、`sharedStrings.xml` 消失**,Excel 又报"需要修复"——等于把 WPS 救回的成果一键作废。**改一个字都不能用 openpyxl 存。**(本 session 实测:openpyxl 改完 H11 后红色 3→0,结构 sharedStrings→inlineStr,幸亏有 WPS 好基线备份才回得来。所以**改前先把 WPS 好版本另存 `_bak_` 备份**。)
- 🔴🔴 **建造阶段(WPS 规范化之前)同样会丢红:每一次 `load_workbook → save` 循环都把 CellRichText 悄悄打回纯字符串,哪怕这次只改了别的格 / 只设了行高、根本没碰富文本格(2026-06-22 悦拾光实证,连丢两次才定位)**。机制:openpyxl 一旦重新加载含富文本的工作簿再 save,所有 CellRichText 一律退化成 str、红 run 归零。所以**富文本红必须是整个建表流程的最后一步**:① 先在同一个脚本里把所有行高设好、所有黑字内容写完;② **最后**才写 CellRichText 红 run;③ `save`;④ 此后**绝不再 `load_workbook`**——要渲染 / 上传直接拿这个文件,要改内容就回到①把整段脚本重跑(含最后写红),不在已写红的文件上二次 load。**验证红色只用「只读 zip 数 `FFFF0000`」**(`zipfile` 读 `xl/worksheets/sheet1.xml` 或 `sharedStrings.xml`),**绝不用 `load_workbook` 复核**——一 load 一 save 红就又归零。典型错序(先写红 → 再 load 设行高 → save)= 红照样没,本 session 正是这样连丢两次。
- ✅ **正解:在 `sharedStrings.xml` 的 XML 层做外科手术,红 run 一个字不碰**。流程:①`zipfile` 解压 WPS 好文件到临时目录;②`sheet1.xml` 里每个格子 `<c r="H11" t="s"><v>45</v></c>` 的 `<v>` 就是 **sharedString 索引**——据此把"要改哪个格"翻成"要改第几条 `<si>`";③lxml 打开 `xl/sharedStrings.xml`,**只替换目标 `<si>` 里的 `<t>` 文字节点**(纯文本格直接重写单个 `<t xml:space="preserve">`;含红 run 的格**只改黑色 `<r>` 的 `<t>`**,红色 `<r>`(带 `<rPr>…<color rgb="FFFF0000"/>`)原样保留);④重新打包。
- ⚠️ **重新打包必须把 `[Content_Types].xml` 放 zip 第一项**(其次 `_rels/`),否则 LibreOffice 等严格解析器报 `source file could not be loaded`(Excel/WPS 宽容,但别赌)。用 `zipfile.ZIP_DEFLATED`,逐文件 `zf.write(full, arc)`。
- **删一条红色风险项 + 顺移编号**(如已核实的"留白"风险撤销 → 整条删):lxml 里定位目标 `<r>`(按 `<t>` 文字开头如 `"9. "` 且含关键词)→ `si.remove(目标<r>)` → 遍历后续 `<r>` 的 `<t>` 把 `"10. "→"9. " "11. "→"10. "` 前缀顺移,保持 1–N 连续。删红 run 时红色计数会随之 −1(删的就是那条红)。
- **改完五查**(本地验不了 Excel,这五项是能自动做的最强保证,过了再发 Maggie):①`xl/sharedStrings.xml` 仍在;②红色 run 数 = 改前预期(删 1 条红就 3→2,没删就不变)——用 `re.findall(r'rgb="FFFF0000"', ss)` 数;③`zipfile.testzip()` 通过 + 所有 `.xml/.rels` 部件 lxml 能 `fromstring` 解析;④目标格文字已更新、编号 1–N 连续、旧表述("留白/未约定"等)全表 `grep` 0 残留;⑤与 WPS 好基线**部件清单同构**(`set(namelist)` 差异仅空目录条目可接受)。一键跑:`scripts/edit-redmarked-xlsx.py --verify <文件> --baseline <WPS好基线>`。
- **最终仍交 Maggie 用 Excel 肉眼终判**(同"本地验不了 Excel"铁律),但上述五查全过再发,不裸交。完整可复用实现(解压→按 si 索引改 `<t>`→删 run 顺移→规范重打包→五查)见 `scripts/edit-redmarked-xlsx.py`。
- 🔴 **「红色run数」五查②不是「标红条数」,别拿它当颜色没动坏的护身符(2026-06-22 世茂确立)**:`red_run_count()` 数的是 `rgb=FFFF0000` 串的出现次数,**等于带红 rPr 的 `<r>` 个数**,不等于「有几条风险被标红」。隐藏陷阱:某些长单元格(世茂 K8 青少物业、K11 高中租赁、A16 整体评价)在 WPS 规范化时被整格染红——**该格每个 `<r>`(标题/每条/空行)都带红 rPr**,K8=8 红run、K11=15、A16=20,全表实际红run≈47,而非交付物语义上的「6 处标红提示」。我连续几次编辑都看「红色保持6 ✅」就放心,那个 6 只是凑巧(H5/H8/H11/H14 四个单纯提示格各1 + 别处)——它**根本不反映三个长红格的真实状态**。教训:① 改前先 `--show-si <idx>` 看目标格的 run 结构,确认它是「纯文本格 / 单红run / 整格全红」哪一种,再决定怎么动;② 含红 run 的格做编辑/插入新条时,新增 `<r>` 会**继承所在格的染色基调**(整格全红的格里插的新条也会是红的),不想红就显式给新 run 的 rPr 设黑 `<color rgb=FF000000/>`;③「整格泛红」是否要修属格式返工、范围大,**先渲染发 Maggie 确认她 Excel/OnlyOffice 里看到的是黑字还是红字再决定**,不自作主张大改已验收过的格。④ 自己看不了图时用**像素分析绕过 vision**:`PIL`+`numpy` 读 x2t 渲染的 PNG,按 `(R>120)&(G<90)&(B<90)` 数红字像素、`(R<90)&(G<90)&(B<90)` 数黑字像素,逐水平带判主色,能量化「整格红 vs 黑字为主」——比纯靠 XML 推断更接近用户实际所见(本次实证 K8 区域红字带6 vs 黑字带13,红黑混杂而非纯红)。
- ⚠️ **本地无法自验 Excel 行为,别反复甩"修好了"让用户当测试员**:x2t/LibreOffice 在本环境都不能可靠复现 Excel 的严格校验(LibreOffice 连干净版都报 "source file could not be loaded",是环境问题非文件问题,不可用它验证)。本 session 连续 4+ 次"还是不行"就是反面典型。**没有能复现失败的工具时,先说清"我这边验不了 Excel",把带富文本红色的版本发给用户、请其 WPS 另存,不要断言成功。**
- **给用户的话术**:标好红后——"文件红色已标,但 openpyxl 生成的格式 Excel 会报'需要修复'。请你把这个文件用 WPS 打开 → 另存为 xlsx,Excel 就正常了、红色也在。另存后发我,我替换到 Nextcloud。" ⚠️ 被另存的必须是**带富文本红色那一版**(别拿中途"去富文本"的版本去另存,那样没红色)。
- **更省事的退路(嫌 WPS 那步麻烦/纯自动化场景)**:纯文本前缀 `【需客户核实】`/`❗待核实:`,整条黑字零格式,Excel 绝不报错——但没有红色高亮。Maggie 要红色就走 WPS 另存法。
- 完整排查全过程见 `references/openpyxl-excel-richtext-pitfall.md`。
- 这道工序对治的是"上下文整合",与「整款通读不摘单句」「合同间整体审查」是同一方法的三个抓手:整款通读=条款内不漏要件,整体审查=条款间不漏关联,整合质询=填表前强制对撞收口。
### ⚠️ 法律风险须标注对应合同条款(Maggie 2026-06-17 万达打样确立)
每一条法律风险**尽量标注其对应的合同条款号**,方便 Maggie 或客户在需要时回原文核对,使风险结论可溯源。
- **明确条款型**(合同里确有该条款)→ 直接标号,嵌在描述里:如「装修期满须恢复原状(第五条3款)」「违约金仅2个月租金(第九条1款)」「续租通知期 第八条3款"三个月" vs 第十条1款"一个月"」。
- **缺失型风险**(合同里压根没有某约定,如无办证退出通道、无任意解除权、无查封拍卖衔接条款)→ **不硬凑条款号**,写清"第X条仅有…,无…"或"合同无…条款",点出"在哪个条款本该有却没有"。如「第八条仅有协商解除/期满终止,无任意解除权」。
- 标注方式:**在风险描述里嵌入条款号(括号或行文)**,不另起统一后缀(Maggie 已确认此方式)。提前解除路径等结论也同样补出处(如「协商解除(第八条1款)」「押金不退(第五条2款)」)。
- **铁律:条款号必须核对合同原文逐条确认,绝不臆造**。标注前先读 OCR 原文 `.md`,把每条风险 → 原文条款匹配一遍;写入后用脚本验证关键条款号是否到位。
- 法条(民法典X条)仍按〔待核实〕处理,与合同条款号是两回事:合同条款号是本合同内部定位,法条编号是外部法律引用。
### ⚠️ 金额/费用栏(H列)也标注对应条款号(Maggie 2026-06-18 世茂+万达确立)
K列法律风险标条款号的同理,**H列每个金额/费用项也标注其在合同中的对应条款号**,方便 Maggie/客户回原文核对。这是 H列金额提取的**标准动作**,与「4c 换算月租金」一起做。
- **格式按世茂来,简单明了**:金额后加括号注条款号,如「租赁保证金:66,230元(5.1,附件三;≈1.95个月平均月租)」「管理费:含税4,144.24/月(3.3,附件一)」「根本违约金(14.2):…」。
- **⚠️ 条款号忠于各合同原文的编号体系,绝不统一臆造**:
- 世茂租赁/物业用**阿拉伯数字**:保证金5.1、保底租金5.2、结算周期5.2.2、违约金14.2;物业履约保证金3.1.1、质量保证金3.1.2。
- 万达租赁用**中文章节**:租金「四」、押金「五」——原文就是「四、租金及支付方式」「五、租赁押金」,**不能硬改成「4.1」造成与原文不符**。
- 万达物业用「**第四条**」:物业费/能耗第四条一款、垃圾清运/装修保证金第四条二款。
- 「格式按世茂来」指的是**括号注法简洁**,不是把所有合同的编号都改成阿拉伯数字——编号本身必须能在该合同原文里查得到。
- **金额数字常在附件,正文条款只定规则 → 双层定位**:世茂保底租金正文5.2只写「标准见附件三」,具体数额在附件三 → 标「(5.2,附件三)」。同理保证金「(5.1,附件三)」、管理费「(3.3,附件一)」。
- **同范本不同份,条款号可能不同,必须各自核**:青少物业管理费在 **3.3**、高中物业管理费在 **3.2**;青少物业装修押金 **3.4.1**、高中物业 **3.3.1**——别因为是同一套世茂物业格式就套用同一条款号。逐份回原文 `grep` 核条款标题。
- **铁律:条款号必须回 OCR 原文逐项核实,绝不臆造**(同 K列法律风险条款号铁律)。
### ⚠️ 金额/费用栏(H列)推算每期支付截止日;推不出则总结+红色提示(Maggie 2026-06-18 世茂确立,确认为**通用规则**)
> 🔵 **通用规则(Maggie 2026-06-18 明确)**:「付款安排 + 无法推算时红色提示」是**所有租赁/物业类合同梳理的标准动作**,不是世茂个案——以后**每一份**租赁/物业合同进 H列都要做。与「H列标条款号」「4c 换算月租金」一并,构成 H列三件套。
H列不只列金额,还要处理合同约定的**付款时间**,让 Maggie/客户一眼知道下一笔哪天该付。**分两条路径,按"起算日能否确定"分流**:
- **路径A(起算日确定)→ 推算具体支付截止日**:把抽象付款规则("预付制""结算周期六个月""上个结算周期最后一个月15日前支付")逐期算成**每一期的具体支付截止日**。**尚未到支付时点的(付款截止日 ≥ 审查当日)整条标红提示**(红色 FFFF0000,标红技术走前述「openpyxl 写富文本红 → WPS 另存规范化」/「sharedStrings XML 层加红 run」法)。
- **路径B(起算日不明/推不出)→ 总结合同写了什么 + 红色提示约定不清**:见下方"🔴🔴 推算不出来就别硬推"条。**绝不硬凑确定日期。**
- **推算前先定起算日**:营业期/计租起算日决定全部结算周期的划分。**装修期是否计租、营业期从哪天起算,必须回原文+向 Maggie 确认,不擅自假设**(世茂高中:Maggie 确认起租日=2026/1/1,含装修期也计租)。起算日错→整串付款日全错→误导付款。
- ⚠️ **"租赁期限X年,自A至B"——A到B的日历跨度可能 > X年,免租装修期常不计入约定的X年租期(2026-06-22 人民中路 Maggie 确立)**。人民中路合同写"租赁期限5年,自2025/3/1至2030/4/30",但该区间日历跨度实为5年2个月:前2个月(2025/3/1–4/30)是免租装修期、**不计入5年**,真正5年计租期是2025/5/1–2030/4/30。识别三个别混的概念:①日历区间(A至B) ②约定租期年限(X年) ③计租期(起租日起算)。G列分行写清三者,免租期单列并注"不计入X年租期、物业费由乙方承担"。Maggie 原话:"免租期没有算到租期里"。注:商业租赁的"租赁期限"措辞常与免租期叠加导致 OCR/字面易误读,是否计入须回原文+问 Maggie。
- **日期是硬事实,用代码算不手算**:按结算周期逐期划区间,套合同付款条款算每期截止日(如"上个结算周期最后一个月的15日前")。算完**先把每期推算结果列给 Maggie 核对合同解释**(起算日含义、各期付款节点解读),确认后再写进表。
- **标红范围**:只标"付款截止日 ≥ 审查当日"的**未到期期次**;已付/已到期的黑字。基准日取审查当日(如 2026/6/18)。这与「需客户核实内容标红」用同一套红色技术,但语义不同——这里红的是"未来待付款提示"。
- 🔴🔴 **推算不出来就别硬推——退到"总结+提示"路线(Maggie 2026-06-18 世茂反转确立)**:起算日合同没写死、各期具体付款日**确实推算不出来**时,**绝不硬凑一个确定日期**(错的确定日期比"不确定"更危险,会误导付款)。Maggie 原话:"算了,世茂的我也推算不出来。这种推算不出来的,就总结下合同里写的结算周期,以及支付时间。无法推算的,就提示合同约定不清楚,请注意实际支付时间之类的。" 改走两段式:
- **第一段(黑字·照实总结合同写了什么)**:`【付款安排】结算周期X个自然月/一个自然年,预付制(条款号):首期于营业期起租日/交付日支付;其后每期于上一结算周期最后一个月15日前提前支付(遇法定节假日顺延)。`
- ⚠️ **已过期的确定节点不列(Maggie 2026-06-18 世茂青少确立)**:合同明确写了的确定付款节点,**只有付款截止日 ≥ 审查当日(未来/待付)才列**;**截止日 < 审查当日(已过期)的一律不列**——付款安排聚焦"尚未发生、需提醒注意"的,过去的节点占篇幅无意义。世茂青少租赁"第二期保底租金余额335,133.92元应于2026/4/15前支付"——2026/4/15 早于审查日 2026/6/18,**已过期 → 删除不列**(Maggie 原话"这个时间点已经过了,没必要列出")。红色提示里同步去掉对该过期节点的引用(如"及第二期付款日(2026/4/15)"删掉)。判据与"标红范围只标未到期期次"同源:**已发生的不提,待发生的才提(未到期还标红)**。
- **第二段(整句标红·提示约定不清)**:`🔴合同未明确约定营业期起租日/交付日,各期具体付款日无法推算,请按实际营业期起算日/交付日及甲方账单核对支付时间。` 整句红色 FFFF0000,走「openpyxl 写富文本红 → WPS 另存规范化」/「sharedStrings XML 层加红 run」标红法。
- **判据:能确定起算日→推算具体日期(前几条);起算日不明/推不出→总结+红色提示(本条)。** 律师式严谨:宁可标"约定不清、请核实实际支付时间",不给一个算错的确定日期。这与"事实问题不靠文本提取下结论""OCR 缺失数字标〔待核〕不编造"同源——**不确定的事项如实提示,不假装确定**。
- **🔑 客户问"能否推算具体付款日"时,回 OCR 原文核条款原话,不靠汇总表摘要判断(2026-06-22 世茂青少物业确立)**:表里的付款节点是压缩摘要,本身可能语义不全,不足以支撑"能否推算"的判断。Maggie 问青少物业"上一个自然年15日前,是不是12月15日前"——回 OCR 原文核 3.3.3/3.3.4,发现原文**真的只写"上一个自然年15日前"、没有月份限定词**(两处独立一致出现 → 非 OCR 丢字,是合同本身缺月份)。结论:即使起算日确定,光凭"15日前"也定不出哪天 → 约定不清。**calculability 是事实问题,回原文条款原话核,不在表摘要上推。**
- **同范本不同份,付款条款表述可能真实不同(不止条款号不同)**:青少物业(3.3.x,结算周期一个自然年,"上一个自然年15日前"**缺月份**) vs 高中物业(3.2.x,结算周期6个自然月,"上一个结算周期**最后一个月**的15日前"**月份完整**)——同套世茂物业格式,付款节点表述却**真实不同**,青少那份更彻底地约定不清。已比对 OCR 原文确认非 OCR 错。"跨副本对撞"既要防 OCR 伪差异、也要识别真差异,**不能因"同范本"就假设两份逐字相同**。校准一份时回兄弟份核原文:相同才一并改,不同则只改该份(本次只改青少 H8,高中 H14 月份完整、归因正确,原样不动)。
- **"约定不清"的红色提示精准归因到具体条款缺陷,不泛泛说"起算日未定"**:旧提示"合同未明确约定交付日/起算日…"归因不全;青少物业真正的双重缺陷是 ①交付日未写死 ②"15日前"连哪个月都没写。改为点明"合同3.3.3/3.3.4仅约定'上一个自然年15日前',未明确具体月份(如是否为12月15日),且交付日/起算日未写定…"——客户拿表即可对照条款知道是合同本身漏洞。**精准归因 = 客户可操作。**
- 🔴 **"推不出"的第二类成因:付款条款文本本身缺关键限定词(月份/日期锚点),不止起算日缺失(2026-06-22 世茂青少物业确立)**:除"起算日未写死"外,**条款字面缺月份/日期锚点**同样导致推不出确定日,且更隐蔽——表里摘要常把它"脑补补全"掩盖掉。世茂实证:青少物业 3.3.3/3.3.4 原文是"乙方应于**上一个自然年 15 日前**支付下个自然年的管理费"——**"自然年"前缺了月份**(不像租赁合同写全的"上一**结算周期最后一个月**15日前")。字面"上一自然年15日前"语义不完整,存在两解:①脱漏"最后一个月"→应为12月15日;②约定不清。**Maggie 直觉问"是不是12月15日"方向多半对,但合同文本本身没写"12月"这三个字,按律师严谨不能替合同补全**。
- 必查动作:用户问"能不能推算出具体日期"时,**绝不拿汇总表里被压缩过的摘要回答**(摘要可能已把缺失的限定词脑补掉)——必须回 OCR/PDF 原文核该付款条款的**逐字表述**,确认月份/日、起算日是否都写全。表摘要"上一个自然年15日前支付下一自然年"看似完整,原文实则缺月份。
- 处置:缺锚点→仍走"总结+红色提示",且**红提示里如实点明是合同文本缺了什么**(如"合同3.3.4仅约定'上一自然年15日前'未明确月份,请按甲方账单核对"),让客户知道是合同本身没写清、不是我们漏算。是否按解读①直接认定确定日期,属法律判断取舍,**提请 Maggie 定,不自作主张补全**。
- 标红语义:这里红的是"**合同约定不清的待核提示**",落在"需客户核实/确认事实"那一类(见「需客户核实内容标红」判据①),整句标红,与"未来待付款提示"标红并行不悖。
- **整批同套格式合同付款条款逐字相同时,四份文案可成套复用**:世茂青少+高中、租赁+物业四份均"首期于起租日/交付日付、其后每期上个结算周期最后一月15日前预付",只结算周期不同(高中租赁6月、高中物业6月、青少租赁12月、青少物业一自然年)——文案套同一模板改结算周期即可,不必每份从头写。
- **世茂四份付款条款实例**(同套世茂52+格式,付款节点逐字相同):租赁/物业均"首期于营业期起租日/交付日支付,之后每个结算周期的保底租金/管理费于**上个结算周期最后一个月的15日前**提前支付(遇法定节假日顺延)"。结算周期:**高中租赁6个月、高中物业6个月、青少租赁12个自然月、青少物业一个自然年**。
- 这与 4c(换算月租金)、H列标条款号同属 H列标准动作——都是"交付物信息完整、可核对、待办凸显"的 Maggie 偏好。
#### 零散情形 → 提炼专业法律概念(Maggie 2026-06-17 万达打样确立)
- 审查中遇到**零散列举的具体情形**,识别其背后的**专业法律概念**,用概念统领、具体情形作括注,比堆砌情形更专业简洁。
- 租赁场景三类常见(背后是不同制度,**别张冠李戴挂法条**):
- 出租方变更/过户 → **所有权变动**(买卖不破租赁,民法典725条)
- 查封、拍卖(执行/第三人处置)→ **第三人主张权利**(民法典729条)—— 注意:查封≠所有权变动,不能挂725
- 征收、拆迁 → **征收征用**(民法典243条)
- 格式:`专业概念(具体情形举例)`。实例:原写"合同无查封拍卖、出租方变更、征收拆迁的衔接条款(援引725条买卖不破租赁)"(情形零散+725挂错),改为"所有权变动(出租方变更)、第三人主张权利(查封、拍卖)、征收征用等情形未作安排,实操中求偿困难"。
- **法条号默认不写进表格正文**(Maggie偏简洁)——概念用准即可,法条留作内部依据;正文落点回到"实操求偿困难"等实际后果。
### ⚠️ 风险定级纪律:克制,按"实际影响"分级(Maggie 2026-06-17 万达打样确立)
站乙方立场审查不等于把每处瑕疵都往高风险写。Maggie 反复纠正"评高了"。三条定级铁律:
**① 形式瑕疵按"是否实际影响成立/生效/履行"定级,不夸大**
- 形式瑕疵 = 签署日期空白、印章不全、填空未填、落款不完整等。
- 判据:若**关键履行要素已明确约定**(租期起止、金额、付款时间,标条款号)**且合同已实际履行**(《民法典》第490/502条:一方履行主要义务对方接受即成立生效),则纯形式瑕疵评 🟢**低风险**,不评高风险、不写"合同效力存疑"。
- 建议落点:**不渲染风险,落到"建议补正以规范合同管理"**。
- 表述模板:"X空白/未填。鉴于〔关键要素已明确(第X条)+合同已实际履行〕,X缺失不影响合同成立与生效,风险较低,但仍建议明确X,以规范合同管理。"
- 实例:万达"签署日期空白"原评🔴"合同是否有效成立存疑"→ 降🟢低风险。
**② 尽调/核验类事项用操作性"请确认…"提示,不写成"未核验→风险"**
- 适用:权属核验、资质核验、证照查验等"应做、通常已做、只是需确认"的事项。
- 写法:操作性核验提示,**假定通常已做**,措辞平和。如"核验出租权:请确认已核验过甲方的不动产权证明原件,并有复印件存档"。
- 等级:归 🟢 低风险(建议规范类),**不放高风险/须核实区**,不写"无从核验→效力风险"。
- 实例:万达"出租权属未核验(风险)"→ 改"核验出租权:请确认已核验…并存档",归🟢低风险。
**③ 一条风险只讲一件事**——别把一个真问题和一个伪问题捆在一条(会一起被拔高)。万达原把"签署日期空白"+"出租权属未核验"捆成一条评🔴;拆开后各自降级。
**⑤ 责任/违约条款必须整款通读,不摘单句(确认偏误警示,2026-06-17 万达违约救济教训)**
> ⚠️ **前置主规则(合同级第一性原则,非仅违约条款)**:整款通读的前提是**完整通读全文 + 准确把握每个条款的上下文语境与语义**。这不是违约条款的特殊要求,而是审查地基——**整个合同、每一条款**都要先通读、读懂语境再下结论。法律审查第一步必须 `read_file` 把整篇合同 OCR 文本(.md,通常仅20–60KB)一次性读完,**禁止用 grep 命中单行代替阅读**。详见 `references/independent-legal-review-framework.md` 第0步·审查第一性原则(2026-06-18 世茂14.2教训:错误归因"PDF太大不能通读",实测 OCR 文本仅58KB完全可整篇读;根因是"命中即停"+只扫字没读懂语义)。
- 违约/责任条款通常含多要件:**结算方式 + 违约金 + 兜底赔偿 + 适用主体 + 情形列举**。全部识别再下结论,看到"违约金X个月"就停 = 断章取义。
- 实例:万达第九条1款,只摘"2个月违约金"判"救济偏薄、对乙方不利",漏看了 ①"甲乙双方…守约方有权解除"=**双方对等适用** ②"按实际使用天数结算租金"=年付未用部分照退 ③"违约金不足以赔偿的赔全部损失"=**兜底全赔**。整款实为均衡条款,结论被推翻、该条移除。
- **先判"对谁适用"再判利弊**:中国合同违约责任多为"守约方/违约方"对等表述。下"对X方不利"前先确认是单方还是双方对等条款;对等条款不存在偏向谁。
- **"偏薄/不足"类结论必须先排除兜底**:全条款搜"不足以赔偿的赔全部损失"类兜底句,有兜底就不能说"无法覆盖损失"。
- **警惕标签预设 = 确认偏误**:自然人房东、格式不规范等标签会诱导预判风险,带预设找证据只看见印证预设的部分。正解:用条款本身说话,问这条实际给了X方什么、拿走了什么。
- **违约金/赔偿/费率必须连「计算基数」一起提取,只写比例=没说清(2026-06-18 世茂青少租赁14.1教训)**:写「千分之二」「3倍」「30%」而不写**乘什么**,等于没提取——读者不知道基数。基数(如「逾期**应付费用总额**的千分之二」「**平均月租金**的3倍」「**合同总价**的30%」)必须与比例同时进 I列/K列。世茂栽点:14.1 原文「按前述**逾期应付费用总额**的千分之二」,我只写「逾期付款违约金千分之2/日」漏了基数,被 Maggie 纠正。提取费率/违约金时强制自问:这个百分比/倍数**乘的是哪个金额**?基数没提到=回原文补。
- **⚠️ 同一合同里多处「同数值」违约金,基数可能完全不同,必须逐条认基数防张冠李戴(2026-06-22 悦拾光实证)**:一份合同常有数个违约金/赔偿率,数字碰巧相同极易混填。悦拾光实证:6.1 **开业违约金** = 首期租金的 **3%**(基数=首期租金,督促按期开业的一次性违约金)vs 30.3 **逾期付款违约金** = **拖欠金额** 的 **3%**/日(基数=拖欠金额,逐日累计)——两个都是「3%」但**基数、性质、计息方式三不同**,旧版 K列把两者混为一谈、基数张冠李戴。铁律:见到同合同多处违约金,**一律按条款号逐条独立认「率×基数×计息单位(一次性/按日/按月)」**,绝不因数字相同就假设是同一个机制。年化/绝对值核高低时(4b)也要带对基数:拖欠金额3%/日=年化1095%畸高(但若是合同真实条款则照实记,疑 OCR 先核——本例双份核过3%属真值非误识),与开业违约金3%(一次性、基数=首期租金)完全两码事。
- ⚠️ **只标你核过的区分维度,别为「解释清楚」凭空添一个没核的维度——会自造新错(2026-06-22 悦拾光 6.1 二次教训,由独立法律校对 subagent 揪出)**:区分两个同数值违约金时,我为了「讲清楚」给 6.1 加注「属一次性」与 30.3「按日累计」对比——**但 6.1 原文是「每逾期一日按首期租金3%」,本身就是按日累计、不是一次性**。真正且唯一核过的区分维度只有**基数不同**(30.3=拖欠金额浮动 / 6.1=首期租金固定),计息单位我没核就脑补了个「一次性」,既错又对乙方低估风险(开业晚60天≈首期租金180%)。教训:写区分注**只写已回原文坐实的那个维度**(这里=基数),没核的维度(计息单位、绝对额、适用主体)一律不写——「为了表述完整而补一个想当然的对比项」是确认偏误的变体,宁可只点准一个维度,不画蛇添足凑三要素。这与「⑤b rule 2 标了条款号≠读懂条款」同源:别拿模糊印象填充你没真读的部分。
- **「除……外,……还应……」句式 = 责任叠加,必须逐层拆全(2026-06-18 世茂14.2教训,整款通读的句法级抓手)**:中文违约后果常是「**除[A]外**,[乙方]**还应**[B];若不足赔偿的**还应[C]补足**」的多层叠加。看到「除…外」就警觉——**「除…外」前面那一层(A)极易被整段漏掉**。世茂栽点:14.2 原文「**除乙方交纳的租赁保证金不予退还用以冲抵违约金赔偿给甲方外**,乙方**还应**按平均月租金3倍或等额保证金(两者取高)支付违约金;不足赔偿的**还应负责补足**」——我只摘了中间「3倍/等额取高」,把「①保证金没收冲抵」整层漏掉、「③不足补足」也丢了,三层只取一层。正确提取必须三层齐全:①保证金没收冲抵 + ②另付主违约金 + ③不足补足。这是「整款通读不摘单句」落到**句法层面**——「除…外」「另…」「还应…」「并…」都是叠加信号词,逐个信号词对应一层后果,一个都不能丢。
- **同口径修正必须扫全表对齐(规则一致性)**:同一套格式合同(如世茂青少+高中租赁,14.1/14.2逐字相同)改了一处条款表述,必须回各校区/各份原文核对是否同款,同款的一并改,否则同表内「青少改了高中没改」自相矛盾。改完用脚本全表扫旧表述残留(`bad=[旧串...]` 遍历所有单元格)确认0残留。
**⑤b 法律结论核证三铁律(2026-06-22 世茂高中物业 9.1/10.1 教训)**
教训:高中物业 K列第2条出现两个错误——①把「2个月 或 _/_元(两者取高)」里的选填留空 `/` 当成「填空额」备选项写进交付物论证("或填空额,取高;填空为空故按2个月计");②写「物业违约可能连带触发租赁解除」,因果方向与原文相反——10.1 实为「租赁终止则物业终止」的**单向**联动,9.1 前提是「乙方过错致出租方解除租赁」在先、物业方才追责,合同**无**「物业违约→租赁解除」链条;且该句与同格第5条「10.1 租赁终止则物业终止」自相矛盾未自检。三条对治:
1. **选填留空 `/` = 不适用,是跨条款通用判别,不只用于提成/分档**:任何「或___元 / 或__%(两者取高)」类条款,填空为 `/` / 空白 / 未填 → 该选项不存在,**直接写确定项的结论**(如「2个月平均月管理费」),**不在交付物里论证那个空选项**(「填空为空故按2个月计」这类推理过程不进交付物)。这是 ⑨(提成空白=不适用)、4e(分档留空=不适用)的**泛化**——「选填留空=不适用」适用于违约金、保证金、费率等一切选填条款,不限于提成/分档。栽点根因:已有规则只绑定在它首次出现的场景,未泛化到新条款。
2. **法律因果链必须核方向,标了条款号 ≠ 读懂条款**:写「A导致B」「A连带触发B」「A可能触发C」这类因果结论前,回原文确认**箭头方向**(是 A→B 还是 B→A),尤其「联动 / 连带 / 触发 / 导致」这类词。合同联动多为**单向**(「租赁终止则物业终止」≠「物业终止则租赁终止」)。标条款号是定位、不是免检牌——标了 (9.1) 仍须真读懂 9.1 的**前提与后果**分别是什么,不能凭「两者有联动」的模糊印象脑补反向因果。栽点根因:印象式推断代替条款核对。
3. **同一单元格内多条结论写完互相对撞一遍**:同一格里引同一条款(如 10.1)的多处表述,方向 / 口径必须一致。填表「整合质询」应含**单元格内一致性自查**——高中物业 K14 第2条与第5条都涉 10.1 却方向写反、自相矛盾而未自检,正因写时凭印象一气呵成、没回头与同格其他条对撞。
4. **引某条款作依据前,先确认该条「正文非空」——空标题条款不能当依据,回原文找真正承载该规则的条款(2026-06-22 悦拾光 23条空壳教训)**:合同里**有标题、正文却是空白**的条款是真实存在的坑(OCR 与原件都如此,非 OCR 丢字)。悦拾光实证:「第二十三条 租赁房屋的转租」**只有这行标题、正文整条空**(OCR 里直接从该标题跳到第二十四条续租)——我一度在 I列写「禁止转租(23/28.9)」,把空壳的23条当依据引了。真正承载「禁止转租」的是 **28.9**(乙方擅自转租=根本违约)。处置铁律:① 任何条款号写进交付物前,回 OCR 原文确认**该条款号下确有承载目标规则的正文**,不是只看到标题就引;② 发现标题在、正文空 → **绝不引这个空号**,全文 `grep` 该规则的关键词(如「转租」)定位到真正写着它的条款(可能在「根本违约」列举、违约责任等别处)再引;③ 判断「正文是否真空」要看相邻条款是否紧接——若「第二十三条」标题下一行就是「第二十四条」,即空壳。这是 rule 2「标了条款号≠读懂条款」的同族延伸:rule 2 防因果方向错,本条防「引了个根本没内容的条款号」——都是「条款号是定位、不是免检牌」。④ **🔴 同范本两份副本,同一条款可能「一份正文空、另一份有正文」——这是真实差异,不是 OCR 错,「镜像印象」是漏读元凶(2026-06-22 悦拾光二次教训,由独立法律校对 subagent 揪出)**:悦拾光一期 23条「租赁房屋的转租」确为空壳(标题直接跳 24条),但**扩租 23条有禁止性正文**「未经甲方书面同意,乙方不得将该房屋转租,亦不得将该房屋进行其他非法或违约处置」。我逐字通读时太想确认「两份是同模板镜像」,反而把扩租这行有正文的 23条整行跳过、一口咬定「两份都空、都用 28.9」——连带写出「两份逐条对应、条款高度一致」的夸大表述。后果:①扩租禁止转租其实有**双重依据**(23条直接禁止 + 28.9根本违约),漏了直接依据;②「高度一致」失实。**这与 4a 的双向用法同源**:4a 既要「同条款数值不一致→疑 OCR」、也要「同范本不假设逐字相同、识别真差异」;本条把它落到「空 vs 有正文」这种最隐蔽的差异上——**越是认定「同模板镜像」,越要逐字核每一条,镜像印象会让你跳过真实差异行**。处置:任何「两份高度一致 / 逐条对应 / 逐字相同」的整体判断,落笔前必须**对两份的每一条标题+正文做一次存在性核对**(尤其转租、优先权、特殊约定这类易被一方删/改的条款),有一处不同就不能写「高度一致」,要点明差异(如「扩租另含 X 条正文,一期仅标题」)。
**⑥ 有约定的事项不拿任意性/兜底性法定标准质疑(意思自治优先,2026-06-17 万达催告期教训)**
- 合同已明确约定的事项,**不得再拿"没有约定时才适用"的法定标准质疑其效力**。《民法典》合同编大量条款是"没有约定或约定不明时"才适用。
- 典型误用:约定了违约金/催告期/解除条件后,又写"是否符合法定'合理'标准存疑"——错。除非约定违反**强制性规定**或构成**显失公平/格式条款无效**等可推翻情形。
- 实例:万达第四条2款已约定"催告10日可解除",不能再套民法典722条"合理期限"质疑这10天够不够。对偏严苛但合法有效的约定,**只做商业风险提示**("代价较重,提示注意按时履约/协商更优条款"),不做法律效力质疑。
**④ 等级调整后的结构维护**:风险在🔴/🟡/🟢板块间移动后——(a) 受影响板块若清空(如🔴须核实区只剩的项都降级走了)→**移除空板块**;(b) 全列风险**编号重排 1–N 连续无跳号**;(c) openpyxl 局部改完跑保真核对(见 Pitfall 1b)。
**⑦ 审查已履行合同,剔除面向"履行前时点"的过时前瞻提示(2026-06-17 万达物业合同教训)**
- 这批合同**都是已实际履行多时的合同**(万达2024/9签、2026/6已运营近两年)。审查时剔除面向**已过去且不可逆时点**(装修前、进场前、签约时)的**前瞻性操作提示**——这类提示对早过了那个时点的合同毫无意义,是马后炮。
- 实例:物业合同低风险区"装修一次性费用(建议装修前纳入预算)""用电容量限制(建议核实现有容量是否充足)"两条——装修2024年底已完成、能正常运营近两年即证明用电够用,两条都删。
- **保留**面向**当前/未来持续**的提示:如"能耗费每年发生→保留对账凭证"(合同仍在履行、费用持续发生)、退出机制/续租/违约等面向未来履行与退出的风险。续签建议(补任意解除权/不可抗力/办学许可条款)也保留——面向"未来续约",不是过时前瞻。
- 判断标准一句话:问"这条提示指向的时点,是否已经过去且不可逆?"——是→删;指向当前或未来→留。
- **跨合同一致性检查**:删某类提示后,复查同表其他合同(主合同/其他校区)有无同类前瞻提示,统一处理。
**⑦b 履行中合同 + 属常规商业安排的条款 → 直接删除,不写"虽然有X但属常规"提示(Maggie 2026-06-18 世茂装修违约金确立)**
- 合同**已在履行**、某条款经核实**属正常商业安排、不构成实际风险**的,**直接不列、不提示**——不要为了"显得审过了"而写"装修违约金1倍属常规督促性、提示按期完成装修开业"之类的安抚性提示。
- 实例:世茂6.4装修延误违约金,核实为日租金**1倍**(≈1,100元/天,常规督促性违约金,合同已在履行)→ Maggie 原话"装修延误违约金不奇怪的情况下,不用提示,删除就好",整条🟡中风险删除,不降级保留、不写提示。
- 与⑦同理(⑦删过时前瞻提示,⑦b删常规无风险条款),都是"交付物只留真正要客户注意的风险,不堆无意义提示"。判断:这条款**当前是否真给乙方带来风险**?否(属常规商业安排)→ 删,不提示。
**⑧ 整体风险分析段(第三部分)须与已确立的定级尺度全程对齐(2026-06-17 万达第三部分重写教训)**
- 校区 sheet 末尾的「整体风险分析与建议」段是早期产出、措辞最容易残留**已被推翻的旧判断**。每次定级尺度有更新,**必须回头重写这一段**,不能只改前面的逐条风险列。
- 万达第三部分重写时清理掉的旧判断(全部违反本节①-⑥与「模版差异≠法律风险」铁律):✗"出租方为自然人→偏向甲方"(标签预设/确认偏误)✗"违约金仅2个月→保护不足"(均衡条款,且法律意见书明确2个月违约金不适用无故退租)✗"提前退出风险高"(协商解除可互不担责、继续履行风险极低)✗ 拿"与模版差距大"当风险论证。
- 重写后结构(站乙方立场、客观中性、不用预设标签):整体评价(已履行可正常运行)→主要法律关注点(标条款)→提前解约成本与路径(**直接引同校区法律意见书的权威数字,可溯源**)→操作建议(意见书五步法)→续签建议(面向未来)→低风险事项(核验出租权、模板套用)。
- **⚠️ 总结段精简尺度(2026-06-17 Maggie 定稿万达表确立)**:第三部分作为给客户看的「总结」,**只保留客户最需要注意的内容**——整体评价、主要法律关注点、提前解约成本、续签建议。**删掉**:①提前解除的具体操作步骤建议(五步法等程序性操作)②低风险事项提醒(核验出租权、模板套用等)。理由:总结要简明扼要、突出重点,操作细节和低风险事项放在前面逐条风险列里即可,不必在总结里重复,以免淹没真正要客户关注的重点。(注:上一条「重写后结构」是完整版结构;本条是 Maggie 进一步精简后的**最终交付尺度**,以本条为准——总结段不含操作建议段与低风险事项段。)
- **⚠️ 汇总表意见简明、删法条号(2026-06-17 Maggie 定稿万达表确立,与第65行呼应)**:汇总表(含第三部分总结)的风险意见**尽量简单明了**,**删掉民法典法条号**(如584/580条等不写进表格正文)。但两类编号**保留**:①合同条款号(第八条、第五条2款等——便于回原文核对,见第50-56行)②引自正式法律意见书的法条(第三部分若直接援引意见书结论,其法条作为依据可留)。一句话:汇总表删「外部法条引用」求简洁,留「合同内部条款定位」便核对。
**⑨ "保底或提成两者取高"——必须核提成比例是否填了数额,空白即不适用(2026-06-17 世茂青少租赁 Maggie 纠正)**
- 商业Mall租赁常见"月租金=每月保底租金 或 每月营业额×提成比例%,两者取高"的约定。**绝不能照搬"两者取高"的字面就写进表**——必须回原文核**提成比例栏是否真的填了数额**。
- 世茂青少/高中租赁实例:附件三租金段写"合计33280.59元 **或按当月总营业额(税前)之/%提成;两者取高**"——提成比例是 `/`(空白占位)、**没有数额**。提成租金无从计算,**实践中即不适用,实际只按保底租金计租**。
- 正确写法(Maggie 2026-06-17 再纠正:判断过程不进交付物):金额栏标题写"营业期**保底租金**"、只列保底数额即可——结论栏只放结论,**判断过程不写进汇总表**。既不写"保底与提成取高"(误导以为有提成机制),也不写"提成比例空白→无法计算→不适用"这类推理过程(推导留在审查阶段,不进交付物)。
- 推广检查:凡遇"两者取高/就高"类租金约定,逐份核提成比例(%处)填没填数额;空白/`/`/未填→按不适用处理。这是"事实核实、不照搬字面"原则在金额栏的具体落地。
### ⚠️ 铁律:每份合同逐条审查,不挑不跳,禁标"简化审查"(Maggie 2026-06-17 万达物业合同确立)
**每一份合同**——无论主合同/附属合同、标准模板/格式文本——都必须**按审查标准逐条审查,从①主体信息 → ②各实体条款 → ③违约/争议/生效 → ④签名落款,全过一遍,不挑重点、不跳条款。**
- **严禁标注"简化审查""重点审查"之类减档说明**。Maggie 原话:"任何一份合同都应该按照审查标准逐条审查,从主体信息到签名落款,不能跳着或者挑着来。" 这种标注既是给客户的负面信号(像在说"没认真审、打了折扣"),也是给偷工减料找说法。审查深度的主次是内部判断,**不写进交付物**。
- **合同间的主次(如物业依附租赁)只影响风险权重表述,不影响审查覆盖面**——附属合同照样逐条审。
- **逐条审查反而捞出挑审漏掉的真问题(万达物业合同实证)**:从"挑审4条"改为"逐条审"后新发现——①协议性质/主体框架错位(套用"前期物业服务协议"住宅业主模板,乙方实为承租人非业主)②第十七条生效条款"业主办理入住手续签字生效"与承租场景不符③第八条广告牌设置与租赁合同"乙方可免费设广告牌"衔接冲突。挑审时全漏了。
- **交付物结构(逐条审查后)**:风险按🔴🟡🟢分级列出(标条款)。物业等附属合同标题与主合同对齐用"站乙方立场独立审查",不用"简化审查"。
- ⚠️ **不加"✅已审查无异常"展示段(Maggie 2026-06-18 反转此前万达打样规则)**:此前为展示"审查覆盖全部条款",会在 K列末尾加一段"✅已审查无异常"罗列审过且无问题的条款。**Maggie 明确不要这个提示——删除。** 逐条审查是**内部要求**(覆盖面靠内部保证),但交付物**只列真正的风险点,不写"已审查无异常"这类覆盖面展示段**。理由同"判断过程不进交付物""总结段只留客户最需注意的内容":客户要看的是风险,不是"我审了哪些没问题"的清单。**已有的旧表若带此段,更新时一并删除。**
**⚠️ 事实问题不靠文本提取下结论(连带自我教训)**:签字/盖章是否空白、印章有无属**事实问题**,PDF 手写签名/印章在 OCR/文本提取里**看不到**。不能凭 `.md` 提取版断言"甲方签字处空白"——必须**看原件 PNG 图片或问 Maggie 确认**。同"自已/自己"教训:提取层看到的"空白/错字"可能只是提取丢失,不是原件真相。涉及签署状态的风险,先核图再定级。
### ⚠️ 交付物呈现规范(Maggie 2026-06-18 世茂确立)
两条关于「交付物里放什么、怎么标」的硬规则,与「判断过程不进交付物」「总结段只留客户最需注意的内容」同源——**交付物只为客户服务,不留我的工作痕迹,待客户做的事用颜色凸显。**
**① 核实痕迹直接删除,客户不需要知道我怎么核的**
- "经PDF原件核实""经原件核实""经PDF原件+数学交叉核实""〔关键数字均经…核实〕"等**我自己的核验过程标注**,一律**不写进交付物**——客户只需要看结论,不需要看我怎么验证的。
- 实例:世茂物业 K列"逾期缴费滞纳金:每日0.5‰(9.2,**经PDF原件核实**)"→删成"(9.2)";高中物业末尾整段"〔关键数字均经PDF原件+数学交叉核实:①…②…③…〕"注脚→整段删除。
- 核验是我的**内部责任**,留痕放工作记录/主审清单即可,不进客户看的表。这与「判断过程不进交付物」「不加✅已审查无异常展示段」是同一条线:交付物 = 客户视角的结论,不是我的工作日志。
**② 需客户核实/确认的内容怎么凸显——⚠️ openpyxl 富文本标红会让 Excel 报错,但 WPS 另存可救(2026-06-18 世茂,最终标红成功保留)**
- 需求:风险点中**需要客户去核实/确认某个事实**的内容(如"两份合同衔接需核实""建议向客户核实""建议签约时补明或确认2028年度计租标准")希望**凸显**,方便客户一眼识别待办。
- **边界(不管用什么方式凸显都适用)**:①只标"需客户核实/确认事实"的——提示类(提示按时缴费、提示知悉、提示确认衔接)不凸显;②我已核实的不凸显(且核实痕迹要删,见①);③范围 Maggie 要的是**整条**(从编号到句末),不是只标半句。
- 🔴🔴 **铁律:openpyxl 的 `CellRichText` 局部着色会让 Microsoft Excel 报"发现部分内容有问题/需要修复"——但 WPS 打开另存可救回(2026-06-18 世茂,最终标红成功)。** 完整经过:
- openpyxl 把带局部色的单元格写成 `inlineStr`+`<is><r><rPr>…`。试过 ①调 `<rPr>` 子元素顺序(rFont→sz→color)②补 `charset=134`/`family=2` ③去掉富文本只留纯文本——**Excel 仍报错**。说明根子不只是富文本,openpyxl 生成的这个表底层某处就不合 Excel 严格 OOXML 校验。
- **WPS、OnlyOffice x2t、openpyxl readback、LibreOffice 全都不报错或无法复现**——唯独 Microsoft Excel 报。所以"WPS 打开正常""openpyxl 读回正常"**完全不能当交付合格证据**。Maggie 的客户/她本人用 Excel,Excel 报错就是不合格。
- **本地没有能复现 Excel 严格校验的工具**(LibreOffice 在本环境连干净文件都报 "source file could not be loaded",x2t 太宽松)。→ **改完无法自验 Excel 行为时,必须如实跟用户说"我这边验不了 Excel,你帮我打开看下",不要断言"修好了"。** 本 session 连续 4+ 次"还是不行"、把用户当测试员,是明确的反面教训,用户失去耐心。
- ✅ **要凸显就用不碰富文本的方式(Excel 绝不报错)**:
1. **纯文本标记(首选)**:在需核实条前加醒目前缀,如 `【需客户核实】…` / `❗待核实:…`,整条普通黑字、零特殊格式。最稳,Excel/WPS 都不报错。
2. **整格统一格式**(`cell.font=Font(...)`、整格背景 `PatternFill`):安全,但会把整格所有条目一起染——仅当"整格就这一条"时可用。
3. **必须某条带色/加粗 → WPS 另存法(2026-06-18 世茂实证:此法成功,Excel 不再报错且红色保留)**:openpyxl 写好带 `CellRichText` 局部标红的 xlsx 后,让用户/我把文件**用 WPS 打开 → 另存为 xlsx**。WPS 会把 openpyxl 那套不合 Excel 严格校验的 XML **重写成规范格式**,结果:①Excel 打开**不再报"需要修复"** ②**红色局部着色保留**。Maggie 亲自验证 Excel 正常打开+红色在。这是\"既要某条标红、又要 Excel 兼容\"目前**唯一跑通**的路径。\n - 代价:需\"WPS 打开另存\"这一步人工(或我若有 WPS CLI 可自动化;本环境暂靠用户手动)。给用户的话术:\"文件我已标红,但 openpyxl 生成的格式 Excel 会报错——你用 WPS 打开后另存一次 xlsx,Excel 就正常了、红色也在。\"\n - ⚠️ 前提:被另存的那一版**必须是带富文本红色的版本**(别拿我中途\"去富文本\"的版本去另存,那样没红色)。\n- **结论**:要\"单元格内某条标红/加粗\",**先 openpyxl 写富文本红色 → 再 WPS 另存规范化**(已验证可行);嫌麻烦或纯自动化场景,退而用**纯文本前缀**(`【需客户核实】`)。默认 Maggie 用 Excel、WPS 只是工具,但 WPS 另存这一步是打通富文本标红的关键。完整排查全过程见 `references/openpyxl-excel-richtext-pitfall.md`。
---
## ⚠️ 三角色分工(四眼分离,Maggie 2026-06-16 确立)
**核心原理**:做的人查不出自己的错(确认偏误)。有效校对必须是**独立角色拿合同原文重新核**,不是看着成品点头。技术上用 `delegate_task` 开上下文隔离的 subagent,校对员看不到承办思路,只看原文和成品 → 真四眼。
| 角色 | 谁来当 | 职责 |
|------|--------|------|
| **① 承办** | 小Maggie主审 + 独立 subagent | **法律审查(动作A)**:小Maggie本人主审,八维全面审查→法律风险清单(不外包,避免超时);**提取分析(动作B)**:独立 subagent,OCR→要素提取→模版比对→退租敞口→填表+提取依据清单 |
| **② 校对** | 独立 subagent ×2 | **法律校对**(维度1-4)‖ **格式校对**(维度5-6) |
| **③ 终审** | 小Maggie 本人 | 汇总校对结果、确认问题闭环、最后把关 |
**防线顺序**:承办 → 校对 → 小Maggie终审 → 交付 → **Maggie最终核对**。到 Maggie 手上前已过三道。
### 承办拆分规则(2026-06-16 小样验证后定为"方案3:小Maggie主审")
- **OCR 是分叉前的共享前置步骤(2026-06-16 厘清)**:合同 PDF → `.md` 文本只做一次,生成"只读底料"。**小Maggie(法律审查)和 subagent(提取分析)各读同一份 .md 原文,并行不冲突**(都是只读,像两个律师各拿一份复印件)。法律审查**必须亲自读合同原文**——不读原文无法做八维审查。旧流程"subagent 读文件出报告、小Maggie 只汇总"已废止;现在法律判断的源头(读原文)牢牢在小Maggie手里。
- **法律审查(动作A)由小Maggie本人主审,默认不外包 subagent**。两条理由:①法律审查最吃专业判断,小Maggie对合同全局上下文最清楚,质量最高;②重型八维审查单个 subagent 极易撞 10 分钟 ACP 超时被杀,半截活白干。
- **万达小样实证(2026-06-16)**:法律审查 subagent 跑满 600s 超时被杀;小Maggie补做的版本是本次质量最高的一份且无超时,并独有发现签署页瑕疵(签署日期空白等模版比对看不到的项)。⚠️ 注:该"签署日期空白"当时被评"合同效力存疑"高风险,2026-06-17 经 Maggie 纠正应降为🟢低风险(合同已实际履行、租期明确,形式瑕疵不影响效力)——发现瑕疵是对的,定级要克制,见「风险定级纪律」节。
- **提取分析(动作B模版比对)+ OCR + 填表 外包独立 subagent**,机械活可并行、不超时。
- **四眼分离不破**:小Maggie主审动作A → 独立法律校对员查;动作B由 subagent 做 → 独立校对员查。做者与校者始终分离(校对查的就是小Maggie主审的成果——正是万达小样里校对揪出"法条未标注"的场景)。
- **弹性**:若某段时间小Maggie任务过载、确实抽不出手,可临时降级为"法律审查 subagent",但必须二选一防超时——①放宽 ACP 超时(`--timeout`)②按维度把八维拆成 2-3 个轻 subagent 再拼。**默认主审,过载才降级。**
- 提取分析 subagent context 必须含:合同OCR原文路径、标准模版核心条款清单、"中性输出合规差距、不作风险判断、开头结尾各重申一次声明"。
### 填表分工(2026-06-16 确立:谁产出谁填,绝不让 subagent 填它没做过的内容)
**核心矛盾**:汇总表的内容来自**两个源头**——动作B(提取分析,subagent 产)+ 动作A(法律审查,**小Maggie主审产**)。若简单"填表外包 subagent",会让 subagent 去填一栏它根本没做、是小Maggie做的"法律风险",必然瞎填或失真。因此填表必须拆成两步两人:
| 步骤 | 谁干 | 填什么 |
|------|------|--------|
| **① 填表初稿** | 提取分析 subagent | 只填**它自己产出的**栏位:当事人/面积/金额/期限/核心内容/**模版差异** + 套用 12 列格式、配色、行高 |
| **② 合并法律风险** | **小Maggie(终审)本人** | 把主审的**法律风险**结论亲手并入"风险点/备注"栏;与模版差异**分列**、加方法论标注(法律风险 ≠ 模版差距) |
| **③ 格式校对** | 格式校对 subagent | 查格式统一、总览-分表一致、加总对不对 |
**铁律:谁产出谁负责那一栏。** 机械的格式骨架 subagent 搭,小Maggie做的法律风险小Maggie自己填,**绝不让 subagent 去填它没做过的法律判断内容**。这与"方案3 小Maggie主审法律审查"一脉相承——法律判断从审查到落表全程在小Maggie手里,不经 subagent 的手,杜绝失真。
> 🔴 **模版差异(L列)虽由 subagent 产,但必须满足两个强制条件(Maggie 2026-06-23 补充,对治"外包给 subagent 就不回原件"的隐患)**:
> 1. **subagent 的 context 必须含 07 原件路径 + "逐条打开原件比对"强制指令**:不是给一份归纳好的 checklist 让它套,而是给 `07- 房屋租赁合同.docx` 原件(或其全文),明确要求"逐条比对原件,禁止用'商业格式''标准格式'等抽象概念当参照系"。checklist 仅作定位导航,真值以原件为准。
> 2. **终审(小Maggie)对 L 列结论像法律风险一样回原件复核,不全信 subagent**:subagent 的模版比对是初稿,终审必须亲自回 07 原件抽查关键条款(缺失项、实质偏离项)是否找全、陈述是否中性、有没有把模版标配当"本合同优势"。这与"动作A 法律审查不外包源头"同源——模版比对的**校验源头**也要在小Maggie手里。
> - 教训来源:人民中路 L 列当初没回 07 原件、拿"星展商业格式"概念写差异,漏了第八条抵押"不得→可"、第十二条办学许可证免责款缺失两处实质偏离(详见「模版差异≠法律风险」铁律下的 07 原件铁律)。
> ⚠️ **退租敞口测算含法律判断,必须小Maggie把关定稿(2026-06-16 Maggie 指示)**:退租敞口(确定责任/不确定责任/可收回/净成本)本质是法律判断,不是机械提取。subagent 可出初稿框架,但**最终结论由小Maggie定稿**,与"法律风险栏"同等对待——不外包拍板。
> ⚠️ **现行 12 列汇总表中,法律风险与模版差异物理分列:K列=「风险点/备注」装法律风险(动作A产出),L列=「与标准模版差异」装模版差异(动作B产出,回 07 原件比对)。** 两列各自标注性质,绝不混列——这是「模版差异 ≠ 法律风险」铁律在表结构上的落地,防止读者把合规差距误读为法律风险。(此前「11列、K列同时承载两者」的旧表述已于 2026-06-23 作废,见 Step3 12列标准结构。)
### 六维校对清单(Maggie 列定,逐项打勾)
| # | 校对什么 | 谁校 | 自动化 |
|---|----------|------|:---:|
| 1 | 提取文字准确(面积/金额/期限/当事人回OCR原文核) | 法律校对 | 🟡半自动 |
| 2 | 总结要点无错漏(核心内容栏有无漏关键条款) | 法律校对 | 👤 |
| 3 | 法律风险完善准确(是否当新合同全面审、有无错漏、定性准否、法条现行有效) | 法律校对 | 👤 |
| 4 | 模版核对准确(差异找全、陈述中性、**没把差距当风险**) | 法律校对 | 👤 |
| 5 | 汇总要点齐备(字段齐全、总览-分表一致、加总对得上) | 格式校对 | ✅自动 |
| 6 | 格式统一(列结构、配色、行高、板块划分合模板) | 格式校对 | ✅自动 |
- 第5、6点 + 第1点数字部分写成**校验脚本**自动跑(字段空缺、总览-分表一致性、金额加总、列结构比对)——机器不漏不手抖
- 第2、3、4点是法律实质判断,法律校对 subagent 做,小Maggie终审复核
- **错别字、格式错误、语义逻辑错误是必校项(2026-06-16 Maggie 补充)**:贯穿全部六维,每份交付都要过——错别字(法律/格式校对都查)、格式错误(格式校对)、语义逻辑错误/指代不清(法律校对)。这是基本质量底线,不因走了 workflow 就免检。
### 校对发现问题后的处理机制(2026-06-16 确立,三角色闭环的"最后一公里")
校对员产出《校对意见清单》后,按以下机制流转——做、校、修、核、定一条龙,缺一环不算闭环。
**① 问题分级**
| 类型 | 例子 | 处理 |
|------|------|------|
| 🔴 **阻断项** | 数字提取错、法律风险定性错、**红线**(把模版差距当法律风险)、法条臆造/未标注 | **改完 + 复核通过前,不交付 Maggie** |
| 🟡 **建议项** | 轻微遗漏、措辞、可补充的小点 | 终审判断采纳与否,可当场补或仅记录 |
**② 谁来修:校对不下场,按问题大小分流**
- **铁律:校对员只挑错、不动手改**——一旦它下场改,就又变回"自己查自己",四眼分离失效
- 小问题(标注、个别数字、补一条风险)→ **终审(小Maggie)局部修**,最快
- 系统性问题(整段审查跑偏、大面积提取错、立场错)→ **退回对应承办环节返工**,重做那一环
- 优先级:**局部修 > 退回返工 > 重做**(与合同审查同一套)
**③ 改完必须闭环复核,不能"改了就算"**
- 修正后拿校对意见**逐条回核**,确认真解决了
- 能脚本验证的(数字、格式、标注一致性)就**脚本验证**
- 没复核通过 → 不算闭环、不交付
**④ 反复出现的问题 → 修根因,不只修个案**
- 某类问题被校对反复挑出(如法律审查老漏标法条)→ **打回本手册/承办指令模板**,从源头堵住
- 修一次性的错 vs 堵住错的来源,后者才治本
**⑤ 终审最终裁判权**
- 校对意见**非绝对权威**。若某条意见本身站不住,终审(小Maggie)有最终取舍权,但**须说明不采纳的理由**
- 对最终质量负责的是总负责人,不是机械执行校对清单(如同律所"校稿提意见、定稿人拍板")
**实战案例(万达小样 2026-06-16,全流程走通)**:校对员揪出"法律审查4个法条编号(722/585/725/496)未按报告自述方法标注〔待核实〕"——定为 🔴 阻断项 → 小Maggie(终审)局部修正统一加注 → execute_code 脚本复核5个编号全部到位 → 闭环 → 交付。校对同时提的"用电增容14千瓦未提及"为 🟡 建议项,不影响结论,记录即可。
### Maggie 审核成果后的修改流转(建议默认,2026-06-17)
交付后 Maggie 亲自审核成果 Excel,往往会调整内容。修改怎么流转,**按改动类型分流**——这是「Maggie最终核对」这道防线的操作细则。Maggie 问「我直接在表格里改,还是把意见给你来改」时,主动按下表建议,不要让她从零纠结:
| 改动类型 | 谁来改 | 为什么 |
|---------|--------|--------|
| **长文本**(法律风险表述、模版差异逐条、退租建议、整体风险分析) | **Maggie 给意见 → 小Maggie 改** | ①这些单元格是高度结构化长文本(🔴🟡分级、12项逐条、〔待核实〕标记、分段),在 Excel 单元格里手改长文本,换行/缩进/emoji 标记极易乱;②**跨 sheet 联动**——校区 sheet 改了,总览对应行的「主要风险点」要同步,手改易漏;③**规则一致性**——一套规则覆盖 N 个校区,改一处口径,小Maggie 能把同类表述在其他校区一并对齐,手改只能改一处 |
| **短数据字段**(金额、面积、日期、主体名称) | **Maggie 直接在表格改更快** | 纯数据订正,不涉格式/联动,绕小Maggie 反而慢 |
- Maggie 给意见的形式自由:表格里批注/标黄发回,或文字直接说「X校区某列某条改成……」。
- **兜底**:若 Maggie 倾向全部自己在表格改,小Maggie 至少要最后帮她**校对一遍格式 + 跨 sheet 一致性**(总览-分表同步、加总、配色、行高——见 Pitfall 1 行高重算)。
- 这道流转走完才真正闭环——接续三角色防线「承办→校对→终审→交付→Maggie最终核对」。
### Maggie 审核 = 规则提炼机会(边改边沟通,2026-06-17 确立)
Maggie 的目标是把她每一处审核修改**内化成 skill/规则**,让下次成果一次到位、不用她反复改。达成方式是固定协议,不是临时沟通:
- **节奏:边改边沟通,不是攒完一起说**(Maggie 2026-06-17 拍板)。理由:要内化的是「**为什么这么改(why)**」而非「改了什么(what)」——理由才是规则,改动只是表象。改完一大批再回头猜理由必猜偏,Maggie 过几天也未必记得当时考量。边改边说,理由最新鲜最准。
- 反面教训:培训合同「自已→自己」若只看改动会误提炼成"错别字不用改",是 Maggie 当场说"己字没错、是读取问题"才避免写错规则。
- **不打断 Maggie 节奏**:她改时带一句简短理由即可(哪怕几个字),不必等小Maggie回复就继续审。小Maggie 后台记录、提炼候选规则,**不刷屏**,攒到一个段落或她审完一个校区再汇总成规则清单发她确认/纠偏。
- **落地机制**:在工作目录建一份「<项目>审核·规则提炼追踪.md」,每处记一条 `修改点 → Maggie的理由 → 提炼的规则`,并标 `适用范围`(打样阶段写"先在X校区打样,暂不推广")+ `状态`(待确认/已确认)。Maggie 确认后才标"已确认"并落实,确认前不铺开到其他校区。
- **打样优先**:新规则先在一个校区(如万达)打样,给 Maggie 看落实效果(重写后的单元格 + 变化对照),她认可标注方式后才推广全部校区。Maggie 说"打样、不着急其他校区"时严格遵守,不自行铺开。
- 提炼出的规则最终固化进本 skill(或对应审核 skill)的正文,不只留在追踪文件里——追踪文件是过程载体,skill 正文才是长期记忆。
---
### 可回溯配套
承办填表时**同产一份「提取依据清单」**——每个关键字段标来源(第几页第几条)。校对员快速溯源,Maggie 核对时点开即知数字出处。
### 弹性
- **日常增量**(动1-2份):承办+校对+终审三角色
- **批量盘点**(5+份变动):校对拆**法律校对‖格式校对两个并行 subagent**,专业更纯
### ⚠️ 校对 subagent 防超时(2026-06-17 世茂重做实证)
重型**法律校对**(逐条核对多份合同回原文)极易撞 600s ACP 超时被杀(世茂4份合同的法律校对一次性跑→超时;物业组单独重试仍超时)。三条应对:
1. **按合同类型/数量拆小再并行**:4份合同别塞一个法律校对 subagent,拆成"租赁组(2份)‖物业组(2份)"两个并行 slot,每个工作量减半,更易在超时前完成。世茂拆分后租赁组顺利 completed 并揪出2个真问题(甲方违约13.4/13.5遗漏、装修延误违约金10倍vs1倍)。
2. **格式校对几乎不超时**(纯脚本核对),优先保它跑通。
3. **某组反复超时 → 终审(小Maggie)亲自接管核该组**:物业合同我已主审通读过全文,物业组校对超时后由我亲核物业K列即可,符合"终审最终裁判权+局部修"。**不无限重试消耗时间**。
- 检查铁律:`delegate_task` 返回后逐个查 `status`,`timeout`/`error` 的不能当没发生——要么拆小重试,要么终审接管,绝不跳过四眼校对环节。
### ⚠️ OCR 缺失数字不进表,标〔待核PDF〕不编造(2026-06-17 世茂高中物业实证)
提取分析 subagent 报的数字若 **OCR 原文无佐证**(如高中物业第九条违约金率正文 OCR 丢失、subagent 记"1%"实为参照青少物业推测),**终审必须回原文核**:搜不到原文支撑的数字,改写成"〔待核PDF〕提取报告记为X但无OCR原文佐证",**绝不让无依据数字当结论进交付表**。这是"OCR交付不把校验责任推给用户、不凭提取推测定稿"(Doro/Maggie 一贯铁律)在批量场景的落地。终审核对每个关键数字(违约金率、金额、面积、日期)时,区分"提取已核原文" vs "提取推测待核",后者一律标待核。
---
## ⚠️ 增量维护(汇总表是持续台账,不是一次性交付)
汇总表需随**新增合同 / 合同到期 / 提前解除**持续更新,每次变动走三角色分工,保证隔多久都输出同一套标准。
- 🟢 **新增**:拉最新版→承办(提取+法律审查)→按板块插行+同步总览→校对→终审
- 🟡 **到期**:状态改"已到期",历史行保留不删(台账可追溯),一般走格式校对
- 🔴 **提前解除**:状态改"已解除",退租敞口→实际结算结果,法律校对核结算
→ 完整步骤见 `references/incremental-maintenance-sop.md`。**所有变动前置铁律:绝不基于旧本地副本改,先从 Nextcloud 拉最新版 xlsx。**
---
## 处理流程
### 整体策略:两阶段法(推荐)
当校区数量≥5时,采用两阶段法比逐个校区做效率高得多:
**阶段一:批量生成分析报告(MD文件)**
1. 按复杂度分批,每批最多3个校区并行(delegate_task限制)
- 简单批(1-2份合同/校区):如仅物业合同或仅租赁合同的校区
- 中等批(2-4份合同/校区):如租赁+物业的校区
- 复杂批(5+份合同/校区):如有多份补充协议/扩租的校区,每个占1个slot
2. 每个subagent读取该校区的MD合同文件,输出一份分析报告到 `<校区名>/XX校区合同分析报告.md`
3. 所有批次完成后,确认17/17(或N/N)覆盖率
**阶段二:从分析报告提取数据→生成汇总Excel**
1. 遍历所有分析报告,提取关键字段
2. 构建campuses_data JSON
3. 一次性生成包含总览sheet的Excel
4. 上传Nextcloud + 发给用户确认
### 单校区处理流程 —— 统一编号 Step 0→7(Maggie 2026-06-23 定,防误读)
> 🔢 **权威编号(唯一口径,全 skill / 闸门脚本 / 对外沟通都用这套,不得另起别名)**:
> Step 0 盘点归类 → Step 1 取文件+OCR → Step 2 承办(法律审查‖提取分析) → Step 3 写12列Excel → Step 4 三角色校对 → Step 5 小Maggie终审 → Step 6 交付自查+存档 →〔全部校区定稿后〕Step 7 整合总览sheet。
> **Step 0→6 是单校区闭环**(每校区独立从头走一遍);**Step 7 是全局收尾**(所有校区定稿后才做一次,不属于单校区流程)。
#### Step 0: 文件盘点与归类(首次校区必做)
第一次接触某校区,**先盘点文件夹有哪些文件、如何排列,逐一核实确认**,再按"租赁/物业 → 场所/位置 → 签约时间"归类排序。详见 `references/file-inventory-classification.md`。归类层级直接映射校区 sheet 的板块划分。后续新签/变更/解除一律按此规则归位。
#### Step 1: 从Nextcloud取文件 + OCR
```python
# 1. docker cp 从 Nextcloud 容器复制 PDF 到本地
# 2. OCR 提取文本(参考 deepseek-ocr skill)
# - 先转图片: pymupdf → 200dpi PNG
# - 逐页 OCR: deepseek_ocr.ocr_file()
# - 合并保存为 .md 文件(页间用 ---PAGE--- 分隔)
# - 纯扫描件文字层=0 必须 OCR;大文件后台跑(见 Pitfall 4)
```
#### Step 2: 承办(四眼分离前半,两个动作并行)
本步是承办环节,**两个动作并行产出**(见「三角色分工」节):
- **动作A · 法律审查 = 小Maggie 本人主审**:亲自 `read_file` 逐字通读本校区合同 OCR 全文(含附件),按八维框架当**全新合同**全面审 → 法律风险清单(不外包 subagent,防超时+保质量)。详见 `references/independent-legal-review-framework.md`。
- **动作B · 提取分析 = 独立 subagent**:OCR 要素提取 + 模版比对 + 退租敞口测算 + 填表初稿。
- 🔴 **模版比对必须回 `07- 房屋租赁合同.docx` 原件逐条核**(subagent context 必带原件路径 + "逐条比对原件、禁用抽象格式概念"指令;终审回原件复核,见「填表分工」节)。
- 简单校区(1-2份合同)单个 subagent 可处理多个校区(最多4个);复杂校区(5+份)单 subagent 只处理1个。
- Subagent context 必含:所有合同MD文件路径、07原件路径、输出路径、报告格式模板、"站南通新东方(乙方/承租方)立场分析,输出中文"。
#### Step 3: 写入Excel汇总表(12列)
每个校区一个独立 sheet。结构如下:
##### Sheet结构
- **Row 1**: 标题(合并A:L),如"万达校区 — 租赁合同梳理"
- **Row 2**: 基本信息(合并A:L),物业地址、产权人、物业方(长信息行用 \n 分行防横向截断,见 Pitfall 17)
- **Row 3**: 分类标题(如"一、租赁合同"),蓝色底D6E4F0
- **Row 4**: 列标题(绿色底E2EFDA)
- **Row 5+**: 数据行
- 分类之间插入标题行
- 最后一个分类: 校区整体风险分析与建议(合并A:L)—— **必含板块,验收必查**
##### 12列标准结构(校区详情sheet,已确认模版 ✅ Maggie 2026-06-23 裁定)
| 列 | 内容 | 宽度 |
|---|---|---|
| A | 序号 | 5 |
| B | 文件名称 | 24 |
| C | 合同类型 | 14 |
| D | 合同当事人 | 26 |
| E | 租赁标的/服务范围 | 22 |
| F | 面积(㎡) | 10 |
| G | 合同期限 | 20 |
| H | 金额/费用 | 20 |
| I | 核心内容 | 40 |
| J | 当前状态 | 10 |
| K | 风险点/备注(**法律风险**,动作A产出) | 40 |
| L | 与标准模版差异(**模版差异**,动作B产出) | 40 |
> 🔴 **L 列独立(Maggie 2026-06-23 裁定)**:模版差异 = 独立的 L 列,**绝不并入 K 列**。这与「模版差异 ≠ 法律风险」铁律严丝合缝——K 列装法律风险(参照法律+司法实践)、L 列装模版差异(参照 07 原件),两件不同性质的事物理分列,杜绝下游把合规差距误读为法律风险。
> ⚠️ **此前一度出现「11 列、模版差异并入 K 列」的旧表述,已于 2026-06-23 作废**——全 skill 以 12 列含独立 L 列为唯一口径(与 `column-structure.md`、`independent-legal-review-framework.md` 第103行「分列」、增量维护 SOP「动作B独立产出」一致)。
> L 列内容必须回 `07- 房屋租赁合同.docx` 原件逐条比对(见「模版差异≠法律风险」铁律下的 07 原件铁律),物业/补充协议标注"无对应标准模版"。
> 文件名称必须用实际PDF文件名(如"北翼玖玖-房租合同.pdf"),不能自起名称。
> 按文件夹结构分板块——房租/扩租/物业等,跟客户实际的文件夹对应,不能自行重新归类。
> 📌 **H列三件套(每个金额/费用项标准动作)**:① 标条款号(数字真实出处,不标"详见附件X"指引条)② 换算"≈X个月月租"③ 推算付款截止日(推不出→总结+红字提示)。
> 📌 **需客户核实内容整条标红**(富文本红是最后一步→WPS另存/sharedStrings XML层;中间任何 load_workbook→save 会把红打回纯文本)。
##### 风险分析区(最后一个section)内容结构
1. 【整体风险分析】— 校区级别的风险概述
2. 【合同变更与提前解除综合分析】— 提前解约成本、部分退租、免责通道
3. 【文件汇总说明】— 文件清单与表格条目的对照关系
4. 【建议】— 针对性建议
#### Step 4: 三角色校对(四眼分离后半)
承办成果交独立校对,**做者与校者分离**(见「三角色分工」「六维校对清单」节):
- **法律校对 subagent**(六维1-4):提取文字准、要点无漏、法律风险准、**模版核对准(差异找全、中性、没把差距当风险)**。
- **格式校对 subagent**(六维5-6):字段齐备、总览-分表一致、加总对得上、列结构/配色/行高合模板。
- **校对只挑错不下场改**;产出《校对意见清单》→ 按 🔴 阻断项/🟡 建议项分级流转 → 改完闭环复核(见「校对发现问题后的处理机制」节)。
- ⚠️ 重型法律校对易撞 600s 超时:按租赁组‖物业组拆小并行;某组反复超时→终审亲自接管核该组(见「校对 subagent 防超时」节)。
#### Step 5: 小Maggie终审
- 合并主审的**法律风险**结论亲手并入 K 列(动作A产出,不经 subagent)。
- **回 07 原件复核 L 列模版差异**(像法律风险一样把关,不全信 subagent)。
- 汇总校对结果、确认每个问题闭环、最终裁判权(校对意见非绝对权威,不采纳须说明理由)。
#### Step 6: 交付前自查 + 存档归位
- **交付前自查(铁律,不是跑完代码就交)**:x2t 渲染 PDF → pdftotext 拍平 grep 验各板块文字完整 → vision 看渲染图验视觉(截断/错位/红色,**图先压<400KB防超时**)。详见 `references/onlyoffice-xlsx-render-and-rowheight.md`、`ocr-rate-symbol-verification.md`。
- **存档归位(Maggie 2026-06-23 纪律)**:汇总表存到**本校区自己的文件夹** `房租物业合同/<校区名>/`,命名 `<校区名/项目名>-梳理-MJ-YYYYMMDD.xlsx`,不放公共目录、不只留本地 /tmp。
- 上传 + scan + 清缓存:
```bash
docker cp <file> <container>:<nc_path>
docker exec <container> chown www-data:www-data <nc_path>
docker exec -u www-data <container> php occ files:scan admin --path=<path>
docker exec <onlyoffice> bash -c 'find /var/lib/onlyoffice/.../cache/files/ -mindepth 1 -delete'
docker restart <onlyoffice>
```
- 交付 Maggie 核对(用 MEDIA: 发),等她最终核对(见「Maggie 审核成果后的修改流转」节)。
#### Step 7: 整合总览sheet(⚠️ 全部校区定稿后才做一次,非单校区步骤)
**现行流程(Maggie 2026-06-22 授权调整,已取代旧的「每做完一个校区即时回填大总览」)**:
- **每个校区先单独做完它自己的汇总表**(Step 0→6),逐个交付给 Maggie 核对、定稿。
- **所有校区都做完、定稿后,最后再统一整合成总览 sheet**——不再每做一个校区就即时回填大总览。
- 总览 sheet 每行一个校区:承租主体、出租方、物业方、面积、期限、租金、物业费、押金、主要风险点、状态→「已梳理」。整合时从各校区已定稿的单表抽取,保证总览与分表一致。
- **理由**:单校区逐个打样定稿(格式/定级口径先在单表上对齐 Maggie 要求)再整合,避免在未定稿的口径上铺开大总览、回头大面积返工。与「打样优先、未定稿不铺开」一脉相承。
- ⚠️ 这是 Maggie **明确授权的 workflow 调整**,已固化于此——按本条执行;其余流程不得擅自改动(见开头「元规则」)。
- 存放:总览表存项目根目录(`履约期内非集采合同-综办/房租物业合同/` 或 Maggie 指定处),与各校区单表(存各自校区文件夹)分工明确。
## 分析报告模板(每校区MD文件)
每个校区的分析报告遵循以下标准结构:
```markdown
# XX校区合同全面分析报告
> **分析立场**:南通新东方(乙方/承租方)
> **合同数量**:X份(描述构成)
> **物业地址**:XXXX
## 一、合同概览
表格列出所有合同:甲方、乙方、位置、面积、期限、签约日期等。
如有多份合同,用总表一目了然。
## 二、租赁合同详情
表格:年租金(含分年列示)、递增规则、免租期、付款方式、押金/保证金、
逾期利率、拖欠解约门槛、提前解约赔偿等。
有补充协议/变更的,按时间线列出变更历史。
## 三、物业合同详情(如有)
表格:物业费标准、付款周期、滞纳金、电费单价、与租赁合同联动关系等。
## 四、终止框架分析
- 确定vs不确定期限
- 提前解约成本估算(确定成本+不确定成本-可收回金额)
- 恢复原状义务
- 免租期追回条款
- 民法典566条/580条适用分析(简要)
## 五、综合风险评级和建议
- 风险评级:🔴高/🟡中/🟢低 + 具体风险项
- 针对性建议(按优先级排列)
```
### 汇总表总览sheet 风险等级配色
```python
# Excel风险等级背景色
red_fill = PatternFill(start_color='FFC7CE', fill_type='solid') # 🔴高风险
yellow_fill = PatternFill(start_color='FFEB9C', fill_type='solid') # 🟡中风险
green_fill = PatternFill(start_color='C6EFCE', fill_type='solid') # 🟢低风险
```
### 总览sheet标准列(12列,已确认模版)
| 列 | 内容 | 宽度 |
|---|---|---|
| A | 序号 | 5 |
| B | 校区名称 | 10 |
| C | 承租主体 | 20 |
| D | 出租方(当前) | 18 |
| E | 物业方 | 18 |
| F | 当前租赁面积(㎡) | 12 |
| G | 租赁期限 | 20 |
| H | 季度租金(元) | 15 |
| I | 季度物业费(元) | 15 |
| J | 押金合计(元) | 12 |
| K | 主要风险点 | 35 |
| L | 备注 | 25 |
> ⚠️ 注意:没有"风险等级"列。风险评级信息写在K列(主要风险点)的开头即可。
> 不要自行添加列——必须与用户确认的模版完全一致。
## 模版对比方法论
> 🔴🔴 **铁律(Maggie 2026-06-23,"记住!!!"):所有"与模版的比对"一律以 `07- 房屋租赁合同.docx` 原件为唯一基准,必须用 python-docx 打开模版原件逐条核对。**
> - **禁止**用"标准商业地产格式""星展商业格式""商业格式常见"等抽象概念当参照系——那是凭印象的二手归纳,不是模版比对。
> - **禁止**拿本 skill 的 checklist/方法论归纳条款当模版替身——清单只是导航,真值在 07 原件 docx 里;每次比对都回原件读真身。
> - 模版原件取法:`docker cp nextcloud-nextcloud-1:"/var/www/html/data/admin/files/小Maggie协作区/南通新东方/参考文件/07- 房屋租赁合同.docx" /tmp/xxx/07模版原件.docx`(注意 `07-` 后有一个空格)。
> - **失效模式(2026-06-23 人民中路+悦拾光实证)**:两份梳理表 L列最初都拿"商业格式"概念写差异、没回 07 原件,结果 ①把模版本身的标配条款(0.1‰逾期、含疫情、优先权…)误当成"本合同特别友好"的优势;②漏掉真实偏离——人民中路第八条抵押被由模版"甲方**不得**抵押"改成"甲方**可**抵押"(对乙方不利)、第十二条办学许可证免责款(模版12.4)被整条删除(教培退出保护缺失)。回原件逐条核才暴露。详见 `references/template-comparison-checklist.md` 顶部铁律。
> - **同源判定**:南通新东方多数租赁合同就是 07 模版填空而成(条款号/措辞/顺序逐条对应),正确定性是"与 07 模版高度同源",差异只在填空值与被改动条款——别把模版标配当本合同特色,也别把"同源合同"误判成"非标准独立友好范本"。
### 关注的模版核心条款
| 条款 | 模版内容 | 对比要点 |
|---|---|---|
| Art.10.2 任意解除权 | 提前X天通知 + 年租金X%违约金 | 是否有此条款、通知期、违约金比例 |
| Art.10.3 甲方终止 | 违约金 + 退押金 + 装修损失公式 | 赔偿是否完整 |
| Art.10.4 逾期付款 | 0.1‰/日 + 15天催缴后X天 | 违约金率、宽限期 |
| Art.11 不可抗力 | 含疫情+行业治理+政策变更 | 范围是否完整 |
| Art.12.4 办学许可证 | 房屋/政策原因无法办证→免责解除 | 是否有此条款 |
| Art.8.4 续租 | 提前1个月通知 | 通知期 |
| Art.9 优先权 | 优先承租+优先购买 | 是否齐全 |
| Art.14.5 非竞争 | 不租给同类机构 | 是否有 |
| 补充条款 | 装修改造+标识广告+增容 | 是否有 |
### 对比原则
- 只关注实质性差异,不比对填空值
- 违约金比例差异必须量化
- 甲方为自然人的合同通常偏差大(非标准格式)
- 物业合同无标准模版,标注"物业服务协议,无对应标准模版"
## 提前退租风险分析框架(参照万达法律意见书)
每个校区的【合同变更与提前解除综合分析】部分,必须按以下框架展开(不是简单罗列条款原文):
### 1. 区分违约金条款的适用范围
- 合同中的违约金条款是否覆盖"无故提前退租"?
- 很多合同的违约金仅适用于列举的特定违约情形(如欠租、擅自转租等),**不能直接适用于主动退租**
- 如有任意解除权条款(模版Art.10.2),则按该条款计算
### 2. 确定责任 vs 不确定责任
| 类别 | 内容 | 说明 |
|------|------|------|
| **确定责任** | 有明确合同依据的(如押金没收、约定违约金) | 直接计算金额 |
| **不确定责任** | 需甲方举证实际损失的 | 列出可能范围 |
不确定责任的三大类:
- **空置期租金损失**:依据《江苏省高级人民法院关于审理城镇房屋租赁合同纠纷案件若干问题的意见》第26条,最长不超过6个月。实际支持金额取决于房屋实际空置时间和甲方是否积极减损
- **免租期租金追偿**:如合同约定了装修免租期,甲方可能主张免租期优惠前提(完整履行租期)不存在而追偿。司法实践中法院酌情处理
- **恢复原状费用**:视合同约定的迁离标准("按现状交付" vs "恢复原始结构")
### 3. 已付未使用租金
- 依据《民法典》第566条(合同解除后的清算规则),承租方有权要求返还已付未使用租金
- 与违约赔偿金额**相互抵扣**后计算净额
### 4. 继续履行风险评估
- 依据《民法典》第580条,租赁合同中承租人使用房屋的义务属非金钱债务,不适于强制履行
- 江苏地区司法实践:承租人明确表示不再租赁甚至已搬离的,法院通常判决解除+违约责任
- 结论:甲方要求继续履行通常不构成实质性法律风险
### 5. 操作建议
按优先级排列:
1. 优先协商解除(合同一般有"协商一致可解除互不担责"条款)——最优路径
2. 尽早发书面解约通知(EMS或可留痕方式)
3. 主动配合房屋交接
4. 注意恢复原状义务(如有)+注销营业执照地址
5. 保留全部往来证据
### 6. 综合成本估算表
风险分析区必须包含一个综合估算,让客户一目了然:
- 确定成本(违约金/押金没收)
- 不确定成本范围(空置+免租期+恢复原状)
- 可收回金额(押金退还/已付未用租金)
- 净成本 = 确定成本 + 不确定成本 - 可收回金额
> **注意**:此框架源自江苏地区司法实践,其他地区可能有差异。法条引用必须核实现行有效版本。
## 跨Session续做铁律
### 1. 维护 PROJECT_STATUS.md
在项目工作目录(如 `/tmp/nantong-hr/`)维护一个 `PROJECT_STATUS.md`,每次做完一批或中断前更新:
```markdown
# XX项目 — 状态文件
## 最新交付物
- 文件名:XXX-20260612.xlsx
- Nextcloud路径:小Maggie协作区/XX/
- 本地副本:/tmp/XX/XXX.xlsx
## 进度(N个校区)
- ✅ 校区A — sheet+总览已填,Maggie已核对通过
- ⏳ 校区B — 待梳理
## 当前任务
补齐XX和YY
## 模版格式
- 总览sheet:12列(列名...)
- 校区sheet:按文件夹分板块,每份合同一行...
```
### 2. 续做时的第一步:找最新交付物
续做时**不能只看本地 /tmp/**——上次的交付物可能只在 Nextcloud 上。必须:
1. 先读 PROJECT_STATUS.md(如果存在)
2. 去 Nextcloud 检查实际最新文件(`docker cp` 拉下来)
3. 打开 Excel 确认实际进度(哪些 sheet 已有、总览哪些行已填)
4. 然后才决定"还差什么"
**反面案例**:只看了本地的旧版 xlsx(20260609),以为只做了1个校区,从头重做了14个校区还换了格式——实际 Nextcloud 上已有15个校区的 20260610 版本。浪费了大量时间且被用户纠正。
### 3. 严格遵守已确认的模版格式
用户说"你看下北翼玖玖的打样"时,**必须逐列核对模版的实际结构**(列数、列名、有无风险等级列等),不能自行"改进"格式。如果认为需要调整格式,先提出建议让用户确认。
### 4. "之前改好的X校区"在哪个文件 → 改前必须确认版本,别在旧版上叠加(Maggie 2026-06-18 万达确立)
用户说"把之前改好的万达也改一下"时,**不能假设手头/主表里的那份就是"改好的"版本**。多校区项目存在两种载体:①独立单校区文件(如世茂样本单独成档)②18-sheet 主汇总表(各校区一个 sheet)。同一校区可能在两处都有,且**版本不同步**。
- **实证**:主汇总表 0612 版里的"万达" sheet,K列仍是 06-17 已被 Maggie 纠正、要降级/删除的旧判断("出租方自然人→偏向甲方"等)——说明 0612 主表里的万达**不是**"改好的"那一版。在它上面加条款号 = 在旧版上叠加,白做。
- **铁律**:改某校区前先 `search_files` 全 Nextcloud + 本地找出该校区的**所有** xlsx 载体,逐个开看哪份是"已改好"的终版(看 K列定级口径是否已对齐最新规则),**版本不明就停下来问 Maggie**,别动手。
- 牵连面:改 18-sheet 主表会重存整个文件(影响全部校区),范围比改单校区文件大,更要先确认动的是不是对的载体、是不是该动这个范围。
## Pitfalls
### 1. OnlyOffice合并单元格行高不自动扩展
合并单元格(如风险分析区A:L合并)设置`height=None`(自动)在OnlyOffice中不生效,内容会被截断。**必须手动计算并设置行高**。
估算方法:
1. 对每行的每列,计算可视行数:将文本按`\n`拆分,每行再按列宽折行(CJK字符占2单位宽,ASCII占1,每行可容纳约 `col_width × 1.2` 个字符单位)
2. 对合并单元格,有效列宽 = 所有合并列宽度之和(如A:K合并=231单位)
3. 取每行中可视行数最大的列
4. 行高 = 可视行数 × 15pt + 20%余量
5. **每次新增内容到K/L列或风险分析区后,必须重新计算该行行高**——不要假设原来的高度还够
> 📐 **行高 409.5/409.6pt 不是 xlsx 天花板,是 OnlyOffice 网页编辑器的 clamp 值**(2026-06-17 实测厘清):openpyxl 从文件层写 900pt 能保留、OnlyOffice x2t 引擎也不 clamp;只有在**网页版编辑器里打开保存**才会把超限行高压回 ~409.5。所以"调高行高显示全部内容"可行——只要从脚本写、走交付链路上传,别再用网页端编辑保存。完整三层行为、x2t round-trip 测法、截断 vs 数据完整的区分见 `references/onlyoffice-xlsx-rowheight-rendering.md`;行高估算用 `scripts/xlsx-rowheight-analyze.py <文件.xlsx>`(只读,标出"当前行高 < 建议行高"的行)。**注意**:若 Maggie 说"就按当前最高行距、不用调"则保持现状不折腾——能调高≠该擅自调(方案≠授权)。
### 1b. 局部编辑已交付 xlsx:openpyxl 只改 value 保格式 + 长单元格 PDF 截断真相(2026-06-17 万达打样)
Maggie 审核后要改某些单元格(如给法律风险列补条款标注)时,**不重新生成整表**,用 openpyxl 局部改:
```python
import openpyxl, shutil
shutil.copy2(SRC, OUT)
wb = openpyxl.load_workbook(OUT) # 不加 data_only,保留公式/样式
ws = wb['万达']
ws.cell(row=5, column=11).value = new_text # 只赋 value,字体/换行/对齐/填充/合并/行高自动保留
wb.save(OUT)
```
- **只赋 `.value` 不动 `.font/.alignment/.fill`**,样式自动保真。改完务必跑保真核对:逐项比对旧/新单元格的 `font.name`、`font.size`、`alignment.wrap_text`、`alignment.vertical`、`merged_cells.ranges` 数量、`row_dimensions[r].height` 是否一致。
- **定位长单元格别靠肉眼数行**:先 `ws.cell(row,col).value[:30]` 确认目标,写入后用 `关键词 in str(cell.value)` 验证内容到位、原错误词清零。
- ⚠️ **长单元格在 PDF/打印导出会被列宽截断,但数据层完整、OnlyOffice 在线编辑视图完整**(2026-06-17 实证:870字符的法律风险单元格,OnlyOffice x2t 导 PDF 后 pdftotext 提取不到条款标注,一度误判"写丢了")。排查时**别用 PDF 文本提取来验证 xlsx 内容是否写入**——要直接 `openpyxl ... data_only=True` 读单元格 value 确认。截断只是导出视图的固有限制(行高920磅+自动换行在编辑视图里足够容纳20行),不是写坏。若客户最终要打印/导 PDF 给客户看,才需另调版式(拆分单元格或缩字号),平时不用管。
- 交付命名走 Maggie 后缀式:`原名-rev. MJ-日期.xlsx`(见 file-naming-convention skill)。
- ⚠️ **pdftotext 验证长单元格文字完整性必须先去折行再 grep,否则假阴性(2026-06-22 世茂实证)**:x2t 渲染 PDF 后用 `pdftotext` 提取来验证某长句是否完整写入时,pdftotext 会**按单元格列宽把长句折行**(如"未明确具体月份(如是否为12月\n15日)"被换行符断开),直接 `grep "完整句"` 会**全部 ❌ 假阴性**,极易误判成"文字截断/写丢"。正解:先 `tr -d '\n' | tr -d ' '` 把整页拍平成单行,再 `grep` 各关键句——本次拍平后六段全 ✅,证明只是渲染折行、文字完整。**别拿带折行的 pdftotext 输出判截断**(同 Pitfall 1b"别用 PDF 文本提取验证 xlsx 内容"的延伸:要么读 xlsx 数据层,要么 pdftotext 拍平后再比对)。
- **交付前渲染自查(铁律,不是跑完代码就交)**:用 OnlyOffice 的 x2t 引擎(Maggie 同款)把 xlsx 渲染成 PDF 看一遍,再用 pdftotext grep 各板块末尾锚点确认无截断。完整配方+权限坑+行高409.5上限真相见 `references/onlyoffice-xlsx-render-and-rowheight.md`。行高统一 **409.6pt**(Maggie 2026-06-17 拍板"按当前最高行距",不再调更高)。
- **🟢 交付前加一道 vision 视觉验收(2026-06-22 vision 配好后确立)**:x2t 渲染 PDF→`pdftoppm` 转 PNG→`vision_analyze` 看图。实测能抓出**纯文字提取(grep)发现不了**的问题:① 红色标记是否真渲染成红色(配合 PIL 像素检测 `(R>120)&(G<90)&(B<90)` 数红像素双重确认)② 文字视觉截断/版面错位 ③ 跨页切断。这是"文字提取验证"的盲区补充——grep 只能证明文字在数据层,看不出视觉呈现。两层都过(pdftotext 拍平 grep 验文字完整 + vision 验视觉呈现)再交。
- 🔴 **vision 报"截断"先区分「PDF 分页切断」vs「真数据丢失」,别误判返工(2026-06-22 悦拾光实证)**:vision 看 x2t 渲染图报某超长行(如 736pt 的付款清单)"底部被切断、内容缺失"时,**先回数据层核**:① openpyxl 读该单元格 value(富文本用 `''.join(t.text...)` 取全文)确认内容完整、② 行高已设足够、③ 全 PDF(不只那一页)pdftotext 拍平 grep 该末尾内容——若三者都在,则 vision 看到的"截断"是 **PDF 分页边界把超长行切到下一页**的视觉现象,在 Excel/OnlyOffice 滚动查看完全正常,**不是数据丢失、不需返工**。只有"打印/导PDF给客户看"场景才需优化分页。区分判据:数据层完整 + 跨页能搜到 = 分页现象(不动);数据层就缺 = 真丢失(修行高/内容)。这与 Pitfall 1b「长单元格 PDF 导出截断但数据完整」同源——视图截断 ≠ 数据坏。
### 2. 核心内容栏不放基础设施规格
"最大供电≥150kW"等基础设施配套约定不是核心商业条款,不放I列(核心内容)。核心内容聚焦于:租金、违约金、解除权、优先权、不可抗力等对业务有实质影响的条款。
### 2b. 租赁标的(E列)房号/铺号写全,不用"等X铺"省略(Maggie 2026-06-18 世茂确立)
E列租赁标的的具体房号/铺号要**全部写上,方便查阅**,不要用"二层18-107-3等5铺"这种省略式。
- 改法:把"二层18-107-3**等5铺**"写全为"二层18-107-3、18-108-2、18-110-2、18-111-2、18-112-2号商铺(套内968.28㎡)"。
- ⚠️ **物业合同的房号以物业合同自己的原文为准核对**,不能直接套租赁合同的(虽多半相同,仍要回物业 OCR 原文核一遍——世茂物业第51行确含全部5房号,与租赁一致)。
- 顺手补套内面积,查阅更完整。
- 这条与"H列金额标条款号""K列风险标条款号"同属一个 Maggie 偏好:**交付物要可核对、信息要完整,不图省略**。
### 3. openpyxl heredoc字符串陷阱
在Python heredoc/f-string中写中文+引号混合内容容易触发SyntaxError。建议用`lines.append()`逐行构建长文本,不用多行字符串拼接。
### 4. OCR大文件用后台进程
4份以上大PDF(>5MB每份)在单个`execute_code`中会超300秒。写OCR脚本到临时文件,用`terminal(background=true, notify_on_complete=true)`运行:
```python
# Write script to /tmp/ocr_batch.py, then:
terminal(command="python3 /tmp/ocr_batch.py", background=True, notify_on_complete=True, timeout=900)
```
OCR跑着的同时,可以并行处理其他校区(先做文件少的校区的OCR+分析)。收到完成通知后再回来做分析和填表。
### 5. 盘点时必须包含空目录
文件夹存在但暂无PDF文件的校区(如待上传的)仍要列入总数和处理清单,标记为"待上传"。不要只统计有PDF的目录——会导致总数与总览sheet不一致。
### 7. 每完成一个校区就上传并发给用户确认
不要攒批——做完一个校区立即上传+验证+**用MEDIA:标签发给用户审阅**,确认格式和内容无误再做下一个。用户明确要求"分析完X先发我看下",逐个交付是硬性要求。
### 8. 检查同一校区是否有配套法律意见书
处理新校区时先搜索Nextcloud相关目录(不止合同目录,也查同名的独立项目文件夹,如`万达校区租赁/`),看是否有已出具的法律意见书。有的话提取核心结论纳入风险分析和K列。
### 9. 企微发文件用MEDIA标签
**不要用send_message工具发企微文件**(不支持)。在回复正文中写`MEDIA:/path/to/file`,gateway自动处理。详见 wecom-file-send-receive skill。
### 10. Nextcloud文件上传可能中断(Cloudflare Tunnel限制)
Nextcloud通过Cloudflare Tunnel暴露时,大文件(>1MB)上传会被截断——日志报"预期文件大小为X字节,实际写入Y字节",物理目录只有`.part`/`.ocTransferId*`碎片。
当用户说"文件已上传"但`find`找不到PDF时:
1. `php occ files:scan` 重新扫描
2. 检查物理目录是否有 `.part` 碎片(`find <path> -name '*.part'`)
3. 查MariaDB确认文件是否注册:
```sql
docker exec nextcloud-db-1 mariadb -u nextcloud -p<password> nextcloud -e "
SELECT f.fileid, f.path, f.name, f.size FROM oc_filecache f
WHERE f.parent IN (<parent_ids>) ORDER BY f.path;"
```
(DB密码在Nextcloud config.php的`dbpassword`字段,不是用户密码)
4. 如确认上传未完成,**不要反复让用户重试网页上传**——Cloudflare Tunnel的问题会持续存在
**替代上传方案**:请用户通过企微私信发文件给小Maggie,文件自动保存到`~/.hermes/cache/documents/`,然后用`docker cp`放入Nextcloud:
```bash
docker cp '<local_path>' <container>:'<nc_path>/<filename>'
docker exec <container> chown www-data:www-data '<nc_path>/<filename>'
docker exec -u www-data <container> php occ files:scan admin --path='<scan_path>'
```
### 11. delegate_task并行批次规划
按复杂度分三档并行处理(每批最多3个slot,是delegate_task的并发上限):
- **简单**(1-2份合同):可以多个校区塞进1个subagent处理(如1个slot做4个简单校区)
- **中等**(2-4份合同):每个校区1个slot
- **复杂**(5+份合同):每个校区1个slot,context需列出所有文件路径
典型3批调度:
```
Batch 1: [星月+解放+跃龙+通大(1 slot简单)] [通大附+通州金鹰(1 slot简单)] [万达(1 slot中等)]
Batch 2: [凤凰文化(1 slot)] [悦拾光(1 slot)] [人民中路(1 slot)]
Batch 3: [世茂(1 slot)] [金飞达(1 slot复杂)] [北翼玖玖(1 slot复杂)]
```
### 12. 总览sheet校区总数必须与目录一致
盘点校区时必须数目录数(包括空目录),不能只数有PDF的目录。出现空目录说明文件待上传,标记为"待上传"而非跳过。用户会核对总数。
### 13. 用户说"这个项目继续"时,先确认是哪个项目
用户说"继续做"、"接着做"等模糊指示时,不要猜——先用session_search查最近的相关session确认。Maggie有多个并行项目(宠物医疗手册、合同梳理、KnowHow协议等),搞错项目浪费双方时间。如果不确定,直接问。
### 14. 不要跨文件夹重新归类合同
客户的文件夹结构(房租/扩租/物业等)是sheet的板块划分依据。即使物业合同在"扩租"文件夹里,也要放在"扩租系列"板块——不能按合同性质重新归类到"物业系列"。客户对着文件夹找文件,必须一一对应。(用户20260609明确纠正过此问题)
### 15. subagent生成的JSON结构必须统一
并行调度多个subagent时,context中必须明确约定JSON输出格式(字段名、数据类型)。不同subagent可能用不同的key名(如`sections` vs `rows`、`risk_summary`是str还是dict),写入Excel时需要额外处理兼容。建议在context中给出JSON schema示例。
### 16. 租赁+物业双合同:客户在两份里的当事人身份常相反,填 D列勿混(2026-06-22 人民中路确立)
同一校区的租赁合同与物业合同里,客户(新东方)的身份**经常相反**:租赁合同里新东方是**乙方(承租方)**;物业合同里新东方常是**甲方(业主/付费方,向物业公司付费)**。填 D列当事人时**逐份回原文核"甲方/乙方分别是谁"**,别因为"都是新东方的合同"就套同一方向。人民中路实证:租赁甲方=琳大鞍(出租)、乙方=新东方;物业甲方=新东方(付费)、乙方=华光物业。处置:物业行 D列主动加注"本合同中新东方为甲方,与租赁合同当事人方向相反"防误读;**审查立场也随身份切换**——审租赁站承租方(乙方)立场,审物业站付费方(甲方)立场。
### 17. 行2基本信息等"长横向信息行"用 \n 换行排版,防 PDF 渲染右侧截断(2026-06-22 人民中路 vision 验收确立)
合并单元格(A2:L2)里塞一长串"项目 | 出租方 | 物业方 | 承租方"信息时,若写成**单行**,x2t/PDF 渲染会因超出页宽被**右边距截断**(人民中路初版"物业方"后的公司名被切掉,是 vision 视觉验收发现的)。正解:长信息行按主体**用 `\n` 分行排版**(项目一行、出租方+物业方一行、承租方一行),并把行高调够(3行约46pt)。这与 Pitfall 1(行高纵向截断)是两个轴:Pitfall 1 防纵向截断、本条防横向截断。**交付前 vision_analyze 看渲染图能抓出这类横向溢出**——是 vision 工具配好后新增的一道视觉验收价值点。
### 18. 🔴 新建/增补单校区汇总表:第一步加载本 skill + 对照已确认样本,禁止 openpyxl 裸做(2026-06-22 悦拾光教训)
被要求「做好/做一下某校区汇总表」时——哪怕指令看起来很简单——**第一步是加载本 skill 并对照已确认的样本(如世茂单校区表)逐板块复刻**,绝不直接 openpyxl 从头裸写。裸做必然漏标准板块、跳过校对。
- **悦拾光实证(两处当场被 Maggie 指出)**:① 裸做的悦拾光表**漏了「校区整体风险分析与建议」段**(skill「Sheet结构」明确要求每校区 sheet 末尾必有此板块,合并 A:L,含整体评价/主要法律关注点/提前解约成本/续签建议——见 ⑧ 整体风险分析段);② 整个**三角色 workflow(承办→校对→终审)被跳过**,没走 `delegate_task` 法律校对‖格式校对,没做终审闭环。
- **铁律①——整体风险分析与建议段是必须板块,单校区/新增校区表同样要有**:不因「只是一份表/只有一个校区」省略。它是校区 sheet 的收口板块,与逐条风险列同等必备。
- **铁律②——指令看似简单 ≠ 可绕过 workflow**:Maggie 给「做好汇总表」这类简短指令时,**仍要走完整 workflow**。她验收时会检查两件事:(a) 标准板块是否齐全(尤其整体风险分析与建议段);(b) 是否真走了 workflow。两者缺一即返工。
- **根因**:把「做表」误判为机械活、绕过 skill 直接裸写代码——于是 skill 里所有沉淀(板块结构、三角色、定级纪律、整体分析段)全部失效。**做表是法律梳理交付物的最后一公里,不是画格子;必须在 skill 框架内做。**
- 落地自检(动手前过一遍):① 我加载本 skill 了吗?② 我对照样本核过板块清单了吗(含整体风险分析与建议段)?③ 我走 workflow / 三角色校对了吗?三个都「是」才动手交付。
### 19. ✅ 列结构口径已裁定:校区详情 sheet = 12 列含独立 L 列(Maggie 2026-06-23 裁定,原矛盾已消除)
**背景(历史教训,留作记录)**:skill 内部曾对汇总表列数有两套未对齐的说法——SKILL.md 正文 Step3、第358行一度写"11 列、模版差异并入 K 列",而 `column-structure.md`、`independent-legal-review-framework.md`「分列」、增量维护 SOP「动作B独立产出」均为"12 列含独立 L 列"。2026-06-23 复盘提请 Maggie 裁定。
**✅ 裁定结果(唯一口径)**:**校区详情 sheet = 12 列,K 列装法律风险(动作A)、L 列「与标准模版差异」装模版差异(动作B),两者物理分列、绝不并入。** 此前的"11 列/并入 K 列"旧表述全部作废,相关位置(SKILL.md Step3 第525行、第363行、column-structure.md 顶部)已于 2026-06-23 同步更正一致。
- **为什么 12 列对**:与「模版差异 ≠ 法律风险」铁律严丝合缝——两件不同性质的事(法律风险 vs 合规差距)就该物理分列,挤在 K 列必然让下游误读。多数 reference 文件本就是 12 列口径,"11 列"是某次临时改动没回滚干净的异类。
- **模版差异内容铁律不变**:L 列内容**必须回 07 原件逐条核**(见「模版对比方法论」顶部铁律 + 填表分工节的 subagent 强制项),列数已定不影响这条,反而强化它。
- **教训**:skill 内部出现"两套说法"时,不应自己"倾向判断"某一套就默认执行(当时我倾向了错的"11 列"),而应提请 Maggie 裁定 + 裁定后立即全文对齐消矛盾——这正是本次的正确处理路径。
### 20. ⚠️ 三条「合同审查」轨道必须精确区分,别把本梳理线笼统叫「workflow」(2026-06-23 三轮追问教训)
环境里有**三条名字都含「合同审查」、但性质完全不同**的轨道,极易混为一谈。Maggie 2026-06-23 连问三次(「workflow里模版对比」→「南通新东方租赁合同审查的workflow」→「这个流程」)才让我对准——根因是我把**本 skill 的梳理线**笼统称作「workflow」、还一度跟 uwf 的 `review-contract.yaml` 混了。Maggie 是律师、要求术语精确(USER.md:不用模糊比喻指代有精确定义的技术对象),含糊命名本身就是返工信号。
| 轨道 | 归谁 | 走什么 | 模版对比? |
|---|---|---|---|
| **A. 批量合同审查** | Doro/邱律师团队 | uwf `review-contract.yaml`(classifier→reviewer→editor→复核→deliverer 五角色流水线) | ❌ 不做模版对比 |
| **B. 单份文件独立审核** | 南通新东方(Maggie 派) | `nantong-xindongfang-review` skill 的**手动**reviewer+editor 合一模式(**明确「不走 workflow」**) | ❌ 不做模版对比 |
| **C. 多校区梳理台账** | 南通新东方(Maggie 派) | **本 skill**(contract-portfolio-analysis)的 Step0→5 + 三角色 | ✅ **模版对比(L列)只在这条线**,回 07 原件 |
- **要害**:用户问「南通新东方租赁合同审查的 workflow / 模版对比」时,**99% 指的是 C(本 skill 梳理线)**——因为模版对比(L列)只活在 C。别下意识跳到 uwf 的 `review-contract.yaml`(那是 A,与南通新东方严格隔离、且根本不做模版对比,grep 它零命中模版内容)。
- **命名纪律**:C 这条线在跟 Maggie 沟通时,称「**南通新东方租赁合同梳理(组合分析)**」或「本 skill 的 Step0→5 流程」,**不要笼统说「workflow」**——「workflow」一词在本环境特指 uwf 那套 YAML 状态机(A),混用会让律师用户反复追问到底指哪条。本 skill 内部把 Step0→5 叫「workflow」是历史习惯(见「元规则」节),但**对外指代时要带限定词**说清是哪条线。
- 自检:被问到「合同审查的某个环节」先定位是 A/B/C 哪条,再答;拿不准就先回一句「你指的是 Doro 批量那条、南通单份审核、还是南通梳理台账?」一句话锁定,比答错三轮强。
### 21. 🔴 校区数/任何「总数」必须用精确列举得出,绝不眼估——南通新东方是 17 个校区(2026-06-23 教训)
**栽点**:我在 SKILL/脚本/记忆里写「21 个校区」,是扫了一眼 `find ... -type d` 的输出**眼估**的——那次 find 把 `参考文件/`、`万达校区租赁/`、`HRD协商解除/`、`业务合同-培训服务/` 等**非校区目录**也列进来了,我没数就拍了个数。Maggie 当场抓出「你为什么说是 21?是 17」。**最讽刺的是:这正发生在我为「不准凭印象、要逐字核实」写存档的当口**——立规矩的同一下笔就犯了规矩。
- **铁律:任何进交付物/skill/记忆的「数量、总数、覆盖率」(校区数、合同份数、N/N 覆盖、行数…)必须由精确命令得出,并把得数的命令一并留痕**,绝不眼估、绝不凭印象续写上次的数。
- **数校区的唯一正确姿势**:在 `房租物业合同/` 目录内跑 `ls -1d */ | wc -l`(只数子目录、不混入文件),或 `ls -1d */` 逐个列名核对——**不要用 `find -type d`**(它会把上层目录、参考文件、非校区项目目录全捞进来,计数虚高)。
- **南通新东方 = 17 个校区**(2026-06-23 精确核定):万达、世茂、人民中路、凤凰文化、北翼玖玖、南通大厦、小石桥晏园、悦拾光、星月、桃坞路、解放中路、跃龙路、通大、通大附、通州金鹰、金飞达、龙信。注意 `参考文件/`、`万达校区租赁/`(独立法律意见书目录)、`HRD协商解除/`、`业务合同-培训服务/`、`国际青创园租赁/`、`交通银行薪酬代发合作/` **都不是「房租物业合同」下的校区**,别误计入。
- **闸门脚本是数量的真相源,不是写死的数字**:`campus-workflow-gate.py` 用**实时 `ls`** 定位校区,靠它而不是任何文档里抄来的数字;文档里出现的「17」只是给人看的提示,若将来校区增减,**以脚本实时列举为准**,并回头改文档别留旧数。
- 这条是「第一铁律·逐字通读」「开工铁律·单校区独立闭环」在**计数动作**上的同一抓手:判断要回原文,**计数要回精确列举**,两者都禁印象式推断。
### 22. 🔴 改本 skill 自身的「多处联动规则」(SKILL.md + 闸门脚本 + reference 三处口径):一次一处原子改 + 改完 grep 验,别在同一轮里又 patch 又长篇说话(2026-06-23 编号统一耗时 40 分钟教训)
**栽点**:统一 Step 编号时,SKILL.md 正文、`scripts/campus-workflow-gate.py`、顶部引用三处要同步改。我连续几轮把 `patch` 调用和一大段解说塞在**同一轮回复**里,patch 没真正落地(被下一条用户消息打断/未执行完),我却**没在第一次核实发现「没落地」时就换方法**,反而重复同样的动作好几轮——直到 Maggie 问「为什么这么久,哪里卡住了」。本质是违反了本 skill「不能假设成功、要核实;发现没成功要立即换方法」的同一条纪律,只不过对象从合同换成了 skill 文件自己。
- **铁律①——一次一处原子改**:改多文件联动规则时,**一个 `patch`/`write_file` 调用只做一处改动,不在同一轮夹带长篇解说**。把「改」和「说」分开:先把这一处改干净、拿到成功回执,再说话/再改下一处。夹带 prose 的复合轮最容易让编辑动作没执行完就被打断。
- **铁律②——改完立即 grep 验残留,不靠「我以为改了」**:每改一处,紧接着用 `search_files`/`grep` 扫**旧串是否清零、新串是否到位**(如统一编号后 `grep "Step 3.5\|Step 0→5\|完整 6 步"` 必须为空)。没亲眼看到「旧串 0 残留 + 新串就位」之前,绝不说「改好了/检查好了」。这是「第一职业纪律·结论必有依据、自己核实」在改自己文件时的同一抓手。
- **铁律③——多处口径必须全绑定一起验**:Step 编号、列结构(12列/L列)、校区数这类「同一事实散落多文件」的口径,改完跑一次**全树扫描**确认所有副本一致(`grep -rn <旧口径> SKILL.md scripts/ references/`)。本 session 正面案例:最后用一次全树 grep 确认「✅ 全树零残留」+ 实跑闸门脚本看输出,才给出有依据的「好了」。
- **判据**:凡是「同一规则要改 N 个文件」的维护任务,N 越大越要原子化 + 每步验,绝不攒成一个大复合轮。被用户追问「卡在哪」时,先如实承认「前面几轮的编辑没落地、我没及时换方法」,再用原子改一次性修干净——不要继续掩饰式重试。
### 23. 🔴🔴 执行纪律:工具调用单独发、不与长篇 prose 同轮;落地用磁盘核实不靠「我以为」;被打断/没落地立即换方法不重复死动作(2026-06-23 人民中路实跑 40 分钟空耗教训,最高频反复犯)
**这是本 session 反复犯、被 Maggie 连环追问(「为什么这么慢」「哪里卡住了」「跟我发消息没关系,这个时间你早该完成」)的头号执行问题,比任何内容规则都更先拖垮交付。** 与 Pitfall 22 同根,但适用面是**所有任务执行**(OCR、读合同、跑脚本、改文件……),不限于改 skill 文件。
- **根因机制(必须正视)**:把「工具调用 + 一段解说话」塞进同一轮回复时,工具要等 prose 写完才执行;用户此时若发新消息,**这一轮被接管、那个还没跑的工具调用直接被丢弃**——不是工具坏,是它根本没执行。表现就是「我以为取了 07 模版/读了那两页,实际磁盘上没有」。而「慢」的体感来自:提交→被丢→下一轮先花一次工具核实没落地→再重做,一来一回空转。\n- **铁律①——动作与解说分轮**:要跑工具就**这一轮只发工具、最多一句话**,结果回来再解释/再决定下一步。绝不「边长篇说边夹个 patch/terminal」。prose 越长,被打断丢弃的窗口越大。\n- **铁律②——每轮先核实再行动,绝不假设上一步成功**:接用户消息的第一个动作 = 用一条命令查磁盘真实状态(`ls -la 工作目录` / `wc -l 产物`),确认上一步到底落没落地,再决定干什么。这是「不能假设成功」在执行层的落地,也是被打断后**唯一正确的续跑姿势**——产物落盘可续,核实即接上,不重来不做丢。\n- **铁律③——发现「没落地」立即换方法,绝不重复同一死动作**:同一个调用连续两轮没成功,就是信号——停下,换更简单/更原子的方式(如把复合 patch 拆成单行替换、把「边说边改」改成「纯工具一发」),而不是第三次第四次重复一模一样的提交。本 session 正是重复了好几轮才换法,才空耗 40 分钟。\n- **铁律④——被追问进度先如实承认,不掩饰**:用户问「卡哪了/为什么慢」时,先用一条命令核实当前真实进度并如实报「X 步没落地、根因是我边说边做被丢、我没及时换方法」,再原子修干净。绝不含糊搪塞「快好了」或继续掩饰式重试——Maggie 明确反感把她当测试员、反感空转。\n- **落地自检(每次要发工具前过一遍)**:① 这一轮我是不是又在「长篇说话 + 夹工具」?是→拆开,先发工具。② 上一步我**亲眼**在工具输出里见到成功回执了吗?没有→先核实别假设。③ 同一动作我是不是已经连试两轮没成?是→换方法别再重复。\n- 这条与「第一职业纪律·结论必有依据自己核实」「Pitfall 22·一次一处原子改+grep 验」三位一体:22 管改 skill 文件、本条管一切任务执行,核心同一句——**少说多做、单发即验、不假设、不空转**。
## 参考文件
- `references/file-inventory-classification.md` — **文件盘点与归类规则**:校区首现时建立,租赁/物业→场所→签约时间,贯穿全流程不跨文件夹重排
- `references/ocr-rate-symbol-verification.md` — **OCR 费率符号核对配方(‰ vs %)**:双跑交叉(整页 vs 裁图放大重 OCR)、量级常识闸门、两次不一致即升级人工带裁图、vision provider 未配退路
- `references/independent-legal-review-framework.md` — **独立法律审查框架(动作A,八维)**:把每份合同当新合同全面审,区别于模版比对
- `references/incremental-maintenance-sop.md` — **增量维护 SOP**:新增/到期/提前解除三类变动的三角色处理流程
- `references/chinese-diagram-rendering.md` — **中文流程图/图表渲染**:matplotlib 豆腐块根因+修复,HTML 首选方案,无法自检图像时的退路
- `templates/lease-review-flowchart.html` — HTML 流程图起始模板(语义配色、div+箭头字符,中文零乱码)
- `references/column-structure.md` — 12列Excel结构详细说明
- `references/onlyoffice-xlsx-rowheight-rendering.md` — **OnlyOffice 行高/合并单元格截断/渲染核查**:409.5pt clamp 真相(文件层 vs x2t vs 网页编辑器三层行为)、x2t round-trip 测 clamp、数据完整≠视图不截断、可复用 SOP
- `scripts/xlsx-rowheight-analyze.py` — **行高分析脚本**(只读):估算每个长单元格所需行高,标出可能截断的行
- `scripts/fix-richtext-rpr-order.py` — **富文本 rPr 顺序修复脚本**:openpyxl 标红(CellRichText)后把 `<rPr>` 子元素改成 Excel 合规顺序(rFont→sz→color)。⚠️ **实证:修了顺序 Excel 仍报"需要修复"**,本脚本不保证解决问题,仅作记录。支持 `--check` 只检查。**正解是别用富文本标红,用纯文本前缀。**
- `scripts/edit-redmarked-xlsx.py` — **安全编辑「已标红(WPS规范化)」xlsx 的脚本+工具库**:绝不用 openpyxl 重存(会毁红色),在 sharedStrings.xml XML 层外科手术只改目标 `<t>`、红 run 不碰。含 `--verify` 五查(sharedStrings在/红色数/zip+XML完整/Content_Types置首/与基线同构)、`--map`(单元格→si索引)、`--show-si`(看 run 结构),及可 import 的 `surgical_edit_si/delete_run_and_renumber/repack`(已验证正确,照抄别重写)。改红标 xlsx 必用。
- `references/openpyxl-excel-richtext-pitfall.md` — **openpyxl 富文本→Excel"需要修复"陷阱全记录**:为什么不能用 CellRichText 局部着色、试过的所有修法(rPr 顺序/charset/去富文本全失败)、为什么 WPS/x2t/openpyxl 都骗过自己唯独 Excel 报错、"本地验不了 Excel 就如实告诉用户别当测试员"的行为铁律、正解(纯文本前缀)。
- `references/template-comparison-checklist.md` — 标准模版对比清单
- `references/termination-risk-framework.md` — 提前退租风险分析框架(法律依据+分析模板+关键判断点)
- `references/nextcloud-file-diagnostics.md` — Nextcloud文件上传失败排查步骤(含MariaDB查询方法)
- `references/onlyoffice-xlsx-render-and-rowheight.md` — **交付前渲染自查配方**(x2t引擎+权限坑)+ 行高409.5上限真相(网页编辑器clamp根因,统一409.6)