Files
mdpolish/research-wiki/explanation/functional-modifier-core.md
T

98 lines
5.5 KiB
Markdown

# 函数式修改核心如何工作
## 1. 它解决什么问题
项目规则如果直接返回一整篇新 Markdown,库无法确认它改了哪里,也无法在文本已经变化时阻止旧位置继续执行。
`mdpolish` 把三个职责分开:项目规则提出修改,库验证并在内存中执行,调用项目决定是否写回文件。
当前机制来自已批准的
[`0008-generic-functional-library-boundary.md`](../design/0008-generic-functional-library-boundary.md)。公共类名、字段和
函数签名以 [`src/mdpolish/`](../../src/mdpolish/) 和测试为准,本文只解释不变量与边界。
## 2. 当前数据流
```text
项目选择 Modifier、参数和顺序
当前 Markdown 快照
Modifier 提出精确修改 ──► 整批验证 ──► 内存中整批应用 ──► 新快照
│ │
└────────── 按项目给定顺序重复 ◄──────────┘
最终只复查,不再应用
┌────────────────┼────────────────┐
▼ ▼ ▼
success unstable failed
```
| 层次 | 负责 | 不负责 |
| --- | --- | --- |
| 不可变数据模型 | 保存快照、范围、候选修改、实际改动、错误和结果 | 项目业务判断 |
| `Modifier` | 冻结身份、版本、参数、适用边界和提议函数 | 直接改变字符串或文件 |
| 修改执行器 | 校验并原子应用一个修改器批次 | 判断规则是否符合某个项目 |
| `Pipeline` | 按显式顺序运行修改器并做最终稳定性复查 | 自动选规则、文件读写和默认组合 |
`mdpolish` 不导入使用项目。项目可以使用正则工厂、通用内置修改器,也可以用普通函数建立自己的 `Modifier`
## 3. 修改器拥有什么权限
修改函数接收不可变 `DocumentSnapshot`,返回一个 `ProposedChange` 元组。每项候选修改说明原因,并包含一条或多条
精确 `TextEdit`。修改器拥有规则判断权,可以提议插入、删除或替换,但不能通过公共契约原地改变快照,也不能用
整篇新文本绕过执行器。
`Modifier` 还保存稳定 ID、语义版本、冻结后的参数和适用边界。普通函数无需继承基类。相同输入、身份、版本和参数
应产生相同顺序的候选修改;修改函数不得读取文件、网络、环境变量、当前时间或随机数。
Python 不能沙箱隔离任意调用方函数。外部函数若私下写文件,属于绕过库契约的副作用,不在 `mdpolish` 的验证、
审计和回滚保证内。
## 4. 为什么修改必须绑定快照
每个快照都带有完整 Markdown 的 SHA-256。候选修改及其中每条编辑必须绑定这个哈希,并提供半开字符串范围、该范围
应有的原文和替换文本。执行器再次确认:
1. 哈希对应当前快照;
2. 范围没有越界;
3. 当前位置与预期原文完全一致;
4. 编辑不是无变化操作;
5. 当前修改器批次没有重复或冲突范围。
任意检查失败,当前修改器的整批候选都不执行。范围使用 Python 字符串索引,不是 UTF-8 字节位置;核心不会隐式
改变换行、Unicode 形式或末尾换行。
执行器从文本后方向前应用编辑,避免前面的修改使后面的下标失效;审计记录仍按原文位置排列。
## 5. `Pipeline` 的状态
`Pipeline` 先预检全部修改器及重复 ID,再按调用方顺序各运行一次。后一个修改器读取前一个修改器生成的新快照。
全部执行完成后,每个修改器对最终快照再提议一次,但复查阶段只验证,不应用,也不会自动开始第二轮。
| 状态 | 含义 | 文本字段 |
| --- | --- | --- |
| `success` | 运行和复查均完成,所选修改器不再提出修改 | `output_markdown` |
| `unstable` | 运行无错误,但最终快照仍有有效候选修改 | `partial_markdown` |
| `failed` | 提议、契约或执行验证发生错误 | `partial_markdown` |
`success` 只说明调用方选择的这组修改器在这次输入上已经稳定,不说明文档不存在其他质量问题。库只返回内存结果;
调用项目检查状态后,自己决定是否保存。
## 6. 当前通用能力与边界
除了核心,发布包只提供:
- `regex_replace()`:把非空正则匹配转换为精确编辑;
- `mapped_line_join()`:按调用方映射合并跨行片段,库不附带词表;
- `html_table_entity_unescape()`:在严格表格单元格文本中解除一层受支持的实体转义;
- `html_table_layout()`:把严格单行 HTML 表格展开为每行一个表格行。
HTML 能力使用失败关闭的词法子集,不是完整 HTML parser,也不识别 Markdown 围栏。正则工厂只保证定位和执行契约,
不保证调用方正则的业务语义正确。
当前没有默认流水线、文件适配器、CLI、profile、配置加载、批处理、artifact、评审器或项目规则集。安装或导入库不会
自动修改任何文本。实际安装、示例和当前检查命令只以根目录 [`README.md`](../../README.md) 为准。