classify-work-items
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseclassify-work-items
工作项分类
Turn findings (from + ) into a
that can create. The hard part is typing: an ADO work item
type only exists if the project's process defines it. Get this wrong and creation fails
on the board, so we discover the process before we decide types.
extract-findingstriage-findingsbacklog_input.jsonado-create-work-itemsSchemas live in — read it for the exact
/ shapes. Don't duplicate them here.
references/data-contracts.mdfindings.jsonbacklog_input.json将(来自 + 的)发现转化为文件,供技能创建工作项使用。最关键的部分是类型匹配:只有项目流程中定义的ADO工作项类型才是有效的。如果类型选择错误,工作项创建会在看板上失败,因此我们需要先识别项目流程,再决定使用哪种类型。
extract-findingstriage-findingsbacklog_input.jsonado-create-work-items相关模式定义在中——如需了解/的具体结构,请查阅该文档,此处不再重复。
references/data-contracts.mdfindings.jsonbacklog_input.json1. Discover the project's process and valid types — FIRST
1. 首先:发现项目的流程和有效工作项类型
You cannot pick a type blind. Basic has no and no ; Scrum uses
instead of ; CMMI uses . Picking a type
the board doesn't have is the #1 cause of create failures. So query the process up front.
BugUser StoryProduct Backlog ItemUser StoryRequirementGet a token (see the ado-auth skill — once, then):
az loginpowershell
$org = $env:AZDO_ORG # e.g. Cartagena365
$project = $env:AZDO_PROJECT # e.g. GlassHull
$token = az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv
$headers = @{ Authorization = "Bearer $token" }
$proj = Invoke-RestMethod -Headers $headers `
"https://dev.azure.com/$org/_apis/projects/$project?includeCapabilities=true&api-version=7.1"
$proj.capabilities.processTemplate.templateName # -> Agile | Scrum | Basic | CMMI(With a PAT instead: .)
$headers = @{ Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$env:AZDO_PAT")) }Once you know the process name, use the process→types table in
to map it to valid types. Do not try to the full
payload in PowerShell 5.1 — that response has case-duplicate
keys (e.g. vs ) and the 5.1 parser throws on them. The table is the reliable source.
references/data-contracts.mdConvertFrom-Json/_apis/wit/workitemtypesURLurlIf / aren't set, ask the user which org/project this backlog
targets before going further — the process is project-specific.
AZDO_ORGAZDO_PROJECT不能盲目选择工作项类型。Basic流程没有和;Scrum流程使用而非;CMMI流程使用。选择看板不存在的类型是导致创建失败的首要原因。因此需要提前查询项目流程。
BugUser StoryProduct Backlog ItemUser StoryRequirement获取令牌(请参考ado-auth技能——先执行,再执行以下命令):
az loginpowershell
$org = $env:AZDO_ORG # 示例:Cartagena365
$project = $env:AZDO_PROJECT # 示例:GlassHull
$token = az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv
$headers = @{ Authorization = "Bearer $token" }
$proj = Invoke-RestMethod -Headers $headers `
"https://dev.azure.com/$org/_apis/projects/$project?includeCapabilities=true&api-version=7.1"
$proj.capabilities.processTemplate.templateName # 返回值示例:Agile | Scrum | Basic | CMMI(使用PAT令牌的替代方式:。)
$headers = @{ Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$env:AZDO_PAT")) }确定流程名称后,请使用中的流程→类型映射表来匹配有效类型。请勿尝试在PowerShell 5.1中对完整的响应执行——该响应包含大小写重复的键(如 vs ),5.1版本的解析器会抛出错误。映射表是可靠的数据源。
references/data-contracts.md/_apis/wit/workitemtypesConvertFrom-JsonURLurl如果未设置/环境变量,请先询问用户待办事项对应的组织/项目,流程是项目专属的,确认后再继续操作。
AZDO_ORGAZDO_PROJECT2. Type each finding — the rules, and why
2. 为每个发现匹配类型——规则及原因
Map by the nature of the work, not by the finding's . Using the table for the
discovered process (columns: defect / new capability / grouping parent):
severity-
Wrong, ambiguous, or mismapped existing thing → the defect type (on Agile/Scrum/CMMI). A field that exists but shows the wrong label, or a value that's mislabeled, is a correctness defect — it should be fixed, not "built". Most rename / disambiguation findings (
Bug|kind: rename) land here. Basic has no dedicated defect type — on the Basic process, defects and new capabilities both collapse todisambiguation(its only non-Epic/Task type), matching the table inIssue.data-contracts.md -
A capability that doesn't exist yet (e.g.— a field, view, or feature that's absent) → the new-capability type:
kind: missing(Agile),User Story(Scrum),Product Backlog Item(CMMI),Requirement(Basic). Filing "add a new field/feature" as a Bug is an anti-pattern — it's net-new scope, not a regression, and teams plan/estimate it differently.Issue -
The initiative itself → one grouping parent: a(or
Feature) that all the children link under. This keeps the audit traceable as one body of work rather than a scatter of orphan tickets. See step 4.Epic
When a finding is genuinely ambiguous between defect and new capability, ask the user rather
than guess — the type drives which team queue it lands in.
根据工作的本质而非发现的(严重程度)进行映射。使用已识别流程对应的映射表(列:缺陷 / 新功能 / 分组父项):
severity-
错误、模糊或映射错误的现有内容 → 对应缺陷类型(Agile/Scrum/CMMI流程为)。例如某个字段已存在但显示错误标签,或某个值标签错误,这类属于正确性缺陷,需要修复而非“新建”。大多数重命名/消歧义类发现(
Bug|kind: rename)都归为此类。 Basic流程没有专门的缺陷类型——在Basic流程中,缺陷和新功能都归类为disambiguation(这是除Epic/Task外的唯一类型),与Issue中的映射表一致。data-contracts.md -
尚未存在的功能(例如——缺失的字段、视图或功能) → 对应新功能类型:Agile流程为
kind: missing,Scrum流程为User Story,CMMI流程为Product Backlog Item,Basic流程为Requirement。将“添加新字段/功能”提交为Bug是反模式——这是新增范围,而非回归问题,团队对其规划/估算方式不同。Issue -
整个倡议本身 → 对应一个分组父项:(或
Feature),所有子项都链接到该父项。这样可以将所有工作作为一个整体进行可追溯的审计,而非分散的孤立工单。请参考步骤4。Epic
如果某个发现确实在缺陷和新功能之间存在歧义,请询问用户而非自行猜测——类型决定了工单会进入哪个团队队列。
3. Map severity → Priority
3. 将严重程度映射为优先级
severityMicrosoft.VSTS.Common.Priority| severity | Priority |
|---|---|
| Critical | 1 |
| High | 2 |
| Medium | 3 |
| Low | 4 |
If a finding has no severity, default to (Medium) and note it.
3severityMicrosoft.VSTS.Common.Priority| severity | Priority |
|---|---|
| Critical | 1 |
| High | 2 |
| Medium | 3 |
| Low | 4 |
如果发现没有设置严重程度,默认设为(中等)并标注说明。
34. Build the fields for each item
4. 为每个工作项构建字段
fields- (required) — specific and self-contained. Name the thing and the expected state, e.g.
System.Title, notPortal label "Auto" should display CRM-canonical "Automotive Cargo". Someone scanning the board should understand it without opening it.Fix naming - — semicolon-separated,
System.Tagsform, e.g."initiative; status". Tag the initiative (so the whole batch is filterable) plus the triage status. ADO splits on"naming-audit; crm-portal; review-confirmed".; - — the integer from step 3.
Microsoft.VSTS.Common.Priority - (optional) — a user identity (UPN/email, e.g.
System.AssignedTo). A fresh backlog is usually left unassigned (assigned later in planning), so omit it unless the user wants these owned now — ask them. To assign the whole batch instead of per item, use thename@cartagena.noenv var at create time. An invalid identity fails the dry run, so a typo never reaches the board.AZDO_ASSIGNED_TO - Body — depends on type:
- :
Bug.Microsoft.VSTS.TCM.ReproSteps - /
User Story/Product Backlog Item:RequirementplusSystem.Description.Microsoft.VSTS.Common.AcceptanceCriteria - Basic :
Issueonly — Basic'sSystem.Descriptiondefines neitherIssuenorMicrosoft.VSTS.TCM.ReproSteps, and adding them failsMicrosoft.VSTS.Common.AcceptanceCriteriaat dry run (the very failure this skill exists to prevent).validateOnly
- These body fields are HTML. Escape →
&,&→<,<→>, and use>/<br>for layout. Unescaped<b>/<either render wrong or get stripped. Pull the finding's>/current/expected/recommendationinto the body so the ticket is actionable on its own.notes
Carry the finding's onto every item (top-level , alongside ). That
is the thread back to the source row — echoes it into
and uses it to write the ticket link onto the
right row. Drop it and write-back can't match.
key"key""type"keyado-create-work-itemsbacklog_result.jsonado-writeback-trackingTiny example (one defect item; full shape in ):
references/data-contracts.mdjson
{
"key": "1",
"type": "Bug",
"fields": {
"System.Title": "Portal label \"Auto\" should display CRM-canonical \"Automotive Cargo\"",
"Microsoft.VSTS.Common.Priority": 1,
"System.Tags": "naming-audit; crm-portal; review-confirmed",
"Microsoft.VSTS.TCM.ReproSteps": "<b>Current:</b> Auto<br><b>Expected:</b> Automotive Cargo"
}
}fields- (必填)——具体且独立完整。明确说明对象和预期状态,例如
System.Title,而非Portal标签"Auto"应显示CRM标准名称"Automotive Cargo"。看板浏览者无需打开工单即可理解内容。修复命名 - ——分号分隔的字符串,格式为
System.Tags,例如"倡议名称; 状态"。标记倡议名称(便于筛选整批工单)以及分类状态。ADO会按"naming-audit; crm-portal; review-confirmed"拆分标签。; - ——步骤3中得到的整数值。
Microsoft.VSTS.Common.Priority - (可选)——用户身份(UPN/邮箱,例如
System.AssignedTo)。 新建的待办事项通常不分配负责人(后续规划阶段再分配),因此除非用户要求现在分配,否则请省略该字段——请询问用户。如果要为整批工单统一分配负责人,可以在创建时使用name@cartagena.no环境变量。无效的用户身份会导致试运行失败,因此输入错误永远不会提交到看板。AZDO_ASSIGNED_TO - 正文——取决于类型:
- :使用
Bug字段。Microsoft.VSTS.TCM.ReproSteps - /
User Story/Product Backlog Item:同时使用Requirement和System.Description字段。Microsoft.VSTS.Common.AcceptanceCriteria - Basic流程的:仅使用
Issue字段——Basic流程的System.Description未定义Issue或Microsoft.VSTS.TCM.ReproSteps,添加这些字段会在试运行的Microsoft.VSTS.Common.AcceptanceCriteria环节失败(这正是本技能要避免的问题)。validateOnly
- 这些正文字段为HTML格式。需将转义为
&,&转义为<,<转义为>,并使用>/<br>进行排版。未转义的<b>/<要么显示异常,要么被剥离。将发现中的>/current/expected/recommendation内容融入正文,使工单可独立执行。notes
将发现的保留到每个工作项中(顶级字段,与同级)。该是追溯到源数据行的线索——会将其回显到中,会使用它将工单链接写入对应的数据行。如果丢失该,则无法完成回写匹配。
key"key""type"keyado-create-work-itemsbacklog_result.jsonado-writeback-trackingkey小示例(一个缺陷工作项;完整结构请参考):
references/data-contracts.mdjson
{
"key": "1",
"type": "Bug",
"fields": {
"System.Title": "Portal label \"Auto\" should display CRM-canonical \"Automotive Cargo\"",
"Microsoft.VSTS.Common.Priority": 1,
"System.Tags": "naming-audit; crm-portal; review-confirmed",
"Microsoft.VSTS.TCM.ReproSteps": "<b>Current:</b> Auto<br><b>Expected:</b> Automotive Cargo"
}
}5. Optional: define the grouping parent
5. 可选:定义分组父项
If these findings are one initiative, add a top-level object with a (or
) and its own (, , optional ).
creates the parent first and links every item under it via
. One parent per backlog run.
parentFeatureEpictypefieldsSystem.TitleSystem.TagsPrioritycreate-backlog.csSystem.LinkTypes.Hierarchy-Reverse如果这些发现属于同一个倡议,请添加一个顶级对象,指定(或)类型及其自身的(、、可选的)。会先创建父项,然后通过将所有子项链接到父项。每次待办事项生成流程只创建一个父项。
parentFeatureEpicfieldsSystem.TitleSystem.TagsPrioritycreate-backlog.csSystem.LinkTypes.Hierarchy-Reverse5b. Estimate time — a child Task per item
5b. 估算时间——为每个工作项添加子Task
Attach a time estimate to each item as a child Task that carries the hours. (Agile's
User Story has no hours field — only Story Points — so the hour estimate lives on a Task,
uniformly under every Bug/Story; see .) Add an object per item
(schema in ).
docs/adr/0001estimatereferences/data-contracts.mdEstimate with work-kind anchors, adjusted for the detail. There is no team history to
calibrate from, so anchors are the baseline:
| kind | baseline | bump up when… |
|---|---|---|
| rename (one spot) | 1–2h | appears across many screens / variants |
| rename (multi) | 3–4h | |
| disambiguation / mapping | 4–8h | maps to many CRM fields (e.g. 5) → top of band |
| missing field (UI + submit) | 6–8h | + validation; + compliance/regulatory → +2–4h |
| structural (new column / split) | 4–6h |
Round to whole hours. If an item exceeds ~16h (2 days), propose splitting it instead of
estimating one big block.
Estimate in detail: break each item into steps with hours that sum to the total. Put the
total in the Task's and , and the
breakdown (each step + hours, then the total) as HTML in the Task's .
Microsoft.VSTS.Scheduling.OriginalEstimateRemainingWorkSystem.DescriptionSuggest, then confirm — never silently apply. Show the user a table and wait:
undefined为每个工作项附加时间估算,作为承载时长的子Task。(Agile流程的User Story没有时长字段——只有Story Points,因此时长估算需放在Task中,统一附加在每个Bug/Story下;请参考。)为每个工作项添加对象(结构请参考)。
docs/adr/0001estimatereferences/data-contracts.md使用工作类型基准进行估算,并根据细节调整。由于没有团队历史数据作为校准参考,基准值为基础:
| kind | 基准时长 | 需增加时长的场景… |
|---|---|---|
| rename(单个位置) | 1–2h | 出现在多个页面/变体中 |
| rename(多个位置) | 3–4h | |
| disambiguation / mapping | 4–8h | 映射到多个CRM字段(例如5个)→ 取基准上限 |
| missing field(UI + 提交) | 6–8h | 包含验证逻辑;包含合规/监管要求 → 增加2–4h |
| structural(新增列 / 拆分) | 4–6h |
估算时长取整小时。如果某个工作项的估算时长超过约16h(2天),建议拆分该工作项,而非估算为一个大的时间块。
详细估算: 将每个工作项拆分为多个步骤,各步骤时长之和等于总时长。将总时长填入Task的和字段,并将拆分明细(每个步骤+时长,然后是总时长)以HTML格式填入Task的字段。
Microsoft.VSTS.Scheduling.OriginalEstimateRemainingWorkSystem.Description先建议,再确认——切勿静默应用。向用户展示表格并等待确认:
undefinedType kind Est why
Type kind Est why
6078 User Story missing+comply 8h new field + submit + compliance check
... ────
~41h (~5–6 days)
Let the user adjust any value ("6078 = 6h"), then write the agreed numbers into each item's
`estimate.task`. Optionally set the parent Feature's `Microsoft.VSTS.Scheduling.Effort` to the
batch total so it rolls up on the Feature.6078 User Story missing+comply 8h new field + submit + compliance check
... ────
~41h (~5–6 days)
允许用户调整任意值(例如“6078 = 6h”),然后将确认后的数值写入每个工作项的`estimate.task`中。可选地将父Feature的`Microsoft.VSTS.Scheduling.Effort`设置为整批工单的总时长,以便在Feature层面汇总显示。6. Write backlog_input.json and hand off
6. 生成backlog_input.json并传递
Assemble per the contract and write it (e.g.
next to the findings). / are optional in the file —
/ override them — but include them for clarity.
{ org?, project?, parent?, items: [...] }backlog_input.jsonorgprojectAZDO_ORGAZDO_PROJECTSanity-check before handing off: every item has a , a valid for the discovered
process, a non-empty , and properly escaped HTML in body fields.
keytypeSystem.TitleThen hand off to ado-create-work-items, which dry-runs first (,
) to catch any remaining type/field problems against the live board before a
real run. If a type still fails validation there, the process likely doesn't have it — come
back to step 1.
AZDO_DRY_RUN=truevalidateOnly按照契约组装结构并写入文件(例如在发现文件旁生成)。/在文件中是可选的——/环境变量会覆盖它们,但建议包含以提高清晰度。
{ org?, project?, parent?, items: [...] }backlog_input.jsonorgprojectAZDO_ORGAZDO_PROJECT传递前进行检查:每个工作项都包含、符合已识别流程的有效、非空的,且正文字段为正确转义的HTML格式。
keytypeSystem.Title然后传递给ado-create-work-items技能,该技能会先执行试运行(,),在实际运行前针对实时看板检查是否存在剩余的类型/字段问题。如果试运行中类型仍验证失败,说明流程可能未定义该类型——请回到步骤1重新处理。
AZDO_DRY_RUN=truevalidateOnly