# Pre-Modified File Detection (v1.x with Existing Tracked Changes) ## Problem Files arriving as "v1.x" or similar versions may already contain tracked changes from other parties (e.g., the counterparty's legal team). The review-rules state: "已有他人的修订模式保持原样不动,不接受也不拒绝,只叠加我们自己的审查修改." ## Technical Impact 1. **python-docx `paragraph.text`** only shows non-tracked-change text (skips content inside `w:ins` elements), so it does NOT reflect the "accepted state" of the document 2. **ContractEditor.tracked_replace** searches through ALL text including `w:ins` content — search strings must match the accepted state 3. **ContractEditor.tracked_replace may fail** when the target text spans across or is inside an existing `w:ins` from another author (lxml parent-child mismatch) ## Detection Procedure ```python from lxml import etree ns = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'} # 1. Detect existing tracked changes and identify authors ins_els = editor.body.findall('.//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}ins') authors = set() for ins in ins_els: author = ins.get('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}author', '') if author: authors.add(author) # If authors contains names other than 'WB', the file is pre-modified ``` ## Reading the Accepted State ```python def get_para_accepted_text(p): """Get paragraph text as it would appear with all changes accepted.""" text = '' W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' for t in p.iter(f'{{{W}}}t'): if t.text: parent = t.getparent() in_del = False while parent is not None: if parent.tag == f'{{{W}}}del': in_del = True break parent = parent.getparent() if not in_del: text += t.text return text ``` ## Workflow When Pre-Modified File Detected 1. **First pass**: Read accepted state of all key paragraphs to understand current document content 2. **Compare** accepted state vs what python-docx `.paragraphs[].text` shows to identify what's been changed 3. **Assess** which of our review issues have already been addressed by the existing modifications 4. **Only add** our own changes for issues NOT already covered 5. **If tracked_replace fails** on text inside another author's `w:ins`: the text is already part of someone else's tracked change. Options: - Skip if the existing change already addresses our concern - Use direct XML manipulation to add our `w:del` + `w:ins` around the problematic text (complex, error-prone) - Note it as "already addressed by [author]" in review notes ## 2026-07-06 Case Study (健康云服务费-赵巷v1.2) - File arrived with tracked changes from authors: 祺帆, 社区, 俊玮 吴 - python-docx showed P59 as "2026年1月20日" but accepted state was "2026年11月20日" (already fixed by 祺帆) - P26 (1.4 侵权条款) already had robust language added by 祺帆 - P109 (7.4) already had comprehensive损失赔偿 language added by existing changes - P115 (8.2) had double period due to 祺帆's ins adding "向甲方所在地法院提起诉讼。" after original "则。" — required manual XML w:del to fix the trailing original period - P118 (9.1) already had 转包连带责任 language added **Key lesson**: Without reading accepted state first, we would have duplicated 5+ modifications already made by other parties.