classify-work-items

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

classify-work-items

工作项分类

Turn findings (from
extract-findings
+
triage-findings
) into a
backlog_input.json
that
ado-create-work-items
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.
Schemas live in
references/data-contracts.md
— read it for the exact
findings.json
/
backlog_input.json
shapes. Don't duplicate them here.
将(来自
extract-findings
+
triage-findings
的)发现转化为
backlog_input.json
文件,供
ado-create-work-items
技能创建工作项使用。最关键的部分是类型匹配:只有项目流程中定义的ADO工作项类型才是有效的。如果类型选择错误,工作项创建会在看板上失败,因此我们需要先识别项目流程,再决定使用哪种类型。
相关模式定义在
references/data-contracts.md
中——如需了解
findings.json
/
backlog_input.json
的具体结构,请查阅该文档,此处不再重复。

1. Discover the project's process and valid types — FIRST

1. 首先:发现项目的流程和有效工作项类型

You cannot pick a type blind. Basic has no
Bug
and no
User Story
; Scrum uses
Product Backlog Item
instead of
User Story
; CMMI uses
Requirement
. Picking a type the board doesn't have is the #1 cause of create failures. So query the process up front.
Get a token (see the ado-auth skill —
az login
once, then):
powershell
$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
references/data-contracts.md
to map it to valid types. Do not try to
ConvertFrom-Json
the full
/_apis/wit/workitemtypes
payload in PowerShell 5.1 — that response has case-duplicate keys (e.g.
URL
vs
url
) and the 5.1 parser throws on them. The table is the reliable source.
If
AZDO_ORG
/
AZDO_PROJECT
aren't set, ask the user which org/project this backlog targets before going further — the process is project-specific.
不能盲目选择工作项类型。Basic流程没有
Bug
User Story
;Scrum流程使用
Product Backlog Item
而非
User Story
;CMMI流程使用
Requirement
。选择看板不存在的类型是导致创建失败的首要原因。因此需要提前查询项目流程。
获取令牌(请参考ado-auth技能——先执行
az login
,再执行以下命令):
powershell
$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")) }
。)
确定流程名称后,请使用
references/data-contracts.md
中的流程→类型映射表
来匹配有效类型。请勿尝试在PowerShell 5.1中对完整的
/_apis/wit/workitemtypes
响应执行
ConvertFrom-Json
——该响应包含大小写重复的键(如
URL
vs
url
),5.1版本的解析器会抛出错误。映射表是可靠的数据源。
如果未设置
AZDO_ORG
/
AZDO_PROJECT
环境变量,请先询问用户待办事项对应的组织/项目,流程是项目专属的,确认后再继续操作。

2. Type each finding — the rules, and why

2. 为每个发现匹配类型——规则及原因

