You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(safeoutputs): add dynamic tags with allowed-tags to create/update work item (#420)
* feat(safeoutputs): add dynamic tags with allowed-tags to create/update work item
Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/35468e9f-e355-404b-bfdf-b5f8b34d9d85
Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
* fix(safeoutputs): extract tag_matches_pattern helper and fix case-insensitive prefix matching
- Add shared `pub(crate) fn tag_matches_pattern(tag, pattern)` to
src/safeoutputs/mod.rs; both prefix-wildcard and exact branches are
now fully case-insensitive (fixes the bug where `allowed-tags: ["Agent-*"]`
silently failed to match `"agent-created"`)
- Replace the duplicated inline closures in create_work_item.rs and
update_work_item.rs with calls to the shared helper
- Add unit tests covering case-insensitive prefix wildcard matching in
mod.rs, create_work_item.rs, and update_work_item.rs
Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/82fb0a02-078e-4c88-bf92-f4b0b0464462
Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
* refactor: remove duplicate tag_matches_pattern tests from work item files
Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/82fb0a02-078e-4c88-bf92-f4b0b0464462
Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
Copy file name to clipboardExpand all lines: docs/safe-outputs.md
+4-1Lines changed: 4 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -64,13 +64,15 @@ Creates an Azure DevOps work item.
64
64
**Agent parameters:**
65
65
- `title`- A concise title for the work item (required, must be more than 5 characters)
66
66
- `description`- Work item description in markdown format (required, must be more than 30 characters)
67
+
- `tags`- Tags to apply to the work item (optional list; each tag must not contain a semicolon). May be subject to the `allowed-tags` allowlist. Merged with any static `tags` configured in front matter.
67
68
68
69
**Configuration options (front matter):**
69
70
- `work-item-type` - Work item type (default: "Task")
70
71
- `area-path`- Area path for the work item
71
72
- `iteration-path`- Iteration path for the work item
72
73
- `assignee`- User to assign (email or display name)
73
-
- `tags`- List of tags to apply
74
+
- `tags`- Static list of tags always applied to the work item (regardless of agent input)
75
+
- `allowed-tags` - Allowlist of tags the agent is permitted to use via the `tags` parameter. If empty, any agent-provided tags are accepted. Supports prefix wildcards: entries ending with `*` match by prefix (e.g., `"agent-*"` matches `"agent-created"`, `"agent-review"`, etc.).
74
76
- `custom-fields` - Map of custom field reference names to values (e.g., `Custom.MyField: "value"`)
75
77
- `max` - Maximum number of create-work-item outputs allowed per run (default: 1)
76
78
- `include-stats` - Whether to append agent execution stats to the work item description (default: true)
allowed-tags: [] # Optional — restrict which tags the agent can set (empty = any; supports prefix wildcards like "agent-*")
113
116
```
114
117
115
118
**Security note:** Every field that can be modified requires explicit opt-in (`true`) in the front matter configuration. If the `max` limit is exceeded, additional entries are skipped rather than aborting the entire batch.
/// Work item description in markdown format. Use headings, lists, code blocks, and other markdown formatting. Ensure adequate content > 30 characters.
22
22
pubdescription:String,
23
+
24
+
/// Tags to apply to the work item. May be subject to an operator-configured
25
+
/// allowlist (`allowed-tags` in front matter). Each tag must not contain a
26
+
/// semicolon (ADO uses semicolons as tag separators).
27
+
#[serde(default)]
28
+
pubtags:Vec<String>,
23
29
}
24
30
25
31
implValidateforCreateWorkItemParams{
26
32
fnvalidate(&self) -> anyhow::Result<()>{
27
33
ensure!(self.title.len() > 5);
28
34
ensure!(self.description.len() > 30);
35
+
for tag in&self.tags{
36
+
ensure!(
37
+
!tag.contains(';'),
38
+
"Tag '{}' contains a semicolon, which is not allowed \
39
+
(ADO uses semicolons as tag separators)",
40
+
tag
41
+
);
42
+
}
29
43
Ok(())
30
44
}
31
45
}
@@ -38,13 +52,19 @@ tool_result! {
38
52
pubstructCreateWorkItemResult{
39
53
title:String,
40
54
description:String,
55
+
/// Agent-provided tags (validated against allowed-tags at execution time)
0 commit comments