可以逐条查证的部分。
四块参考材料:点击命中的到底是什么,预检拿什么规范去量,AI agent 接在哪一环,以及六条承重决定,每一条都给得出仓库里能打开的文件。
一次点击命中的是什么。
普通矢量编辑器看到的
- 路径
- 字形轮廓
- 矩形
- 裁剪组
Tavotto 看到的
- 标题 “Reaction kinetics” axes_0.title
- 图例 axes_0.legend
- 曲线 axes_0.lines_2
- 刻度标签 axes_0.xticks
- 标注箭头 axes_0.texts_0.arrow
一次点击,解析到画出它的对象。
命中判据跟着真实几何走:曲线按到渲染路径的距离算,填充区域按渲染器填色用的同一条缠绕规则算。不看包围盒。
出版要求是物理量。
栏宽以毫米计,字号下限以 pt 计,位图下限以 dpi 计。Tavotto 拿排好的版面逐项去量,依据是一份引擎与界面共读的带版本 profile;期刊栏宽不同,一行覆盖即可,覆盖会记进 proof report。
- 80 / 150 mm
- 默认 profile 的单栏与双栏宽度
- 8.5 pt
- 严格字号下限,按最终物理尺寸判;8 pt 是绝对底线
- 300 dpi
- 栅格化输出的最低要求
- 0.5-1.5 pt
- 边框与曲线比对的线宽档位
面板缩到 60%:按 9 pt × 0.6 = 5.4 pt 判。不过。
预检会报出什么
- 阻断
- 在你书面确认之前不让导出。
- 警告
- 一定展示,绝不静默略过。
- 无法核验
- 真的查不了的那些,比如外部位图内部的文字。需要人来看。
- 建议
- 绝不替你做决定。
同一份渲染事实。
每次导出都从同一份 PDF 合成出发:PDF 里是真文字,PNG 是这份 PDF 的栅格化。两种格式不可能各说各话。
AI 在哪一环
编程助手写的第一版 matplotlib 已经够好,剩下的是视觉活:图例高了两行、标签压住了数据点。这一层归 Tavotto,agent 写的脚本仍然是源头。在任何终端把图递过来:
tavotto open figures/Fig1_kinetics.pdf 它会把这张图所在的图库当项目打开,把图送进已经开着的窗口,不另起一套。
Codex 插件
一个 skill、一个本地 MCP server,加一块与桌面应用同一份前端代码构建的内嵌画布。Codex Desktop 里的部分集成尚未在真实环境验证过,插件 README 写明了是哪些。
图底下的工程。
六条承重决定,每一条都能在仓库里查证。
- 渲染
-
全部本地。跑脚本、渲染、排版、导出都在你的机器上,图和脚本不上传。
docs/privacy.md - 网络
-
应用自己只发两类请求:每天一次的版本检查,和明确同意后才开启的匿名用量统计。两个开关彼此独立。统计的事件结构里没有任何字段装得下文件名、路径或图内文字。
docs/analytics/telemetry-events.md - 重放验证
-
CI 持续证明:当前会话、全量重放、全新进程、写回后重开,四者的 manifest 逐元素一致。
tests/test_equivalence_matrix.py - 黄金向量
-
patch 规范化在 Python 与 Rust 各有一份实现,由同一份向量文件钉到逐字节一致;预检同理,Python 与 TypeScript 各一份。
tests/golden/ - 内置运行时
-
桌面安装包自带钉死版本的 CPython 与科学栈,各平台锁定完全相同的包版本。
packaging/runtime-lock.json - 发布测试
-
发布前,打包产物必须真启动、真渲染、真导出、干净退出。每晚再把 Windows 安装包装一遍、冒烟、升级、卸载,用户名是中文。
.github/workflows/nightly.yml
开源,AGPL-3.0 许可;这些决定的来龙去脉在仓库的 ADR 里。 docs/adr