| layout | default |
|---|---|
| title | Custom Field Mapping Guide |
| permalink | /guides/custom-field-mapping/ |
Customize ADO field mappings for your specific Azure DevOps process templates and agile frameworks.
This guide explains how to create and use custom field mapping configurations to adapt SpecFact CLI to your organization's specific Azure DevOps field names and work item types.
SpecFact CLI uses field mappers to normalize provider-specific field structures (GitHub markdown, ADO fields) into canonical field names that work across all providers. For Azure DevOps, you can customize these mappings to match your specific process template.
Different Azure DevOps organizations use different process templates (Scrum, SAFe, Kanban, Basic, or custom templates) with varying field names:
- Scrum: Uses
Microsoft.VSTS.Scheduling.StoryPoints - Agile: Uses
Microsoft.VSTS.Common.StoryPoints - Custom Templates: May use completely different field names like
Custom.StoryPointsorMyCompany.Effort
Custom field mappings allow you to:
- Map your organization's custom ADO fields to canonical field names
- Support multiple agile frameworks (Scrum, SAFe, Kanban)
- Normalize work item type names across different process templates
- Maintain compatibility with SpecFact CLI's backlog refinement features
Field mapping files are YAML configuration files that define how ADO field names map to canonical field names.
# Framework identifier (scrum, safe, kanban, agile, default)
framework: scrum
# Field mappings: ADO field name -> canonical field name
field_mappings:
System.Description: description
System.AcceptanceCriteria: acceptance_criteria
Custom.StoryPoints: story_points
Custom.BusinessValue: business_value
Custom.Priority: priority
System.WorkItemType: work_item_type
# Work item type mappings: ADO work item type -> canonical work item type
work_item_type_mappings:
Product Backlog Item: User Story
User Story: User Story
Feature: Feature
Epic: Epic
Task: Task
Bug: BugAll field mappings must map to these canonical field names:
description: Main description/content of the backlog itemacceptance_criteria: Acceptance criteria for the itemstory_points: Story points estimate (0-100 range, Scrum/SAFe)business_value: Business value estimate (0-100 range, Scrum/SAFe)priority: Priority level (1-4 range, 1=highest, all frameworks)value_points: Value points (SAFe-specific, calculated from business_value / story_points)work_item_type: Work item type (Epic, Feature, User Story, Task, Bug, etc., framework-aware)
- Story Points: Must be in range 0-100 (automatically clamped)
- Business Value: Must be in range 0-100 (automatically clamped)
- Priority: Must be in range 1-4, where 1=highest (automatically clamped)
- Value Points: Automatically calculated as
business_value / story_pointsif both are present
framework: scrum
field_mappings:
System.Description: description
System.AcceptanceCriteria: acceptance_criteria
Microsoft.VSTS.Scheduling.StoryPoints: story_points
Microsoft.VSTS.Common.BusinessValue: business_value
Microsoft.VSTS.Common.Priority: priority
System.WorkItemType: work_item_type
System.IterationPath: iteration
System.AreaPath: area
work_item_type_mappings:
Product Backlog Item: User Story
Bug: Bug
Task: Task
Epic: Epicframework: safe
field_mappings:
System.Description: description
System.AcceptanceCriteria: acceptance_criteria
Microsoft.VSTS.Scheduling.StoryPoints: story_points
Microsoft.VSTS.Common.BusinessValue: business_value
Microsoft.VSTS.Common.Priority: priority
System.WorkItemType: work_item_type
# SAFe-specific fields
Microsoft.VSTS.Common.ValueArea: value_points
work_item_type_mappings:
Epic: Epic
Feature: Feature
User Story: User Story
Task: Task
Bug: Bugframework: kanban
field_mappings:
System.Description: description
System.AcceptanceCriteria: acceptance_criteria
Microsoft.VSTS.Common.Priority: priority
System.WorkItemType: work_item_type
System.State: state
# Kanban doesn't require story points, but may have them
Microsoft.VSTS.Scheduling.StoryPoints: story_points
work_item_type_mappings:
User Story: User Story
Task: Task
Bug: Bug
Feature: Feature
Epic: Epicframework: default
field_mappings:
System.Description: description
Custom.AcceptanceCriteria: acceptance_criteria
Custom.StoryPoints: story_points
Custom.BusinessValue: business_value
Custom.Priority: priority
System.WorkItemType: work_item_type
work_item_type_mappings:
Product Backlog Item: User Story
Requirement: User Story
Issue: BugBefore creating custom field mappings, you need to know which fields are available in your Azure DevOps project. There are two ways to discover available fields:
The easiest way to discover and map ADO fields is using the interactive mapping command:
specfact backlog map-fields --ado-org myorg --ado-project myprojectThis command will:
- Fetch all available fields from your Azure DevOps project
- Filter out system-only fields automatically
- Pre-populate default mappings from
AdoFieldMapper.DEFAULT_FIELD_MAPPINGS - Prefer
Microsoft.VSTS.Common.*fields overSystem.*fields for better compatibility - Use regex/fuzzy matching to suggest potential matches when no default exists
- Display an interactive menu with arrow-key navigation (↑↓ to navigate, Enter to select)
- Pre-select the best match (existing custom > default > fuzzy match > "")
- Guide you through mapping ADO fields to canonical field names
- Validate the mapping before saving
- Save the mapping to
.specfact/templates/backlog/field_mappings/ado_custom.yaml
Interactive Menu Navigation:
- Use ↑ (Up arrow) and ↓ (Down arrow) to navigate through available ADO fields
- Press Enter to select a field
- The menu shows all available ADO fields in a scrollable list
- Default mappings are pre-selected automatically
- Fuzzy matching suggests relevant fields when no default mapping exists
Example Output:
Fetching fields from Azure DevOps...
✓ Loaded existing mapping from .specfact/templates/backlog/field_mappings/ado_custom.yaml
Interactive Field Mapping
Map ADO fields to canonical field names.
Description (canonical: description)
Current mapping: System.Description
Available ADO fields:
> System.Description (Description) [default - pre-selected]
Microsoft.VSTS.Common.AcceptanceCriteria (Acceptance Criteria)
Microsoft.VSTS.Common.StoryPoints (Story Points)
Microsoft.VSTS.Scheduling.StoryPoints (Story Points)
...
<no mapping>You can also discover available fields directly from the Azure DevOps REST API:
Step 1: Get your Azure DevOps PAT (Personal Access Token)
- Go to:
https://dev.azure.com/{org}/_usersSettings/tokens - Create a new token with "Work Items (Read)" permission
Step 2: Fetch fields using curl or HTTP client
# Replace {org}, {project}, and {token} with your values
curl -u ":{token}" \
"https://dev.azure.com/{org}/{project}/_apis/wit/fields?api-version=7.1" \
| jq '.value[] | {referenceName: .referenceName, name: .name}'Step 3: Identify field names from API response
The API returns a JSON array with field information:
{
"value": [
{
"referenceName": "System.Description",
"name": "Description",
"type": "html"
},
{
"referenceName": "Microsoft.VSTS.Common.AcceptanceCriteria",
"name": "Acceptance Criteria",
"type": "html"
}
]
}Common ADO Field Names by Process Template:
- Scrum:
Microsoft.VSTS.Scheduling.StoryPoints,System.AcceptanceCriteria - Agile:
Microsoft.VSTS.Common.StoryPoints,System.AcceptanceCriteria - SAFe:
Microsoft.VSTS.Scheduling.StoryPoints,Microsoft.VSTS.Common.AcceptanceCriteria - Custom Templates: May use
Custom.*prefix (e.g.,Custom.StoryPoints,Custom.AcceptanceCriteria)
Note: The field Microsoft.VSTS.Common.AcceptanceCriteria is commonly used in many ADO process templates, while System.AcceptanceCriteria is less common. SpecFact CLI supports both by default and prefers Microsoft.VSTS.Common.* fields over System.* fields when multiple alternatives exist for better compatibility across different ADO process templates.
Use the interactive mapping command to create and update field mappings:
specfact backlog map-fields --ado-org myorg --ado-project myprojectThis command:
- Fetches available fields from your ADO project
- Shows current mappings (if they exist)
- Guides you through mapping each canonical field
- Validates the mapping before saving
- Saves to
.specfact/templates/backlog/field_mappings/ado_custom.yaml
Options:
--ado-org: Azure DevOps organization (required)--ado-project: Azure DevOps project (required)--ado-token: Azure DevOps PAT (optional, uses token resolution priority: explicit > env var > stored token)--reset: Reset custom field mapping to defaults (deletesado_custom.yamland restores default mappings)--ado-base-url: Azure DevOps base URL (defaults tohttps://dev.azure.com)
Token Resolution:
The command automatically uses stored tokens from specfact auth azure-devops if available. Token resolution priority:
- Explicit
--ado-tokenparameter AZURE_DEVOPS_TOKENenvironment variable- Stored token via
specfact auth azure-devops - Expired stored token (with warning and options to refresh)
Examples:
# Uses stored token automatically (recommended)
specfact backlog map-fields --ado-org myorg --ado-project myproject
# Override with explicit token
specfact backlog map-fields --ado-org myorg --ado-project myproject --ado-token your_token_here
# Reset to default mappings
specfact backlog map-fields --ado-org myorg --ado-project myproject --resetAutomatic Usage:
After creating a custom mapping, it is automatically used by all subsequent backlog operations in that directory. No restart or additional configuration needed. The AdoFieldMapper automatically detects and loads .specfact/templates/backlog/field_mappings/ado_custom.yaml if it exists.
Use the --custom-field-mapping option when running the refine command:
Use the --custom-field-mapping option when running the refine command:
specfact backlog refine ado \
--ado-org my-org \
--ado-project my-project \
--custom-field-mapping /path/to/ado_custom.yaml \
--state ActiveThe CLI will:
- Validate the file exists and is readable
- Validate the YAML format and schema
- Set it as an environment variable for the converter to use
- Display a success message if validation passes
Place your custom mapping file at:
.specfact/templates/backlog/field_mappings/ado_custom.yamlSpecFact CLI will automatically detect and use this file if no --custom-field-mapping parameter is provided.
You can also create field mapping files manually by editing YAML files directly.
Step 1: Create the directory structure
mkdir -p .specfact/templates/backlog/field_mappingsStep 2: Create ado_custom.yaml file
Create a new file .specfact/templates/backlog/field_mappings/ado_custom.yaml with the following structure:
# Framework identifier (scrum, safe, kanban, agile, default)
framework: default
# Field mappings: ADO field name -> canonical field name
field_mappings:
System.Description: description
Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria
Microsoft.VSTS.Scheduling.StoryPoints: story_points
Microsoft.VSTS.Common.BusinessValue: business_value
Microsoft.VSTS.Common.Priority: priority
System.WorkItemType: work_item_type
# Work item type mappings: ADO work item type -> canonical work item type
work_item_type_mappings:
Product Backlog Item: User Story
User Story: User Story
Feature: Feature
Epic: Epic
Task: Task
Bug: BugStep 3: Validate the YAML file
Use a YAML validator or test with SpecFact CLI:
# The refine command will validate the file automatically
specfact backlog refine ado --ado-org myorg --ado-project myproject --state ActiveYAML Schema Reference:
framework(string, optional): Framework identifier (scrum,safe,kanban,agile,default)field_mappings(dict, required): Mapping from ADO field names to canonical field names- Keys: ADO field reference names (e.g.,
System.Description,Microsoft.VSTS.Common.AcceptanceCriteria) - Values: Canonical field names (
description,acceptance_criteria,story_points,business_value,priority,work_item_type)
- Keys: ADO field reference names (e.g.,
work_item_type_mappings(dict, optional): Mapping from ADO work item types to canonical work item types- Keys: ADO work item type names (e.g.,
Product Backlog Item,User Story) - Values: Canonical work item type names (e.g.,
User Story,Feature,Epic)
- Keys: ADO work item type names (e.g.,
Examples for Different ADO Process Templates:
Scrum Template:
framework: scrum
field_mappings:
System.Description: description
System.AcceptanceCriteria: acceptance_criteria
Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria # Alternative
Microsoft.VSTS.Scheduling.StoryPoints: story_points
Microsoft.VSTS.Common.BusinessValue: business_value
Microsoft.VSTS.Common.Priority: priority
System.WorkItemType: work_item_typeAgile Template:
framework: agile
field_mappings:
System.Description: description
Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria
Microsoft.VSTS.Scheduling.StoryPoints: story_points
Microsoft.VSTS.Common.BusinessValue: business_value
Microsoft.VSTS.Common.Priority: priority
System.WorkItemType: work_item_typeSAFe Template:
framework: safe
field_mappings:
System.Description: description
Microsoft.VSTS.Common.AcceptanceCriteria: acceptance_criteria
Microsoft.VSTS.Scheduling.StoryPoints: story_points
Microsoft.VSTS.Common.BusinessValue: business_value
Microsoft.VSTS.Common.Priority: priority
System.WorkItemType: work_item_type
Microsoft.VSTS.Common.ValueArea: value_pointsCustom Template:
framework: default
field_mappings:
System.Description: description
Custom.AcceptanceCriteria: acceptance_criteria
Custom.StoryPoints: story_points
Custom.BusinessValue: business_value
Custom.Priority: priority
System.WorkItemType: work_item_typeSet the SPECFACT_ADO_CUSTOM_MAPPING environment variable:
export SPECFACT_ADO_CUSTOM_MAPPING=/path/to/ado_custom.yaml
specfact backlog refine ado --ado-org my-org --ado-project my-projectPriority Order:
- CLI parameter (
--custom-field-mapping) - highest priority - Environment variable (
SPECFACT_ADO_CUSTOM_MAPPING) - Auto-detection from
.specfact/templates/backlog/field_mappings/ado_custom.yaml(created byspecfact initorspecfact backlog map-fields)
If no custom mapping is provided, SpecFact CLI uses default mappings that work with most standard ADO process templates:
System.Description→descriptionSystem.AcceptanceCriteria→acceptance_criteriaMicrosoft.VSTS.Common.AcceptanceCriteria→acceptance_criteria(alternative, commonly used)Microsoft.VSTS.Common.StoryPoints→story_pointsMicrosoft.VSTS.Scheduling.StoryPoints→story_points(alternative)Microsoft.VSTS.Common.BusinessValue→business_valueMicrosoft.VSTS.Common.Priority→prioritySystem.WorkItemType→work_item_type
Multiple Field Alternatives: SpecFact CLI supports multiple ADO field names mapping to the same canonical field. For example, both System.AcceptanceCriteria and Microsoft.VSTS.Common.AcceptanceCriteria can map to acceptance_criteria. The mapper will check all alternatives and use the first found value.
Custom mappings override defaults. If a field is mapped in your custom file, it will be used instead of the default.
SpecFact CLI includes built-in field mapping templates for common frameworks:
ado_default.yaml: Generic mappings for most ADO templatesado_scrum.yaml: Scrum-specific mappingsado_agile.yaml: Agile-specific mappingsado_safe.yaml: SAFe-specific mappingsado_kanban.yaml: Kanban-specific mappings
These are located in resources/templates/backlog/field_mappings/ and can be used as reference when creating your custom mappings.
The CLI validates custom mapping files before use:
- File Existence: File must exist and be readable
- YAML Format: File must be valid YAML
- Schema Validation: File must match
FieldMappingConfigschema (Pydantic validation)
File Not Found:
Error: Custom field mapping file not found: /path/to/file.yamlInvalid YAML:
Error: Invalid custom field mapping file: YAML parsing errorInvalid Schema:
Error: Invalid custom field mapping file: Field 'field_mappings' must be a dict- Start with Defaults: Use the built-in template files as a starting point
- Test Incrementally: Add custom mappings one at a time and test
- Version Control: Store custom mapping files in your repository
- Document Custom Fields: Document any custom ADO fields your organization uses
- Framework Alignment: Set the
frameworkfield to match your agile framework - Work Item Type Mapping: Map your organization's work item types to canonical types
Custom field mappings work seamlessly with backlog refinement:
- Field Extraction: Custom mappings are used when extracting fields from ADO work items
- Field Display: Extracted fields (story_points, business_value, priority) are displayed in refinement output
- Field Validation: Fields are validated according to canonical field rules (0-100 for story_points, 1-4 for priority)
- Writeback: Fields are mapped back to ADO format using the same custom mappings
If fields are not being extracted:
- Check Field Names: Verify the ADO field names in your mapping match exactly (case-sensitive)
- Use
specfact backlog map-fieldsto discover the exact field names in your project - Or use the ADO REST API to fetch available fields
- Use
- Check Work Item Type: Some fields may only exist for certain work item types
- Test with different work item types (User Story, Feature, Epic)
- Check Multiple Alternatives: Some fields have multiple names (e.g.,
System.AcceptanceCriteriavsMicrosoft.VSTS.Common.AcceptanceCriteria)- Add both alternatives to your mapping if needed
- SpecFact CLI checks all alternatives and uses the first found value
- Test with Defaults: Try without custom mapping to see if defaults work
- Check Logs: Enable verbose logging to see field extraction details
- Verify API Response: Check the raw ADO API response to see which fields are actually present
If your custom mapping is not being applied:
- Check File Location: Ensure the mapping file is in the correct location:
.specfact/templates/backlog/field_mappings/ado_custom.yaml(auto-detection)- Or use
--custom-field-mappingto specify a custom path
- Validate YAML Syntax: Use a YAML validator to check syntax
- Common issues: incorrect indentation, missing colons, invalid characters
- Check File Permissions: Ensure the file is readable
- Verify Schema: Ensure the file matches the
FieldMappingConfigschema- Required:
field_mappings(dict) - Optional:
framework(string),work_item_type_mappings(dict)
- Required:
If the interactive mapping command (specfact backlog map-fields) fails:
-
Check Token Resolution: The command uses token resolution priority:
- First: Explicit
--ado-tokenparameter - Second:
AZURE_DEVOPS_TOKENenvironment variable - Third: Stored token via
specfact auth azure-devops - Fourth: Expired stored token (shows warning with options)
Solutions:
- Use
--ado-tokento provide token explicitly - Set
AZURE_DEVOPS_TOKENenvironment variable - Store token:
specfact auth azure-devops --pat your_pat_token - Re-authenticate:
specfact auth azure-devops
- First: Explicit
-
Check ADO Connection: Verify you can connect to Azure DevOps
- Test with:
curl -u ":{token}" "https://dev.azure.com/{org}/{project}/_apis/wit/fields?api-version=7.1"
- Test with:
-
Verify Permissions: Ensure your PAT has "Work Items (Read)" permission
-
Check Token Expiration: OAuth tokens expire after ~1 hour
- Use PAT token for longer expiration (up to 1 year):
specfact auth azure-devops --pat your_pat_token
- Use PAT token for longer expiration (up to 1 year):
-
Verify Organization/Project: Ensure the org and project names are correct
- Check for typos in organization or project names
-
Check Base URL: For Azure DevOps Server (on-premise), use
--ado-base-urloption -
Reset to Defaults: If mappings are corrupted, use
--resetto restore defaults:specfact backlog map-fields --ado-org myorg --ado-project myproject --reset
If you see validation errors:
- Check YAML Syntax: Use a YAML validator to check syntax
- Check Schema: Ensure all required fields are present
- Check Field Types: Ensure field values match expected types (strings, integers)
If work item types are not being normalized:
- Add to
work_item_type_mappings: Add your work item type to the mappings section - Check Case Sensitivity: Work item type names are case-sensitive
- Use Default: If not mapped, the original work item type is used
- Backlog Refinement Guide - Complete guide to backlog refinement
- ADO Adapter Documentation - ADO adapter patterns
- Field Mapper API Reference - Technical architecture details