Repository navigation
重构:脚本共享路径与读取函数收进 _skill_io,npm 包不再发布 CI 专用脚本 - #304
Merged
Merged
Conversation
One copy of the repo / prebuilt paths, SKILL.md frontmatter reading, the fidelity-fixture loader, JSON reading and the ## section splitter. The characterization tests were recorded from the readers being replaced: the line-fenced and split-on-`---` frontmatter readers disagree on seven of 14 edge cases (leading blank line, `a---b` in a value, `----`, non-mapping, ...), so both are kept and pinned, and they are checked to agree on every prebuilt SKILL.md. scripts/tests/conftest.py puts scripts/ on sys.path so a single test file can load a script that imports a sibling.
…kill_io Twenty-four scripts drop their own `Path(__file__).resolve().parent.parent`; validate.py and validate-self-audit-sources.py use the shared frontmatter readers, cite.py / query.py the shared section splitter, regrade-report.py / validate-fixture-terms.py the shared fixture loader, and check-manifest-versions.py / validate-routing.py the shared JSON reader, each keeping its own failure shape. run-gates.py keeps its own ROOT: check-gate-liveness.py loads it by path from an arbitrary --root, where a cached sibling module would point at the wrong tree. tools/ is untouched; the create-master install copies tools/ without scripts/. Every validator's stdout and exit code, on the tree and on five broken copies (invalid YAML, leading blank line, broken fixture, broken JSON, unclosed frontmatter), is unchanged with PYTHONHASHSEED fixed; only crash tracebacks gain a frame.
_cap_tests, _dry_run_suite, _plan_suite, _make_sender, _load_audit_inputs and _attach_tool_log take over the blocks run_tests ran inline; the order of checks, the error messages and the result dicts' key order are unchanged. The thread-pool section stays inline: grade_one and run_subagent close over the suite state. Dry-run and --plan output for every suite and the eval-SDK smoke are identical before and after.
Nothing in bin/, hooks/, tools/, prebuilt/, SKILL.md or the READMEs invokes run-gates.py, check-gate-liveness.py, regrade/reaudit-report.py, the eval-SDK checks or the content gates that only run-gates lists; several also need eval/ or tests/, which never shipped. Everything a persona, the README or a shipped script references still ships (cite, query, validate and its sub-checks, validate-fidelity, test-fidelity, validate-citation-contract, validate-routing, verify_citations and the _ helpers). 244 -> 227 files, tarball 546,942 -> 494,837 bytes. A CLI test fails if a shipped script imports or spec-loads a sibling that does not ship.
xr843
force-pushed
the
refactor/shared-skill-io
branch
from
October 3, 2026 07:08
49e86f8 to
6ba39c5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
审计实测:24 个脚本各自写一遍
ROOT / PREBUILT_DIR = Path(__file__)...,现成的scripts/_masterpaths.py只有 4 个在用;frontmatter 解析有 6 份实现,load_fixtures、parse_sections、_read_json各重复两份。另外 npm 包把scripts/整个发出去,连只在本仓 CI 里跑的门禁也在里面。本 PR 只做重构,不改任何门禁的输出、消息和退出码。共享模块
scripts/_skill_io.py。 内容包括:路径常量(ROOT/SCRIPTS_DIR/PREBUILT_DIR)、frontmatter 读取、fidelity fixture 加载、JSON 读取,以及cite.py/query.py共用的##分段函数。导入时只用标准库(pyyaml 用到时才导入),兼容 Python 3.9。frontmatter 仍保留两种读法:validate.py按整行围栏切分,sources:类读取则按前两个---子串切分。两者在畸形输入上本来就不一致,14 个边界用例里有 7 个结果不同(开头空行、值里含a---b、----、非 mapping 等)。所以先把旧实现的输出录成表格测试(scripts/tests/test_skill_io.py)再迁移,并断言两种读法在每份 prebuilt SKILL.md 上结果相同。两份_read_json各自的失败形态(返回None或返回{"__error__": ...})都保留。load_fixtures保留模块级包装,测试对PREBUILT的 monkeypatch 照样生效。没迁的部分及原因。
run-gates.py保留自己的ROOT:check-gate-liveness.py会从任意--root按路径加载它,如果改用已缓存的兄弟模块,会指向错误的目录树。tools/一行未改:create-master 安装时只拷tools/,不拷scripts/(见skill-catalog.json的bundle_paths),所以tools/必须自给自足,verify_sources.py的两处和master_builder.py的一处 frontmatter 读取原样保留,模块文档里写明了原因。_masterpaths.py用的是abspath(不解析符号链接),和resolve()语义不同,也未合并。新增的scripts/tests/conftest.py把scripts/加进sys.path,单独跑某个测试文件时也能导入兄弟模块(persona-fidelity CI 就是单文件跑的)。test-fidelity.py的run_tests。 dry-run、plan、SDK client、审计输入这几块,以及三处重复的 tool log 写入,拆成具名 helper。检查顺序、错误消息、结果 dict 的键序都不变。线程池部分没动:grade_one/run_subagent是闭包,引用了 suite 状态,拆开风险高。npm 包。 逐一 grep 了
bin/、hooks/、tools/、prebuilt/**、SKILL.md、README 和 plugin manifest,并核对了脚本之间的 import / spec 加载关系,确认有 18 个脚本只被run-gates.py、check-gate-liveness.py或 CI 调用,其中几个还依赖从未打进包的eval/或tests/。用"!scripts/<x>.py"把它们排除。有 SKILL.md、README 或已发布脚本引用的一律保留,validate-routing.py只在 master-help SKILL.md 里作为说明被提到,属于模糊情况,也保留。新增一条 CLI 测试:已发布脚本 import 或 spec 加载的兄弟脚本如果没发布,测试就失败(临时排除_masterpaths.py验证过,它确实会变红)。验证
--json变体、cite/query、test-fidelity--dry-run/--plan、regrade/reaudit 等)分别在干净树和 5 份故意弄坏的副本上运行(frontmatter YAML 非法、开头空行加 fojin_text_id 改错、fixture 缺字段加垃圾条目、routing.json 与 gemini-extension.json 写坏、frontmatter 不闭合),对比 main(rebase 后的git archive 2873ac8)与本分支的结果。216 份输出中,退出码全部一致,stdout 只有 4 份不同,且都只差崩溃 traceback 里的栈帧(多一层_skill_io),最终异常行完全相同。validate.py的 missing-field 报错顺序在前后两侧不一样。查明是REQUIRED_FIELDS等集合受 hash 随机化影响:同一棵树连跑 3 次,md5 都不同,这是原有行为。之后统一固定PYTHONHASHSEED=0重跑。python3 scripts/run-gates.py全量:23 道全部通过,退出码 0;pytest 1547 passed、2 skipped(新增 65 条),CLI 127 个测试通过。--only eval-sdk中 smoke 与--break均符合预期;check-eval-sdk-surface在本机因 SDK 版本与钉版不符而失败,在 main 上同样失败,CI 会装钉版。scripts/tests/与tests/下每个测试文件单独运行,全部通过。compileall tools scripts通过。test-fidelity.py的 pytest 覆盖率仍为 91%,_skill_io.py为 100%。npm pack --dry-run:246 → 229 个文件,tarball 562,227 → 510,086 字节(-9.3%),解包后 1,710,423 → 1,548,875 字节。打包安装测试(packed npm artifact installs all skills…)通过。另外把新 tarball 解开,在包目录里直接跑 cite、query、validate--strict、validate-fidelity、validate-citation-contract、validate-routing、test-fidelity--all --dry-run等 14 个已发布脚本,全部能运行。validate-promptfoo-configs因包里没有tests/persona/退出 1,main 的包也一样。未运行任何付费评测。
发现但未修(本 PR 只做重构):按
---切分的读法遇到值里含---会把 frontmatter 截断;validate.py报告顺序不确定;load_fixtures沿用平台默认编码读取。