From 808aa8438e197f14f225fecb948543c000cbc767 Mon Sep 17 00:00:00 2001 From: Mengz <2567587994@qq.com> Date: Sun, 26 Jul 2026 16:55:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(skills):=20=E6=89=A9=E5=B1=95=E7=BC=96?= =?UTF-8?q?=E6=8E=92=E5=99=A8=E7=BB=BC=E5=90=88=E8=AF=84=E4=BC=B0=E7=BB=B4?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gitlink-maintenance-orchestrator/SKILL.md | 60 ++++--- .../agents/openai.yaml | 4 +- .../examples/fixtures/cli-contract-guard.json | 7 + .../examples/fixtures/code-review.json | 8 + .../examples/fixtures/maintainer-radar.json | 7 + .../examples/fixtures/pr-integrator.json | 8 + .../examples/fixtures/pr-topology.json | 7 + .../references/comprehensive-dimensions.md | 87 ++++++++++ .../references/pipeline-contract.md | 17 ++ .../validate_chinese_report.cpython-312.pyc | Bin 0 -> 7239 bytes .../scripts/run-maintenance-pipeline.ps1 | 148 +++++++++++++++++- .../scripts/test-maintenance-output.ps1 | 3 +- .../test_orchestrator_prompt_contract.py | 5 +- .../scripts/test_validate_chinese_report.py | 19 ++- .../scripts/validate_chinese_report.py | 55 ++++++- 15 files changed, 389 insertions(+), 46 deletions(-) create mode 100644 skills/gitlink-maintenance-orchestrator/references/comprehensive-dimensions.md create mode 100644 skills/gitlink-maintenance-orchestrator/scripts/__pycache__/validate_chinese_report.cpython-312.pyc diff --git a/skills/gitlink-maintenance-orchestrator/SKILL.md b/skills/gitlink-maintenance-orchestrator/SKILL.md index b239665..3dc271e 100644 --- a/skills/gitlink-maintenance-orchestrator/SKILL.md +++ b/skills/gitlink-maintenance-orchestrator/SKILL.md @@ -5,7 +5,7 @@ description: "五个 GitLink 维护 Skill 的只读编排器:用户只需点 # GitLink 维护审查编排器 -这个 Skill 只负责编排和校验,不替代五个专项 Skill 的判断。它把“证据采集、三路并行专项检查、集成门禁、维护者排序、首屏报告”组织成一次可复现的只读运行,并保留每个专项的独立结果,便于维护者快速处理而不是阅读五份重复长报告。 +这个 Skill 负责编排、交叉校验和综合决策,不替代五个专项 Skill 的原始判断。它把“证据采集、三路并行专项检查、集成门禁、维护者排序、跨专项一致性判断、综合报告”组织成一次可复现的只读运行,并保留每个专项的大部分评估维度。执行前必须读取 [`references/comprehensive-dimensions.md`](references/comprehensive-dimensions.md)。 ## 五个 Skill 的职责 @@ -28,41 +28,54 @@ description: "五个 GitLink 维护 Skill 的只读编排器:用户只需点 - 共享一次队列快照和每个目标 PR 的固定 head 上下文,编排五个专项 Skill;不要求用户逐条重复五个 Skill 的提示词。 - 全流程只读,不评论、不 approve、不合并、不关闭、不分配、不修改标签或权限。 - 单 PR 和多 PR 都支持;多 PR 先做队列级拓扑/维护排序,再对重点 PR 逐条做代码、契约和集成检查,不能混合 Diff。 -- 报告首屏先按 PR 分节;每条 PR 分别显示代码审查、CLI 契约、仓库关系、集成门禁、维护状态和最终结论六张判断卡。聊天结论也按 PR 和这六个方面组织,但必须重新提炼成更短的维护者语言。 +- 报告按 PR 分节,完整展示代码与贡献、CLI 契约、仓库关系、集成门禁、维护治理五组专项维度,再展示证据一致性、风险传播、动作责任和置信度等编排器独有判断。不得用五张阶段总评代替完整维度。 - 每张卡先显示醒目加粗结论,再写简短解释、明确 `依据:` 和影响/下一步;不得把五个专项压成一段或把多个 PR 合并总结。 - 人读 `final-report.md` 必须使用中文叙述;命令名、路径、稳定编号和机器状态枚举可以保留英文。每个阶段的 `assessment.fact` 与 `assessment.basis` 在交给 finalize 前先转成忠实的中文摘要,不能把整份英文阶段报告直接拼入。 - 一次运行只生成一份主要人读报告 `/final-report.md`。五个专项 JSON 和 `final-report.json` 作为机器证据附件,不再让维护者阅读五份独立长 Markdown。 -最终回复必须由执行 Skill 的 Agent 在读完 `final-report.md` 和 `final-report.json` 后重新提炼,不能复制报告首屏、不能机械删除 Markdown/HTML 格式、不能把卡片原文改成纯文本后直接输出。聊天摘要要比报告更短,按每个 PR 输出六个方面的结论、最关键依据和解释/影响,每个方面一至两句完整自然语言;省略路径清单、阶段索引、分页过程、机器状态标签和次要证据。全部 PR 摘要后再给最多五项跨专项动作,并用可点击链接或当前 Agent 平台的文件附件交付 `final-report.md`。若无法落盘,输出完整 Markdown 并标记“未落盘”。 +最终回复必须由执行 Skill 的 Agent 在读完 `final-report.md` 和 `final-report.json` 后重新提炼,不能复制报告首屏、不能机械删除 Markdown/HTML 格式、不能把卡片原文改成纯文本后直接输出。聊天摘要要比报告短,但每个 PR 必须覆盖 [`references/comprehensive-dimensions.md`](references/comprehensive-dimensions.md) 规定的 15 项直接判断,每项一至两句,包含结论、最关键依据和影响。省略路径清单、阶段索引、分页过程、机器状态标签和次要证据。全部 PR 摘要后再给最多五项跨专项动作,并用可点击链接或当前 Agent 平台的文件附件交付 `final-report.md`。若无法落盘,输出完整 Markdown 并标记“未落盘”。 聊天摘要示例只表达风格,不是可复制模板: ```text PR #430 -代码审查:建议修改后再审。它补齐维护队列的真实状态过滤,但当前 fixture 仍显示 closed 项会进入 open 队列,这会直接误导维护者的待审范围。 -CLI 契约:需要先稳定字段语义。新增 changes、waiting_on 和 SLA 字段有实际价值,但空值、兼容回退和错误提示还要和主线帮助/JSON 输出对齐。 -仓库关系:适合排在 #431 前面评审。#431 会消费 #430 的队列字段,所以先确认 #430 的运行时契约,可以减少后续 Skill 协议返工。 -集成门禁:暂时不能进入合并队列。构建和基础测试可以作为正向证据,但真实队列过滤失败仍是集成前必须修复的问题。 -维护状态:当前主要等待作者修复。维护者最需要检查的是过滤逻辑、字段空值和回归测试是否补齐。 -最终结论:先修复再复审。这个 PR 的方向成立,但真实队列可信度是它能否合入的前提。 +最终建议:修改后再审。功能方向成立,但真实队列过滤失败会直接误导维护者。 +贡献价值与功能增量:补齐队列变化和等待责任信号,能减少人工比对;主线没有等价完整实现。 +Review 履约:当前没有足够的正式 Review 基线,不能判断作者是否已经完成全部修改要求。 +逻辑、质量与可维护性:主流程沿用现有架构,但 open 状态二次过滤存在错误,需要修复后再评价稳定性。 +测试、安全与性能:基础测试通过,真实状态、权限失败和大队列边界仍需补测;未发现已证实的安全阻断。 +参数、帮助与兼容:新增参数具有价值,旧调用默认行为需要继续保持。 +JSON、错误、编码与文档:字段类型基本稳定,但空值语义和错误原因不能被统一误报为 JSON 解析失败。 +主线与 merged 历史关系:属于已有 workflow 队列能力的增量演进,不是重复实现。 +open PR 重叠、依赖与处理顺序:与消费这些字段的下游 PR 互补,应先稳定本 PR 契约。 +合并态、构建与冲突:基础构建成立,仍需在最新主线合并工作树确认无冲突。 +测试、CI、安全与发布门禁:当前 head 的 CI 关联和失败路径验证不完整,暂不能进入合并队列。 +SLA、等待方与 Reviewer 负载:当前等待作者修复;完整 reviewer 负载需要仓库级快照。 +责任停滞、Issue 和安全运营优先级:修复责任明确,超过阈值后应升级复看提醒。 +证据完整性与跨专项一致性:五个阶段使用同一 head,但 CI 和 Review 证据仍有缺口;各专项结论没有无法解释的冲突。 +优先动作、责任方与复验条件:作者先修复过滤并补失败测试,维护者随后重跑契约和集成门禁。 完整报告:[final-report.md](D:\path\to\final-report.md) ``` -最终聊天不能只回复路径、状态计数或跨 PR 总段落。Markdown 能使用醒目颜色和加粗;聊天摘要除必要的 PR 编号、证据编号和最终报告链接外,不输出 HTML/Markdown 展示标签。 +最终聊天不能只回复路径、状态计数、五个阶段状态或跨 PR 总段落。Markdown 能使用醒目颜色和加粗;聊天摘要除必要的 PR 编号、证据编号和最终报告链接外,不输出 HTML/Markdown 展示标签。 -首屏固定先使用: +报告中的每个维度固定使用以下卡片语法;必须重复覆盖完整维度表,不能只生成示例中的几项: ```markdown # PR 维护全流程摘要 ## PR # -**代码审查:** 核心队列结果不可靠 **[action_required]**:closed 项进入 open 响应;依据:CR-001 与真实 fixture;下一步:修复过滤并补测试。 -**CLI 契约:** 新增字段保持向后兼容 **[passed]**:字段可选且旧调用不变;依据:CG 对照和 golden 输出;影响:现有脚本无需迁移。 -**仓库关系:** 需要先稳定上游契约 **[reorder]**:存在字段生产/消费关系;依据:主线、全部 open/merged PR 索引;影响:调整评审顺序。 -**集成门禁:** 当前不能进入合并队列 **[blocked]**:真实响应测试失败;依据:IN-001 和当前 head 验证;下一步:修复后重跑。 -**维护状态:** 等待作者修复后复看 **[action_required]**:责任链明确;依据:Review、提交和 SLA 快照;下一步:作者更新后通知 reviewer。 -**最终结论:** 修复真实状态过滤后重新审查 **[blocked]**:存在一个阻断和两个高风险项;依据:CR-001、IN-001、MR-001;下一步:按动作顺序处理。 +### 代码审查 +**贡献价值:** 高频维护价值成立 **[merge]**:补齐队列变化信号;依据:主线缺口和用户流程;证据摘录:需求与 Diff;影响:减少人工比对。 +**逻辑正确性:** 真实状态过滤不可靠 **[action_required]**:closed 项进入 open 响应;依据:CR-001 和真实 fixture;证据摘录:失败输出;影响:修复并补测试。 + +### CLI 契约 +**JSON 与文本输出:** 空值语义尚未稳定 **[observe]**:新增字段可选但错误回退不完整;依据:golden 对照;证据摘录:结构化输出;影响:稳定后再供下游消费。 + +### 编排器综合判断 +**证据完整性与新鲜度:** CI 和 Review 证据不完整 **[observe]**:五阶段 head 一致但两类证据缺失;依据:运行账本;证据摘录:collection manifest;影响:不能给出高置信度合并结论。 +**最终结论:** 修复真实状态过滤后重新审查 **[blocked]**:存在一个阻断和两个高风险项;依据:CR-001、IN-001、MR-001;证据摘录:失败 fixture 与门禁结果;下一步:按动作顺序处理。 ## 先处理这 3 项 @@ -71,7 +84,7 @@ CLI 契约:需要先稳定字段语义。新增 changes、waiting_on 和 SLA 3. [MR-001][high] 转派 安全复查;责任:maintainer。 ``` -多个 PR 重复完整六张卡,每张卡只能引用该 PR 的证据。跨 PR 动作放在全部 PR 卡片之后。 +多个 PR 重复完整综合维度矩阵,每张卡只能引用该 PR 的证据。跨 PR 动作放在全部 PR 卡片之后。 ## 编排流程 @@ -151,7 +164,7 @@ pr-topology.json } ``` -每条 `evidence` 不能只有 `E-xxx`、`CR-xxx` 等编号,至少还要提供 `summary`、`source`、`ref`、`status` 和可选的 `scope`。`summary` 必须说明实际观察到什么,例如“正常路径测试通过但无权限路径未覆盖”,不能只重复结论。编排器会把这些字段直接写入六张判断卡、待办和证据台账;没有可读证据时必须写明限制,而不是只显示编号。 +每条 `evidence` 不能只有 `E-xxx`、`CR-xxx` 等编号,至少还要提供 `summary`、`source`、`ref`、`status` 和可选的 `scope`。`summary` 必须说明实际观察到什么,例如“正常路径测试通过但无权限路径未覆盖”,不能只重复结论。编排器会把这些字段直接写入综合维度卡片、待办和证据台账;没有可读证据时必须写明限制,而不是只显示编号。 `top_actions.evidence` 和 `findings.evidence` 可以引用证据或发现 ID 以便追溯,但阶段结果必须同时保留对应的可读 `evidence` 对象。编排器在渲染时必须将发现 ID 展开为问题摘要和直接证据,不能在待办或最终结论中只显示 `CR-001`、`E-001` 等标识。 @@ -173,11 +186,10 @@ pr-topology.json - 只有拓扑关系需要调整顺序时:最终决策可为 `reorder`。 - 没有阻断项但存在维护动作时:显示 `action_required`,不自动回写远端。 -### 5. 生成维护者首屏 +### 5. 生成完整综合报告 -最终报告必须先按目标 PR 展示六张判断卡,顺序固定为代码审查、CLI 契约、仓库关系、 -集成门禁、维护状态、最终结论。每张卡先给醒目结论,再写当前 PR 的事实、`依据:` -以及影响或下一步;不能把五个阶段压缩成一段总体叙述。全部目标 PR 的判断卡展示完后, +最终报告必须按目标 PR 展示 [`references/comprehensive-dimensions.md`](references/comprehensive-dimensions.md) 中五个专项的完整维度,再展示编排器独有判断和最终结论。每张卡先给醒目结论,再写当前 PR 的事实、`依据:` +以及影响或下一步;不能把五个阶段压缩成五张总评。全部目标 PR 的判断卡展示完后, 再给最多五项跨专项待办,每项包含对象、责任方、下一动作、严重性和一个主证据。 阻断数、高风险数、安全门禁和验证状态可以作为卡片之后的索引,不能替代解释。 完整 findings、可读证据台账、限制和下一次复查条件放入附录或 JSON。证据编号仅用于追溯,不能替代证据摘要;维护者不打开 JSON 也应能在 Markdown 中看到观察事实、来源、命令或文件位置、状态和适用范围。 @@ -209,7 +221,7 @@ python -X utf8 .\skills\gitlink-maintenance-orchestrator\scripts\validate_chines --require-pr 123 ``` -多 PR 报告为每个目标重复 `--require-pr`。任何目标缺少完整六张判断卡、卡片没有明确 +多 PR 报告为每个目标重复 `--require-pr`。任何目标缺少完整综合维度、卡片没有明确 `依据:`、中文被写成连续问号或报告退化为英文模板时,校验失败且不得交付路径。 `collect` 只执行 `gitlink-cli` 的读操作,不发布评论、不添加标签、不分配 reviewer、不关闭或合并 PR。若 PowerShell 禁止执行 `gitlink-cli.ps1`,传入可执行的 `gitlink-cli.exe` 或 `gitlink-cli.cmd` 到 `-CliPath`。 diff --git a/skills/gitlink-maintenance-orchestrator/agents/openai.yaml b/skills/gitlink-maintenance-orchestrator/agents/openai.yaml index 883e0fd..488c132 100644 --- a/skills/gitlink-maintenance-orchestrator/agents/openai.yaml +++ b/skills/gitlink-maintenance-orchestrator/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "GitLink 维护审查编排器" - short_description: "编排五个维护 Skill 生成可验证的 PR 维护摘要" - default_prompt: "使用 $gitlink-maintenance-orchestrator 分析指定仓库或一个/多个 PR;完整证据保存为中文 Markdown,聊天结论由执行 Agent 读完报告后重新提炼,按 PR 分别概括代码审查、CLI 契约、仓库关系、集成门禁、维护状态和最终结论,每方面说明结论、关键依据与影响,不复制报告卡片原文、不输出 HTML/Markdown 展示标签,全程只读。" + short_description: "编排五个维护 Skill 生成全面、可验证的 PR 综合报告" + default_prompt: "使用 $gitlink-maintenance-orchestrator 分析指定仓库或一个/多个 PR;完整证据保存为中文 Markdown,报告覆盖五个专项的大部分评估维度以及证据一致性、风险传播、责任动作和决策置信度。聊天结论由执行 Agent 读完报告后重新提炼,按 PR 输出 15 项简明判断,每项说明结论、关键依据与影响,不复制报告卡片原文、不输出 HTML/Markdown 展示标签,全程只读。" diff --git a/skills/gitlink-maintenance-orchestrator/examples/fixtures/cli-contract-guard.json b/skills/gitlink-maintenance-orchestrator/examples/fixtures/cli-contract-guard.json index cbc7621..13e9a75 100644 --- a/skills/gitlink-maintenance-orchestrator/examples/fixtures/cli-contract-guard.json +++ b/skills/gitlink-maintenance-orchestrator/examples/fixtures/cli-contract-guard.json @@ -12,6 +12,13 @@ "fact": "新增命令保持原有参数、帮助、JSON 类型和错误语义,未观察到用户可感知的契约破坏", "basis": "对默认分支与当前 head 执行相同帮助和结构化输出测试,契约测试完整通过" }, + "dimensions": [ + {"aspect": "参数与帮助", "conclusion": "新增入口保持旧调用兼容", "decision": "merge", "fact": "新参数为可选项且默认行为不变", "basis": "baseline 与 head 帮助对照", "evidence": ["E-CG-001"], "impact": "现有用户无需迁移"}, + {"aspect": "JSON 与文本输出", "conclusion": "机器输出结构稳定", "decision": "merge", "fact": "新增字段未改变既有字段类型,文本没有混入 JSON", "basis": "结构化输出解析测试", "evidence": ["E-CG-001"], "impact": "自动化脚本可继续解析"}, + {"aspect": "错误与退出码", "conclusion": "错误语义保持可区分", "decision": "merge", "fact": "参数错误与远端失败仍返回不同错误路径", "basis": "失败命令与退出码对照", "evidence": ["E-CG-001"], "impact": "调用方无需修改判断逻辑"}, + {"aspect": "编码与颜色", "conclusion": "UTF-8 和机器输出边界正常", "decision": "merge", "fact": "中文输出可严格解码,JSON 不包含 ANSI", "basis": "原始字节和 JSON 解析验证", "evidence": ["E-CG-001"], "impact": "跨平台输出风险较低"}, + {"aspect": "兼容与文档", "conclusion": "文档与当前行为一致", "decision": "merge", "fact": "帮助和示例覆盖新增入口及默认行为", "basis": "文档、帮助和运行结果对照", "evidence": ["E-CG-001"], "impact": "用户可按现有文档使用"} + ], "findings": [], "top_actions": [], "evidence": [ diff --git a/skills/gitlink-maintenance-orchestrator/examples/fixtures/code-review.json b/skills/gitlink-maintenance-orchestrator/examples/fixtures/code-review.json index dd0e3b9..418892c 100644 --- a/skills/gitlink-maintenance-orchestrator/examples/fixtures/code-review.json +++ b/skills/gitlink-maintenance-orchestrator/examples/fixtures/code-review.json @@ -12,6 +12,14 @@ "fact": "PR 为示例命令增加批量处理能力,但错误路径缺少回归测试,核心失败行为尚未被证明可靠", "basis": "对照默认分支与当前 Diff,并执行 go test ./shortcuts/example;正常路径通过,失败路径覆盖不完整" }, + "dimensions": [ + {"aspect": "贡献价值", "conclusion": "批量处理能力具有明确使用价值", "decision": "merge", "fact": "PR 减少重复命令调用并覆盖常用维护流程", "basis": "对照默认分支功能入口与 PR 描述", "evidence": ["E-CR-001"], "impact": "功能方向可以保留"}, + {"aspect": "Review 履约", "conclusion": "本轮没有可核对的正式 Review", "decision": "observe", "fact": "当前证据没有包含有效 Review 意见与对应提交", "basis": "Review 证据未采集完整", "evidence": ["E-CR-001"], "impact": "不能判断作者是否完成 Review 修改"}, + {"aspect": "逻辑正确性", "conclusion": "失败路径仍不可靠", "decision": "action_required", "fact": "正常路径可用,但远端失败和非法输入没有完整行为证据", "basis": "当前 Diff 与专项测试结果", "evidence": ["E-CR-001"], "impact": "修复错误处理后复验"}, + {"aspect": "代码质量与可维护性", "conclusion": "主流程结构清晰", "decision": "merge", "fact": "批量入口沿用现有 shortcut 结构,未发现明显重复实现", "basis": "目录职责和调用链对照", "evidence": ["E-CR-001"], "impact": "当前结构不阻断合并"}, + {"aspect": "测试覆盖", "conclusion": "失败和权限场景缺测", "decision": "action_required", "fact": "成功场景通过,但无权限和非法路径没有回归测试", "basis": "测试文件与执行命令对照", "evidence": ["E-CR-001"], "impact": "补齐失败路径后重跑"}, + {"aspect": "安全与性能", "conclusion": "未发现已证实的安全或性能阻断", "decision": "observe", "fact": "现有范围未发现凭据泄露和无界批量循环,但恶意输入未完整验证", "basis": "Diff 安全热点和测试范围", "evidence": ["E-CR-001"], "impact": "保持观察并补输入边界测试"} + ], "findings": [ {"id": "CR-001", "severity": "high", "status": "open", "summary": "错误路径缺少回归测试", "evidence": ["E-CR-001"], "related_ids": []} ], diff --git a/skills/gitlink-maintenance-orchestrator/examples/fixtures/maintainer-radar.json b/skills/gitlink-maintenance-orchestrator/examples/fixtures/maintainer-radar.json index bf7bfa1..c8da07e 100644 --- a/skills/gitlink-maintenance-orchestrator/examples/fixtures/maintainer-radar.json +++ b/skills/gitlink-maintenance-orchestrator/examples/fixtures/maintainer-radar.json @@ -12,6 +12,13 @@ "fact": "PR #123 已有明确修复动作但仍等待作者补测,继续占用维护者复看队列", "basis": "队列快照显示 waiting_on=author,当前 head 和 Review 后续动作尚未变化" }, + "dimensions": [ + {"aspect": "响应 SLA", "conclusion": "当前复看等待正在累积", "decision": "action_required", "fact": "作者补测尚未完成,PR 继续占用复看队列", "basis": "队列时间与状态快照", "evidence": ["E-MR-001"], "impact": "修复后应及时通知 reviewer"}, + {"aspect": "当前等待方", "conclusion": "当前明确等待作者", "decision": "action_required", "fact": "waiting_on=author 且修复动作已指向 CR-001", "basis": "队列字段和技术动作关联", "evidence": ["E-MR-001"], "impact": "维护者暂不重复 Review"}, + {"aspect": "Reviewer 负载", "conclusion": "本次没有足够数据判断负载平衡", "decision": "observe", "fact": "fixture 只包含目标 PR,没有完整 reviewer 队列", "basis": "扫描范围限制", "evidence": ["E-MR-001"], "impact": "需要仓库级快照后再调度"}, + {"aspect": "责任停滞", "conclusion": "责任链清晰但尚未推进", "decision": "action_required", "fact": "作者有明确补测任务,当前 head 尚未变化", "basis": "waiting_on 与 head 快照", "evidence": ["E-MR-001"], "impact": "超过阈值后升级维护提醒"}, + {"aspect": "安全与 Issue 优先级", "conclusion": "没有已证实的安全 HOT 事项", "decision": "observe", "fact": "当前高优先级来自测试缺口而非已确认漏洞", "basis": "安全门禁和 finding 分类", "evidence": ["E-MR-001"], "impact": "保持技术修复优先,不误报安全漏洞"} + ], "findings": [], "top_actions": [ {"id": "MR-001", "owner": "maintainer", "severity": "medium", "action": "安排维护者复看 PR #123,当前等待作者补测", "evidence": ["queue:pr-123"]} diff --git a/skills/gitlink-maintenance-orchestrator/examples/fixtures/pr-integrator.json b/skills/gitlink-maintenance-orchestrator/examples/fixtures/pr-integrator.json index 1297330..1ae628a 100644 --- a/skills/gitlink-maintenance-orchestrator/examples/fixtures/pr-integrator.json +++ b/skills/gitlink-maintenance-orchestrator/examples/fixtures/pr-integrator.json @@ -12,6 +12,14 @@ "fact": "贡献方向与仓库需求一致,但代码审查发现的失败路径缺口尚未修复,当前实现不能安全进入合并队列", "basis": "当前 head 的基础构建可执行,但 CR-001 未解决且全量集成验证只完成部分门禁" }, + "dimensions": [ + {"aspect": "合并态与冲突", "conclusion": "尚未完成最新主线合并验证", "decision": "observe", "fact": "当前 fixture 没有最新主线合并工作树结果", "basis": "合并态证据缺失", "evidence": ["E-IN-001"], "impact": "合并前必须在最新主线复验"}, + {"aspect": "构建", "conclusion": "基础构建可执行", "decision": "merge", "fact": "当前 head 在规定环境完成基础构建", "basis": "本地工作树构建结果", "evidence": ["E-IN-001"], "impact": "构建不构成当前阻断"}, + {"aspect": "测试与功能一致性", "conclusion": "PR 声明仅部分得到验证", "decision": "action_required", "fact": "成功路径成立,但错误路径与描述中的可靠性目标不一致", "basis": "专项测试和 CR-001", "evidence": ["E-IN-001"], "impact": "补测并修复后重跑"}, + {"aspect": "CI 与证据关联", "conclusion": "CI 证据未完整关联当前 head", "decision": "observe", "fact": "fixture 没有提供可核对的 head SHA 构建记录", "basis": "CI 证据关联字段缺失", "evidence": ["E-IN-001"], "impact": "不能把历史构建当作当前通过"}, + {"aspect": "安全与发布影响", "conclusion": "没有已证实的发布阻断", "decision": "observe", "fact": "安全门禁通过,但失败路径和回滚证据不完整", "basis": "安全状态与限制列表", "evidence": ["E-IN-001"], "impact": "补齐验证后确认发布风险"}, + {"aspect": "集成结论", "conclusion": "当前不能进入合并队列", "decision": "action_required", "fact": "CR-001 未解决且合并态、CI 和全量测试不完整", "basis": "代码审查与集成证据汇总", "evidence": ["E-IN-001"], "impact": "完成高优先级动作后重新评估"} + ], "findings": [], "top_actions": [ {"id": "IN-001", "owner": "author", "severity": "high", "action": "修复 CR-001 后重新执行合并态验证", "evidence": ["CR-001"]} diff --git a/skills/gitlink-maintenance-orchestrator/examples/fixtures/pr-topology.json b/skills/gitlink-maintenance-orchestrator/examples/fixtures/pr-topology.json index 63e6327..39a7289 100644 --- a/skills/gitlink-maintenance-orchestrator/examples/fixtures/pr-topology.json +++ b/skills/gitlink-maintenance-orchestrator/examples/fixtures/pr-topology.json @@ -12,6 +12,13 @@ "fact": "PR #123 与 #124 修改同一命令入口,功能不完全重复,但合并顺序可能改变最终输出契约", "basis": "比较两条 PR 的文件集合、队列快照和目标行为后确认存在共享入口,尚无证据判定其中一条完全替代另一条" }, + "dimensions": [ + {"aspect": "对当前主线", "conclusion": "目标是对主线能力的增量扩展", "decision": "merge", "fact": "主线已有基础入口,但没有本 PR 的批量行为", "basis": "默认分支源码与目标 Diff 对照", "evidence": ["E-TP-001"], "impact": "不存在主线完全覆盖"}, + {"aspect": "对 open 队列", "conclusion": "与 #124 存在共享入口", "decision": "reorder", "fact": "两条 open PR 修改同一命令入口但目标不同", "basis": "完整 open 队列和文件语义比较", "evidence": ["E-TP-001"], "impact": "需要联合评审接口边界"}, + {"aspect": "对 merged 历史", "conclusion": "继承既有 shortcut 架构", "decision": "merge", "fact": "已合入历史提供基础命令框架,但没有等价批量实现", "basis": "merged PR 索引与主线提交历史", "evidence": ["E-TP-001"], "impact": "应按增量演进评审"}, + {"aspect": "完整性比较", "conclusion": "目标与 #124 互补而非替代", "decision": "observe", "fact": "两条 PR 的覆盖范围和验证重点不同", "basis": "功能范围、测试和文件路径比较", "evidence": ["E-TP-001"], "impact": "不建议仅按文件交集择一"}, + {"aspect": "依赖与处理顺序", "conclusion": "先稳定共享入口再合入下游", "decision": "reorder", "fact": "合并顺序可能改变最终命令和输出契约", "basis": "入口生产与消费关系", "evidence": ["E-TP-001"], "impact": "先确认接口再处理后续 PR"} + ], "findings": [ {"id": "TP-001", "severity": "medium", "status": "open", "summary": "与 PR #124 修改同一命令入口,建议合并顺序复核", "evidence": ["E-TP-001"], "related_ids": ["PR-124"]} ], diff --git a/skills/gitlink-maintenance-orchestrator/references/comprehensive-dimensions.md b/skills/gitlink-maintenance-orchestrator/references/comprehensive-dimensions.md new file mode 100644 index 0000000..2d2ad94 --- /dev/null +++ b/skills/gitlink-maintenance-orchestrator/references/comprehensive-dimensions.md @@ -0,0 +1,87 @@ +# 综合维护评估维度 + +总报告必须覆盖下列六组维度。专项阶段应逐项写入 `dimensions`;没有证据时保留该项并标记 `observe`、`partial` 或 `not_run`,不能省略。 + +## 1. 代码与贡献 + +| 维度 | 最低判断内容 | +|---|---| +| 贡献价值 | 真实问题、受益对象、相对主线增量、维护成本 | +| Review 履约 | 有效 Review、对应提交、修改是否满足要求、剩余动作 | +| 逻辑正确性 | 正常、失败、边界、状态一致性和错误处理 | +| 代码质量与可维护性 | 架构一致性、职责、复杂度、重复、长期维护成本 | +| 测试覆盖 | 单元、集成、回归、失败和跨平台场景 | +| 安全与性能 | 权限、注入、路径、凭据、依赖、资源和性能退化 | + +## 2. CLI 契约 + +| 维度 | 最低判断内容 | +|---|---| +| 参数与帮助 | 命令层级、flag、别名、默认值、帮助与示例 | +| JSON 与文本输出 | 字段、类型、可选性、人读与机读隔离 | +| 错误与退出码 | 参数、认证、权限、远端和解析失败语义 | +| 编码与颜色 | UTF-8、乱码、ANSI、`NO_COLOR` 和跨平台 | +| 兼容与文档 | 旧调用、迁移成本、README 和帮助一致性 | + +## 3. 仓库关系 + +| 维度 | 最低判断内容 | +|---|---| +| 对当前主线 | 已实现、补缺、扩展、重复或回归 | +| 对 open 队列 | 依赖、竞争、重叠、互补、冲突和联审对象 | +| 对 merged 历史 | 继承来源、已合入等价实现和演进关系 | +| 完整性比较 | 重叠实现的范围、测试、架构适配和维护成本 | +| 依赖与处理顺序 | 硬依赖、顺序依赖、合入次序和解除条件 | + +## 4. 集成门禁 + +| 维度 | 最低判断内容 | +|---|---| +| 合并态与冲突 | 最新主线合并、冲突文件和基线 SHA | +| 构建 | 仓库规定环境、构建命令、结果和限制 | +| 测试与功能一致性 | PR 声明、实际行为、全量/专项测试和失败路径 | +| CI 与证据关联 | head SHA、分支回退、未关联构建和时效 | +| 安全与发布影响 | 安全门禁、依赖、迁移、发布和回滚 | +| 集成结论 | 是否进入 merge queue、阻塞项和复验条件 | + +## 5. 维护治理 + +| 维度 | 最低判断内容 | +|---|---| +| 响应 SLA | 首响、Review、复看和合并等待时间 | +| 当前等待方 | 作者、reviewer、maintainer、外部依赖或未知 | +| Reviewer 负载 | 分配数量、瓶颈和可释放容量 | +| 责任停滞 | 已分配但无进展、requested changes 后未更新 | +| 安全与 Issue 优先级 | 安全运营信号、关联 Issue 和队列优先级 | + +## 6. 编排器独有判断 + +| 维度 | 最低判断内容 | +|---|---| +| 证据完整性与新鲜度 | 五阶段齐全、run/head/as_of 一致、缺失和过期证据 | +| 跨专项结论一致性 | 结论是否冲突,冲突如何按证据和门禁解释 | +| 风险传播与门禁对齐 | CR/CG/TP 风险如何影响 IN 和 MR | +| 动作去重与责任归属 | 重复动作合并、责任方、先后顺序和解除条件 | +| 决策置信度 | 覆盖率、限制、未验证项和结论可信程度 | + +## 聊天直接输出 + +聊天摘要不能把总报告压缩成五个阶段状态。每个 PR 至少输出以下 15 项简明判断,每项一至两句,包含结论、最关键依据和影响: + +1. 最终建议 +2. 贡献价值与功能增量 +3. Review 履约 +4. 逻辑、质量与可维护性 +5. 测试、安全与性能 +6. 参数、帮助与兼容 +7. JSON、错误、编码与文档 +8. 主线与 merged 历史关系 +9. open PR 重叠、依赖与处理顺序 +10. 合并态、构建与冲突 +11. 测试、CI、安全与发布门禁 +12. SLA、等待方与 Reviewer 负载 +13. 责任停滞、Issue 和安全运营优先级 +14. 证据完整性与跨专项一致性 +15. 优先动作、责任方与复验条件 + +多个 PR 分别输出,不能共用结论。聊天不复制 Markdown 卡片、HTML 标签、阶段索引、分页过程或完整证据台账;完整内容通过报告链接交付。 diff --git a/skills/gitlink-maintenance-orchestrator/references/pipeline-contract.md b/skills/gitlink-maintenance-orchestrator/references/pipeline-contract.md index c51cca0..ff7d9f0 100644 --- a/skills/gitlink-maintenance-orchestrator/references/pipeline-contract.md +++ b/skills/gitlink-maintenance-orchestrator/references/pipeline-contract.md @@ -46,6 +46,17 @@ "fact": "核心成功路径可用,但远端失败没有回归证据", "basis": "当前 head 的 Diff、专项测试和失败路径测试清单" }, + "dimensions": [ + { + "aspect": "逻辑正确性", + "conclusion": "失败路径仍不可靠", + "decision": "action_required", + "fact": "远端失败没有稳定错误映射", + "basis": "当前 Diff 与失败路径测试", + "evidence": ["E-CR-001"], + "impact": "修复并补测后复验" + } + ], "findings": [], "top_actions": [], "evidence": [], @@ -59,6 +70,11 @@ `action_required`、`reorder`、`observe`、`blocked`。阶段之间不得篡改其他 Skill 的 finding,只通过 `related_ids` 关联。 +`dimensions` 必须覆盖该阶段在 +[`comprehensive-dimensions.md`](comprehensive-dimensions.md) 中列出的全部维度。每个维度必须有 `aspect`、`conclusion`、`decision`、`fact`、`basis`、`evidence` 和 `impact`。没有证据时仍保留维度,并明确写 `not_run`、`partial` 或 `observe`;禁止用阶段级 `assessment` 代替全部维度。 + +编排器在五阶段之后额外生成“证据完整性与新鲜度、跨专项结论一致性、风险传播与门禁对齐、动作去重与责任归属、决策置信度”五项判断。这些判断属于编排器,不得伪装成某个专项 finding。 + ## 最终决策规则 按以下顺序计算最终决策: @@ -75,6 +91,7 @@ finding,只通过 `related_ids` 关联。 ## 首屏压缩规则 +- 每个 PR 先展示五个专项的完整维度矩阵,再展示编排器独有判断和最终结论。 - 首屏最多五项待办,按 `blocking > high > medium > low`、再按责任等待方和证据置信度排序。 - 同一对象、同一动作、同一责任方的重复项合并;保留全部 `source_ids` 供追溯。 - 首屏每项只展示一个主证据,完整证据放到 JSON 或附录。 diff --git a/skills/gitlink-maintenance-orchestrator/scripts/__pycache__/validate_chinese_report.cpython-312.pyc b/skills/gitlink-maintenance-orchestrator/scripts/__pycache__/validate_chinese_report.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..233986c384538e14d0f4f12caae4a536227379e8 GIT binary patch literal 7239 zcma($X;4&Gy0`azVNnp3+z1otju>My&V(41K&u!;0%){pY}>vUXl%O4T~s=^r*IOr zF+?!9kcmlP%!1=a5;H-TXkJp4)O&v#!6&)#)x1|jFI2s%p`umq&AdPFJNI@sgs9`G z>U+=fZRb1R`Ig)NW-w?mXwCmhHnl9ku)m@~vdP7cd+15nL?U)qHP!wV9z^Lt6F z%#s$^yu;=75H5zqnMM}_4-)rN?naVkC>P_WaN4z>q;VJS_BXe9NdPNp^!P}c#J9Sr zeT4sj52wf$KgFz^Mr17#Ugz@p{EUn7_Gn}<&g zpNsV#id^oCe((`%OiY%Pm*J6*PQ->jo&(n%8S0K4{yg^iaB6b;-6PRZ*YuhG80a8L zQPhwqAG;_)F*b5Kdi?FkJN>cYkw{l468bQD`jX{wRuAj(t9`MK%TvQ&M%qRMy;YI> zJ>&sA^65uN0wn)*+i?7=6VXfOVttpRZJ!7V5hagb?Vmo{3A>GSUJ*H?bwoD$#hdXf zr{W(UiM@MTAQHLU4(A4-01zS72qjtqtZtZvqY28+6h1AJ4|yKNIO59*JDOmLSr1PMo`PEi&32 zX@6^Ka5y$}JvoQ_TSy;1-Sa^tbcRg>HjyjW@Me-~APGEj{79rTK~Xqd5IuV3Wc;hw zS!69!U%eOq;xup(4Q9G;C^FP3h>CQ44Os|UJn~uWPls3~AVlAPBQiWB*o&whw0!IX z(8knYTm0x%q&u|Jk}{-#gvlKKJbvh;z%Ql2Nau;j;OmjmPb1xL3Cb2NL9}KTc`R6n z44uTQ%ZtT*3LB4IYL9$%IC}b;Fee@}N#XIUAH+vT6Si<}YIrzu=xlWOeZhEAEb%g$ zW=VW%qz5iYY)G_$goH`efXva;1Jj?Kjey;tOA-GP&Re)H!abYaB)U=J<(wMnjlO*e zFhw&4B#4?OQ&O_m#41xA%=p{ z&AHVUbs$@~@>^XVA4B?FJ~xS1v(3#esx@GS`�sNPG)RG&GYwCSZh_8h;C3>=wL_ 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 TF|J(_mM?+hmgi8ffMov None: "重新提炼", "不能复制报告首屏", "不能机械删除 Markdown/HTML 格式", - "每个方面一至两句完整自然语言", + "15 项直接判断", + "每项一至两句", "可点击链接或当前 Agent 平台的文件附件", ] missing = [marker for marker in required_markers if marker not in content] @@ -25,6 +26,6 @@ def test_chat_summary_requires_agent_synthesis() -> None: def test_default_agent_prompt_requires_a_plain_summary() -> None: content = read_utf8(ROOT / "agents" / "openai.yaml") - required_markers = ["重新提炼", "不复制报告卡片原文", "不输出 HTML/Markdown 展示标签"] + required_markers = ["重新提炼", "15 项", "不复制报告卡片原文", "不输出 HTML/Markdown 展示标签"] missing = [marker for marker in required_markers if marker not in content] assert not missing, f"missing agent prompt markers: {missing}" diff --git a/skills/gitlink-maintenance-orchestrator/scripts/test_validate_chinese_report.py b/skills/gitlink-maintenance-orchestrator/scripts/test_validate_chinese_report.py index 24e0351..af0f9af 100644 --- a/skills/gitlink-maintenance-orchestrator/scripts/test_validate_chinese_report.py +++ b/skills/gitlink-maintenance-orchestrator/scripts/test_validate_chinese_report.py @@ -2,21 +2,24 @@ import unittest -from validate_chinese_report import validate_report +from validate_chinese_report import REQUIRED_ASPECTS, REQUIRED_GROUPS, validate_report class ChineseReportValidatorTests(unittest.TestCase): def test_accepts_complete_chinese_report(self) -> None: - report = """# PR 维护全流程摘要 + groups = "\n".join(REQUIRED_GROUPS) + cards = "\n".join( + f"**{aspect}:** 证据支持当前判断 " + f"**[observe]**:已完成 {aspect} 的专项分析;依据:当前 Diff、测试和只读平台快照;" + "证据摘录:目标提交和验证命令均已记录;影响:维护者可据此决定下一步。" + for aspect in REQUIRED_ASPECTS + ) + report = f"""# PR 维护全流程摘要 **范围:** Gitlink/gitlink-cli **风险:** 阻断 1 项,高风险 2 项,以下内容用于帮助维护者快速确认处理顺序和责任人。 ## PR #123 -**代码审查:** 需要修改 **[action_required]**:失败路径缺少覆盖;依据:当前 Diff 与专项测试;证据摘录:无权限测试未覆盖,来源:`shortcuts/example/example_test.go:42`;下一步:补回归测试。 -**CLI 契约:** 兼容性部分成立 **[partial]**:旧调用正常但 JSON 缺边界;依据:帮助和输出对照;证据摘录:`--help` 可用但 JSON golden 缺少非法参数样例;下一步:补 golden。 -**仓库关系:** 需要调整顺序 **[reorder]**:目标消费上游字段;依据:主线、open 和 merged 索引;证据摘录:open PR #124 修改同一字段;影响:先稳定上游。 -**集成门禁:** 当前被阻断 **[blocked]**:关键测试未完成;依据:合并态和验证账本;证据摘录:`go test ./...` 尚未在合并工作树执行;下一步:补测试。 -**维护状态:** 需要维护者接单 **[action_required]**:责任方尚未确认;依据:时间和分配快照;证据摘录:队列快照中的 reviewer 与 assignee 均为空;下一步:安排 reviewer。 -**最终结论:** 修复阻断问题后重新审查 **[blocked]**:存在未解决高风险项;依据:CR-001 与 IN-001;证据摘录:失败路径缺测试且全量验证未运行;下一步:修复并重跑。 +{groups} +{cards} ## 先处理这几项 先修复真实响应错误,再补充测试,然后重新执行完整验证并由维护者复看。 ## 五个专项状态索引 diff --git a/skills/gitlink-maintenance-orchestrator/scripts/validate_chinese_report.py b/skills/gitlink-maintenance-orchestrator/scripts/validate_chinese_report.py index 87dd867..910b857 100644 --- a/skills/gitlink-maintenance-orchestrator/scripts/validate_chinese_report.py +++ b/skills/gitlink-maintenance-orchestrator/scripts/validate_chinese_report.py @@ -20,12 +20,47 @@ REQUIRED_MARKERS = ( "## 完整证据与限制", "## 证据台账", ) +REQUIRED_GROUPS = ( + "### 代码审查", + "### CLI 契约", + "### 仓库关系", + "### 集成门禁", + "### 维护状态", + "### 编排器综合判断", +) REQUIRED_ASPECTS = ( - "代码审查", - "CLI 契约", - "仓库关系", - "集成门禁", - "维护状态", + "贡献价值", + "Review 履约", + "逻辑正确性", + "代码质量与可维护性", + "测试覆盖", + "安全与性能", + "参数与帮助", + "JSON 与文本输出", + "错误与退出码", + "编码与颜色", + "兼容与文档", + "对当前主线", + "对 open 队列", + "对 merged 历史", + "完整性比较", + "依赖与处理顺序", + "合并态与冲突", + "构建", + "测试与功能一致性", + "CI 与证据关联", + "安全与发布影响", + "集成结论", + "响应 SLA", + "当前等待方", + "Reviewer 负载", + "责任停滞", + "安全与 Issue 优先级", + "证据完整性与新鲜度", + "跨专项结论一致性", + "风险传播与门禁对齐", + "动作去重与责任归属", + "决策置信度", "最终结论", ) FORBIDDEN_ENGLISH_TEMPLATES = ( @@ -74,10 +109,16 @@ def validate_report(text: str, required_prs: list[int] | None = None) -> list[st continue next_heading = PR_HEADING.search(text, start + 1) end = next_heading.start() if next_heading else len(text) - cards = CARD_PATTERN.findall(text[start:end]) + section = text[start:end] + for group in REQUIRED_GROUPS: + if group not in section: + errors.append(f"PR #{number} is missing assessment group: {group}") + cards = CARD_PATTERN.findall(section) aspects = {card[0] for card in cards} if len(cards) < len(REQUIRED_ASPECTS): - errors.append(f"PR #{number} has {len(cards)} judgment cards, need 6") + errors.append( + f"PR #{number} has {len(cards)} judgment cards, need {len(REQUIRED_ASPECTS)}" + ) for aspect in REQUIRED_ASPECTS: if aspect not in aspects: errors.append(f"PR #{number} is missing aspect card: {aspect}")