Custom Field Mapping Guide
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.
Overview
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.
Why Custom Field Mappings?
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 Template Format
Field mapping files are YAML configuration files that define how ADO field names map to canonical field names.
Basic Structure
# 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: Bug
Canonical Field Names
All 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)
Field Validation Rules
- 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-Specific Examples
Scrum Process Template
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: Epic
SAFe Process Template
framework: 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: Bug
Kanban Process Template
framework: 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: Epic
Custom Process 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_type
work_item_type_mappings:
Product Backlog Item: User Story
Requirement: User Story
Issue: Bug
Discovering Available ADO Fields
Before 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:
Method 1: Using Interactive Mapping Command (Recommended)
The easiest way to discover and map ADO fields is using the interactive mapping command:
specfact backlog map-fields --ado-org myorg --ado-project myproject
This 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>
Method 2: Using ADO REST API
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.
Using Custom Field Mappings
Method 1: Interactive Mapping Command (Recommended)
Use the interactive mapping command to create and update field mappings:
specfact backlog map-fields --ado-org myorg --ado-project myproject
This 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 --reset
Automatic 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.
Method 2: CLI Parameter
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 Active
The 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
Method 2: Auto-Detection
Place your custom mapping file at:
.specfact/templates/backlog/field_mappings/ado_custom.yaml
SpecFact CLI will automatically detect and use this file if no --custom-field-mapping parameter is provided.
Method 3: Manually Creating Field Mapping Files
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_mappings
Step 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: Bug
Step 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 Active
YAML 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_type
Agile 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_type
SAFe 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_points
Custom 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_type
Method 4: Environment Variable
Set 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-project
Priority 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)
Default Field Mappings
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.
Built-in Template Files
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.
Validation and Error Handling
File Validation
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)
Common Errors
File Not Found:
Error: Custom field mapping file not found: /path/to/file.yaml
Invalid YAML:
Error: Invalid custom field mapping file: YAML parsing error
Invalid Schema:
Error: Invalid custom field mapping file: Field 'field_mappings' must be a dict
Best Practices
- 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
Integration with Backlog Refinement
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
Troubleshooting
Fields Not Extracted
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
Mapping Not Applied
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:
Interactive Mapping Fails
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
Validation Errors
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)
Work Item Type Not Mapped
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
Related Documentation
- Backlog Refinement Guide - Complete guide to backlog refinement
- ADO Adapter Documentation - ADO adapter patterns
- Field Mapper API Reference - Technical architecture details