关于 commit-message-generator
commit-message-generator 是用于审查 Datex Studio 功能分支待提交改动并撰写可追溯提交消息的技能。它通过 dxs 读取分支数据;若分支对应 Project Task,则会将分支 URL 写入该任务的 cr0c5_commit 字段。
主要功能
- 01通过 dxs 检查分支改动和差异
- 02确认分支类型及待处理内容
- 03追溯改动对应的工作项
- 04为 Datex Studio 撰写提交消息
- 05将分支 URL 写入 Project Task
适用场景
- 01为功能分支的待提交改动准备消息
- 02确认分支是否包含实际改动
- 03查找提交对应的工作项引用
- 04将 Project Task 与分支关联
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ datex/ skills --skill commit-message-generator安装后在 Claude Code 中输入/commit-message-generator确认已加载。
附带文件references/traceability.md
详细介绍
提交消息生成器
审查 Datex Studio 功能分支中待处理的更改,并生成一条高质量的提交消息,用于记录到该分支上。此技能通过 dxs 在服务端读取分支,不会运行 git commit;Datex Studio 有自己的提交流程,此处生成的消息旨在粘贴到分支的提交 UI 中(或用户选择的任何下游交付渠道中)。
它只会进行一次写入,而且仅此一次:当分支解析为 Project Task 时,会将分支 URL 写入该任务的 cr0c5_commit 字段,以便双方都能找到此链接(Phase 5c)。不会更改其他任何内容——无论是分支、配置还是仓库。
每条消息都必须包含一个指向变更依据工作项的链接。可追溯性检查是一个首要阶段,并非格式细节——请参阅 references/traceability.md。
参考资料
- ../datex-studio-shared/branch-setup.md — 分支选择(适用 Branch ID Policy:切勿臆测)
- references/traceability.md — 票据引用的发现、提供方适配器(CRM Project Task / Case / Project Request、Azure DevOps)、合规判定,以及
Ref:输出位置
前提条件
- Datex Studio 仓库中某个功能分支的 Branch ID
- 目标环境(默认为
prod;仅当用户明确要求时才传入--target qa或--target dev)
执行模式
此技能有两种模式。默认使用交互模式。 只有在提示中明确表明时才切换到一次性模式,例如“one-shot mode”、“此请求来自自动化系统”、“当前没有用户”或要求通过指定工具交付结果。
| 交互模式 | 一次性模式 | |
|---|---|---|
| 有用户参与 | 是 | 否 |
| 输出渠道 | 消息以及面向用户的摘要 | 仅消息 |
| 存在歧义时 | 询问 | 按照下方规则自行判断,绝不询问 |
关键区别在于输出渠道,而非质量。交互模式有两个输出:提交消息,以及一段对话摘要,用来传达不应放进消息的所有内容。一次性模式只有一个输出。因此,原本会告知用户的观察结果,要么纳入消息,要么舍弃——而舍弃观察结果,正是会让合规检查沦为作秀的做法。
单次执行规则
-
绝不提问,绝不阻塞。 始终生成一条消息。没有人会回答,因此提问就等于无声失败。
-
将面向用户的观察提升到消息中,在 Description 中以
⚠行呈现——例如工单已关闭、工单声称存在同级分支、解析出的标题与commitTitle不符、消息属于事后补录。交互模式下,这些内容保留在摘要中;单次执行时,它们要么写入消息,要么不写。 -
谨慎处理引用。 绝不要引用需要确认的内容。具体来说:
- 反向边或工单编号查询返回 2 个或更多候选项 →
UNVERIFIED。不要擅自选择。在 ⚠ 行中列出候选项,不输出Ref:行。 - 关键词搜索命中项——交互模式下你会建议用户确认的那些——不要采纳。判定为
MISSING;在 ⚠ 行中列出相近但不匹配的结果,让人工完成后续处理。 - 仅采纳自证的引用:提示词或提交字段中明确给出的 ID 或深层链接,或唯一一个反向边命中项。
无人值守时提交错误链接,比坦诚标记为
MISSING更糟——这会把猜测伪装成审计记录,而之后没人会再核查。 - 反向边或工单编号查询返回 2 个或更多候选项 →
-
分支 ID 必须来自提示词。 Branch ID Policy 中的“提问”规则不适用。如果没有提供分支 ID,则不输出任何内容,并报告该请求不可用——不要根据上下文猜测。
-
通过提示词指定的工具交付(例如
SaveCommitMessage)。如果会话中没有该工具,则退而将消息作为最终输出返回,并说明缺少该工具——绝不要丢弃结果。
保持 ⚠ 行易读
观察提升后可能会累积多条警告,而 Description 是开发者真正会阅读的唯一部分。请确保内容实用:
- 最多保留 3 条
⚠行。 超出后,保留对引用可信度影响最大的三条,并将其余内容合并为一行。 - 按后果排序: 首先是可追溯性缺陷(缺失/未验证/不一致的引用),然后是分支状态警告(空、事后补录),最后是代码审查相关行。
- 合并自然相关的观察,避免输出近似重复内容——“工单已关闭且还声称存在分支 83001”应合并为一行,而不是两行。
工作流
[Phase 0: Mode]
Interactive (default) or one-shot? One-shot = explicit signal in the prompt.
One-shot: never ask, never block, promote observations into the message,
be conservative about references, deliver via the named tool.
|
[Phase 1: Setup]
Get branch ID from user (branch-setup.md rules; one-shot: from the prompt)
Confirm target environment (default: prod)
|
[Phase 2: Gather]
dxs source branch show <id> → metadata (author, status, app, commit title/description)
└─ GUARD: is this a feature branch? If isCommit/isRelease/isMainBranch, STOP and ask.
dxs -b <id> source changes → inventory of added/updated/deleted configs
dxs -b <id> source changes --with-diffs → actual diffs for analysis
dxs -b <id> source deps → dependency surface (optional, when diffs are ambiguous)
|
[Phase 3: Trace] ← traceability compliance check
Scan prompt + commitTitle/commitDescription for a ticket ref, AND ask CRM which
Project Task claims this branch (reverse edge on cr0c5_commit) — always both.
Resolve it against its provider (CRM Project Task / Case / Project Request, Azure DevOps).
Verdict: COMPLIANT | UNVERIFIED | MISSING. Keep the resolved ticket's description —
it feeds Phase 4's analysis and its divergence check. Warns, never blocks.
|
[Phase 4: Analyze]
Read each diff, informed by the ticket's stated requirement. Identify the dominant
theme (feature / bug fix / refactor / chore).
Flag anything that looks like a significant issue (bug, security concern, dead code) —
do NOT list the issues in the commit message; note that a review is recommended instead.
|
[Phase 5: Draft Message]
Build the title + body per the "Output Format" section, including the Ref: lines.
|
[Phase 5b: Deliver] ← one-shot only
Call the delivery tool the prompt named (e.g. SaveCommitMessage).
|
[Phase 5c: Stamp reverse edge] ← both modes, only when a Project Task resolved
dxs crm commit-ref append <task> <branch-url> --label <app> (idempotent)
|
[Phase 6: (optional) Persist to knowledge base]
If CreateKnowledgeNode is available in this session, save the message as an Article
under CommitMessages/<Org>/<App>/<BranchId>_<yyyyMMdd>_<hhmm>.md. Otherwise print
the intended path and skip.
|
Return the message to the user.
阶段详情
阶段 1:设置
- 确定模式(参见“执行模式”)。除非提示词表明是单次执行,否则以下内容均假设为交互模式。
- 向用户获取分支 ID。遵循 branch-setup.md 中的 Branch ID Policy——先询问,绝不假设,即使本次会话中较早时曾出现分支 ID。 单次执行: 从提示词中获取分支 ID。如果没有提供,则停止并报告该请求不可用——绝不要推断。
- 确定目标环境。除非用户另有说明,否则默认为
prod。dxs接受--target prod|qa|dev;若未指定,则使用prod。
阶段 2:收集
尽可能并行运行以下四条命令——它们均为只读且彼此独立:
dxs source branch show <BRANCH_ID>
dxs -b <BRANCH_ID> source changes
dxs -b <BRANCH_ID> source changes --with-diffs
dxs -b <BRANCH_ID> source deps
另外还有四条命令值得了解——当上述四条命令结果不明确时再使用:
# Confirm a single config really is unchanged (cheap second opinion on a no-op)
dxs source diff --from <BASE_BRANCH_ID> --to <BRANCH_ID> --config <referenceName>
# Upstream changes in base not yet pulled into this branch (proves drift)
dxs source diff --branch <BRANCH_ID>
# Dependency deltas WITH direction — `source deps` alone has no notion of it
dxs source deps-diff --from <BASE_BRANCH_ID> --to <BRANCH_ID>
# Linked Azure DevOps work items (note: -b, not positional)
dxs -b <BRANCH_ID> source workitems --description
--from 参数中的 base_branch_id 来自 source changes 响应。
在未接入分支级 DevOps 关联的租户中,
source workitems会返回空列表和devops_organizations: []——包括此处测试的所有分支,其中一个分支还被某个 ADO 工作项明确指向。请在阶段 3 检查此项,但应将空结果视为“无数据”,绝不要视为“不存在工作项”。
守卫:确认这确实是一个功能分支
在分析任何内容之前,先检查 branch show。此技能会为尚未提交的工作起草消息;其他分支类型要么已提交,要么根本不是开发工作。
| 标志 | 类型 | 操作 |
|---|---|---|
isFeatureBranch: true,isCommit: false | 功能分支,工作待处理 | 继续 |
isCommit: true(状态为 WorkspaceHistory) | 提交快照——已提交,包含 commitTitle 和 commitDescription | 停止并询问 |
isRelease / isCurrentRelease / isMainBranch | 发布分支或主分支 | 停止并询问 |
对于非功能分支,说明该分支的实际类型,引用其现有的 commitTitle 和 commitDate,并询问用户是想要换一个分支,还是确实想要一条追溯性消息。不要默默继续——为已提交的快照起草的消息无处可贴,而且会让人以为工作仍在等待提交。
如果用户确认仍要继续,就照常处理,并在摘要中(而非消息中)注明这是追溯性的。
单轮模式: 无人可问,因此继续处理——但要在消息中说明这一点。添加追溯性 ⚠ 行(参见输出格式),其中包含现有的 commitTitle 和 commitDate,这样接收系统就能识别这是对已提交工作的描述,而不是对待提交工作的描述。
用途:
-
branch show— 作者、状态以及上面守卫会读取的分支类型标志。还包括commitTitle/commitDescription,这是查找 Phase 3 票据引用的主要位置。注意,它不会返回分支的name或description;referenceName是应用定义名称(例如FootprintManager),而applicationDefinitionId是仓库 ID。 -
source changes— 待处理配置的清单。changes_by_type始终为空——请忽略它。created/updated/deleted分组即使在包含三个实质性配置更新的分支上也会返回空值。请读取all_changes;这些分组无论如何都不能说明任何情况。all_changes中的一行并不能证明存在实际工作。 检查每个条目通过--with-diffs返回的has_changes——这是权威信号:信号 含义 has_changes: true内容确实发生了变化。这属于工作。 has_changes: false无操作。检出产物或仅元数据变化;配置与基准相同。 has_changes: null(且modificationTypeId: "add")新配置,没有基准可供比较。视为工作。 modificationTypeId只是较弱的提示:"unspecified"始终表示has_changes: false(已检出但从未编辑),但"update"也会与has_changes: false一同出现。请以has_changes为准,而不是类型。如果所有条目都是无操作,则该分支为空——请参阅下面的“空分支”。
-
source changes --with-diffs— 要分析的实际代码/配置内容,以及每个条目的has_changes标志。
防护:空分支
功能分支可能正常处于打开状态,all_changes 中也列出了配置,但没有任何工作——开发者在设计器中检出配置后,从未保存编辑。每个条目的 has_changes 都会返回 false。
这种情况很常见,值得明确检查;这是关于此类分支最重要的一点。发生这种情况时:
- 先确认,再断言。
--with-diffs报告has_changes: false是一种信号;dxs source diff --from <baseBranchId> --to <BRANCH_ID> --config <referenceName>返回unchanged,则是另一个成本很低的佐证。 基础分支 ID 是source changes响应中的base_branch_id。 - 直截了当地说明,不要编造改动。 将其标题标为一个空分支,而不要费力描述并不存在的工作。这里不适用祈使语气——没有可命名的操作——因此描述性标题是正确的,并且优先于 conventional commits 的建议。
- 如果工单已解析(参见“输出格式”),请使用“无工作”⚠ 行,而不是分歧行。正确关联工单的空分支并非引用错误,而是未保存的工作。
- 不要添加代码审查 ⚠ 行。 此标记用于指出在 差异 中发现的问题;没有差异,就没有可审查的内容。空分支警告已带有 ⚠ 标题前缀。
- 说明检出了哪些配置——如果它们恰好就是工单涉及的配置,这一点值得告知用户,因为这表明工作已经开始后又丢失了,而不是从未开始。
source deps— 外部依赖项(此分支引用的组件包)。当差异提到分支之外的类型或流程,或者依赖项更新构成大部分改动时,这很有用。一行由unique_identifier+version标识(没有单一的整数行 ID);branch_id是持有该包的分支,无法解析时为null;version_info包含version_name、commit_title、created_date、is_latest。--tree会添加children/depth,其中is_direct始终表示此分支的直接依赖项,因此所有嵌套节点的值都为false。--tree需要 dxs ≥ 0.5.4:较旧版本会返回空树,退出代码为 0。
阶段 3:追踪(可追溯性合规检查)
确定此分支可追溯到哪个工作项。完整规则、提供方适配器和命令语法见 references/traceability.md;流程如下:
- 发现 — 按优先级依次扫描:用户的提示词,然后是阶段 2 中的
commitDescription和commitTitle(这两个字段就是全部范围——分支没有名称或描述)。候选项可能有多种形式:CRM 深层链接(…&etn=msdyn_projecttask&id=<guid>)、案例编号(C260612_0005)、项目请求(PR-260610_003)、ADO 工作项(AB#118432)或单独的 GUID。先收集所有候选项,再逐一解析。 - 反向边查找 — 查询哪个 Project Task 声明关联到此分支:
dxs crm odata msdyn_projecttasks -f "contains(cr0c5_commit,'/<BRANCH_ID>/')". 命中一条即为权威结果——工单声明了此链接,因此优先于根据标题推断的任何结果。即使步骤 1 已成功,也要运行此查询:这是发现某分支指向一个工单、但另一个工单也声明关联到该分支的唯一方法。零命中不能证明任何事(该字段由人工维护,且数据稀疏)——继续后续步骤。详情和斜杠锚定规则见 references/traceability.md。 **单次运行:**命中 2 条或更多 →UNVERIFIED,列出候选项,不输出Ref:。 - 搜索 — 仅当步骤 1 和 2 都无结果时执行:使用提交标题进行最多约 2 次 CRM 关键词搜索,并运行
dxs devops search搜索 ADO 工作项。 将命中结果提交给用户确认;绝不默默采用搜索结果。 **单次运行:**绝不采用搜索命中结果——无法获得确认。判定为MISSING;在 ⚠ 行中列出相近结果,以便人工完成核查。 - 解析 — 通过对应的提供方适配器获取记录。保留描述字段(
msdyn_descriptionplaintext、案例的description、ADO 的description):这些字段说明了用户提出的需求,有助于完善阶段 4。 - 判定 —
COMPLIANT(已找到并解析)、UNVERIFIED(已找到,但查找失败或没有适配器)或MISSING(未找到)。
此检查只发出警告,绝不会阻止操作。 UNVERIFIED 和 MISSING 会在标题前加上 ⚠,并在正文中添加一行;消息仍会完整生成。
按目标位置区分合理性检查的观察结果。不一致——工单描述的工作与差异明显不同——应写入消息,作为一行 ⚠ 提示,因为阅读提交内容的人才能发现链接错误。其他所有情况(工单已关闭、工单已关联到其他分支、解析后的标题与 commitTitle 不匹配)都只写入给用户的摘要。参见
references/traceability.md 中的“合理性检查”。
阶段 4:分析
阅读差异。目标是充分理解分支的意图,以便用一句话描述,并找出评审者应该了解的事项。
如果阶段 3 已解决某个工单,先阅读其描述并以此为依据。工单说明了请求的内容;差异说明了实际构建的内容。描述实际构建的内容——但使用需求中的术语,并以需求说明“原因”。
差异检查。 将工单中陈述的需求与差异实际实现的内容进行比较。如果二者描述的工作明显不同,提交消息始终描述差异——绝不描述工单——并附上一行 ⚠ 差异说明(见“输出格式”)。差异意味着两种情况之一,二者都值得人工关注:分支关联了错误的工单,或分支所做的工作与要求不符。
明确判断阈值。只有主题不匹配时才触发——例如,账单筛选器工单对应依赖版本同步,或修复拾取问题的工单对应空分支。仅仅因为分支是部分实现、过程中做了重构,或修复了相邻问题,不会触发;这些都很正常。如有疑虑,不要触发,而是在摘要中说明。
对于每个已更改的配置,简要评估:
- 此更改是否符合连贯的主题(功能 X、修复 Y、重构 Z)?
- 是否存在逻辑错误、未处理的边界情况或缺失的错误处理?
- 安全风险:表达式中未清理的输入、动态筛选器中的注入途径、参数中的敏感数据?
- 设计异味:无用代码、各配置之间的重复逻辑、明显有问题的模式?
如果发现重大问题,不要在提交消息中逐项列出。应在标题中设置警告标记,并在正文中添加一行,建议进行代码评审(见“输出格式”)。branch-code-reviewer 技能用于逐项列出问题;此技能的任务是描述更改内容。
阶段 5:起草消息
生成一条包含三个部分的消息。下游解析器会按空行拆分输出:
- 标题——第一行。使用 Conventional Commits 风格,约 72 个字符。
如果阶段 3 返回了
MISSING/UNVERIFIED,或阶段 4 发现了需要评审的事项,则在标题前加上 ⚠。无论触发了多少项关注,只加一个前缀。 - 描述——第二段(到下一个空行之前的所有内容)。先写简短、易读的摘要,然后写任何
⚠行,最后写Ref:行。这是开发者在 Datex Studio 的提交对话框中唯一能看到并编辑的部分,因此要保持重点明确,并将引用内容放在此段内;如果在Ref:前加空行,它就会被移到发布说明中,无法显示。 - 发布说明——从第三段开始的所有内容。即详细正文。在交互式流程中,开发者看不到此部分,只有下游发布说明工具会使用它。在现有的
SaveCommitMessage一次性传递中,没有单独的参数用于此部分,因此它会包含在工具的description字段中——请写成普通人也能合理阅读的内容,而不是仅供工具使用的草稿。
确切格式见下文“输出格式”。每个部分都应控制在合理的行宽内。
CLI 提交说明交接
当用户希望将详细部分保存到 Studio 提交中时,请使用 commit-release-notes。它会将简短描述与 UTF-8 说明文件分开保存,并记录已实现的 CLI 传输与回读方式。仅请求起草并不代表授权提交。其 CLI 流程不会改变下述一次性传递约定。
阶段 5b(仅限单次模式):交付
在单次模式下,消息必须送达请求方系统——仅以散文形式返回并不算交付。
调用提示词中指定的工具。已知的交付工具是 SaveCommitMessage:
| 参数 | 类型 | 传入内容 |
|---|---|---|
branch_id | integer | 分支 ID——必须是数字,而不是字符串 |
title | string | 标题行;适用时包含 ⚠ 前缀 |
description | string | 完整消息——标题、空行、描述段落、空行、发行说明 |
environment | enum | production | qa | dev——不是 CLI 中的 prod |
这四项都必填;environment 虽有默认值,但仍必须传入。
以下三点务必处理正确:
description是完整消息,而不只是中间部分。 其约定是“首行简洁,然后空一行,再写补充信息”——这是标准的主题加正文格式。因此,标题行会重复出现:在title中一次,在description的首行再一次。这种重复是有意的;不要删除。- 三个部分合并到两个字段中。 没有单独的发行说明参数,因此发行说明应放在描述段落之后,包含在
description中。请严格保留空行分隔——下游才能据此将各部分重新拆分。 - 映射环境名称。
dxs使用--target prod;此工具需要的是production。qa和dev则相同。传入prod会导致架构验证失败。
在 title 中保留 ⚠ 前缀。 这是已经确定的决定,不是疏忽——不要因为它是非 ASCII 字符,或担心下游 UI 的显示效果而将其删除。这个前缀表示有事项需要人工关注;标题悄无声息地丢失此前缀,比显示效果不完美更糟。
如果会话中无法使用指定工具,不要默默丢弃结果:将完整消息作为最终输出返回,并明确说明交付工具缺失,以便调用方判断是交付失败,而不是生成失败。调用工具的同时,也请在最终输出中返回消息——这不费什么事,还能让人从对话记录中诊断故障。
交互模式下完全跳过此阶段。
阶段 5c:写入反向边(两种模式)
当阶段 3 解析出项目任务时,将此分支的 Studio URL 写入该任务的
cr0c5_commit,这样从工单一侧也能发现此链接。这正是阶段 3 中的反向边查找
能在下一个分支上生效的原因——目前该字段仅在约 145 个任务上填有内容,因为一直是人工维护。
dxs crm commit-ref append <TASK_GUID> \
"https://wavelength.host/studio/application/<BRANCH_ID>/home" \
--label <ApplicationDefinitionName>
在以下情况下,此操作会在交互模式和单次运行模式下自动执行:
- 判定结果为
COMPLIANT——绝不写入猜测结果,因此在UNVERIFIED或MISSING时绝不写入;并且 - 解析出的记录是项目任务。案例、项目请求、内部 Datex 工单和 ADO 工作项都没有
cr0c5_commit字段——跳过它们。
重要细节:
- 此操作具有幂等性。 如果 URL 已存在,命令不会写入任何内容,并返回
changed: false,原因是"value already present"。在同一分支上重新运行此技能是安全的。不要传入--allow-duplicate——这会绕过保护,并使字段内容无限增长。 --label是应用程序定义名称(来自branch show的referenceName,例如FootprintManager)。这与字段中已有的惯例一致,即在 URL 上方显示标签行。- 写入失败不会使消息失效。 报告失败并继续——提交消息才是交付成果;写入标签只是副作用。
- 在交互式摘要中报告结果(
changed: true/false)。在单次运行模式下,仅在写入失败时提及——成功写入不值得添加一条 ⚠ 提示。
为何可安全地无人值守运行。 单次运行模式只会采用可自行佐证的引用——明确的 ID 或链接,或单个反向边匹配结果——因此绝不会将仅凭关键词搜索猜出的任务写入字段。此写入沿用保守解析规则,无需另行设置保护。
阶段 6(可选):保存到知识库
检查本次会话中是否提供了 CreateKnowledgeNode 工具。如果有,将起草的消息保存为类型为文章的知识产品:
- 路径:
CommitMessages/<Organization>/<ApplicationDefinitionName>/<BranchId>_<yyyyMMdd>_<hhmm>.md- 示例:
CommitMessages/Colorado Cold Connect/Footprint Cloud/67388_20260127_1419.md - 如果文件夹层级不存在,则创建它。
- 示例:
- 标签: 键为
branch,值为分支 ID。 - 架构: 调用
CreateKnowledgeNode之前,检查article工件类型的架构——字段名称可能因知识库版本而异。
这两个名称来自不同的命令——仅凭 branch show 无法获取它们:
| 名称 | 来源 |
|---|---|
<Organization> | dxs auth status → active_identity.organization(例如 Datex)。dxs source repo list 的每一行中也包含 organization.name。 |
<ApplicationDefinitionName> | dxs source branch show → referenceName(例如 FootprintManager)。这与仓库的 name 相同,且 applicationDefinitionId 与仓库的 id 相同。 |
将当前本地时间转换为 yyyyMMdd_hhmm(24 小时制),用于文件名。
如果没有提供 CreateKnowledgeNode(大多数仅使用 CLI 的会话都没有),则跳过此步骤。打印出原本应使用的路径,以便用户选择手动保存。
输出格式
<Title — single line. Conventional commits style. Prefix with ⚠ when Phase 3 or
Phase 4 surfaced something that warrants attention.>
<Description — one paragraph, ~1-3 sentences, summarizing the change in
human terms. This is what the developer sees and edits in the commit dialog,
so keep it focused on the "what" and "why" at a high level. Then, still inside
this same paragraph and in this order:
⚠ lines, when applicable — use these four templates verbatim:
"⚠ Recommend running a code review before merging — <one-line reason>."
"⚠ No ticket reference found — this commit is untraced. Add a Project Task,
Case, or work item link before committing."
"⚠ Ticket reference <ID> could not be verified — <one-line reason>."
"⚠ Referenced ticket describes different work than these changes — <ticket
subject> vs <what the diffs do>. Verify the reference before committing."
"⚠ Branch contains no changes — <n> config(s) are checked out but identical
to base. The work described by the referenced ticket does not appear to
have been saved."
One-shot only — promoted from what would have been the chat summary. Use only
in one-shot mode; interactively these belong in your summary:
"⚠ Referenced ticket is <state> — verify it is the right reference."
"⚠ Ticket reference is ambiguous — <n> candidates matched (<ids or
subjects>); none adopted. Add an explicit link before committing."
"⚠ No ticket reference found; closest matches were <candidates>. Not adopted
without confirmation — add a link before committing."
"⚠ This message is retroactive — the branch was already committed on <date>
as \"<existing commitTitle>\"."
Ref: lines, when a reference resolved — two lines per reference:
"Ref: <record type> — <resolved title>"
"<full deep link, bare and unwrapped>">
<Release Notes — the detailed body, never shown to the developer. Typically
two paragraphs:
(1) what was added/changed/deleted at the config level — counts and notable
config names;
(2) how it works at a high level — one or two sentences explaining the
mechanism, not individual line changes.>
这三个部分以空行分隔:解析器使用这些空行作为边界,因此不要省略它们,也不要在部分内部添加额外空行。
示例(干净分支,已追溯):
feat(mobile): add Mobile Configurator hub for per-warehouse settings
Adds a new Mobile Configurator hub with sub-tabs for warehouses, owners,
order classes, and equipment types, so Settings exposes per-warehouse
configuration to mobile users.
Ref: Project Task — Mobile Configurator for Warehouse Settings
https://datexcorp.crm.dynamics.com/main.aspx?appid=ee829a66-fb63-ea11-a811-000d3a37800e&forceUCI=1&pagetype=entityrecord&etn=msdyn_projecttask&id=52c6bf79-36d5-49e7-9657-5426b2c68c0f
Adds 29 new configs: one hub (mobile_configurator_hub), four sub-tabs
(Warehouses, Owners, Order Classes, Equipment Types), and the grids/editors/
flows that back them. Existing Settings navigation is updated to expose the
hub.
The hub reads/writes warehouse-scoped settings via a new storage collection
and a pair of crud flows; per-owner and per-equipment-type overrides are
layered on top in the respective sub-tabs.
示例(已标记分支——存在审查疑虑,并追溯到一个案例):
⚠ fix(udf): correct TypeId remap in custom_field_editor
Fixes a UDF type-remap bug where Text fields rendered as Selection lists,
with a small refactor that inlines a datasource and refreshes three hubs
after the editor closes.
⚠ Recommend running a code review before merging — the save flow has
duplicated error handling that can show two dialogs on failure.
Ref: Case C260612_0005 — Text UDFs render as Selection list
https://datexcorp.crm.dynamics.com/main.aspx?appid=ee829a66-fb63-ea11-a811-000d3a37800e&forceUCI=1&pagetype=entityrecord&etn=incident&id=6364eb8e-6266-f111-a825-000d3a3037d2
Updates custom_field_editor to remap TypeId 5→1 so "Text" UDFs no longer
render as "Selection list". Inlines ds_get_custom_field_options into
custom_field_options_grid (deletes the standalone datasource) and adjusts
three hubs to await the editor dialog and refresh on close.
示例(已追溯,但工单与工作内容不匹配):
⚠ chore(deps): sync Carriers, Manifesting, and PackVerification packages
Pulls in the 2026-07-30 builds of three component packages — Carriers,
Manifesting, and PackVerification — with no application configuration changes
of its own.
⚠ Referenced ticket describes different work than these changes — "Billing
Queries" (custom billing contract line filters) vs a dependency version sync.
Verify the reference before committing.
Ref: Project Task — Billing Queries
https://datexcorp.crm.dynamics.com/main.aspx?appid=ee829a66-fb63-ea11-a811-000d3a37800e&pagetype=entityrecord&etn=msdyn_projecttask&id=5ed1a581-9d40-4c05-87ef-a12902234fc5
Updates 1 config: appConfig, a metadata-only change recording the new
dependency versions. No configs added or deleted.
Dependency versions move from the 2026-07-29 afternoon builds to the
2026-07-30 morning builds. The other 56 dependencies are unchanged.
请注意,消息描述的是差异(软件包同步),而不是工单(账单筛选器)。⚠ 行负责将两者关联起来。
示例(空分支——配置已检出,但从未编辑):
⚠ chore(manufacturing): no changes to commit — branch is empty
Two configurations are checked out on this branch —
manufacturing_order_lines_grid and order_line_manufacturing_confirmation_editor
— but both are identical to base, so there is nothing to commit.
⚠ Branch contains no changes — 2 configs are checked out but identical to base.
The work described by the referenced ticket does not appear to have been saved.
Ref: Case C260714_0012 — Manufacturing orders only look at the Staging Location when consuming materials
https://datexcorp.crm.dynamics.com/main.aspx?appid=ee829a66-fb63-ea11-a811-000d3a37800e&pagetype=entityrecord&etn=incident&id=a670499b-947f-f111-9b47-7ced8d70177e
Updates 0 configs. Both entries in the pending list report has_changes: false;
the only difference from base is the branch-local config row id assigned at
checkout. No configs added or deleted.
The two checked-out configs are exactly the ones the referenced case implicates,
which suggests the work was started in the designer but never saved.
请注意,此处使用的是“无更改”⚠ 行,而不是偏离行——工单引用正确,只是没有实际工作。也没有代码审查行:没有可供审查的差异。
示例(一次性生成——将观察结果写入消息):
与上面的已追溯示例使用同一分支,但在无人值守的情况下生成。关于已关闭工单和同级分支的备注原本会通过聊天发送给用户;一次性生成时,这些备注会写在这里,或者不写。
⚠ feat(pallet-build): accept tote ID alongside cart and job IDs
Extends pallet build with serials so a tote barcode works anywhere a cart or
job number does, moving toward a single barcode carrying the whole flow.
⚠ Referenced ticket is Inactive (closed) and also claims branch 83001 — verify
it is the right reference.
⚠ Recommend running a code review before merging — widening the job lookup in
reset_pickJob_fields makes its silent multi-match early-return more reachable.
Ref: Project Task — Update to use tote ID instead of job ID
https://datexcorp.crm.dynamics.com/main.aspx?appid=ee829a66-fb63-ea11-a811-000d3a37800e&pagetype=entityrecord&etn=msdyn_projecttask&id=3e6b6a20-b38b-4265-b34a-8578f7f53329
Updates 3 configs: two flows (get_orderJob_by_cart, reset_pickJob_fields) and
one hub (pallet_build_with_serials_hub). No configs added or deleted.
Both flows widen their jobs_header predicates to match on toteId in addition to
jobId and cartId, and reset_pickJob_fields now normalizes its inparam to the
real jobId so downstream lookups are unaffected by which barcode was scanned.
请注意,关于已关闭工单和同级分支的两条观察被合并到一条⚠ 行中,而不是分成两条;同时,追溯信息排在代码审查行之前。
通过 SaveCommitMessage 交付后,该消息会映射为:
{
"branch_id": 82931,
"title": "⚠ feat(pallet-build): accept tote ID alongside cart and job IDs",
"description": "⚠ feat(pallet-build): accept tote ID alongside cart and job IDs\n\nExtends pallet build with serials so a tote barcode works anywhere a cart or\njob number does, moving toward a single barcode carrying the whole flow.\n⚠ Referenced ticket is Inactive (closed) and also claims branch 83001 — verify\nit is the right reference.\n⚠ Recommend running a code review before merging — widening the job lookup in\nreset_pickJob_fields makes its silent multi-match early-return more reachable.\nRef: Project Task — Update to use tote ID instead of job ID\nhttps://datexcorp.crm.dynamics.com/main.aspx?...&etn=msdyn_projecttask&id=3e6b6a20-b38b-4265-b34a-8578f7f53329\n\nUpdates 3 configs: two flows (get_orderJob_by_cart, reset_pickJob_fields) and\none hub (pallet_build_with_serials_hub). No configs added or deleted.\n\nBoth flows widen their jobs_header predicates to match on toteId in addition to\njobId and cartId, and reset_pickJob_fields now normalizes its inparam to the\nreal jobId so downstream lookups are unaffected by which barcode was scanned.",
"environment": "production"
}
branch_id 是一个数字。标题出现两次——一次作为 title,一次作为 description 的第一行。三个部分都在 description 中,并以空行分隔,以便之后可以再次拆分。
示例(未追溯分支——MISSING 判定):
⚠ refactor(shipping): consolidate rate lookup into a single flow
Collapses three near-duplicate rate-lookup flows into one parameterized flow
and repoints the four callers at it.
⚠ No ticket reference found — this commit is untraced. Add a Project Task,
Case, or work item link before committing.
Deletes ds_rate_lookup_ltl, ds_rate_lookup_parcel, and ds_rate_lookup_ftl;
adds ds_rate_lookup with a carrier-mode parameter. Four callers updated.
The consolidated flow branches on carrier mode internally, so callers pass a
mode instead of choosing a flow.
提示
- 标题语气——使用祈使语气,遵循 Conventional Commits 风格
(
feat(scope): add X、fix(scope): correct Y、refactor(scope): simplify Z)。 范围可选;当某一领域明显占主导时再使用。 - 不要逐行复述差异——差异本身已经是事实依据。消息的作用是让人能在 30 秒内了解要点。
- 仅涉及依赖项的提交——同步提交表现为没有实质性的配置更改,只有依赖项版本变动。将其描述为“引入依赖项更新:<列表>”。先检查变动方向——
dxs source deps-diff --from <baseBranchId> --to <BRANCH_ID>对任一方向的版本变动都会报告为“已更新”。版本回退意味着基础分支在创建当前分支后已有进展;这是上游偏移,不是当前分支所做的工作,必须从消息中排除。只有向前变动才算同步。dxs source diff --branch <BRANCH_ID>会列出尚未拉取的上游更改,可用于确认偏移。 - 可追溯性是警告,不是门槛——
MISSING判定不会抑制消息。应附上 ⚠ 行照常输出,并由开发者决定。 - 切勿编造工单引用——只引用实际解析到的记录或用户提供的记录。自信地给出错误链接,比坦诚地标注 ⚠ 更糟。
- Project Tasks 没有易读编号——GUID 就是标识符,因此深层链接是唯一可分享的形式。Cases(
C260612_0005)和 Project Requests(PR-260610_003)有易读 ID;如有,优先使用这些 ID。 - 作者归属——分支作者会显示在
branch show输出中;不要在消息中添加作者行(Datex Studio 会在分支本身记录作者)。 - 切勿运行
git commit——Datex Studio 的提交通过平台 UI 完成,而不是通过git。此技能唯一的写入操作是在 Phase 5c 添加cr0c5_commit可追溯性标记;它绝不会修改分支、其配置或仓库。 - 切勿向
commit-ref append传递--allow-duplicate——重复项防护机制可确保在分支上重新运行此技能时的安全性。
常见错误
| 错误 | 修正方法 |
|---|---|
| 假定某个分支 ID 仅仅因为它在会话早些时候出现过就可以使用 | 遵循分支 ID 政策——仅重复使用明确选择的 ID,否则就询问(一轮模式:从提示词中获取,绝不推断) |
| 在一轮模式下提问 | 没人会回答;提问等于悄无声息地失败。根据一轮模式规则作出决定 |
| 在一轮模式下丢失摘要观察结果 | 将它们提升为 ⚠ 行——一轮模式没有第二个渠道 |
| 未经确认就采用搜索命中项 | 一轮模式绝不采用原本需要确认的内容;结论为 MISSING,并列出相近但未匹配的结果 |
| 在一轮模式下生成内容,却不调用交付工具 | 返回文字不等于交付;调用指定工具,如果工具不可用则说明这一点 |
向 SaveCommitMessage 传入 environment: "prod" | 该工具的枚举值为 production | qa | dev;只有 dxs --target 使用 prod |
只将中间部分作为 description 传入 | description 是完整消息——标题、空行、正文。标题重复是有意为之 |
| 因为工具没有 Release Notes 字段而省略它 | 它应放在 description 中的 Description 段落之后,并保留空行 |
| 为提交快照或发布起草消息 | 运行 Phase 2 守卫——分析前检查 isFeatureBranch / isCommit |
将 all_changes 中的一行视为工作已完成的证据 | 检查每条记录的 has_changes;false 表示配置与基准相同 |
读取 changes_by_type | 它始终为空,即使分支有实际更新也是如此——请使用 all_changes |
| 将空分支描述得像是做了什么 | 说明它是空的,使用“无更改”⚠ 行,并跳过代码审查行 |
| 将依赖关系向后移动报告为同步 | 向后 = 分支切出后基准已前进;这是偏移,不要将其纳入 |
| 在差异内容与工单描述不同时仍按工单描述来写 | 消息始终描述差异内容;添加 ⚠ 差异行将二者联系起来 |
| 将工单与差异不匹配的问题藏在聊天摘要中 | 差异必须写入消息——提交的阅读者需要据此发现错误关联 |
运行 git commit 或修改仓库状态 | 唯一获准的写入操作是 Phase 5c 的 cr0c5_commit 标记;绝不触碰分支和仓库 |
在 UNVERIFIED 或 MISSING 结论上添加 cr0c5_commit 标记 | 仅对已解决的 Project Task 添加标记——绝不将猜测写入工单 |
| 在提交正文中逐条列出审查发现 | 只列出主题;将详情交给 branch-code-reviewer,并仅用 ⚠ 标记 |
| 将正则匹配视为有效的工单引用 | 通过适配器解析记录——格式有效的 ID 也可能指向不存在的内容 |
| 因为没有找到工单而拒绝输出消息 | 检查只发出警告,从不阻止;附上 ⚠ 可追溯性行并输出消息 |
在空行之后放置 Ref: | 它会落入 Release Notes,开发者看不到——应将其保留在 Description 段落中 |
| 未确认就根据模糊搜索猜测工单 | 向用户提议候选项;仅采用用户确认的内容 |
未检查可用性就调用 CreateKnowledgeNode | 根据工具是否可用来决定是否执行 Phase 6;如果缺少该工具,则正常跳过 |
默认使用 --target dev/qa | 默认值是 prod;只有用户明确指定环境时才覆盖 |