长期协作规则只放稳定约定;业务口径、接口、字段和验收清单以 docs/ 为准。
- 开发前先看
git status --short、相关docs/和现有实现。 - 不在
master/main直接开发;修复使用fix/*,功能使用feature/*等符合 Git 开发规范的分支名。 - 不回滚他人改动;只改当前需求相关文件。
- 复用现有封装和代码风格;必要注释用中文说明“做什么/为什么”。
- 口径不明时先确认,并同步更新对应
docs/。 - 提交前只暂存当前需求文件,确认没有把本地
.env、构建产物或他人改动带入提交。
MD To Word converts AI-generated Markdown into editable Word .docx.
backend/: FastAPI + Pandoc conversion service.extension/: Chrome/Edge Manifest V3 extension.agent/: self-hosted feedback triage and repair runtime.docs/AgentRequirements/: Agent 权威需求、架构、接口和验收记录。docs/AgentProblem/: 按阶段整理的历史问题与解决方案,不替代权威需求。logs/: real user samples and failure cases.
- Agent 的目标、范围、架构、接口和验收标准以
docs/AgentRequirements/为唯一权威来源;从其README.md开始阅读。 - 阶段状态和真实验收证据只更新
docs/AgentRequirements/implementation-plan.md,不要写入本文件。 agent/是当前实现,不是历史代码;删除或重建其中模块前必须先核对现有调用、测试 和当前阶段边界。- 数据库 migration 和第三方 checkpoint 建表只能由维护者审查后显式执行;测试、应用 启动和普通开发命令不得自动修改数据库 Schema。
- 生产密钥通过部署 Secret 注入。本地集成测试只使用被 Git 忽略的私有
.env,配置名 以.env.example为准;不得提交、记录或通过聊天传递任何密钥。 - Fake Provider 是自动测试默认值。真实 Supabase、模型、Langfuse、GitHub 或沙箱调用 只用于明确批准的手工集成验收,并使用可丢弃的测试数据。
- 真实缺陷允许在维护者明确批准后增加平台依赖;必须固定版本、提交锁文件,并同步进入 生产与 Sandbox 镜像。Agent 生成的补丁仍不得修改依赖、Dockerfile 或受信平台模块。
- 历史故障与排障结论写入
docs/AgentProblem/;稳定行为或接口变化仍必须同步更新docs/AgentRequirements/,避免从复盘文档反推当前契约。 - Sandbox 临时 workspace 的目录和文件权限必须由受信代码显式规范,不能依赖开发机
umask;新增或调整物化/补丁流程时必须在
UMask=0077与容器固定非 root UID 下验证 pytest 能读取源码、配置和新增 fixture。 - 生产 Agent 更新必须先停止 Scheduler,并显式重启 Worker 以加载新 Python 代码;
systemctl enable --now不会重启已活动服务。标准更新统一使用deploy/agent/deploy.sh,不要用服务处于active代替代码版本验证。 - Provider 排障必须区分传输失败与结构失败:
provider_unavailable表示传输/上游服务在 有限重试后仍不可用,invalid_response表示已收到响应但严格 Schema/本地 Policy 校验 失败。/models返回 200 只证明基础连通与认证,不能替代代表性的结构化生成验证。invalid_response的两层来源用 Trace 区分:Generation 被标 ERROR 是 Provider 严格 Schema 层,journalctl 的structured output rejected行给出字段路径与校验器文案; Generation 全部成功而 run 失败,是reproduction.py的本地 Policy。 - 严格 Structured Outputs 只能表达单字段约束。凡是要靠 Pydantic
model_validator或field_validator才能表达的跨字段规则(模式选择、路径白名单),必须同时写进对应提示 词 —— 模型看不到 Policy 文件,也无法从 Schema 推断。提示词内容变化要同步 bump 对应的*_PROMPT_VERSION。 - 校验器的
ValueError消息会原样回传给模型作为格式修正提示。一个校验器里的每个失败 条件必须各有可执行的消息、点名该改哪个字段;合并成一条会让模型重试越改越偏,维护者 也只能从日志看到字段:value_error。收紧或放宽白名单前先查docs/AgentRequirements/security-and-sandbox.md,受信平台模块的只读约束是刻意的。
Agent 代码或权威设计文档变更后至少运行:
.venv/bin/python -m pytest agent/tests -q
.venv/bin/python -m compileall -q agent如果变更影响共享依赖、后端契约或转换行为,还要运行后端全量测试。真实服务验收不能 替代自动测试,自动测试也不能冒充真实服务验收。
Sandbox 或 Docker 边界变化时还要运行 agent/tests/test_docker_integration.py。缺少
Docker 时可以在开发过程中跳过,但交付时必须明确报告,不能把 skipped 记为通过。
trace-site/的运行摘要以 Supabase 为事实来源,Langfuse 只提供脱敏 observation 快照;展示缺失不得反推 Agent 阶段未执行。- Langfuse 索引是异步的。快照投影必须等到稳定命名的
feedback-repair-run根出现;run_id精确匹配失败时只能退回该命名根,不能把父节点尚未索引的孤儿调用当作根。 model_calls + tool_calls > 0而合成根没有 observation 后代时,快照是不完整缓存, 详情页和批量回填都必须重抓;真实零调用运行允许只有合成根。- 修改
trace-site/后至少运行npm test、npm run typecheck和npm run build。
Preview and export must normalize math consistently.
- Frontend preview uses
extension/src/normalizer.ts. - Backend export uses
backend/app/normalizer.py. - When changing math normalization, update both unless the behavior is intentionally backend-only.
Support common AI output, not only strict Markdown.
- Convert bare block math:
[newline formula newline]->$$...$$
- Convert AI inline math:
(z_T)->$z_T$- Keep normal text such as
(Render)unchanged.
- Repair AI subscript mistakes inside math:
*{LL}->_{LL}*2->_2*i->_i
- Preserve visible set braces:
m\in{0,1}^{L}->m\in\{0,1\}^{L}- Do not break
\frac{},\mathbb{},\underbrace{}, etc.
- Repair single backslash line breaks in math environments:
- In
cases,aligned,matrix, etc., line-end\->\\.
- In
- Expand tall parentheses for Word:
f(\underbrace{...}_{x_t},t)->f\left(\underbrace{...}_{x_t},t\right).
Run focused tests after normalization changes:
cd backend
.venv/bin/python -m pytest tests/test_normalizer.py -vRun full backend verification before claiming done:
# Linux/macOS backend venv
cd backend && .venv/bin/python -m pytest -v
# Windows backend venv from WSL repository root
backend/.venv/Scripts/python.exe -m pytest backend/tests -vRun extension build after frontend changes:
cd extension
npm run buildFor real regressions, reproduce with logs/runlog.txt before and after the fix.
Backend deploys to Render from backend/.
- Environment: Docker
- Health path:
/health - Public service URL:
https://mdtoword.onrender.com
Extension is not deployed to Render. Build and load extension/dist in browser extensions.
Docker 有两个互相独立的用途:
- Render 根据
backend/Dockerfile构建并运行公开转换后端,容器内包含 Pandoc、Mermaid CLI 和 Chromium;插件使用线上服务时不依赖开发者电脑,也不要求本地 Docker 常驻。 agent/sandbox/Dockerfile是 Agent 执行不可信测试和补丁的隔离镜像。当前开发环境由 本地 Docker Desktop/WSL 和agent.sandbox.worker_http提供;只有执行 Agent 的 reproduce/repair/publish 或 Docker 集成测试时才需要开启。
生产常驻 Agent 必须把 Controller 与 Sandbox Worker 部署到受控的独立主机/内网;该
主机需要 Docker Engine。不要把 Worker 合并进公开 Render 转换服务,也不要公开暴露
Docker Socket 或 Worker 端口。完整拓扑与启停说明见
docs/AgentRequirements/deployment-and-operations.md。
生产 Agent 的标准部署形态是独立 Linux ECS:Controller/Scheduler 与 Worker 由 systemd
管理,Worker 只监听 127.0.0.1:8090,本地电脑和 Docker Desktop 无需常驻。生产更新使用
两条命令;部署脚本内部按“停止领取、安装并审计、显式启用、输出状态”的顺序执行:
sudo git -C /opt/mdtoword pull --ff-only origin main
sudo bash /opt/mdtoword/deploy/agent/deploy.shinstall.sh 仍是保持 Scheduler 关闭的底层 fail-safe;标准更新由 deploy.sh 在审计正确且
维护者输入 ENABLE 后恢复自动领取。不要绕过该顺序直接编辑 systemd 单元或在公开安全组
中开放 8090/Docker Socket。
After backend changes:
git pushWait for Render deployment.
After extension changes:
cd extension
npm run buildThen refresh the unpacked extension in chrome://extensions or edge://extensions.