should be `$X(t) delivery-assurance · Skills-SI Market , or `\\mu delivery-assurance · Skills-SI Market should be `$\\mu delivery-assurance · Skills-SI Market \n\n - Common cause: a sed/cleanup script stripped the opening ` delivery-assurance · Skills-SI Market but left the closing ` delivery-assurance · Skills-SI Market \n\n - Fix: ensure every math expression has matching `$... delivery-assurance · Skills-SI Market or `\\[...\\]` delimiters\n\n - **Do NOT use broad sed patterns to fix math** — read each error location and fix individually\n\n2. **LR mode errors** (`Not allowed in LR mode`):\n\n - Usually caused by `\\begin{figure}` or `\\begin{table}` inside a paragraph without proper separation\n\n - Fix: add `\\par` or blank line before the float environment\n\n3. **Undefined control sequence**:\n\n - Missing package → add `\\usepackage{xxx}` to 论文正文.tex preamble\n\n - Typo in command → fix the command name\n\n4. **BibTeX failures**:\n\n - If BibTeX fails because of earlier LaTeX errors, fix the LaTeX errors first, then recompile\n\n - Verify that `\\bibliography{references}` and `\\bibliographystyle{plainnat}` exist in 论文正文.tex\n\n - Verify that references.bib has no syntax errors (unmatched braces, missing commas)\n\n**After each fix, recompile and reverify:**\n\n```bash\n\ncd 论文/\n\nxelatex -interaction=nonstopmode 论文正文.tex\n\nbibtex 论文正文 2>&1 | tail -5\n\nxelatex -interaction=nonstopmode 论文正文.tex\n\nxelatex -interaction=nonstopmode 论文正文.tex\n\ncd ..\n\n# Reverify\n\nMATH_ERR=$(grep -c 'Bad math environment delimiter\\|Missing \\$ inserted' 论文/编译日志.log 2>/dev/null || echo 0)\n\necho \"Remaining math errors: $MATH_ERR\"\n\n```\n\n**⛔ Do NOT proceed to Step 5 until MATH_ERR = 0 and LR_ERR = 0.** BibTeX will also fail if there are LaTeX errors upstream — fix LaTeX first.\n\nWhen fixing errors in 论文正文.tex, only fix the specific error (e.g., add a missing package, fix a typo). Avoid rewrite or restructure 论文正文.tex — the template's preamble, cover page, page margins, section numbering format, and header/footer settings must remain unchanged.\n\n### 执行节点 5:Post-compile checks\n\n```bash\n\nbash 工具/compile_check.sh 论文/ 2>/dev/null || bash skills/shared-scripts/compile_check.sh 论文/\n\n```\n\nThe script checks: PDF existence/size, undefined references, overfull hbox, TOC, abstracts, bibliography entries, citation count, citation format (上标/顺序/合并), unused figures, figure stacking, TikZ diagram presence.\n\n**⛔ MANDATORY: 引用格式问题必须修复(不可忽略):**\n\ncompile_check.sh 会检查 3 类引用格式问题,任何一类 FAIL/WARN 都必须修复:\n\n1. **上标格式 FAIL** → 如果 bibliographystyle 是 `plain/plainnat/unsrt` 但 `\\cite{}` 没有上标\n\n - 修复方法A:改 bibliographystyle 为 `gbt7714-numerical` 或 `plainnat` + `\\usepackage[numbers,square,super]{natbib}`\n\n - 修复方法B:把正文里所有 `\\cite{x}` 改为 `\\upcite{x}` 或 `\\textsuperscript{\\cite{x}}`\n\n2. **多引用顺序 WARN** → `\\cite{c,a,b}` 但全文 a 先出现\n\n - 修复方法:改成 `\\cite{a,b,c}`(按全文首次出现顺序)\n\n - 用以下 bash 找出所有需修复的位置:\n\n ```bash\n\n grep -rnP '\\\\(up)?cite\\{[^}]+\\}' 论文/章节/*.tex 论文/论文正文.tex\n\n ```\n\n3. **连续引用未合并 WARN** → `\\cite{a}\\cite{b}` 或 `\\cite{a} \\cite{b}`\n\n - 修复方法:合并为 `\\cite{a,b}`\n\n - 批量修复:\n\n ```bash\n\n # 找出全部需合并的位置\n\n grep -rnoP '\\\\(up)?cite\\{[^}]+\\}\\s*\\\\(up)?cite\\{[^}]+\\}' 论文/章节/*.tex 论文/论文正文.tex\n\n ```\n\n**⛔ 修复后必须重新编译验证:** `xelatex → bibtex → xelatex → xelatex`,然后重新运行 compile_check.sh 确认无 FAIL。\n\nAdditionally verify:\n\n```bash\n\n# List of visuals / list of tables (stats competition requirement)\n\n[ -s 论文/论文正文.lof ] && echo \"✅ 插图清单已产出\" || echo \"⚠ 插图清单为空\"\n\n[ -s 论文/论文正文.lot ] && echo \"✅ 表格清单已产出\" || echo \"⚠ 表格清单为空\"\n\n```\n\n**Template format verification (stats competition)**:\n\n```bash\n\necho \"=== 模板格式校验 ===\"\n\nif grep -q 'stats\\|统计建模' 论文/论文正文.tex 2>/dev/null || [ \"$COMPETITION\" = \"stats\" ]; then\n\n # Validate page margins (is expected to be 2.54cm top/bottom, 3.17cm left/right)\n\n grep -q '2.54cm' 论文/论文正文.tex && echo \"✅ 页边距无误\" || echo \"⚠ 页边距可能不对(应为上下2.54cm,左右3.17cm)\"\n\n # Validate Chinese section numbering\n\n grep -q 'chinese{section}' 论文/论文正文.tex && echo \"✅ 中文章节编号\" || echo \"⚠ 缺少中文章节编号(一、二、三...)\"\n\n # Validate cover page\n\n grep -q '参赛学校\\|参赛作品\\|作品编号' 论文/论文正文.tex && echo \"✅ 封面出现\" || echo \"⚠ 缺少封面\"\n\n # Verify abstract format (should be \\section*{摘要}, not \\begin{abstract})\n\n grep -q 'section\\*.*摘要' 论文/论文正文.tex && echo \"✅ 摘要格式无误\" || echo \"⚠ 摘要格式可能不对\"\n\n # Validate natbib (stats uses natbib, not gbt7714)\n\n grep -q 'natbib' 论文/论文正文.tex && echo \"✅ natbib 引用格式\" || echo \"⚠ 缺少 natbib(统计建模应用 natbib)\"\n\n # Validate no header line\n\n grep -q 'headrulewidth.*0pt' 论文/论文正文.tex && echo \"✅ 无页眉线\" || echo \"⚠ 可能有页眉线\"\n\n # Validate listoffigures / listoftables\n\n grep -q 'listoffigures' 论文/论文正文.tex && echo \"✅ 插图清单命令\" || echo \"⚠ 缺少 \\\\listoffigures\"\n\n grep -q 'listoftables' 论文/论文正文.tex && echo \"✅ 表格清单命令\" || echo \"⚠ 缺少 \\\\listoftables\"\n\nfi\n\n```\n\nIf any format checks fail, Meta-model-agent should fix 论文正文.tex to match the template format before recompiling.\n\n### 执行节点 6:Competition compliance\n\nVerify items:\n\n1. **Page count**: determine which parts count under the active competition Profile and require the count to be `≤ MAX_PAGES`. Separately reject substantively incomplete chapters; never require the paper to fill the page ceiling.\n\n2. **Anonymous**: no team info (队号, 队员, 指导老师)\n\n3. **Abstract exists** (数模竞赛: at least Chinese; 统计建模: both Chinese and English)\n\n4. **TOC exists** (required by MathorCup etc.)\n\n5. **Code appendix exists**\n\n6. **No undefined references/citations**\n\n“Code appendix exists”不得只检查标题或“代码/程序”关键词。必须读取 `程序/code_manifest.json`,逐项核验源码存在、SHA-256 未陈旧、`required_in_appendix=true` 的文件均有 `CODE_FILE` 标记和真实 `\\lstinputlisting`/代码块。三种赛制均只核验主程序和逐问核心实现;辅助源码只能列入支撑材料清单,附录显示名必须为英文代码名。\n\nCUMCM 页数必须读取编译后的 `AbstractStart/AbstractEnd` 与 `BodyStart/BodyEnd` 标签:摘要不超过 1 页,正文不超过 30 页,附录页数单独报告且不计入正文。模板含目录、标签缺失或仅用字符数估算时直接失败。\n\n\u003cpage_diagnosis>\n\n#### 正文充分性诊断(与页数上限分开)\n\n不要再把“正文达到 MAX_PAGES 的 80%”作为硬目标。`MAX_PAGES` 只表示上限。即使页数较少,也只有在论证链缺失时才扩充正文。\n\n```bash\n\necho \"=== 页数不足诊断 ===\"\n\necho \"页数上限: MAX_PAGES;另行检查正文论证充分性\"\n\necho \"\"\n\necho \"=== 各章节字符数(找出最薄的章节)===\"\n\nfor f in 论文/章节/*.tex; do\n\n chars=$(wc -c \u003c \"$f\")\n\n echo \" $(basename $f): $chars 字符 (~$(echo \"scale=1; $chars/900\" | bc) 页)\"\n\ndone\n\necho \"\"\n\necho \"=== 推荐扩充的章节(字符数最少的 3 个)===\"\n\nfor f in $(ls -S 论文/章节/*.tex | tail -3); do\n\n chars=$(wc -c \u003c \"$f\")\n\n echo \" ⚠ $(basename $f): 仅 $chars 字符\"\n\ndone\n\n```\n\n只有出现以下问题时才标记为 CRITICAL 并扩充:\n\n- 某个子问题缺少模型机制或必要公式推导\n\n- 结果只有数字或图表,没有验证和解释\n\n- 摘要/结论中的关键主张无法在正文定位\n\n扩充时只添加有证据来源的内容:\n\n- Read 建模报告.md and 计算结果.md for detailed content\n\n- Add unexpanded derivations, result analysis, validation, parameter discussions, and limitations\n\n- Recompile after expansion\n\n\u003c/page_diagnosis>\n\n### 执行节点 7:⛔ FINAL QUALITY GATE (must ALL pass before finishing)\n\nRun all checks and verify every item passes. **Do NOT output the report until all CRITICAL items are resolved.**\n\n```bash\n\necho \"==========================================\"\n\necho \" FINAL QUALITY GATE\"\n\necho \"==========================================\"\n\nGATE_FAIL=0\n\n# 1. PDF exists and non-trivial\n\nif [ -f 论文/数模论文.pdf ] && [ $(wc -c \u003c 论文/数模论文.pdf) -gt 100000 ]; then\n\n echo \"✅ PDF exists ($(wc -c \u003c 论文/数模论文.pdf) bytes)\"\n\nelse\n\n echo \"❌ PDF missing or too small\"; GATE_FAIL=$((GATE_FAIL+1))\n\nfi\n\n# 2. No LaTeX errors\n\nMATH_ERR=$(grep -c 'Bad math environment delimiter\\|Missing \\$ inserted' 论文/编译日志.log 2>/dev/null || echo 0)\n\nLR_ERR=$(grep -c 'Not allowed in LR mode' 论文/编译日志.log 2>/dev/null || echo 0)\n\n[ \"$((MATH_ERR+LR_ERR))\" -eq 0 ] && echo \"✅ No LaTeX errors\" || { echo \"❌ $MATH_ERR math + $LR_ERR LR errors\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 3. Bibliography not empty\n\nBBL_ENTRIES=$(grep -c '\\\\bibitem' 论文/论文正文.bbl 2>/dev/null || echo 0)\n\n[ \"$BBL_ENTRIES\" -gt 0 ] && echo \"✅ Bibliography: $BBL_ENTRIES entries\" || { echo \"❌ Bibliography empty (BibTeX failed)\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 4. No unembedded publish=true visuals\n\nUNEMBED=0\n\nfor pdf in 图表/*.pdf; do\n\n [ -f \"$pdf\" ] || continue\n\n bn=$(basename \"$pdf\")\n\n python3 -c \"import json,sys; d=json.load(open('图表/figure_manifest.json',encoding='utf-8')); sys.exit(0 if any(x.get('publish') and x.get('path','').replace('\\\\\\\\','/').endswith('/'+sys.argv[1]) for x in d.get('figures',[])) else 1)\" \"$bn\" || continue\n\n grep -rq \"$bn\" 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null || UNEMBED=$((UNEMBED+1))\n\ndone\n\n[ \"$UNEMBED\" -eq 0 ] && echo \"✅ All publication visuals embedded\" || { echo \"❌ $UNEMBED publish=true visuals not embedded in manuscript\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 5. Page count\n\nPAGE_EST=0\n\nfor f in 论文/章节/*.tex; do [ -f \"$f\" ] || continue; c=$(wc -c \u003c \"$f\"); PAGE_EST=$((PAGE_EST + c)); done\n\nPAGE_EST=$((PAGE_EST / 900))\n\necho \" Body estimate: ~$PAGE_EST pages; MAX_PAGES is the submission ceiling, not a fill target\"\n\n# 6. Overfull vbox (table/visual overflow)\n\nVBOX_ERR=$(grep -c 'Overfull.*vbox' 论文/编译日志.log 2>/dev/null || echo 0)\n\n[ \"$VBOX_ERR\" -eq 0 ] && echo \"✅ No table/visual overflow\" || { echo \"❌ $VBOX_ERR overfull vbox — tables may be cut off\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 7. AI writing patterns (itemize in body)\n\nAI_LISTS=0\n\nfor f in 论文/章节/*.tex; do\n\n [ -f \"$f\" ] || continue\n\n echo \"$(basename $f)\" | grep -qi 'appendix\\|附录' && continue\n\n c=$(grep -c '\\\\begin{itemize}' \"$f\" 2>/dev/null || echo 0)\n\n AI_LISTS=$((AI_LISTS + c))\n\ndone\n\n[ \"$AI_LISTS\" -eq 0 ] && echo \"✅ No bullet lists in body\" || { echo \"❌ $AI_LISTS itemize — convert to prose\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 8. Template integrity — compare preamble against established template\n\necho \"--- Template integrity ---\"\n\nTMPL=\"\"\n\nfor t in 模板/stats_论文正文.tex 模板/cumcm_论文正文.tex 模板/mcm_论文正文.tex 模板/bachelor_论文正文.tex 模板/master_论文正文.tex 模板/journal_论文正文.tex; do\n\n [ -f \"$t\" ] && TMPL=\"$t\" && break\n\ndone\n\nif [ -n \"$TMPL\" ] && [ -f 论文/论文正文.tex ]; then\n\n # Extract preamble (before \\begin{document}) from both files\n\n TMPL_PRE=$(sed -n '1,/\\\\begin{document}/p' \"$TMPL\" | grep '\\\\usepackage\\|\\\\documentclass\\|\\\\ctexset\\|\\\\pagestyle\\|\\\\renewcommand.*headrulewidth\\|\\\\listoftables\\|\\\\listoffigures\\|\\\\cline\\|\\\\bibliography' | sort)\n\n MAIN_PRE=$(sed -n '1,/\\\\begin{document}/p' 论文/论文正文.tex | grep '\\\\usepackage\\|\\\\documentclass\\|\\\\ctexset\\|\\\\pagestyle\\|\\\\renewcommand.*headrulewidth\\|\\\\listoftables\\|\\\\listoffigures\\|\\\\cline\\|\\\\bibliography' | sort)\n\n MISSING=$(comm -23 \u003c(echo \"$TMPL_PRE\") \u003c(echo \"$MAIN_PRE\") 2>/dev/null | head -5)\n\n if [ -z \"$MISSING\" ]; then\n\n echo \"✅ Template preamble intact\"\n\n else\n\n echo \"❌ Template preamble was modified — these lines from template are missing in 论文正文.tex:\"\n\n echo \"$MISSING\" | sed 's/^/ /'\n\n GATE_FAIL=$((GATE_FAIL+1))\n\n fi\n\n # Validate cover page structure (if template has one)\n\n if grep -q '参赛学校\\|参赛作品' \"$TMPL\" 2>/dev/null; then\n\n grep -q '参赛学校\\|参赛作品' 论文/论文正文.tex 2>/dev/null && echo \"✅ Cover page present\" || { echo \"❌ Cover page missing/rewritten\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n grep -q 'cline{2-2}' 论文/论文正文.tex 2>/dev/null && echo \"✅ Cover underlines (cline)\" || { echo \"❌ Cover cline missing\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n fi\n\n # Validate bracket placeholders not remaining\n\n if grep -q '\\[论文标题\\]\\|\\[学校名称\\]\\|\\[队员1\\]\\|\\[指导老师\\]\\|\\[竞赛年份\\]\\|\\[届数\\]\\|\\[中文摘要内容\\]' 论文/论文正文.tex 2>/dev/null; then\n\n echo \"❌ Unreplaced bracket placeholders in 论文正文.tex\"; GATE_FAIL=$((GATE_FAIL+1))\n\n else\n\n echo \"✅ All placeholders replaced\"\n\n fi\n\n # Validate hand-written visual/table list (anti-pattern)\n\n if grep -P '^(表|图)\\d+\\.' 论文/论文正文.tex 2>/dev/null | head -1 | grep -q '.'; then\n\n echo \"❌ Hand-written figure/table list (use \\\\listoftables/\\\\listoffigures)\"; GATE_FAIL=$((GATE_FAIL+1))\n\n fi\n\nelse\n\n echo \" (no template found for comparison, skipping)\"\n\nfi\n\n# 9. Visual plan reconciliation (validate planning docs)\n\necho \"--- Visual plan validate ---\"\n\nPLAN_FIGS=0; ACTUAL_FIGS=$(ls 图表/*.pdf 2>/dev/null | wc -l)\n\nfor plan in 选题规划.md 论文规划.md 问题分析.md; do\n\n [ -f \"$plan\" ] || continue\n\n pf=$(grep -ci 'fig_\\|图.*:\\|visual.*:' \"$plan\" 2>/dev/null || echo 0)\n\n [ \"$pf\" -gt \"$PLAN_FIGS\" ] && PLAN_FIGS=$pf\n\ndone\n\nif [ \"$PLAN_FIGS\" -gt 0 ]; then\n\n echo \" Planned: ~$PLAN_FIGS visuals, Actual: $ACTUAL_FIGS PDFs\"\n\n [ \"$ACTUAL_FIGS\" -ge \"$PLAN_FIGS\" ] && echo \"✅ Visual count meets original plan\" || echo \" ⚠ Visual count is below the early plan; confirm omitted items are registered publish=false with reasons\"\n\nelse\n\n echo \" No visual plan found, actual: $ACTUAL_FIGS PDFs\"\n\nfi\n\n# 10. TikZ 几何/算法/架构图\n\n# TikZ 由 systems-diagramming 编译成 图表/结构示意图.pdf, 通过 \\includegraphics 嵌入\n\n# (不是 sections 里的裸 tikzpicture 代码)。两种形态都算已嵌入。\n\nTIKZ_IN_PAPER=$(grep -rl 'tikzpicture\\|结构示意图\\|tikz_' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null | wc -l)\n\n# ⛔ 只在\"真实产出了 tikz_*.pdf 产物\"时才硬核对(避免规划提了但用 DrawIO 替代时误报失败)\n\nTIKZ_PDF_TOTAL=0; TIKZ_PDF_MISSING=0\n\nfor tpdf in 图表/结构示意图.pdf 图表/结构示意图_*.pdf 图表/tikz_*.pdf; do\n\n [ -f \"$tpdf\" ] || continue\n\n python3 -c \"import json,sys; d=json.load(open('图表/figure_manifest.json',encoding='utf-8')); sys.exit(0 if any(x.get('publish') and x.get('path','').replace('\\\\\\\\','/').endswith('/'+sys.argv[1]) for x in d.get('figures',[])) else 1)\" \"$(basename \"$tpdf\")\" || continue\n\n TIKZ_PDF_TOTAL=$((TIKZ_PDF_TOTAL+1))\n\n grep -rq \"$(basename \"$tpdf\")\" 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null || TIKZ_PDF_MISSING=$((TIKZ_PDF_MISSING+1))\n\ndone\n\nif [ \"$TIKZ_PDF_TOTAL\" -gt 0 ]; then\n\n # 有 publish=true 的 TikZ 产物 → 务必全部嵌入\n\n if [ \"$TIKZ_PDF_MISSING\" -gt 0 ]; then\n\n echo \"❌ $TIKZ_PDF_MISSING 张 TikZ PDF 未嵌入任何章节\"; GATE_FAIL=$((GATE_FAIL+1))\n\n else\n\n echo \"✅ TikZ diagrams embedded ($TIKZ_PDF_TOTAL)\"\n\n fi\n\nelif grep -qi 'tikz\\|架构\\|路线图\\|几何示意\\|算法流程' 论文规划.md 问题分析.md 2>/dev/null; then\n\n # 规划提到 TikZ 但没产出 tikz_*.pdf(可能已用 DrawIO 替代) → 仅提醒, 不判失败\n\n [ \"$TIKZ_IN_PAPER\" -gt 0 ] && echo \"✅ TikZ embedded\" || echo \" ⚠ 规划提到 TikZ 但未发现 tikz_*.pdf(可能已用 DrawIO 替代, 不阻塞)\"\n\nelse\n\n [ \"$TIKZ_IN_PAPER\" -gt 0 ] && echo \"✅ TikZ diagrams embedded ($TIKZ_IN_PAPER)\" || echo \" (no TikZ planned)\"\n\nfi\n\n# 11. Citations in body\n\nCITE_COUNT=$(grep -roh '\\\\cite{' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null | wc -l)\n\n[ \"$CITE_COUNT\" -gt 0 ] && echo \"✅ Citations: $CITE_COUNT\" || { echo \"❌ No citations in body text\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 12. No placeholders remaining\n\nPLACEHOLDERS=$(grep -rl 'PLACEHOLDER\\|待补充\\|TODO\\|\\[论文标题\\]\\|\\[中文摘要内容\\]' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null | wc -l)\n\n[ \"$PLACEHOLDERS\" -eq 0 ] && echo \"✅ No placeholders\" || { echo \"❌ $PLACEHOLDERS files have placeholders\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 13. Undefined references\n\nUNDEF_REFS=$(grep -c 'LaTeX Warning.*Reference.*undefined' 论文/编译日志.log 2>/dev/null || echo 0)\n\n[ \"$UNDEF_REFS\" -eq 0 ] && echo \"✅ No undefined refs\" || { echo \"❌ $UNDEF_REFS undefined references\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 14. Overfull hbox(零容忍)\n\nHBOX_ERR=$(grep -c 'Overfull.*hbox' 论文/编译日志.log 2>/dev/null || echo 0)\n\n[ \"$HBOX_ERR\" -eq 0 ] && echo \"✅ No overfull hbox\" || { echo \"❌ $HBOX_ERR overfull hbox — fix wide tables/formulas\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 15. Visual stacking\n\nSTACKING=0\n\nfor f in 论文/章节/*.tex; do [ -f \"$f\" ] || continue; s=$(awk '/\\\\end\\{(figure|table)\\}/{a=1;t=0;next} a&&/\\\\begin\\{(figure|table)\\}/{if(t\u003c3)c++;a=0;next} a&&/[a-zA-Z\\x80-\\xff]{3,}/{t++} a&&t>=3{a=0} END{print c+0}' \"$f\" 2>/dev/null); STACKING=$((STACKING+s)); done\n\n[ \"$STACKING\" -eq 0 ] && echo \"✅ No visual stacking\" || { echo \"❌ $STACKING visual stacking — add analysis text between visuals\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 16. TOC\n\nif grep -q 'tableofcontents' 论文/论文正文.tex 2>/dev/null; then\n\n [ -s 论文/论文正文.toc ] && echo \"✅ TOC generated\" || {\n\n echo \"❌ TOC empty — running extra compile pass...\"\n\n cd 论文/\n\n xelatex -interaction=nonstopmode 论文正文.tex > /dev/null 2>&1\n\n xelatex -interaction=nonstopmode 论文正文.tex > /dev/null 2>&1\n\n cd ..\n\n [ -s 论文/论文正文.toc ] && echo \"✅ TOC generated following extra compile\" || { echo \"❌ TOC still empty\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n }\n\nfi\n\n# 17. Abstracts (Chinese papers)\n\nif grep -q 'ctex' 论文/论文正文.tex 2>/dev/null; then\n\n grep -rq '摘.*要' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null && echo \"✅ Chinese abstract\" || { echo \"❌ No Chinese abstract\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n grep -rq 'Abstract' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null && echo \"✅ English abstract\" || { echo \"❌ No English abstract\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\nfi\n\n# 18. Run compile_check.sh + writing_check.sh for full details\n\necho \"\"\n\necho \"--- Full validate scripts ---\"\n\nbash 工具/compile_check.sh 论文/ 2>/dev/null || bash skills/shared-scripts/compile_check.sh 论文/ 2>/dev/null\n\nbash 工具/writing_check.sh 论文/ 2>/dev/null || bash skills/shared-scripts/writing_check.sh 论文/ 2>/dev/null\n\nWC_EXIT=$?\n\n[ \"$WC_EXIT\" -eq 0 ] && echo \"✅ Writing checks passed\" || { echo \"❌ Writing checks failed (exit=$WC_EXIT)\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 19. 符号阐明 longtable 核验\n\necho \"--- Symbol table format ---\"\n\nfor f in 论文/章节/*.tex; do\n\n [ -f \"$f\" ] || continue\n\n if grep -q '\\\\section{符号说明}\\|\\\\section.*符号' \"$f\" 2>/dev/null; then\n\n if grep -q '\\\\begin{longtable}' \"$f\" 2>/dev/null; then\n\n echo \"✅ 符号阐明采用 longtable\"\n\n elif grep -q '\\\\begin{table}' \"$f\" 2>/dev/null; then\n\n echo \"❌ 符号阐明仍用 table(应转 longtable 防分页)\"; GATE_FAIL=$((GATE_FAIL+1))\n\n fi\n\n fi\n\ndone\n\n# 20. 正文长表格核验(>12 行必须摘要化;需跨页时使用 longtable)\n\necho \"--- Long table validate ---\"\n\nfor f in 论文/章节/*.tex; do\n\n [ -f \"$f\" ] || continue\n\n echo \"$(basename $f)\" | grep -qi 'symbol\\|appendix\\|A_code' && continue\n\n if grep -q '\\\\begin{tabular}' \"$f\" 2>/dev/null; then\n\n ROW_COUNT=$(awk '/\\\\begin\\{tabular\\}/,/\\\\end\\{tabular\\}/' \"$f\" 2>/dev/null | grep -c '&' || echo 0)\n\n [ \"$ROW_COUNT\" -gt 12 ] && { echo \"❌ $(basename $f): $ROW_COUNT 行结果表应在正文摘要化,完整表移至附录并按需使用 longtable\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n fi\n\ndone\n\n# 21. babel[english] 冲突\n\necho \"--- babel validate ---\"\n\nif grep -q 'ctex\\|cumcmthesis\\|gmcmthesis' 论文/论文正文.tex 2>/dev/null; then\n\n grep -q 'babel.*english' 论文/论文正文.tex 2>/dev/null && { echo \"❌ 中文论文有 babel[english]\"; GATE_FAIL=$((GATE_FAIL+1)); } || echo \"✅ 无 babel 冲突\"\n\nfi\n\n# 22. 数值一致性(JSON vs 论文)\n\necho \"--- Numerical consistency ---\"\n\nif [ -f 图表/全部结果.json ]; then\n\n python3 -c \"\n\nimport json, re, os\n\nwith open('图表/全部结果.json','r',encoding='utf-8') as f: outcomes=json.load(f)\n\ndef extract(obj,p=''):\n\n n={}\n\n if isinstance(obj,dict):\n\n for k,v in obj.items(): n.update(extract(v,f'{p}.{k}'))\n\n elif isinstance(obj,(int,float)) and not isinstance(obj,bool):\n\n if 0.001\u003cabs(obj)\u003c1e10: n[p]=obj\n\n return n\n\njn=extract(outcomes); pn=set()\n\nfor tf in sorted(os.listdir('论文/章节')):\n\n if not tf.endswith('.tex'): continue\n\n with open(f'论文/章节/{tf}','r',encoding='utf-8',errors='ignore') as f: t=f.read()\n\n for m in re.finditer(r'(?\u003c![a-zA-Z])(\\d+\\.?\\d+)(?![a-zA-Z_{}])',t):\n\n try: pn.add(float(m.group(1)))\n\n except: pass\n\nmiss=sum(1 for k,v in jn.items() if not any(abs(p-v)\u003cabs(v)*0.01+0.001 for p in pn) and any(w in k.lower() for w in ['rmse','r2','accuracy','f1','objective','optimal','best']))\n\nprint(f'❌ {miss} key values missing in manuscript' if miss else '✅ Key values consistent')\n\nimport sys; sys.exit(1 if miss>3 else 0)\n\n\" 2>/dev/null\n\n [ $? -ne 0 ] && GATE_FAIL=$((GATE_FAIL+1))\n\nfi\n\n# 22.5 \"太完美\"结果检测(AI 编造或过拟合特征)\n\necho \"--- Unrealistic values validate ---\"\n\nif [ -f 图表/全部结果.json ]; then\n\n python3 -c \"\n\nimport json\n\nwith open('图表/全部结果.json','r',encoding='utf-8') as f: data=json.load(f)\n\nsuspicious = []\n\ndef validate(name, val):\n\n if not isinstance(val,(int,float)) or isinstance(val,bool): return\n\n key = name.lower()\n\n if any(w in key for w in ['r2','r_squared','accuracy','acc','precision','recall','f1','auc']) and val > 0.999:\n\n suspicious.append(f'{name}={val:.4f} 过于完美(>0.999)')\n\n if any(w in key for w in ['rmse','mae','mse','loss']) and val == 0:\n\n suspicious.append(f'{name}=0 完美误差')\n\n if ('p_value' in key or 'pvalue' in key) and val == 0:\n\n suspicious.append(f'{name}=0 完美显著')\n\n if any(w in key for w in ['improvement','speedup','gain','提升']) and val > 10:\n\n suspicious.append(f'{name}={val} 提升过大({val*100:.0f}%)')\n\ndef walk(obj, path=''):\n\n if isinstance(obj,dict):\n\n for k,v in obj.items(): walk(v, f'{path}.{k}')\n\n elif isinstance(obj,list):\n\n for i,v in enumerate(obj): walk(v, f'{path}[{i}]')\n\n else: validate(path, obj)\n\nwalk(data)\n\nif suspicious:\n\n print(f'🚩 {len(suspicious)} 处可疑的完美结果(可能过拟合或数值编造):')\n\n for s in suspicious[:5]: print(f' {s}')\n\n print(' 需在论文中阐明合理性,或回到 computational-realization 核验数据泄漏')\n\nelse:\n\n print('✅ 数值合理性通过')\n\n\" 2>/dev/null\n\nfi\n\n# 22.6 合理性复核章节是否出现(务必)\n\necho \"--- 合理性复核章节核验 ---\"\n\nif [ -f 计算结果.md ]; then\n\n if grep -q '合理性审查\\|数值合理\\|背景对照\\|sanity.*verify' 计算结果.md 2>/dev/null; then\n\n echo \"✅ 计算结果.md 涵盖合理性复核章节\"\n\n else\n\n echo \"❌ 计算结果.md 缺少合理性复核章节 — 回到 computational-realization Phase 1.7 补充\"\n\n GATE_FAIL=$((GATE_FAIL+1))\n\n fi\n\nfi\n\n# 22.7 数据源时间戳一致性(代码 vs 图形与表格 vs 论文)\n\necho \"--- 数据源时间戳一致性 ---\"\n\nif [ -f 图表/全部结果.json ]; then\n\n JSON_TIME=$(stat -c %Y 图表/全部结果.json 2>/dev/null || stat -f %m 图表/全部结果.json 2>/dev/null || echo 0)\n\n # 核验是否有 PDF 图形与表格比 JSON 旧(阐明代码重跑了但图没更新)\n\n STALE_FIGS=0\n\n for pdf in 图表/*.pdf; do\n\n [ -f \"$pdf\" ] || continue\n\n PDF_TIME=$(stat -c %Y \"$pdf\" 2>/dev/null || stat -f %m \"$pdf\" 2>/dev/null || echo 0)\n\n if [ \"$JSON_TIME\" -gt \"$PDF_TIME\" ] && [ \"$((JSON_TIME - PDF_TIME))\" -gt 60 ]; then\n\n echo \" ⚠ $(basename $pdf) 比 全部结果.json 旧 — 图形与表格数据可能过期\"\n\n STALE_FIGS=$((STALE_FIGS+1))\n\n fi\n\n done\n\n if [ \"$STALE_FIGS\" -gt 0 ]; then\n\n echo \" ❌ $STALE_FIGS 张图形与表格可能采用了旧数据(JSON 更新后图形与表格未重新产出)\"\n\n echo \" → 推荐重跑 evidence-visualization 环节更新图形与表格\"\n\n GATE_FAIL=$((GATE_FAIL+1))\n\n else\n\n echo \"✅ 数据源时间戳保持一致\"\n\n fi\n\nfi\n\n# 22.8 正文长表格检测(>12 行的表格不应在正文中完整展开)\n\necho \"--- 正文长表格检测 ---\"\n\nLONG_TABLES=0\n\nfor f in 论文/章节/*.tex; do\n\n [ -f \"$f\" ] || continue\n\n # 跳过附录文件\n\n echo \"$(basename $f)\" | grep -qi 'appendix\\|附录\\|A_code' && continue\n\n # 统计各个 tabular/longtable 环境内的数据行数(\\\\ 的数量)\n\n python3 -c \"\n\nimport re\n\nwith open('$f', 'r', encoding='utf-8', errors='ignore') as fh:\n\n content = fh.read()\n\n# 找全部 tabular/longtable 环境\n\nfor env in ['tabular', 'longtable', 'tabular*']:\n\n pattern = r'\\\\\\\\begin\\{' + env + r'[*]?\\}.*?\\\\\\\\end\\{' + env + r'[*]?\\}'\n\n for match in re.finditer(pattern, content, re.DOTALL):\n\n table_text = match.group()\n\n row_count = table_text.count('\\\\\\\\\\\\\\\\') - table_text.count('\\\\\\\\hline') // 2\n\n if row_count > 12:\n\n print(f'$(basename $f): {env} 有 {row_count} 行(>12)')\n\n\" 2>/dev/null | while read line; do\n\n echo \" ❌ $line — 正文表格超过 12 行,应截断(前3+后3+省略),完整版放附录\"\n\n LONG_TABLES=$((LONG_TABLES+1))\n\n done\n\ndone\n\n[ \"$LONG_TABLES\" -eq 0 ] && echo \"✅ 正文无超长表格\" || GATE_FAIL=$((GATE_FAIL+1))\n\n# 23. AI 写作痕迹(列表环境)\n\necho \"--- AI writing patterns ---\"\n\nAI_LISTS=0\n\nfor f in 论文/章节/*.tex; do\n\n [ -f \"$f\" ] || continue\n\n echo \"$(basename $f)\" | grep -qi 'appendix\\|A_code' && continue\n\n c=$(grep -c '\\\\begin{itemize}\\|\\\\begin{enumerate}' \"$f\" 2>/dev/null || echo 0)\n\n AI_LISTS=$((AI_LISTS+c))\n\ndone\n\n[ \"$AI_LISTS\" -le 3 ] && echo \"✅ AI patterns: $AI_LISTS lists\" || { echo \"❌ $AI_LISTS lists in body — convert to prose\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 24. 元叙述泄露\n\necho \"--- Meta content leak ---\"\n\nMETA=0\n\nfor f in 论文/章节/*.tex; do\n\n [ -f \"$f\" ] || continue\n\n l=$(grep -ci 'RESULTS\\.md\\|META_MODEL_AGENT\\.md\\|MODELING_REPORT\\|PROBLEM_ANALYSIS\\|latex_includes' \"$f\" 2>/dev/null || echo 0)\n\n META=$((META+l))\n\ndone\n\n[ \"$META\" -eq 0 ] && echo \"✅ No meta leaks\" || { echo \"❌ $META meta content leaks\"; GATE_FAIL=$((GATE_FAIL+1)); }\n\n# 25. 过度声称\n\necho \"--- Overclaiming ---\"\n\nOC=0\n\nfor f in 论文/章节/*.tex; do\n\n [ -f \"$f\" ] || continue\n\n for w in \"首次提出\" \"首次发现\" \"完美\" \"最优的\" \"无可比拟\" \"前所未有\" \"开创性\" \"革命性\"; do\n\n c=$(grep -c \"$w\" \"$f\" 2>/dev/null || echo 0); OC=$((OC+c))\n\n done\n\ndone\n\n[ \"$OC\" -eq 0 ] && echo \"✅ No overclaiming\" || echo \"⚠ $OC overclaiming instances\"\n\necho \"\"\n\necho \"==========================================\"\n\nif [ \"$GATE_FAIL\" -eq 0 ]; then\n\n echo \" ✅ ALL CRITICAL CHECKS PASSED — ready to submit\"\n\nelse\n\n echo \" ❌ $GATE_FAIL CRITICAL FAILURES — MUST FIX prior to finishing\"\n\n echo \" Go back and fix each ❌ item, recompile, then re-run this gate.\"\n\nfi\n\necho \"==========================================\"\n\n```\n\n**⛔ If GATE_FAIL > 0, you MUST go back and fix every ❌ item, recompile, and re-run this gate. Do NOT output the final report with any ❌ remaining. Repeat until GATE_FAIL = 0.**\n\n### 执行节点 8:Output report\n\nCompetition name, status, PDF path, total pages, body pages, compliance pass/fail.\n\n## 核心规则\n\n- No latexmk — manual step-by-step compilation\n\n- Avoid delete .bbl file after compilation (bibliography data)\n\n- Figure paths auto-corrected by compile_utils.sh: `图表/` → `../图表/`\n\n- Total/countable pages ≤ MAX_PAGES. Page count is a ceiling;正文充分性按逐问论证链独立检查。\n\n- Every embedded LaTeX figure must stay within `\\linewidth` and `0.70\\textheight` with `keepaspectratio`; every DOCX image must stay within the computed page body width. Oversized or unreadably shrunken figures are gate failures.\n\n- Anonymous: no team info in body\n\n- Primary output: `论文/数模论文.pdf`, temp files: `临时文件/`\n\n","licenseDocuments":[]}}
L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Productivité · SKILL.md

delivery-assurance

delivery-assurance

Meta-model-agent 完成编译、版式、匿名、页数、引用与提交前合规验收。适用于提交质量验收。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: delivery-assurance description: "Meta-model-agent 完成编译、版式、匿名、页数、引用与提交前合规验收。适用于提交质量验收。"

提交质量验收

数据准备一致性验收

有数据时,核对论文独立“数据预处理”小节、全部结果.json.data_preparation、数据/processed/ 文件哈希和模型代码读取路径一致,并确认处理前后质量统计与泄漏说明真实可复核。无数据时确认存在明确豁免且没有伪造的处理后数据或清洗结论。

模型身份与摘要一致性验收

逐问核验审计身份与论文表达卡。正式名称必须显式暴露线性/整数/鲁棒/随机规划、回归、时间序列、状态空间、车辆路径、网络流、多指标决策等标准结构;论文展示名称应简洁并保留主要结构。比较、验证或应用类问题必须说明继承关系,不得强造独立模型。摘要和正文先说明模型或继承关系,再说明核心方法;关键词至少包含一个标准模型族。

建模报告.md 的审计身份与 全部结果.json.model_identity 必须逐字一致;摘要和正文与论文表达卡保持语义一致,不得复制身份卡字段标签。最终摘要还必须拦截内部术语、完整算法链、未解释方案缩写、数字流水账和缺失的模型边界。

发布声明、公式与页面构成验收

  • 核对 全部结果.json.publication_claims 的来源键、派生关系与正文显示值;同一指标在摘要、正文、图表、表格和结论中不得冲突。
  • 核对真实问题数、逐问章节文件和主文件 \input/\include 一一闭合,禁止章节存在但最终 PDF 漏问。
  • 读取 latex-math.md,检查原生公式、符号与量纲、\eqref/\ref/\cref、重复标签和硬编码图表公式编号。
  • 读取 page-composition.md 并在实际 PDF 上执行页面审计。编译成功、页数合规和页面质量是三个独立门禁。
  • Overfull box、裁切、标题孤悬、图题分离和不可读小字在冠军模式下不得带入终稿;低占用页面必须人工确认是否来自章节自然结束,而不是用空白或大图填页。

必读的版面子协议

  • 始终读取 参考资料/paper-layout/core.md 与 body-density.md。
  • PDF/LaTeX 验收读取 latex-figures.md。
  • PDF/LaTeX 验收同时读取 latex-math.md 与 page-composition.md。
  • DOCX 验收读取 docx-figures.md。
  • 子协议中的尺寸和页数语义优先于本文件中的旧示例。

DOCX 路线使用 python 工具/docx_export.py --workspace . 生成 论文/数模论文.docx 和 论文/docx_report.json。不得对 DOCX 路线执行 XeLaTeX/BibTeX;验收以 Markdown 正文、DOCX 包、尺寸报告以及可选的 LibreOffice PDF 预览为准。

竞赛专用硬门禁

编译前必须读取 状态/工作流状态.json 中的竞赛 Profile 和 参考资料/竞赛规则.md:

  • CUMCM:核验当届官方通知、匿名电子正文、模板、引用、图表及编号/附件要求。
  • 51MCM:核验 51mcmthesis、withoutpreface、报名号/题号/组别字段,以及正文不存在学校、成员、邮箱和电话信息。
  • MCM/ICM:核验全英文、12pt、Summary Sheet、已填写 Control Number、A--F 题号、无个人/学校身份信息,完整 PDF 不超过 25 页。

编译成功不能覆盖竞赛 Profile 门禁失败。

稳定执行契约

  • 执行目标:完成论文编译、版式、匿名、页数、引用与提交文件的终局验收。
  • 调用参数:[paper-directory]。
  • 权威输入:论文/论文正文.tex、论文/章节/、图表资产、模板规则与竞赛要求。
  • 允许交付:论文/数模论文.pdf、论文/编译日志.log及必要的验收记录;仅可做有边界的修复。
  • 禁止写入:不得越权修改已冻结的上游事实、用户原始文件或本协议未授权的目录。
  • 可用工具边界:Bash(*), Read, Write, Edit, Grep, Glob。
  • 最小交付:PDF可打开、编译无关键错误、引用闭合、模板完整、匿名与页数合规。
  • 恢复入口:优先读取当前工作、状态记录和已有产物,从最近一次通过门禁的位置继续。
  • 失败回退:最多按既定次数修复编译;模型或结果问题必须回退上游,不得在验收阶段擅改事实。
  • 收口顺序:先核对输入,再完成产物,再运行本环节门禁,最后登记状态;门禁未通过不得宣告完成。

Compile and validate: $ARGUMENTS

运行参数

  • ENGINE = xelatex

  • MAX_COMPILE_ATTEMPTS = 3

  • PAPER_DIR = 论文/

  • MAX_PAGES / COMPETITION — From Additional Parameters.

执行流程

工作节点 1:Validate environment


if ! which xelatex 2>/dev/null; then

    echo "xelatex not found, attempting install..."

    if which miktex 2>/dev/null; then

        miktex packages install xetex ctex xecjk gbt7714 fontspec

        miktex fndb refresh

    elif which initexmf 2>/dev/null; then

        initexmf --set-config-value=[MPM]AutoInstall=1

    fi

fi

which xelatex && which bibtex && echo "ready" || echo "xelatex/bibtex not found"

fc-list :lang=zh | head -5

kpsewhich gbt7714.sty 2>/dev/null || echo "gbt7714.sty not found (will auto-install on first compile)"

工作节点 2:Pre-compile cleanup


if [ -f "工具/compile_utils.sh" ]; then

    bash 工具/compile_utils.sh 论文/

elif [ -f "skills/shared-scripts/compile_utils.sh" ]; then

    bash skills/shared-scripts/compile_utils.sh 论文/

else

    echo "compile_utils.sh not found, manual cleanup needed"

fi

This utility auto-handles: special chars cleanup, table format fixes, includegraphics path correction (图表/ → ../图表/), hidelinks, 图表/图表/ nesting, math_commands conflicts, wide table resizebox wrapping, narrow table resizebox removal, light-color text fixes, TikZ library injection.

If script not found, perform these steps manually.

⛔ 表格行结束符修复(Misplaced \noalign 的根因):


# 检测并修复 tabular/longtable 中的单 \ 行结束符(应该是 \\)

# 这是 heredoc 不加引号导致 \\ 被转义为 \ 的常见问题

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    # 检测:tabular 环境内,行末只有单个 \ 后跟换行(应该是 \\)

    if grep -P '(?<!\\)\\(?!\\)(?=\s*$)' "$f" | grep -v '\\begin\|\\end\|\\hline\|\\toprule\|\\midrule\|\\bottomrule\|\\caption\|\\label\|\\centering\|\\input\|\\include\|\\usepackage\|\\section\|\\subsection' > /dev/null 2>&1; then

        echo "⚠ $(basename $f): 可能有表格行结束符问题(单 \\ 应为 \\\\)"

        # 在 tabular/longtable 环境内,把行末的单 \ 替换为 \\

        python3 -c "

import re

with open('$f', 'r', encoding='utf-8') as fh:

    content = fh.read()

# 只在 tabular/longtable 环境内修复

def fix_table_endings(match):

    table = match.group(0)

    # 把数据行末尾的单 \ (后跟换行) 替换为 \\\\

    fixed = re.sub(r'(?<=&[^&\n]*)\\\s*\n', r'\\\\\\\\\n', table)

    return fixed

for env in ['tabular', 'longtable']:

    pattern = r'(\\\\begin\{' + env + r'[*]?\}.*?\\\\end\{' + env + r'[*]?\})'

    content = re.sub(pattern, fix_table_endings, content, flags=re.DOTALL)

with open('$f', 'w', encoding='utf-8') as fh:

    fh.write(content)

" 2>/dev/null

    fi

done

Additionally validate ref/label matching and embed missing visuals:


mkdir -p 临时文件

grep -oh '\\ref{[^}]*}' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null | sort -u > 临时文件/_refs.txt

grep -oh '\\label{[^}]*}' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null | sort -u > 临时文件/_labels.txt

comm -23 <(sed 's/\\ref/\\label/g' 临时文件/_refs.txt) 临时文件/_labels.txt > 临时文件/_missing_labels.txt

cat 临时文件/_missing_labels.txt

⛔ 中文引号统一为全角引号(避免 PDF 出现 ''乱码或两个堆叠反引号):

中文论文用 xeCJK,全角引号 "..." 会自动化渲染为漂亮的对称弯引号。

LaTeX 风格 ...'' `` 在中文字体下会呈现成两个堆叠的反引号,很丑。

ASCII 直引号 "..." 在 LaTeX 中渲染为右右引号 ''...''。

统一替换为全角引号。


# 把所有错误引号统一为全角引号

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    python3 -c "

import re

content = open('$f', 'r', encoding='utf-8').read()

# 保护数学环境

placeholders = []

def stash(m):

    placeholders.append(m.group(0)); return f'\\x00M{len(placeholders)-1}\\x00'

content = re.sub(r'\\\$[^\\\$]*\\\#x27;, stash, content)

content = re.sub(r'\\\\\\[.*?\\\\\\]', stash, content, flags=re.DOTALL)

# 保护 \begin{verbatim}/lstlisting 等代码环境

content = re.sub(r'\\\\begin\{(verbatim|lstlisting|minted)\}.*?\\\\end\{\\1\}', stash, content, flags=re.DOTALL)

# 1. LaTeX 风格 ``...'' → 全角双引号

content = re.sub(r\"\`\`([^\`'\\\\n]+?)''\", '\u201c\\\\g<1>\u201d', content)

# 2. ASCII 直引号 \"...\" → 全角双引号(成对处理)

parts = content.split('\"')

if len(parts) > 2:

    result = parts[0]

    for i, p in enumerate(parts[1:], 1):

        result += ('\u201c' if i % 2 == 1 else '\u201d') + p

    content = result

# 还原

for i, ph in enumerate(placeholders):

    content = content.replace(f'\\x00M{i}\\x00', ph)

open('$f', 'w', encoding='utf-8').write(content)

" 2>/dev/null

done

If labels are missing, find corresponding figure/table code in 图表/*.tex and embed into the correct section file.

Also verify compile_utils.sh output for "UNEMBEDDED" warnings against figure_manifest.json. Only an item selected for publication is a blocking omission.

MANDATORY FIX LOOP — do NOT proceed to compilation until every publish=true figure and every table selected by the manuscript embedding plan is embedded:


UNEMBED=0

# Validate PDF visuals

for pdf in 图表/*.pdf; do

    [ -f "$pdf" ] || continue

    bn=$(basename "$pdf")

    python3 -c "import json,sys; d=json.load(open('图表/figure_manifest.json',encoding='utf-8')); sys.exit(0 if any(x.get('publish') and x.get('path','').replace('\\\\','/').endswith('/'+sys.argv[1]) for x in d.get('figures',[])) else 1)" "$bn" || continue

    grep -rq "$bn" 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null || { echo "UNEMBEDDED PDF: $bn"; UNEMBED=$((UNEMBED+1)); }

done

# Validate only TABLE_*.tex files selected by the manuscript embedding plan

for tbl in 图表/TABLE_*.tex; do

    [ -f "$tbl" ] || continue

    bn=$(basename "$tbl")

    python3 -c "import json,sys; d=json.load(open('图表/figure_manifest.json',encoding='utf-8')); sys.exit(0 if any(x.get('publish') and x.get('path','').replace('\\\\','/').endswith('/'+sys.argv[1]) for x in d.get('tables',[])) else 1)" "$bn" || continue

    # Validate if any label from this table file appears in sections

    for lbl in $(grep -oh '\\label{[^}]*}' "$tbl" 2>/dev/null); do

        grep -rq "$lbl" 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null || { echo "UNEMBEDDED TABLE: $lbl (from $bn)"; UNEMBED=$((UNEMBED+1)); }

    done

done

# Raw 图表引用.tex labels are diagnostic; the published asset loops above remain authoritative

echo "Total unembedded: $UNEMBED"

If UNEMBED > 0, you MUST fix all selected publication items before compiling. For each unembedded item:

  • PDF figure: copy the \begin{figure}...\end{figure} block from 图表/图表引用.tex into the target section

  • TABLE_*.tex: copy the \begin{table}...\end{table} block from 图表/TABLE_*.tex into the target section (use \input{../图表/TABLE_xxx.tex} or paste the tabular code directly)

  • Add 1-2 sentences of lead-in text before and 3-5 sentences of analysis after each embedded item

  • Re-run the count verify above — repeat until UNEMBED = 0

Do NOT compile with unembedded publication figures or selected正文 tables. Unpublished diagnostic assets are allowed to remain outside the paper.


# Diagnose generated PDFs; only publish=true omissions are blocking

for pdf in 图表/*.pdf; do

    [ -f "$pdf" ] || continue

    bn=$(basename "$pdf")

    python3 -c "import json,sys; d=json.load(open('图表/figure_manifest.json',encoding='utf-8')); sys.exit(0 if any(x.get('publish') and x.get('path','').replace('\\\\','/').endswith('/'+sys.argv[1]) for x in d.get('figures',[])) else 1)" "$bn" || continue

    grep -rq "$bn" 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null || echo "⚠ $bn not referenced"

done

执行节点 3:Compile (manual steps, no latexmk)


cd 论文/

xelatex -interaction=nonstopmode 论文正文.tex

bibtex 论文正文

xelatex -interaction=nonstopmode 论文正文.tex

xelatex -interaction=nonstopmode 论文正文.tex

执行节点 4:Error fix loop (MANDATORY — do NOT skip)

After each compilation, verify 编译日志.log for CRITICAL errors. You MUST fix ALL errors before declaring compilation complete.


# Count critical errors

MATH_ERR=$(grep -c 'Bad math environment delimiter\|Missing \$ inserted\|begin{document} ended by' 论文/编译日志.log 2>/dev/null || echo 0)

LR_ERR=$(grep -c 'Not allowed in LR mode' 论文/编译日志.log 2>/dev/null || echo 0)

UNDEF_CS=$(grep -c 'Undefined control sequence' 论文/编译日志.log 2>/dev/null || echo 0)

TOTAL_ERR=$((MATH_ERR + LR_ERR))

echo "Math errors: $MATH_ERR, LR mode errors: $LR_ERR, Undefined CS: $UNDEF_CS"

if [ "$TOTAL_ERR" -gt 0 ]; then

    echo "CRITICAL: $TOTAL_ERR errors — MUST FIX prior to proceeding"

    # Show error locations

    grep -B2 'Bad math\|Missing \$ inserted\|begin{document} ended\|Not allowed in LR mode' 论文/编译日志.log | grep -E '^\./|^l\.' | head -20

fi

Error fix rules (iterate up to 5 times, not 3):

  1. Math environment errors (Bad math environment delimiter, Missing $ inserted, \begin{document} ended by \end{equation}):

    • Read the error location from 编译日志.log (e.g., ./章节/3_model_theory.tex:42)

    • Open the file and find the broken math: usually \X(t)$ should be $X(t)$, or \mu$ should be $\mu$

    • Common cause: a sed/cleanup script stripped the opening $ but left the closing $

    • Fix: ensure every math expression has matching $...$ or \[...\] delimiters

    • Do NOT use broad sed patterns to fix math — read each error location and fix individually

  2. LR mode errors (Not allowed in LR mode):

    • Usually caused by \begin{figure} or \begin{table} inside a paragraph without proper separation

    • Fix: add \par or blank line before the float environment

  3. Undefined control sequence:

    • Missing package → add \usepackage{xxx} to 论文正文.tex preamble

    • Typo in command → fix the command name

  4. BibTeX failures:

    • If BibTeX fails because of earlier LaTeX errors, fix the LaTeX errors first, then recompile

    • Verify that \bibliography{references} and \bibliographystyle{plainnat} exist in 论文正文.tex

    • Verify that references.bib has no syntax errors (unmatched braces, missing commas)

After each fix, recompile and reverify:


cd 论文/

xelatex -interaction=nonstopmode 论文正文.tex

bibtex 论文正文 2>&1 | tail -5

xelatex -interaction=nonstopmode 论文正文.tex

xelatex -interaction=nonstopmode 论文正文.tex

cd ..

# Reverify

MATH_ERR=$(grep -c 'Bad math environment delimiter\|Missing \$ inserted' 论文/编译日志.log 2>/dev/null || echo 0)

echo "Remaining math errors: $MATH_ERR"

⛔ Do NOT proceed to Step 5 until MATH_ERR = 0 and LR_ERR = 0. BibTeX will also fail if there are LaTeX errors upstream — fix LaTeX first.

When fixing errors in 论文正文.tex, only fix the specific error (e.g., add a missing package, fix a typo). Avoid rewrite or restructure 论文正文.tex — the template's preamble, cover page, page margins, section numbering format, and header/footer settings must remain unchanged.

执行节点 5:Post-compile checks


bash 工具/compile_check.sh 论文/ 2>/dev/null || bash skills/shared-scripts/compile_check.sh 论文/

The script checks: PDF existence/size, undefined references, overfull hbox, TOC, abstracts, bibliography entries, citation count, citation format (上标/顺序/合并), unused figures, figure stacking, TikZ diagram presence.

⛔ MANDATORY: 引用格式问题必须修复(不可忽略):

compile_check.sh 会检查 3 类引用格式问题,任何一类 FAIL/WARN 都必须修复:

  1. 上标格式 FAIL → 如果 bibliographystyle 是 plain/plainnat/unsrt 但 \cite{} 没有上标

    • 修复方法A:改 bibliographystyle 为 gbt7714-numerical 或 plainnat + \usepackage[numbers,square,super]{natbib}

    • 修复方法B:把正文里所有 \cite{x} 改为 \upcite{x} 或 \textsuperscript{\cite{x}}

  2. 多引用顺序 WARN → \cite{c,a,b} 但全文 a 先出现

    • 修复方法:改成 \cite{a,b,c}(按全文首次出现顺序)

    • 用以下 bash 找出所有需修复的位置:

      
      grep -rnP '\\(up)?cite\{[^}]+\}' 论文/章节/*.tex 论文/论文正文.tex
      
      
  3. 连续引用未合并 WARN → \cite{a}\cite{b} 或 \cite{a} \cite{b}

    • 修复方法:合并为 \cite{a,b}

    • 批量修复:

      
      # 找出全部需合并的位置
      
      grep -rnoP '\\(up)?cite\{[^}]+\}\s*\\(up)?cite\{[^}]+\}' 论文/章节/*.tex 论文/论文正文.tex
      
      

⛔ 修复后必须重新编译验证: xelatex → bibtex → xelatex → xelatex,然后重新运行 compile_check.sh 确认无 FAIL。

Additionally verify:


# List of visuals / list of tables (stats competition requirement)

[ -s 论文/论文正文.lof ] && echo "✅ 插图清单已产出" || echo "⚠ 插图清单为空"

[ -s 论文/论文正文.lot ] && echo "✅ 表格清单已产出" || echo "⚠ 表格清单为空"

Template format verification (stats competition):


echo "=== 模板格式校验 ==="

if grep -q 'stats\|统计建模' 论文/论文正文.tex 2>/dev/null || [ "$COMPETITION" = "stats" ]; then

    # Validate page margins (is expected to be 2.54cm top/bottom, 3.17cm left/right)

    grep -q '2.54cm' 论文/论文正文.tex && echo "✅ 页边距无误" || echo "⚠ 页边距可能不对(应为上下2.54cm,左右3.17cm)"

    # Validate Chinese section numbering

    grep -q 'chinese{section}' 论文/论文正文.tex && echo "✅ 中文章节编号" || echo "⚠ 缺少中文章节编号(一、二、三...)"

    # Validate cover page

    grep -q '参赛学校\|参赛作品\|作品编号' 论文/论文正文.tex && echo "✅ 封面出现" || echo "⚠ 缺少封面"

    # Verify abstract format (should be \section*{摘要}, not \begin{abstract})

    grep -q 'section\*.*摘要' 论文/论文正文.tex && echo "✅ 摘要格式无误" || echo "⚠ 摘要格式可能不对"

    # Validate natbib (stats uses natbib, not gbt7714)

    grep -q 'natbib' 论文/论文正文.tex && echo "✅ natbib 引用格式" || echo "⚠ 缺少 natbib(统计建模应用 natbib)"

    # Validate no header line

    grep -q 'headrulewidth.*0pt' 论文/论文正文.tex && echo "✅ 无页眉线" || echo "⚠ 可能有页眉线"

    # Validate listoffigures / listoftables

    grep -q 'listoffigures' 论文/论文正文.tex && echo "✅ 插图清单命令" || echo "⚠ 缺少 \\listoffigures"

    grep -q 'listoftables' 论文/论文正文.tex && echo "✅ 表格清单命令" || echo "⚠ 缺少 \\listoftables"

fi

If any format checks fail, Meta-model-agent should fix 论文正文.tex to match the template format before recompiling.

执行节点 6:Competition compliance

Verify items:

  1. Page count: determine which parts count under the active competition Profile and require the count to be ≤ MAX_PAGES. Separately reject substantively incomplete chapters; never require the paper to fill the page ceiling.

  2. Anonymous: no team info (队号, 队员, 指导老师)

  3. Abstract exists (数模竞赛: at least Chinese; 统计建模: both Chinese and English)

  4. TOC exists (required by MathorCup etc.)

  5. Code appendix exists

  6. No undefined references/citations

“Code appendix exists”不得只检查标题或“代码/程序”关键词。必须读取 程序/code_manifest.json,逐项核验源码存在、SHA-256 未陈旧、required_in_appendix=true 的文件均有 CODE_FILE 标记和真实 \lstinputlisting/代码块。三种赛制均只核验主程序和逐问核心实现;辅助源码只能列入支撑材料清单,附录显示名必须为英文代码名。

CUMCM 页数必须读取编译后的 AbstractStart/AbstractEnd 与 BodyStart/BodyEnd 标签:摘要不超过 1 页,正文不超过 30 页,附录页数单独报告且不计入正文。模板含目录、标签缺失或仅用字符数估算时直接失败。

<page_diagnosis>

正文充分性诊断(与页数上限分开)

不要再把“正文达到 MAX_PAGES 的 80%”作为硬目标。MAX_PAGES 只表示上限。即使页数较少,也只有在论证链缺失时才扩充正文。


echo "=== 页数不足诊断 ==="

echo "页数上限: MAX_PAGES;另行检查正文论证充分性"

echo ""

echo "=== 各章节字符数(找出最薄的章节)==="

for f in 论文/章节/*.tex; do

    chars=$(wc -c < "$f")

    echo "  $(basename $f): $chars 字符 (~$(echo "scale=1; $chars/900" | bc) 页)"

done

echo ""

echo "=== 推荐扩充的章节(字符数最少的 3 个)==="

for f in $(ls -S 论文/章节/*.tex | tail -3); do

    chars=$(wc -c < "$f")

    echo "  ⚠ $(basename $f): 仅 $chars 字符"

done

只有出现以下问题时才标记为 CRITICAL 并扩充:

  • 某个子问题缺少模型机制或必要公式推导

  • 结果只有数字或图表,没有验证和解释

  • 摘要/结论中的关键主张无法在正文定位

扩充时只添加有证据来源的内容:

  • Read 建模报告.md and 计算结果.md for detailed content

  • Add unexpanded derivations, result analysis, validation, parameter discussions, and limitations

  • Recompile after expansion

</page_diagnosis>

执行节点 7:⛔ FINAL QUALITY GATE (must ALL pass before finishing)

Run all checks and verify every item passes. Do NOT output the report until all CRITICAL items are resolved.


echo "=========================================="

echo "  FINAL QUALITY GATE"

echo "=========================================="

GATE_FAIL=0

# 1. PDF exists and non-trivial

if [ -f 论文/数模论文.pdf ] && [ $(wc -c < 论文/数模论文.pdf) -gt 100000 ]; then

    echo "✅ PDF exists ($(wc -c < 论文/数模论文.pdf) bytes)"

else

    echo "❌ PDF missing or too small"; GATE_FAIL=$((GATE_FAIL+1))

fi

# 2. No LaTeX errors

MATH_ERR=$(grep -c 'Bad math environment delimiter\|Missing \$ inserted' 论文/编译日志.log 2>/dev/null || echo 0)

LR_ERR=$(grep -c 'Not allowed in LR mode' 论文/编译日志.log 2>/dev/null || echo 0)

[ "$((MATH_ERR+LR_ERR))" -eq 0 ] && echo "✅ No LaTeX errors" || { echo "❌ $MATH_ERR math + $LR_ERR LR errors"; GATE_FAIL=$((GATE_FAIL+1)); }

# 3. Bibliography not empty

BBL_ENTRIES=$(grep -c '\\bibitem' 论文/论文正文.bbl 2>/dev/null || echo 0)

[ "$BBL_ENTRIES" -gt 0 ] && echo "✅ Bibliography: $BBL_ENTRIES entries" || { echo "❌ Bibliography empty (BibTeX failed)"; GATE_FAIL=$((GATE_FAIL+1)); }

# 4. No unembedded publish=true visuals

UNEMBED=0

for pdf in 图表/*.pdf; do

    [ -f "$pdf" ] || continue

    bn=$(basename "$pdf")

    python3 -c "import json,sys; d=json.load(open('图表/figure_manifest.json',encoding='utf-8')); sys.exit(0 if any(x.get('publish') and x.get('path','').replace('\\\\','/').endswith('/'+sys.argv[1]) for x in d.get('figures',[])) else 1)" "$bn" || continue

    grep -rq "$bn" 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null || UNEMBED=$((UNEMBED+1))

done

[ "$UNEMBED" -eq 0 ] && echo "✅ All publication visuals embedded" || { echo "❌ $UNEMBED publish=true visuals not embedded in manuscript"; GATE_FAIL=$((GATE_FAIL+1)); }

# 5. Page count

PAGE_EST=0

for f in 论文/章节/*.tex; do [ -f "$f" ] || continue; c=$(wc -c < "$f"); PAGE_EST=$((PAGE_EST + c)); done

PAGE_EST=$((PAGE_EST / 900))

echo "  Body estimate: ~$PAGE_EST pages; MAX_PAGES is the submission ceiling, not a fill target"

# 6. Overfull vbox (table/visual overflow)

VBOX_ERR=$(grep -c 'Overfull.*vbox' 论文/编译日志.log 2>/dev/null || echo 0)

[ "$VBOX_ERR" -eq 0 ] && echo "✅ No table/visual overflow" || { echo "❌ $VBOX_ERR overfull vbox — tables may be cut off"; GATE_FAIL=$((GATE_FAIL+1)); }

# 7. AI writing patterns (itemize in body)

AI_LISTS=0

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    echo "$(basename $f)" | grep -qi 'appendix\|附录' && continue

    c=$(grep -c '\\begin{itemize}' "$f" 2>/dev/null || echo 0)

    AI_LISTS=$((AI_LISTS + c))

done

[ "$AI_LISTS" -eq 0 ] && echo "✅ No bullet lists in body" || { echo "❌ $AI_LISTS itemize — convert to prose"; GATE_FAIL=$((GATE_FAIL+1)); }

# 8. Template integrity — compare preamble against established template

echo "--- Template integrity ---"

TMPL=""

for t in 模板/stats_论文正文.tex 模板/cumcm_论文正文.tex 模板/mcm_论文正文.tex 模板/bachelor_论文正文.tex 模板/master_论文正文.tex 模板/journal_论文正文.tex; do

    [ -f "$t" ] && TMPL="$t" && break

done

if [ -n "$TMPL" ] && [ -f 论文/论文正文.tex ]; then

    # Extract preamble (before \begin{document}) from both files

    TMPL_PRE=$(sed -n '1,/\\begin{document}/p' "$TMPL" | grep '\\usepackage\|\\documentclass\|\\ctexset\|\\pagestyle\|\\renewcommand.*headrulewidth\|\\listoftables\|\\listoffigures\|\\cline\|\\bibliography' | sort)

    MAIN_PRE=$(sed -n '1,/\\begin{document}/p' 论文/论文正文.tex | grep '\\usepackage\|\\documentclass\|\\ctexset\|\\pagestyle\|\\renewcommand.*headrulewidth\|\\listoftables\|\\listoffigures\|\\cline\|\\bibliography' | sort)

    MISSING=$(comm -23 <(echo "$TMPL_PRE") <(echo "$MAIN_PRE") 2>/dev/null | head -5)

    if [ -z "$MISSING" ]; then

        echo "✅ Template preamble intact"

    else

        echo "❌ Template preamble was modified — these lines from template are missing in 论文正文.tex:"

        echo "$MISSING" | sed 's/^/    /'

        GATE_FAIL=$((GATE_FAIL+1))

    fi

    # Validate cover page structure (if template has one)

    if grep -q '参赛学校\|参赛作品' "$TMPL" 2>/dev/null; then

        grep -q '参赛学校\|参赛作品' 论文/论文正文.tex 2>/dev/null && echo "✅ Cover page present" || { echo "❌ Cover page missing/rewritten"; GATE_FAIL=$((GATE_FAIL+1)); }

        grep -q 'cline{2-2}' 论文/论文正文.tex 2>/dev/null && echo "✅ Cover underlines (cline)" || { echo "❌ Cover cline missing"; GATE_FAIL=$((GATE_FAIL+1)); }

    fi

    # Validate bracket placeholders not remaining

    if grep -q '\[论文标题\]\|\[学校名称\]\|\[队员1\]\|\[指导老师\]\|\[竞赛年份\]\|\[届数\]\|\[中文摘要内容\]' 论文/论文正文.tex 2>/dev/null; then

        echo "❌ Unreplaced bracket placeholders in 论文正文.tex"; GATE_FAIL=$((GATE_FAIL+1))

    else

        echo "✅ All placeholders replaced"

    fi

    # Validate hand-written visual/table list (anti-pattern)

    if grep -P '^(表|图)\d+\.' 论文/论文正文.tex 2>/dev/null | head -1 | grep -q '.'; then

        echo "❌ Hand-written figure/table list (use \\listoftables/\\listoffigures)"; GATE_FAIL=$((GATE_FAIL+1))

    fi

else

    echo "  (no template found for comparison, skipping)"

fi

# 9. Visual plan reconciliation (validate planning docs)

echo "--- Visual plan validate ---"

PLAN_FIGS=0; ACTUAL_FIGS=$(ls 图表/*.pdf 2>/dev/null | wc -l)

for plan in 选题规划.md 论文规划.md 问题分析.md; do

    [ -f "$plan" ] || continue

    pf=$(grep -ci 'fig_\|图.*:\|visual.*:' "$plan" 2>/dev/null || echo 0)

    [ "$pf" -gt "$PLAN_FIGS" ] && PLAN_FIGS=$pf

done

if [ "$PLAN_FIGS" -gt 0 ]; then

    echo "  Planned: ~$PLAN_FIGS visuals, Actual: $ACTUAL_FIGS PDFs"

    [ "$ACTUAL_FIGS" -ge "$PLAN_FIGS" ] && echo "✅ Visual count meets original plan" || echo "  ⚠ Visual count is below the early plan; confirm omitted items are registered publish=false with reasons"

else

    echo "  No visual plan found, actual: $ACTUAL_FIGS PDFs"

fi

# 10. TikZ 几何/算法/架构图

# TikZ 由 systems-diagramming 编译成 图表/结构示意图.pdf, 通过 \includegraphics 嵌入

# (不是 sections 里的裸 tikzpicture 代码)。两种形态都算已嵌入。

TIKZ_IN_PAPER=$(grep -rl 'tikzpicture\|结构示意图\|tikz_' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null | wc -l)

# ⛔ 只在"真实产出了 tikz_*.pdf 产物"时才硬核对(避免规划提了但用 DrawIO 替代时误报失败)

TIKZ_PDF_TOTAL=0; TIKZ_PDF_MISSING=0

for tpdf in 图表/结构示意图.pdf 图表/结构示意图_*.pdf 图表/tikz_*.pdf; do

    [ -f "$tpdf" ] || continue

    python3 -c "import json,sys; d=json.load(open('图表/figure_manifest.json',encoding='utf-8')); sys.exit(0 if any(x.get('publish') and x.get('path','').replace('\\\\','/').endswith('/'+sys.argv[1]) for x in d.get('figures',[])) else 1)" "$(basename "$tpdf")" || continue

    TIKZ_PDF_TOTAL=$((TIKZ_PDF_TOTAL+1))

    grep -rq "$(basename "$tpdf")" 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null || TIKZ_PDF_MISSING=$((TIKZ_PDF_MISSING+1))

done

if [ "$TIKZ_PDF_TOTAL" -gt 0 ]; then

    # 有 publish=true 的 TikZ 产物 → 务必全部嵌入

    if [ "$TIKZ_PDF_MISSING" -gt 0 ]; then

        echo "❌ $TIKZ_PDF_MISSING 张 TikZ PDF 未嵌入任何章节"; GATE_FAIL=$((GATE_FAIL+1))

    else

        echo "✅ TikZ diagrams embedded ($TIKZ_PDF_TOTAL)"

    fi

elif grep -qi 'tikz\|架构\|路线图\|几何示意\|算法流程' 论文规划.md 问题分析.md 2>/dev/null; then

    # 规划提到 TikZ 但没产出 tikz_*.pdf(可能已用 DrawIO 替代) → 仅提醒, 不判失败

    [ "$TIKZ_IN_PAPER" -gt 0 ] && echo "✅ TikZ embedded" || echo "  ⚠ 规划提到 TikZ 但未发现 tikz_*.pdf(可能已用 DrawIO 替代, 不阻塞)"

else

    [ "$TIKZ_IN_PAPER" -gt 0 ] && echo "✅ TikZ diagrams embedded ($TIKZ_IN_PAPER)" || echo "  (no TikZ planned)"

fi

# 11. Citations in body

CITE_COUNT=$(grep -roh '\\cite{' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null | wc -l)

[ "$CITE_COUNT" -gt 0 ] && echo "✅ Citations: $CITE_COUNT" || { echo "❌ No citations in body text"; GATE_FAIL=$((GATE_FAIL+1)); }

# 12. No placeholders remaining

PLACEHOLDERS=$(grep -rl 'PLACEHOLDER\|待补充\|TODO\|\[论文标题\]\|\[中文摘要内容\]' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null | wc -l)

[ "$PLACEHOLDERS" -eq 0 ] && echo "✅ No placeholders" || { echo "❌ $PLACEHOLDERS files have placeholders"; GATE_FAIL=$((GATE_FAIL+1)); }

# 13. Undefined references

UNDEF_REFS=$(grep -c 'LaTeX Warning.*Reference.*undefined' 论文/编译日志.log 2>/dev/null || echo 0)

[ "$UNDEF_REFS" -eq 0 ] && echo "✅ No undefined refs" || { echo "❌ $UNDEF_REFS undefined references"; GATE_FAIL=$((GATE_FAIL+1)); }

# 14. Overfull hbox(零容忍)

HBOX_ERR=$(grep -c 'Overfull.*hbox' 论文/编译日志.log 2>/dev/null || echo 0)

[ "$HBOX_ERR" -eq 0 ] && echo "✅ No overfull hbox" || { echo "❌ $HBOX_ERR overfull hbox — fix wide tables/formulas"; GATE_FAIL=$((GATE_FAIL+1)); }

# 15. Visual stacking

STACKING=0

for f in 论文/章节/*.tex; do [ -f "$f" ] || continue; s=$(awk '/\\end\{(figure|table)\}/{a=1;t=0;next} a&&/\\begin\{(figure|table)\}/{if(t<3)c++;a=0;next} a&&/[a-zA-Z\x80-\xff]{3,}/{t++} a&&t>=3{a=0} END{print c+0}' "$f" 2>/dev/null); STACKING=$((STACKING+s)); done

[ "$STACKING" -eq 0 ] && echo "✅ No visual stacking" || { echo "❌ $STACKING visual stacking — add analysis text between visuals"; GATE_FAIL=$((GATE_FAIL+1)); }

# 16. TOC

if grep -q 'tableofcontents' 论文/论文正文.tex 2>/dev/null; then

    [ -s 论文/论文正文.toc ] && echo "✅ TOC generated" || {

        echo "❌ TOC empty — running extra compile pass..."

        cd 论文/

        xelatex -interaction=nonstopmode 论文正文.tex > /dev/null 2>&1

        xelatex -interaction=nonstopmode 论文正文.tex > /dev/null 2>&1

        cd ..

        [ -s 论文/论文正文.toc ] && echo "✅ TOC generated following extra compile" || { echo "❌ TOC still empty"; GATE_FAIL=$((GATE_FAIL+1)); }

    }

fi

# 17. Abstracts (Chinese papers)

if grep -q 'ctex' 论文/论文正文.tex 2>/dev/null; then

    grep -rq '摘.*要' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null && echo "✅ Chinese abstract" || { echo "❌ No Chinese abstract"; GATE_FAIL=$((GATE_FAIL+1)); }

    grep -rq 'Abstract' 论文/章节/*.tex 论文/论文正文.tex 2>/dev/null && echo "✅ English abstract" || { echo "❌ No English abstract"; GATE_FAIL=$((GATE_FAIL+1)); }

fi

# 18. Run compile_check.sh + writing_check.sh for full details

echo ""

echo "--- Full validate scripts ---"

bash 工具/compile_check.sh 论文/ 2>/dev/null || bash skills/shared-scripts/compile_check.sh 论文/ 2>/dev/null

bash 工具/writing_check.sh 论文/ 2>/dev/null || bash skills/shared-scripts/writing_check.sh 论文/ 2>/dev/null

WC_EXIT=$?

[ "$WC_EXIT" -eq 0 ] && echo "✅ Writing checks passed" || { echo "❌ Writing checks failed (exit=$WC_EXIT)"; GATE_FAIL=$((GATE_FAIL+1)); }

# 19. 符号阐明 longtable 核验

echo "--- Symbol table format ---"

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    if grep -q '\\section{符号说明}\|\\section.*符号' "$f" 2>/dev/null; then

        if grep -q '\\begin{longtable}' "$f" 2>/dev/null; then

            echo "✅ 符号阐明采用 longtable"

        elif grep -q '\\begin{table}' "$f" 2>/dev/null; then

            echo "❌ 符号阐明仍用 table(应转 longtable 防分页)"; GATE_FAIL=$((GATE_FAIL+1))

        fi

    fi

done

# 20. 正文长表格核验(>12 行必须摘要化;需跨页时使用 longtable)

echo "--- Long table validate ---"

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    echo "$(basename $f)" | grep -qi 'symbol\|appendix\|A_code' && continue

    if grep -q '\\begin{tabular}' "$f" 2>/dev/null; then

        ROW_COUNT=$(awk '/\\begin\{tabular\}/,/\\end\{tabular\}/' "$f" 2>/dev/null | grep -c '&' || echo 0)

        [ "$ROW_COUNT" -gt 12 ] && { echo "❌ $(basename $f): $ROW_COUNT 行结果表应在正文摘要化,完整表移至附录并按需使用 longtable"; GATE_FAIL=$((GATE_FAIL+1)); }

    fi

done

# 21. babel[english] 冲突

echo "--- babel validate ---"

if grep -q 'ctex\|cumcmthesis\|gmcmthesis' 论文/论文正文.tex 2>/dev/null; then

    grep -q 'babel.*english' 论文/论文正文.tex 2>/dev/null && { echo "❌ 中文论文有 babel[english]"; GATE_FAIL=$((GATE_FAIL+1)); } || echo "✅ 无 babel 冲突"

fi

# 22. 数值一致性(JSON vs 论文)

echo "--- Numerical consistency ---"

if [ -f 图表/全部结果.json ]; then

    python3 -c "

import json, re, os

with open('图表/全部结果.json','r',encoding='utf-8') as f: outcomes=json.load(f)

def extract(obj,p=''):

    n={}

    if isinstance(obj,dict):

        for k,v in obj.items(): n.update(extract(v,f'{p}.{k}'))

    elif isinstance(obj,(int,float)) and not isinstance(obj,bool):

        if 0.001<abs(obj)<1e10: n[p]=obj

    return n

jn=extract(outcomes); pn=set()

for tf in sorted(os.listdir('论文/章节')):

    if not tf.endswith('.tex'): continue

    with open(f'论文/章节/{tf}','r',encoding='utf-8',errors='ignore') as f: t=f.read()

    for m in re.finditer(r'(?<![a-zA-Z])(\d+\.?\d+)(?![a-zA-Z_{}])',t):

        try: pn.add(float(m.group(1)))

        except: pass

miss=sum(1 for k,v in jn.items() if not any(abs(p-v)<abs(v)*0.01+0.001 for p in pn) and any(w in k.lower() for w in ['rmse','r2','accuracy','f1','objective','optimal','best']))

print(f'❌ {miss} key values missing in manuscript' if miss else '✅ Key values consistent')

import sys; sys.exit(1 if miss>3 else 0)

" 2>/dev/null

    [ $? -ne 0 ] && GATE_FAIL=$((GATE_FAIL+1))

fi

# 22.5 "太完美"结果检测(AI 编造或过拟合特征)

echo "--- Unrealistic values validate ---"

if [ -f 图表/全部结果.json ]; then

    python3 -c "

import json

with open('图表/全部结果.json','r',encoding='utf-8') as f: data=json.load(f)

suspicious = []

def validate(name, val):

    if not isinstance(val,(int,float)) or isinstance(val,bool): return

    key = name.lower()

    if any(w in key for w in ['r2','r_squared','accuracy','acc','precision','recall','f1','auc']) and val > 0.999:

        suspicious.append(f'{name}={val:.4f} 过于完美(>0.999)')

    if any(w in key for w in ['rmse','mae','mse','loss']) and val == 0:

        suspicious.append(f'{name}=0 完美误差')

    if ('p_value' in key or 'pvalue' in key) and val == 0:

        suspicious.append(f'{name}=0 完美显著')

    if any(w in key for w in ['improvement','speedup','gain','提升']) and val > 10:

        suspicious.append(f'{name}={val} 提升过大({val*100:.0f}%)')

def walk(obj, path=''):

    if isinstance(obj,dict):

        for k,v in obj.items(): walk(v, f'{path}.{k}')

    elif isinstance(obj,list):

        for i,v in enumerate(obj): walk(v, f'{path}[{i}]')

    else: validate(path, obj)

walk(data)

if suspicious:

    print(f'🚩 {len(suspicious)} 处可疑的完美结果(可能过拟合或数值编造):')

    for s in suspicious[:5]: print(f'    {s}')

    print('  需在论文中阐明合理性,或回到 computational-realization 核验数据泄漏')

else:

    print('✅ 数值合理性通过')

" 2>/dev/null

fi

# 22.6 合理性复核章节是否出现(务必)

echo "--- 合理性复核章节核验 ---"

if [ -f 计算结果.md ]; then

    if grep -q '合理性审查\|数值合理\|背景对照\|sanity.*verify' 计算结果.md 2>/dev/null; then

        echo "✅ 计算结果.md 涵盖合理性复核章节"

    else

        echo "❌ 计算结果.md 缺少合理性复核章节 — 回到 computational-realization Phase 1.7 补充"

        GATE_FAIL=$((GATE_FAIL+1))

    fi

fi

# 22.7 数据源时间戳一致性(代码 vs 图形与表格 vs 论文)

echo "--- 数据源时间戳一致性 ---"

if [ -f 图表/全部结果.json ]; then

    JSON_TIME=$(stat -c %Y 图表/全部结果.json 2>/dev/null || stat -f %m 图表/全部结果.json 2>/dev/null || echo 0)

    # 核验是否有 PDF 图形与表格比 JSON 旧(阐明代码重跑了但图没更新)

    STALE_FIGS=0

    for pdf in 图表/*.pdf; do

        [ -f "$pdf" ] || continue

        PDF_TIME=$(stat -c %Y "$pdf" 2>/dev/null || stat -f %m "$pdf" 2>/dev/null || echo 0)

        if [ "$JSON_TIME" -gt "$PDF_TIME" ] && [ "$((JSON_TIME - PDF_TIME))" -gt 60 ]; then

            echo "  ⚠ $(basename $pdf) 比 全部结果.json 旧 — 图形与表格数据可能过期"

            STALE_FIGS=$((STALE_FIGS+1))

        fi

    done

    if [ "$STALE_FIGS" -gt 0 ]; then

        echo "  ❌ $STALE_FIGS 张图形与表格可能采用了旧数据(JSON 更新后图形与表格未重新产出)"

        echo "  → 推荐重跑 evidence-visualization 环节更新图形与表格"

        GATE_FAIL=$((GATE_FAIL+1))

    else

        echo "✅ 数据源时间戳保持一致"

    fi

fi

# 22.8 正文长表格检测(>12 行的表格不应在正文中完整展开)

echo "--- 正文长表格检测 ---"

LONG_TABLES=0

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    # 跳过附录文件

    echo "$(basename $f)" | grep -qi 'appendix\|附录\|A_code' && continue

    # 统计各个 tabular/longtable 环境内的数据行数(\\ 的数量)

    python3 -c "

import re

with open('$f', 'r', encoding='utf-8', errors='ignore') as fh:

    content = fh.read()

# 找全部 tabular/longtable 环境

for env in ['tabular', 'longtable', 'tabular*']:

    pattern = r'\\\\begin\{' + env + r'[*]?\}.*?\\\\end\{' + env + r'[*]?\}'

    for match in re.finditer(pattern, content, re.DOTALL):

        table_text = match.group()

        row_count = table_text.count('\\\\\\\\') - table_text.count('\\\\hline') // 2

        if row_count > 12:

            print(f'$(basename $f): {env} 有 {row_count} 行(>12)')

" 2>/dev/null | while read line; do

        echo "  ❌ $line — 正文表格超过 12 行,应截断(前3+后3+省略),完整版放附录"

        LONG_TABLES=$((LONG_TABLES+1))

    done

done

[ "$LONG_TABLES" -eq 0 ] && echo "✅ 正文无超长表格" || GATE_FAIL=$((GATE_FAIL+1))

# 23. AI 写作痕迹(列表环境)

echo "--- AI writing patterns ---"

AI_LISTS=0

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    echo "$(basename $f)" | grep -qi 'appendix\|A_code' && continue

    c=$(grep -c '\\begin{itemize}\|\\begin{enumerate}' "$f" 2>/dev/null || echo 0)

    AI_LISTS=$((AI_LISTS+c))

done

[ "$AI_LISTS" -le 3 ] && echo "✅ AI patterns: $AI_LISTS lists" || { echo "❌ $AI_LISTS lists in body — convert to prose"; GATE_FAIL=$((GATE_FAIL+1)); }

# 24. 元叙述泄露

echo "--- Meta content leak ---"

META=0

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    l=$(grep -ci 'RESULTS\.md\|META_MODEL_AGENT\.md\|MODELING_REPORT\|PROBLEM_ANALYSIS\|latex_includes' "$f" 2>/dev/null || echo 0)

    META=$((META+l))

done

[ "$META" -eq 0 ] && echo "✅ No meta leaks" || { echo "❌ $META meta content leaks"; GATE_FAIL=$((GATE_FAIL+1)); }

# 25. 过度声称

echo "--- Overclaiming ---"

OC=0

for f in 论文/章节/*.tex; do

    [ -f "$f" ] || continue

    for w in "首次提出" "首次发现" "完美" "最优的" "无可比拟" "前所未有" "开创性" "革命性"; do

        c=$(grep -c "$w" "$f" 2>/dev/null || echo 0); OC=$((OC+c))

    done

done

[ "$OC" -eq 0 ] && echo "✅ No overclaiming" || echo "⚠ $OC overclaiming instances"

echo ""

echo "=========================================="

if [ "$GATE_FAIL" -eq 0 ]; then

    echo "  ✅ ALL CRITICAL CHECKS PASSED — ready to submit"

else

    echo "  ❌ $GATE_FAIL CRITICAL FAILURES — MUST FIX prior to finishing"

    echo "  Go back and fix each ❌ item, recompile, then re-run this gate."

fi

echo "=========================================="

⛔ If GATE_FAIL > 0, you MUST go back and fix every ❌ item, recompile, and re-run this gate. Do NOT output the final report with any ❌ remaining. Repeat until GATE_FAIL = 0.

执行节点 8:Output report

Competition name, status, PDF path, total pages, body pages, compliance pass/fail.

核心规则

  • No latexmk — manual step-by-step compilation

  • Avoid delete .bbl file after compilation (bibliography data)

  • Figure paths auto-corrected by compile_utils.sh: 图表/ → ../图表/

  • Total/countable pages ≤ MAX_PAGES. Page count is a ceiling;正文充分性按逐问论证链独立检查。

  • Every embedded LaTeX figure must stay within \linewidth and 0.70\textheight with keepaspectratio; every DOCX image must stay within the computed page body width. Oversized or unreadably shrunken figures are gate failures.

  • Anonymous: no team info in body

  • Primary output: 论文/数模论文.pdf, temp files: 临时文件/

Skills enregistrées