Files
wandering 0d9cc7b4ca feat(core): 报销口径与文本宽度两道闸——会议费并入差旅单,超宽文本不再静默 500
这一批是 2026-10-21 正式填报踩出来的两类问题,一起收进来。

**一、报销口径只在一处判定(新增 src/core/expense_kind.py)**

用户定案:因出差发生的会议费/会务费/培训费这类普通发票**并入差旅单**(明细的会务费培训费栏、
会议通知当附件),不拆成两张单、也不因此放弃差旅补助;只有货物类(易耗品/材料/配件)才走
普通报销 + 申购单。以前 case_status、validate_info、browser_new_form 三处都写"混合发票只能走
普通报销",等于把这条合法路径说成错的,Agent 照做就会白拆一张单还漏补助。现在 is_conference_like /
goods_invoices 是唯一判定,工具提示与 case_status 的 warnings 都由它驱动。

**二、文本宽度闸:自由文本超宽 = 无提示 500(新增宽度口径 + 两道预检)**

联机实测:差旅明细备注写到 101 字,POST 回 500 且页面无任何提示、弹窗停在原地,现场看着像"脚本没点着
确定";同一张单 97 字(宽度 130)却存进去了,上限夹在两者之间且后端不肯说。于是取汉字/全角记 2、
字母数字记 1 的"宽度",validator.TEXT_WIDTH_LIMIT=100(≈50 汉字,同时满足"100 字符"与"131 字节"
两种可能口径),普通报销说明另用 DESCRIPTION_WIDTH_LIMIT=40。拦截点两处:规则里的 max_len_bytes
(validate_extracted_info 的 missing_fields 会写明"过长:宽度 N > 上限 M")与 browser_fill 在 POST 前的
_text_limit_problems(失败返回 too_long 列出超长字段)。

**三、交通工具代码表挪进 core(新增 src/core/vehicles.py)**

财务系统 #jtgj 的 value 表与中文别名(train→火车 等)从填报层挪到 core,一处三用:填报取 value、
体检判合法、报错给候选。老写法 if vehicle in vehicle_map 遇英文枚举是**静默不选**且仍返回成功,
直到提交被必填挡回来——现在认不出的值直接报错。

其余:cases.goods_general_items 给 case_status 补"有 N 张货物类普通发票"的 warning;
travel.py 改用 vehicles 并显式报错;config/validation_rules.json 加 max_len_bytes;
INSTRUCTIONS/SKILL/判读参考/操作指南同步口径与宽度提示。新增 tests/test_text_limits.py 与
tests/test_vehicles_and_scope.py。

验证:ruff / format / mypy src / deptry / pytest / mcp-smoke / docs-check / skill-check 全绿。
--no-verify 提交并手跑等价检查。
2026-10-21 13:49:12 +08:00
..

last_reviewed
last_reviewed
2026-10-20

.agents/skills — Agent 技能目录

本目录由 DSH(及兼容的 Agent)自动发现,每个子目录一个技能,SKILL.md 用 YAML front matter 描述触发条件。

技能 说明
reimbursement/ 报销业务操作纪律:流程顺序、review_required 必须逐条复核、双通道冲突处理、禁止宣布可提交;
references/ 下是七类票据与两种报销数据的字段判读细则(由原内置 LLM 提示词迁移而来)
pre-commit-check/ 提交前质量门禁:ruff lint/format、mypy、deptry,并自动修复可修项
clean-git-history/ 用 git-filter-repo 清理误提交的敏感文件与历史

使用方式

命中描述的场景时 Agent 自动加载,无需手动调用。reimbursement 的技能正文与 docs/MCP.md 有意分工: 前者讲「怎么做才对」,后者讲「接口长什么样」。

装到用户级(跨项目可用)

本目录的技能只在打开本项目时可见。要让任何项目都能用 reimbursement:

make skill-install    # 或 python tasks.py skill-install
make skill-check      # 比对安装副本与仓库,漂移退出码 1

真源永远是仓库里这份,别去编辑安装副本(下次同步会被覆盖)。

坑:技能来源由宿主的 skills-manager 管,开关会变;装进已停用的来源目录里文件明明存在、宿主却永远扫不到。 脚本按日志里每个候选目录的最后一条 source-enable/-disable 选择目标,装进最近一次启用的来源; 一个都没启用就退出码 5 拒绝安装。状态随时用 --list-sources 查看(会显示各来源最后一次事件时间)。