Map by the nature of the work, not by the finding's
severity
. Using the table for the discovered process (columns: defect / new capability / grouping parent):
  • Wrong, ambiguous, or mismapped existing thing → the defect type (
    Bug
    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 (
    kind: rename
    |
    disambiguation
    ) land here. Basic has no dedicated defect type — on the Basic process, defects and new capabilities both collapse to
    Issue
    (its only non-Epic/Task type), matching the table in
    data-contracts.md
    .
  • A capability that doesn't exist yet (e.g.
    kind: missing
    — a field, view, or feature that's absent) → the new-capability type:
    User Story
    (Agile),
    Product Backlog Item
    (Scrum),
    Requirement
    (CMMI),
    Issue
    (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.
  • The initiative itself → one grouping parent: a
    Feature
    (or
    Epic
    ) 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.
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
    |
    disambiguation
    )都归为此类。 Basic流程没有专门的缺陷类型——在Basic流程中,缺陷和新功能都归类为
    Issue
    (这是除Epic/Task外的唯一类型),与
    data-contracts.md
    中的映射表一致。
  • 尚未存在的功能(例如
    kind: missing
    ——缺失的字段、视图或功能) → 对应新功能类型:Agile流程为
    User Story
    ,Scrum流程为
    Product Backlog Item
    ,CMMI流程为
    Requirement
    ,Basic流程为
    Issue
    。将“添加新字段/功能”提交为Bug是反模式——这是新增范围,而非回归问题,团队对其规划/估算方式不同。
  • 整个倡议本身 → 对应一个分组父项
    Feature
    (或
    Epic
    ),所有子项都链接到该父项。这样可以将所有工作作为一个整体进行可追溯的审计,而非分散的孤立工单。请参考步骤4。
如果某个发现确实在缺陷和新功能之间存在歧义,请询问用户而非自行猜测——类型决定了工单会进入哪个团队队列。

3. Map severity → Priority

3. 将严重程度映射为优先级

severity
becomes
Microsoft.VSTS.Common.Priority
(an integer 1–4). Lower number = higher priority, matching ADO:
severityPriority
Critical1
High2
Medium3
Low4
If a finding has no severity, default to
3
(Medium) and note it.
severity
会转化为
Microsoft.VSTS.Common.Priority
(整数1–4)。数值越小优先级越高,与ADO的规则一致:
severityPriority
Critical1
High2
Medium3
Low4
如果发现没有设置严重程度,默认设为
3
(中等)并标注说明。

4. Build the fields for each item

4. 为每个工作项构建字段

fields
are raw ADO reference names (strings or numbers). Build per type:
  • System.Title
    (required) — specific and self-contained. Name the thing and the expected state, e.g.
    Portal label "Auto" should display CRM-canonical "Automotive Cargo"
    , not
    Fix naming
    . Someone scanning the board should understand it without opening it.
  • System.Tags
    — semicolon-separated,
    "initiative; status"
    form, e.g.
    "naming-audit; crm-portal; review-confirmed"
    . Tag the initiative (so the whole batch is filterable) plus the triage status. ADO splits on
    ;
    .
  • Microsoft.VSTS.Common.Priority
    — the integer from step 3.
  • System.AssignedTo
    (optional) — a user identity (UPN/email, e.g.
    name@cartagena.no
    ). 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 the
    AZDO_ASSIGNED_TO
    env var at create time. An invalid identity fails the dry run, so a typo never reaches the board.
  • Body — depends on type:
    • Bug
      :
      Microsoft.VSTS.TCM.ReproSteps
      .
    • User Story
      /
      Product Backlog Item
      /
      Requirement
      :
      System.Description
      plus
      Microsoft.VSTS.Common.AcceptanceCriteria
      .
    • Basic
      Issue
      :
      System.Description
      only — Basic's
      Issue
      defines neither
      Microsoft.VSTS.TCM.ReproSteps
      nor
      Microsoft.VSTS.Common.AcceptanceCriteria
      , and adding them fails
      validateOnly
      at dry run (the very failure this skill exists to prevent).
  • These body fields are HTML. Escape
    &
    &
    ,
    <
    &lt;
    ,
    >
    &gt;
    , and use
    <br>
    /
    <b>
    for layout. Unescaped
    <
    /
    >
    either render wrong or get stripped. Pull the finding's
    current
    /
    expected
    /
    recommendation
    /
    notes
    into the body so the ticket is actionable on its own.
Carry the finding's
key
onto every item
(top-level
"key"
, alongside
"type"
). That
key
is the thread back to the source row —
ado-create-work-items
echoes it into
backlog_result.json
and
ado-writeback-tracking
uses it to write the ticket link onto the right row. Drop it and write-back can't match.
Tiny example (one defect item; full shape in
references/data-contracts.md
):
json
{
  "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
是原始的ADO引用名称(字符串或数字)。需按类型构建:
  • System.Title
    (必填)——具体且独立完整。明确说明对象和预期状态,例如
    Portal标签"Auto"应显示CRM标准名称"Automotive Cargo"
    ,而非
    修复命名
    。看板浏览者无需打开工单即可理解内容。
  • System.Tags
    ——分号分隔的字符串,格式为
    "倡议名称; 状态"
    ,例如
    "naming-audit; crm-portal; review-confirmed"
    。标记倡议名称(便于筛选整批工单)以及分类状态。ADO会按
    ;
    拆分标签。
  • Microsoft.VSTS.Common.Priority
    ——步骤3中得到的整数值。
  • System.AssignedTo
    (可选)——用户身份(UPN/邮箱,例如
    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
      :仅使用
      System.Description
      字段——Basic流程的
      Issue
      未定义
      Microsoft.VSTS.TCM.ReproSteps
      Microsoft.VSTS.Common.AcceptanceCriteria
      ,添加这些字段会在试运行的
      validateOnly
      环节失败(这正是本技能要避免的问题)。
  • 这些正文字段为HTML格式。需将
    &
    转义为
    &amp;
    <
    转义为
    &lt;
    >
    转义为
    &gt;
    ,并使用
    <br>
    /
    <b>
    进行排版。未转义的
    <
    /
    >
    要么显示异常,要么被剥离。将发现中的
    current
    /
    expected
    /
    recommendation
    /
    notes
    内容融入正文,使工单可独立执行。
将发现的
key
保留到每个工作项中
(顶级字段
"key"
,与
"type"
同级)。该
key
是追溯到源数据行的线索——
ado-create-work-items
会将其回显到
backlog_result.json
中,
ado-writeback-tracking
会使用它将工单链接写入对应的数据行。如果丢失该
key
,则无法完成回写匹配。
小示例(一个缺陷工作项;完整结构请参考
references/data-contracts.md
):
json
{
  "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
parent
object with a
Feature
(or
Epic
)
type
and its own
fields
(
System.Title
,
System.Tags
, optional
Priority
).
create-backlog.cs
creates the parent first and links every item under it via
System.LinkTypes.Hierarchy-Reverse
. One parent per backlog run.
如果这些发现属于同一个倡议,请添加一个顶级
parent
对象,指定
Feature
(或
Epic
)类型及其自身的
fields
System.Title
System.Tags
、可选的
Priority
)。
create-backlog.cs
会先创建父项,然后通过
System.LinkTypes.Hierarchy-Reverse
将所有子项链接到父项。每次待办事项生成流程只创建一个父项。

5b. 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
docs/adr/0001
.) Add an
estimate
object per item (schema in
references/data-contracts.md
).
Estimate with work-kind anchors, adjusted for the detail. There is no team history to calibrate from, so anchors are the baseline:
kindbaselinebump up when…
rename (one spot)1–2happears across many screens / variants
rename (multi)3–4h
disambiguation / mapping4–8hmaps 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
Microsoft.VSTS.Scheduling.OriginalEstimate
and
RemainingWork
, and the breakdown (each step + hours, then the total) as HTML in the Task's
System.Description
.
Suggest, then confirm — never silently apply. Show the user a table and wait:
undefined
为每个工作项附加时间估算,作为承载时长的子Task。(Agile流程的User Story没有时长字段——只有Story Points,因此时长估算需放在Task中,统一附加在每个Bug/Story下;请参考
docs/adr/0001
。)为每个工作项添加
estimate
对象(结构请参考
references/data-contracts.md
)。
使用工作类型基准进行估算,并根据细节调整。由于没有团队历史数据作为校准参考,基准值为基础:
kind基准时长需增加时长的场景…
rename(单个位置)1–2h出现在多个页面/变体中
rename(多个位置)3–4h
disambiguation / mapping4–8h映射到多个CRM字段(例如5个)→ 取基准上限
missing field(UI + 提交)6–8h包含验证逻辑;包含合规/监管要求 → 增加2–4h
structural(新增列 / 拆分)4–6h
估算时长取整小时。如果某个工作项的估算时长超过约16h(2天),建议拆分该工作项,而非估算为一个大的时间块。
详细估算: 将每个工作项拆分为多个步骤,各步骤时长之和等于总时长。将总时长填入Task的
Microsoft.VSTS.Scheduling.OriginalEstimate
RemainingWork
字段,并将拆分明细(每个步骤+时长,然后是总时长)以HTML格式填入Task的
System.Description
字段。
先建议,再确认——切勿静默应用。向用户展示表格并等待确认:
undefined

Type 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
{ org?, project?, parent?, items: [...] }
per the contract and write it (e.g.
backlog_input.json
next to the findings).
org
/
project
are optional in the file —
AZDO_ORG
/
AZDO_PROJECT
override them — but include them for clarity.
Sanity-check before handing off: every item has a
key
, a
type
valid for the discovered process, a non-empty
System.Title
, and properly escaped HTML in body fields.
Then hand off to ado-create-work-items, which dry-runs first (
AZDO_DRY_RUN=true
,
validateOnly
) 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.
按照契约组装
{ org?, project?, parent?, items: [...] }
结构并写入文件(例如在发现文件旁生成
backlog_input.json
)。
org
/
project
在文件中是可选的——
AZDO_ORG
/
AZDO_PROJECT
环境变量会覆盖它们,但建议包含以提高清晰度。
传递前进行检查:每个工作项都包含
key
、符合已识别流程的有效
type
、非空的
System.Title
,且正文字段为正确转义的HTML格式。
然后传递给ado-create-work-items技能,该技能会先执行试运行(
AZDO_DRY_RUN=true
validateOnly
),在实际运行前针对实时看板检查是否存在剩余的类型/字段问题。如果试运行中类型仍验证失败,说明流程可能未定义该类型——请回到步骤1重新处理。