重构为函数式通用 Markdown 修改库
This commit is contained in:
@@ -1,127 +0,0 @@
|
||||
# 使用本地页面评审一次 Markdown 清洗运行
|
||||
|
||||
## 1. 适用范围
|
||||
|
||||
本指南用于打开已经发布在 `artifacts/<YYYY-MM-DD>/runs/<run_id>/` 的本地清洗运行。完整双栏比较要求运行目录包含
|
||||
`review-locator.json`,并且原文仍位于运行时记录的位置且哈希未改变。
|
||||
|
||||
评审器只读文件,不重新运行组件、不修改原文和产物。当前不适用于 GovDoc、远程目录、多人共享或生产部署。
|
||||
|
||||
本指南于 2026-08-23 使用 Python 3.13.11、当前用户 nvm 中的 Node.js 24.19.0 和运行
|
||||
`clindb-first-batch-reviewer-v1` 实际验证。
|
||||
|
||||
## 2. 准备一次可评审运行
|
||||
|
||||
先按 [`run-local-clindb-first-batch-experiment.md`](run-local-clindb-first-batch-experiment.md) 产生一次新的运行。成功终端摘要
|
||||
会给出绝对 artifact 路径,例如:
|
||||
|
||||
```text
|
||||
artifacts=/home/lihaoze/work/mdpolish/artifacts/<YYYY-MM-DD>/runs/<run_id>
|
||||
```
|
||||
|
||||
确认该目录内存在:
|
||||
|
||||
```text
|
||||
manifest.json
|
||||
review-locator.json
|
||||
documents/
|
||||
```
|
||||
|
||||
不要编辑定位文件,也不要向旧运行目录手工补写它。历史运行缺少 locator 时,使用不同运行 ID 重新实验。
|
||||
|
||||
## 3. 准备评审器
|
||||
|
||||
评审器前端的安装、检查和构建要求 Node.js 24 LTS。当前用户 nvm 已安装与 `.nvmrc` 匹配的版本。在仓库根目录执行:
|
||||
|
||||
```bash
|
||||
cd reviewer
|
||||
nvm use
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
`node --version` 必须是受支持的 `v24`。本仓库不负责修改系统级 Node.js;版本不符时先在开发环境外准备正确运行时。
|
||||
|
||||
首次安装或锁文件变化后,仍在 `reviewer/` 目录执行:
|
||||
|
||||
```bash
|
||||
npm ci
|
||||
```
|
||||
|
||||
当前有效的 Python 与 reviewer 检查命令只以根目录 [`README.md`](../../README.md#当前可用检查) 为准。检查通过后构建页面:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
## 4. 启动一次运行
|
||||
|
||||
回到仓库根目录,用当前 Python 虚拟环境启动只读服务并传入运行目录:
|
||||
|
||||
```bash
|
||||
.venv/bin/python -m reviewer.server \
|
||||
--run-dir /home/lihaoze/work/mdpolish/artifacts/<YYYY-MM-DD>/runs/<run_id>
|
||||
```
|
||||
|
||||
启动成功时只打印运行 ID、文档数量和随机本机端口,不打印原文或绝对源路径:
|
||||
|
||||
```text
|
||||
mdpolish 评审器已启动:http://127.0.0.1:<port>(<run_id>,<count> 份文档)
|
||||
```
|
||||
|
||||
在本机浏览器打开该地址。评审结束后回到终端按 `Ctrl+C` 停止服务。
|
||||
|
||||
开发页面时开两个终端。第一个终端在仓库根目录把 Python API 固定到 Vite 代理使用的本机端口:
|
||||
|
||||
```bash
|
||||
.venv/bin/python -m reviewer.server \
|
||||
--run-dir /home/lihaoze/work/mdpolish/artifacts/<YYYY-MM-DD>/runs/<run_id> \
|
||||
--port 4174
|
||||
```
|
||||
|
||||
第二个终端启动只绑定 `127.0.0.1:5173` 的 Vite 页面;它只把 `/api/` 代理给上述 Python 服务,Node.js 不读取 artifact:
|
||||
|
||||
```bash
|
||||
cd reviewer
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## 5. 页面怎么查看
|
||||
|
||||
1. 先确认顶部整体状态和总修改数与 `manifest.json` 一致;
|
||||
2. 在左侧选择文档,主双栏默认显示清洗前和最终成功输出;
|
||||
3. 在组件时间线选择一个组件,双栏切换为该组件执行前后;
|
||||
4. 检查组件版本和修改数,零修改应显示 `0`,而不是从时间线消失;
|
||||
5. 点击修改详情,跳到对应组件阶段的位置并核对理由、`before` 和 `after`;
|
||||
6. 对 `failed` / `unstable` 只查看错误和残留候选,不寻找不存在的正式输出。
|
||||
|
||||
页面中的总修改数是实际 `Change` 条数,不是 diff hunk 数、字符数或问题数量。
|
||||
|
||||
## 6. 常见错误
|
||||
|
||||
### 原文路径失效或哈希改变
|
||||
|
||||
评审器不会搜索同名文件。确认输入没有被移动或修改;如果需要在新位置运行,使用新的运行 ID 重新执行实验。不要改 locator
|
||||
绕过哈希检查。
|
||||
|
||||
### 历史运行没有 `review-locator.json`
|
||||
|
||||
历史产物仍可在页面查看清单和已有审计,也可人工查看 manifest、result 和 diff,但第一版页面不能自动找到完整原文或
|
||||
组件阶段。不要回写历史目录;需要完整双栏时重新运行一次即可。
|
||||
|
||||
### 不支持 schema
|
||||
|
||||
评审器只支持当前文档列出的 schema 版本。不要删除或伪造 `schema_version`;应升级评审器适配器或使用与产物匹配的代码。
|
||||
|
||||
### 没有 `cleaned.md`
|
||||
|
||||
对应文档状态是 `failed` 或 `unstable` 时这是正常边界。页面不会从 Change 重建并冒充正式结果。
|
||||
|
||||
### 服务拒绝 Host、Origin 或写请求
|
||||
|
||||
评审器只接受本机同源的只读请求。不要通过反向代理、远程端口转发或网页跨域调用它;这些用法没有批准。
|
||||
|
||||
## 7. 数据边界
|
||||
|
||||
页面会在本机内存中读取完整原文和成功输出。不要截图、复制或通过浏览器扩展分享真实内容。运行目录继续受 Git 忽略并按
|
||||
manifest 的 `retention_until` 管理;页面不会自动删除到期产物。
|
||||
@@ -1,129 +0,0 @@
|
||||
# 运行本地 ClinDB arXiv 清洗实验
|
||||
|
||||
## 1. 适用范围
|
||||
|
||||
本指南只运行仓库内已经批准的本地实验脚本:
|
||||
|
||||
- 输入:`data/md/` 中的 `dmp.md`、`ejhf.md`、`jama.md`、`sim.md` 和 `springer.md`;
|
||||
- 流水线:只包含 `paper.arxiv_submission_stamp` `1.0.0`;
|
||||
- 输出:`artifacts/<YYYY-MM-DD>/runs/<run_id>/`;
|
||||
- 输入只读,不覆盖原文件;
|
||||
- 不处理 `/home/lihaoze/gov_test_data`。
|
||||
|
||||
本指南于 2026-08-22 在 Python 3.13.11 环境实际验证。
|
||||
|
||||
## 2. 前置条件
|
||||
|
||||
在仓库根目录执行,并确认隔离环境和基础检查可用:
|
||||
|
||||
```bash
|
||||
.venv/bin/python --version
|
||||
.venv/bin/ruff check .
|
||||
.venv/bin/mypy src tests scripts/run_clindb_arxiv_experiment.py scripts/run_clindb_first_batch_experiment.py
|
||||
.venv/bin/pytest
|
||||
```
|
||||
|
||||
确认 5 份本地输入存在:
|
||||
|
||||
```bash
|
||||
find data/md -maxdepth 1 -type f -name '*.md' -printf '%f\n' | sort
|
||||
```
|
||||
|
||||
预期看到:
|
||||
|
||||
```text
|
||||
dmp.md
|
||||
ejhf.md
|
||||
jama.md
|
||||
sim.md
|
||||
springer.md
|
||||
```
|
||||
|
||||
## 3. 运行实验
|
||||
|
||||
为本次实验人工选择一个小写运行 ID。同一天已经使用过的 ID 不能覆盖;需要重跑时换一个新 ID。
|
||||
|
||||
```bash
|
||||
.venv/bin/python scripts/run_clindb_arxiv_experiment.py \
|
||||
--run-id clindb-arxiv-stamp-review
|
||||
```
|
||||
|
||||
成功时终端只显示运行 ID、状态、文档数、修改数和产物目录,例如:
|
||||
|
||||
```text
|
||||
run_id=clindb-arxiv-stamp-review
|
||||
status=success
|
||||
documents=5
|
||||
changes=2
|
||||
artifacts=/.../mdpolish/artifacts/<YYYY-MM-DD>/runs/clindb-arxiv-stamp-review
|
||||
```
|
||||
|
||||
终端不会打印论文原文或 diff。
|
||||
|
||||
## 4. 查看结果
|
||||
|
||||
进入终端输出的运行目录。目录结构为:
|
||||
|
||||
```text
|
||||
manifest.json
|
||||
documents/
|
||||
├── dmp/
|
||||
│ ├── result.json
|
||||
│ ├── cleaned.md
|
||||
│ └── changes.diff
|
||||
├── ejhf/
|
||||
├── jama/
|
||||
├── sim/
|
||||
└── springer/
|
||||
```
|
||||
|
||||
先看 `manifest.json` 的整批状态和汇总,再查看各文档:
|
||||
|
||||
- `cleaned.md`:成功清洗后的完整 Markdown;
|
||||
- `changes.diff`:输入到成功输出的人工对比;
|
||||
- `result.json`:组件、理由、位置、`before`、`after` 和哈希等机器审计。
|
||||
|
||||
`dmp`、`ejhf` 和 `jama` 当前应为零修改,diff 是空文件;`sim` 和 `springer` 当前各有一条删除。
|
||||
|
||||
## 5. 判断成功
|
||||
|
||||
本轮验收口径是:
|
||||
|
||||
- manifest 整体状态为 `success`;
|
||||
- 5 份文档全部为 `success`;
|
||||
- 合计 2 条修改;
|
||||
- `sim` 修改位置为 1:1;
|
||||
- `springer` 修改位置为 18:1;
|
||||
- Springer 两条合法 `arXiv preprint arXiv:` 参考文献保留;
|
||||
- 每份 `cleaned.md` 的 SHA-256 等于对应 `result.json.current_sha256`;
|
||||
- 输入文件运行前后不变。
|
||||
|
||||
只看到运行目录存在不等于成功,必须先检查 manifest 和文档状态。
|
||||
|
||||
## 6. 常见失败
|
||||
|
||||
### 运行目录已经存在
|
||||
|
||||
脚本拒绝覆盖同一日期下的同名运行目录。选择新的 `--run-id`,不要删除或覆盖旧目录来绕过检查。
|
||||
|
||||
### 输入缺失或不是 UTF-8
|
||||
|
||||
整批预检会失败,不运行任何组件,也不发布最终目录。先确认 `data/md/` 中 5 份文件存在且未被修改。
|
||||
|
||||
### 状态为 `failed` 或 `unstable`
|
||||
|
||||
对应文档只会生成 `result.json`,不会生成 `cleaned.md` 或 diff。查看错误或残留候选,不要把其他文档的部分成功
|
||||
当成整批成功。
|
||||
|
||||
### Snap 版本的 `jq` 报权限错误
|
||||
|
||||
产物目录权限是 `0700`。某些 Snap 沙箱工具不能进入私有目录,即使当前用户拥有权限。可直接用编辑器查看 JSON,
|
||||
或使用当前虚拟环境中的 Python 读取;不要为了兼容受限工具放宽产物权限。
|
||||
|
||||
## 7. 数据边界
|
||||
|
||||
产物包含完整论文和原文片段,只能保存在本机 Git 忽略的 `artifacts/`。不得执行 `git add -f`,不得复制到 Wiki、
|
||||
其他仓库、云存储或外部系统。
|
||||
|
||||
`manifest.json` 中的 `retention_until` 是默认 30 天到期时间。第一版不会自动删除;到期后如需清理,必须先确认
|
||||
具体运行目录。
|
||||
@@ -1,150 +0,0 @@
|
||||
# 运行本地 ClinDB 第一批完整清洗实验
|
||||
|
||||
## 1. 适用范围
|
||||
|
||||
本指南只运行仓库内已经批准的 first-batch 实验脚本:
|
||||
|
||||
- 输入:`data/md/` 中的 `dmp.md`、`ejhf.md`、`jama.md`、`sim.md` 和 `springer.md`;
|
||||
- 流水线:`design/0006` 固定的 8 个组件和顺序;
|
||||
- 输出:`artifacts/<YYYY-MM-DD>/runs/<run_id>/`;
|
||||
- 输入只读,不覆盖原文件;
|
||||
- 不读取或复制图片,不处理 `/home/lihaoze/gov_test_data`。
|
||||
|
||||
本指南于 2026-08-23 在 Python 3.13.11 环境实际验证。
|
||||
|
||||
## 2. 前置检查
|
||||
|
||||
在仓库根目录执行:
|
||||
|
||||
```bash
|
||||
.venv/bin/python --version
|
||||
.venv/bin/ruff check .
|
||||
.venv/bin/mypy src tests scripts/run_clindb_arxiv_experiment.py scripts/run_clindb_first_batch_experiment.py
|
||||
.venv/bin/pytest
|
||||
diff -u <(tail -n +2 AGENTS.md) <(tail -n +2 CLAUDE.md)
|
||||
```
|
||||
|
||||
当前检查结果只以根目录 [`README.md`](../../README.md#当前可用检查) 为准。检查通过后再确认 5 份输入存在:
|
||||
|
||||
```bash
|
||||
find data/md -maxdepth 1 -type f -name '*.md' -printf '%f\n' | sort
|
||||
```
|
||||
|
||||
必须看到 `dmp.md`、`ejhf.md`、`jama.md`、`sim.md` 和 `springer.md`。不要把真实论文复制进测试 fixture。
|
||||
|
||||
## 3. 运行实验
|
||||
|
||||
人工选择一个当天未使用的安全运行 ID:
|
||||
|
||||
```bash
|
||||
.venv/bin/python scripts/run_clindb_first_batch_experiment.py \
|
||||
--run-id clindb-first-batch-review
|
||||
```
|
||||
|
||||
成功时终端只显示运行身份和汇总,不打印原文:
|
||||
|
||||
```text
|
||||
run_id=clindb-first-batch-review
|
||||
status=success
|
||||
documents=5
|
||||
changes=155
|
||||
artifacts=/.../mdpolish/artifacts/<YYYY-MM-DD>/runs/clindb-first-batch-review
|
||||
```
|
||||
|
||||
同一天同名目录已存在时脚本会拒绝覆盖。需要重跑时使用新 ID,不要删除旧目录来绕过检查。
|
||||
|
||||
## 4. 先看哪些结果
|
||||
|
||||
先确认运行目录根部同时存在 `manifest.json` 和 `review-locator.json`。定位文件只供本机评审器寻找原文,包含绝对路径,
|
||||
不得提交或分享。然后打开 `manifest.json`,确认:
|
||||
|
||||
- `run.status` 是 `success`;
|
||||
- `summary.document_count` 和 `summary.success_count` 都是 5;
|
||||
- `summary.failed_count`、`summary.unstable_count` 都是 0;
|
||||
- `summary.change_count` 是 155;
|
||||
- `pipeline.components` 的顺序与 `design/0006` 一致。
|
||||
|
||||
然后查看每份文档目录:
|
||||
|
||||
```text
|
||||
documents/<document_id>/
|
||||
├── result.json
|
||||
├── cleaned.md
|
||||
└── changes.diff
|
||||
```
|
||||
|
||||
- `changes.diff` 用于人工查看输入到最终输出的总变化;
|
||||
- `result.json` 用于按组件、理由、位置和哈希追踪每条修改;
|
||||
- `cleaned.md` 是成功输出全文。
|
||||
|
||||
当前 5 份输入的预期计数是:
|
||||
|
||||
| 文档 | `Change` 数 |
|
||||
| --- | ---: |
|
||||
| dmp | 47 |
|
||||
| ejhf | 9 |
|
||||
| jama | 79 |
|
||||
| sim | 3 |
|
||||
| springer | 17 |
|
||||
| **合计** | **155** |
|
||||
|
||||
按组件应为:Word 批注 2、手稿行号 75、arXiv 戳 2、重复页眉 2、映射断词 6、HTML 实体 31、
|
||||
HTML 表格布局 9、参考文献空行 28。
|
||||
|
||||
## 5. 人工复核重点
|
||||
|
||||
除了逐份查看 diff,至少确认:
|
||||
|
||||
- JAMA 的 Abstract 前作者和单位编号仍在,只删除 Abstract 后的 75 个手稿行号;
|
||||
- Springer 两条 `arXiv preprint arXiv:` 合法参考文献仍在;
|
||||
- Springer 正文中的编号方法列表没有被参考文献规则整理;
|
||||
- dmp 的重复页眉删除后,正文句子接回,参考文献第 18、19 条之间仍有一个空行;
|
||||
- 9 张表仍是 HTML,属性和单元格内容未被布局组件改写;
|
||||
- 双重实体变成单层 `<`、`>` 或 `&`,没有直接生成标签边界;
|
||||
- 图片引用文字保持不变。
|
||||
|
||||
清洗目录没有复制图片资产,所以直接打开 `cleaned.md` 时图片仍可能无法显示。这不表示图片引用被清洗组件删除;
|
||||
资产打包和路径改写需要单独设计。
|
||||
|
||||
## 6. 验证幂等和输入不变
|
||||
|
||||
流水线会在每份文档结束时做最终稳定性复查。需要额外复核整个保存结果时,可以把 `cleaned.md` 作为内存输入再次运行
|
||||
同一 `build_pipeline()`;5 份都应为 `success` 且合计零 `Change`。
|
||||
|
||||
实验层已经在发布前后复读输入并比较字节哈希。需要人工记录运行前后的摘要时,可在运行前后分别执行:
|
||||
|
||||
```bash
|
||||
sha256sum data/md/*.md
|
||||
```
|
||||
|
||||
两次输出必须逐项一致。每个 `cleaned.md` 的 SHA-256 还必须等于对应 `result.json.current_sha256`。
|
||||
|
||||
## 7. 常见失败
|
||||
|
||||
### 状态不是 `success`
|
||||
|
||||
查看对应 `result.json` 的 `errors` 或 `residual_proposals`。`failed` / `unstable` 文档不会有正式 `cleaned.md`,
|
||||
不能把其他文档的部分成功当成整批成功。
|
||||
|
||||
### 修改数不是 155
|
||||
|
||||
先按组件和文档分组定位差异。输入变化、组件参数变化或识别边界变化都必须回到 design/reference 核对;不要放宽断言、
|
||||
补跑第二轮或手工改产物。
|
||||
|
||||
### 图片不显示
|
||||
|
||||
当前运行只保存 Markdown、审计和 diff,不复制图片。不要为了显示图片而修改输入路径或把真实资产强制加入 Git。
|
||||
|
||||
### 私有目录无法被 Snap 工具读取
|
||||
|
||||
运行目录权限是 `0700`,文件是 `0600`。使用普通编辑器或当前虚拟环境中的 Python 读取,不要放宽权限。
|
||||
|
||||
## 8. 数据边界
|
||||
|
||||
产物包含完整论文和原文片段,只能保存在本机 Git 忽略的 `artifacts/`。不得执行 `git add -f`,不得复制到 Wiki、
|
||||
其他仓库、云存储或外部系统。
|
||||
|
||||
`manifest.json` 中的 `retention_until` 是默认 30 天到期时间。当前不自动删除;到期后如需清理,必须先确认具体运行目录。
|
||||
|
||||
需要在只读页面中查看完整前后文和各组件阶段时,继续按
|
||||
[`review-local-cleaning-run.md`](review-local-cleaning-run.md) 操作。
|
||||
Reference in New Issue
Block a user