Skip to content
atomize
GitHub

Templates

Estimate Tasks

Development docs · main. Your installed version may differ.

Translates the Story Estimate into the Task's unit, then distributes it across Tasks.

estimation:
strategy: "percentage" # How to calculate task points
source: "Custom.TShirtSize" # Optional: Story field holding the Story Estimate
conversion: # Optional: Story unit → Task unit (omit for one-to-one)
table: { S: 2, M: 4, L: 5, XL: 13 } # or `factor: 4` for 1 point = 4 hours
rounding: "nearest" # How to round calculated values
minimumTaskEstimate: 0.5 # Minimum Task Estimate, in the Task's unit
ifParentHasNoEstimation: "use-default" # warn (default) | skip | use-default
defaultParentEstimation: "M" # Story Estimate to assume when the real one is missing

See the estimation field reference for field details, defaults and constraints.

VS Code snippets: type atm-estimation-factor or atm-estimation-table to insert a factor or a size-table configuration, or atm-estimation-target for taskType and targetFields; atm-estimation includes the normalize choice.

Examples: points-to-hours (factor), fibonacci-hours-table (numeric table), tshirt-size-estimation (size field, fractional sizes) and custom-fields-and-task-type (taskType and targetFields); see the examples README for what each produces.

TermMeaningSet with
Story EstimateThe size recorded on a Story, in the Story's own unit: points, a T-shirt size, hours, or any other scale your process uses.source chooses the Story field.
Task EstimateThe effort Atomize writes on each generated Task, in the Task's own unit (hours on Azure DevOps).estimationPercent or estimationFixed on each task.
Estimation ConversionThe rule that translates a Story Estimate into the Task's unit before it is distributed: a factor or a value-by-value table. Without one, the Story Estimate is used one-to-one.conversion
Unresolvable Story EstimateA Story Estimate that is missing, or that the conversion can't translate. Atomize never guesses one.ifParentHasNoEstimation and defaultParentEstimation
Estimation Field MappingWhich Story field supplies the Story Estimate, which Work Item type the Tasks are created as, and which Task fields receive the Task Estimate.source, taskType and targetFields

For each Story, Atomize:

  1. Reads the Story Estimate from the source field, or from the platform's default fields when source is not set.
  2. Converts it to the Task's unit with conversion. A table matches values exactly; with multipliers: true, a value such as 0.3XL is also accepted as 0.3 × the XL entry.
  3. Splits the result across the active tasks by their percentages. When the percentages don't add up to 100%, normalize decides whether they are scaled.
  4. Applies rounding, then minimumTaskEstimate.

Conversion happens before percentage distribution. For example, a 5-point Story with factor: 4 becomes 20 hours; a Task weighted at 20% receives 4 hours before rounding and the minimum. A fixed estimate is written as supplied and bypasses percentage rounding and the minimum.

See the conversion reference and rounding reference for lookup and rounding rules.

If a Story has no estimate, or a conversion table cannot resolve it, Atomize applies the chosen unresolvable-estimate policy; it never guesses a size.

ifParentHasNoEstimationWhat happens
warn (default)The Story's Tasks are created with blank Task Estimates, never 0, and a warning is reported.
skipNo Tasks are created for that Story, and the reason is reported.
use-defaultAtomize uses defaultParentEstimation as the Story Estimate, in the Story's unit, and converts it like a real one. Without a defaultParentEstimation, it behaves like warn.

A defaultParentEstimation must itself be convertible: a number when there is no table, or a table key (including an enabled multiple).

Each platform supplies a default mapping, and a Template can override each part using the platform's own field names:

  • source: the Story field that holds the Story Estimate. It replaces the default fields, with no fallback, so a Story with that field blank has an Unresolvable Story Estimate.
  • taskType: the Work Item type Tasks are created as.
  • targetFields: the Task fields that receive the Task Estimate. They replace all the default writes, and values are written exactly as calculated.

On Azure DevOps, the Story Estimate defaults to the first of Microsoft.VSTS.Scheduling.StoryPoints, Effort, Size and OriginalEstimate that has a value; Tasks are created as Task; and the Task Estimate is written to RemainingWork and OriginalEstimate, with CompletedWork set to 0. See Task Creation for every field Atomize writes on Azure DevOps.

Online Validation (atomize validate --profile <name>, or Online in VS Code) checks estimation overrides against the project:

  • Errors: source is missing on a filtered Story type; taskType does not exist; a targetFields entry is missing on the child type or is not numeric.
  • Warnings (errors in strict mode): picklist values of source that conversion.table does not cover; table keys that are not allowed values (often typos); a source field that accepts free text or is a suggested picklist, because values outside the table leave Task Estimates blank; numeric operators on estimation when source holds text.

When creating tasks, Atomize sets these fields:

# Task definition
tasks:
- title: "Implement API"
description: "Implementation details"
estimationPercent: 40
tags: ["backend", "api"]
activity: "Development"
assignTo: "john@company.com"
priority: 2

Maps to Azure DevOps fields:

  • System.Title ← title
  • System.Description ← description
  • Microsoft.VSTS.Scheduling.RemainingWork and Microsoft.VSTS.Scheduling.OriginalEstimate ← the Task Estimate (see below); Microsoft.VSTS.Scheduling.CompletedWork is set to 0
  • System.Tags ← tags (joined with "; ")
  • Microsoft.VSTS.Common.Activity ← activity
  • System.AssignedTo ← assignTo
  • Microsoft.VSTS.Common.Priority ← priority

Tasks are created as the Task work item type unless the Template sets taskType.

  1. Read the Story Estimate. Without estimation.source, Atomize uses the first of these fields that has a value: Microsoft.VSTS.Scheduling.StoryPoints (Agile), Microsoft.VSTS.Scheduling.Effort (Scrum), Microsoft.VSTS.Scheduling.Size (CMMI), then Microsoft.VSTS.Scheduling.OriginalEstimate (Stories estimated directly in hours). With estimation.source set, only that field is read, with no fallback. It can be any writable number field, or a single-line text or picklist field such as a T-shirt size.
  2. Convert it to hours. estimation.conversion applies a factor (e.g. 1 point = 4 hours) or a table (e.g. L: 20). With multipliers: true, values such as 0.3XL are also accepted. Without a conversion, a numeric Story Estimate is used as hours one-to-one.
  3. Split it across the tasks by estimationPercent. If the percentages don't add up to 100%, estimation.normalize decides whether they are scaled. Then rounding and minimumTaskEstimate are applied.

When a Story has no estimate, or its value isn't covered by the conversion, its tasks are still created with blank estimates and a warning is reported. Set ifParentHasNoEstimation: skip to skip the Story instead, or use-default together with defaultParentEstimation.

To write the estimate somewhere else, set estimation.targetFields. It replaces the default fields: the value is written as calculated, and CompletedWork is left alone. Target fields must be writable number fields that aren't picklists; Online Validation reports anything else as an error. When you pick target fields in the CLI wizard, System.* fields and fields in Microsoft.VSTS.Common.* (priority, stack rank, business value, ...) are left out, because those don't hold effort. If you type one in, Online Validation warns.

See the estimation field reference for every option.

To change a task’s percentage for some Stories, use conditional estimation.