Configuration reference

Complete config.yml reference for Jira and ClickUp providers, teams, metrics, QHS, and targets.

config.yml is the only file customers edit. Comments in the repo’s config.yml are the detailed inline reference.

Top-level keys

KeyRequiredDescription
providerYesjira or clickup
teamsYesSquad list (max 10)
jira / clickupYesAPI credentials
customer_nameNoLabel in logs and /health
metricsYesWorkflow, bugs, FTPR, optional QHS/targets

Teams

teams:
  - name: Backend
    jira:
      project_key: BE
    clickup:
      folder_id: "16615923"
      list_ids: ["198503460"]
      routing:
        squad_value: Backend
        extra_tags: [backend_squad]
    metrics:          # optional per-squad override
      jira:
        workflow:
          cycle_start_statuses: [Development]
      exclusions:
        title_keywords: ["WIP |"]
        tags: [skip_metrics]
        task_ids: ["abc123"]

Shorthand keys: jira_project, clickup_list_id, clickup_list_ids, clickup_folder_id, clickup_space_id

Each name becomes a team tab.

Jira credentials

jira:
  url: https://acme.atlassian.net
  email: pulse-bot@acme.com
  token: ""

ClickUp credentials

clickup:
  token: ""
  workspace: "12345678"

workspace is the ClickUp Team ID. Pulse validates it with GET /team/{workspace} on the first API call.


Jira configuration

metrics.jira.workflow

KeyPurpose
cycle_start_statusesWhen cycle time starts (default: In Progress)
cycle_end_statusesOptional explicit cycle end (default: use done)
lead_start_statusesLead time start (default: ticket created)
lead_end_statusesDone statuses
qa_in_progress_statusesExact statuses counted for Avg Time in QA
qa_in_progress_containsSubstring match for QA/test columns
qa_ready_statusesQueue before QA, audit/info only, not avg QA time
qa_ready_containsSubstring match for ready-QA columns
bottleneck_exclude_statusesExact statuses omitted from Bottleneck Index
bottleneck_exclude_prefixesPrefix exclusions (done, closed, complete, …)
status_orderBoard column order for FTPR backward-move detection

Status names are case-insensitive.

Cycle time vs lead time: These are independent. Lead time uses created (or lead_start_statuses, or ClickUp start/due dates) through done. Cycle time only starts when status history shows the ticket entered cycle_start_statuses (for example In Progress). A completed ticket can have lead time but a blank cycle time if it was closed without ever entering that status (common for bugs closed from backlog, or when status names in history do not match config). Blank cycle does not mean a sync error.

metrics.jira.ftpr

KeyPurpose
reopen_statusesMoving to these after Done = FTPR fail
fail_labelsJira labels that force fail

Default: backward move in status_order after first cycle_start_statuses, or reopen after Done.

metrics.jira.bugs

bugs:
  task_types: [Bug]           # Software projects
  tags: [bug]                 # Jira labels, JSM, label-based bugs
  title_keywords: ["[Bug]"]   # title contains
  title_prefix: "BUG |"       # alias for title_keywords

A ticket is a bug if any rule matches.

metrics.jira.subtasks

subtasks:
  include: false
  issue_types: [Sub-task, Subtask]

Default: JQL adds parent is EMPTY.

metrics.jira.custom_fields

custom_fields:
  ticket_size_field: Story Points
  ticket_size_value_map: "0=XS, 1=S, 2=M, 3=L, 4=XL, 5=XXL"
  ticket_size_order: [XS, S, M, L, XL, XXL]
  urgency_field: Priority
  urgency_value_map: ""
  urgency_order: [Low, Normal, High, Critical]

Resolved by display name via /rest/api/3/field. Duplicate names → Config audit warning/error (never silent guess). Supports number, select, and ADF text fields.

Bugs by priority and bug lead by urgency (Jira and ClickUp): one source per workspace. If urgency_field is empty, charts use Jira native priority. If urgency_field is set, charts use only that field; issues with no value count as Unknown (native priority is not used as a fallback).

metrics.jira.flow

flow:
  work_statuses: [In Progress, QA In Progress, In Review]
  wait_statuses: [To Do, Ready for test, Blocked]

Powers flow efficiency and status distribution charts.

Jira fetch scope

  • Tickets resolved or created in the date range
  • Plus open bugs (created before range end, not resolved before range start)
  • Does not use Jira’s updated field (avoids stale tickets from comment-only edits)
  • Changelog fetched selectively when needed (PULSE_JIRA_CHANGELOG_WORKERS, default 5)

ClickUp configuration

Squad source (at least one per team)

KeyPurpose
list_idSingle home list
list_idsMultiple lists
folder_idExpands to all lists in folder
space_idExpands folderless lists + all folder lists in space

teams[].clickup.routing

KeyPurpose
squad_valueDropdown option for this squad (only when use_squad_field: true)
squad_fieldOptional per-squad override of the custom dropdown field name
extra_tagsTag identity match
locationsLocation name match (case-insensitive)
location_idsLocation ID match
location_nameSubstring in location name
list_namesExact list name match
title_keywordsTitle prefix match
use_title_keywordsApply title keywords (default false, last-resort fallback)
product_support_list_idsShared support lists. still needs tag/title/location match

Routing order (when multi_squad: false, strongest match wins):

  1. Tags, locations, list names (identity)
  2. Explicit list_ids / folder_id / space_id
  3. Squad dropdown, only when use_squad_field: true and multiple squads share the same list/folder
  4. Title keywords (when use_title_keywords: true)

metrics.clickup.routing

routing:
  multi_squad: false
  use_squad_field: false   # default; set true when squads share a ClickUp folder/list
  squad_field: Squad         # default dropdown label (global fallback)
  squad_field_by_space:      # optional: different field name per ClickUp space_id
    "12345678": Squad
  cross_squad_value: Cross-squad   # optional shared-pool dropdown value

squad_field is the display name of your custom dropdown in ClickUp (not a built-in field). Pulse resolves it in order: per-squad routing.squad_field, then squad_field_by_space[space_id], then global squad_field. Custom fields in ClickUp are created per Space, Folder, or List, so the label can differ per space.

Bad folder_id or space_id values surface as errors in the Config audit panel (not silent empty squads).

metrics.clickup.workflow

Same keys as Jira, plus:

KeyPurpose
cycle_start_fallbackWhen ticket never entered cycle start: none (default), flow_work, first_history, created

metrics.clickup.ftpr

ftpr:
  fail_tags: [ftpr-fail]
  assume_pass_without_fail_tag: true   # default

Grouped by completion month by default (same as throughput/cycle). Set metrics.clickup.ftpr.group_by: due_date to bucket by due-date month instead; tickets without a due date are then excluded from FTPR. Requires fail-tag automations.

Bug reopen rate uses status history (not fail tags): a bug counts as reopened when it leaves a done status after the first completion. Needs lead_end_statuses aligned with your done columns and status data from bulk_time_in_status.

metrics.clickup.bugs

bugs:
  tags: [bug]
  title_prefix: "BUG |"
  title_keywords: [defect]
  custom_item_types: [Bug]

metrics.clickup.custom_fields

custom_fields:
  ticket_size_field: Story Points
  urgency_field: ""          # empty = native ClickUp priority for bug charts
  urgency_order: [Low, Normal, High, Critical]
  urgency_value_map: ""      # optional aliases, e.g. 1=Low, 2=Normal

Bugs by priority and bug lead by urgency use one source for the whole workspace, never a mix per ticket:

  1. urgency_field empty (default): bucket by ClickUp native priority (Urgent / High / Normal / Low).
  2. urgency_field set: bucket by that custom dropdown only. Tickets with the field empty count as Unknown. Native priority is ignored.

Both charts follow the same rule. Leave urgency_field empty unless your squad consistently fills the custom dropdown on bugs.

The name must match ClickUp exactly (emoji prefixes included). Pulse does not create or assume a custom urgency field for you.

ClickUp fetch architecture

  1. Global pool, one fetch for all squads’ list IDs (parallel, default 6 workers)
  2. Completed tasks via date_done_gt + open tasks for bug backlog
  3. bulk_time_in_status batched (100 IDs per call) for cycle/lead/QA/FTPR-adjacent timing
  4. Per-squad routing filters the pool

Tune: PULSE_CLICKUP_PARALLEL (can only lower the plan worker cap), PULSE_CACHE_TTL_SECONDS (default 300)

Shared configuration

metrics.exclusions (global)

KeyPurpose
issue_typesJira types to drop (default: [Epic, Spike], set [] to include)
tagsTag/label exclusion
title_keywordsTitle substring exclusion
list_idsClickUp list IDs skipped before routing

teams[].metrics.exclusions (squad-only)

Same as global, plus task_ids, drops specific tickets from this squad’s metrics only (routing unchanged).

metrics.qhs

qhs:
  weights:
    ftpr: 0.45
    cycle: 0.35
    bugs: 0.20
  cycle_score:
    days_multiplier: 4
    min: 35
    max: 95
  bug_score:
    per_bug_penalty: 1
    min: 35
    max: 95

Formula (shown live on Quality Insights):

  • With FTPR: round(w_ftpr×FTPR + w_cycle×cycle_score + w_bugs×bug_score)
  • Without FTPR: cycle + bug weights re-normalized
  • Cycle score: clamp(100 − median_cycle_days × days_multiplier, min, max)
  • Bug score: clamp(100 − bugs_closed × per_bug_penalty, min, max)

metrics.targets

Optional good/warn thresholds for metric card colors and FTPR chart target line:

metrics:
  targets:
    ftpr:
      good: 85
      warn: 70
      lower_is_better: false
    median_cycle:
      good: 5
      warn: 10
      lower_is_better: true

Supported keys: ftpr, qhs, median_cycle, average_cycle, median_lead, average_lead, avg_time_qa, bugs_closed, open_bugs, throughput, bug_density, bug_reopen_rate. Defaults apply when omitted.

Complete config.yml key index

Only the block for your active provider is required (metrics.jira or metrics.clickup). The other provider block can be omitted.

Top level

KeyRequiredExampleWhat it does
providerYesjiraWhich API Pulse calls. jira or clickup.
teamsYessee belowSquad list (max 10). Each name becomes a dashboard tab.
jiraIf provider: jiraurl, email, tokenJira Cloud site and API credentials.
clickupIf provider: clickuptoken, workspaceClickUp API token and Team ID.
customer_nameNoAcme CorpShown in logs and /health. Not a UI logo.
dashboard.themeNocharcoalDefault UI theme: default, light, matrix, dutch, ember, charcoal.
api.clickup_planNobusinessParallelism and rate limits for ClickUp. Default free.
api.jira_planNostandardJira search page size and changelog workers. Default free.
performance.*Nosee belowCache and reuse toggles. All default on.

teams[] (each squad)

KeyProviderExampleWhat it does
nameBothPlatformTab label in the UI. Not the Jira project key.
jira.project_keyJiraPLATJira project key used in JQL.
clickup.list_idClickUp"901234567890"Single home list for this squad.
clickup.list_idsClickUp["901…", "902…"]Multiple lists.
clickup.folder_idClickUp"901…"All lists under this folder.
clickup.space_idClickUp"901…"Folderless lists plus all folder lists in the space.
clickup.routing.*ClickUpsquad_value: PlatformPer-squad routing rules when lists are shared.
teams[].metricsBothnested blockOverrides global metrics for this squad only.
teams[].metrics.exclusionsBothtags, task_idsDrop tickets from this squad's metrics (routing unchanged).

Shorthand: jira_project, clickup_list_id, clickup_list_ids, clickup_folder_id, clickup_space_id (same meaning as nested keys).

metrics.jira.workflow

KeyDefault (if omitted)ExampleWhat it does
cycle_start_statuses[In Progress][In Progress]Cycle time starts when the ticket first enters one of these statuses.
cycle_end_statuses[] (use done)[Done]Optional explicit cycle end. Empty means first lead_end_statuses transition.
lead_start_statuses[] (created)[To Do]Lead time start. Empty uses ticket created date.
lead_end_statuses[Done][Done, Live]Statuses that count as done for lead/cycle end.
qa_in_progress_statuses[In QA][QA In Progress, In Review]Exact statuses counted for Avg time in QA.
qa_in_progress_contains[][qa, test]Substring match for QA-in-progress columns (combined with exact list).
qa_ready_statuses[Ready for QA][Ready for test]Queue/wait before QA. Used in audit and flow charts, not avg QA time.
qa_ready_contains[][ready]Substring match for ready-for-QA columns.
bottleneck_exclude_statuseslong default list[To Do, Done]Statuses omitted from Bottleneck Index.
bottleneck_exclude_prefixes[done, closed, complete]samePrefix exclusions for bottleneck (case-insensitive).
status_ordersee defaultsboard column orderFTPR backward-move detection after first cycle_start_statuses.

Status names are matched case-insensitively.

metrics.jira.ftpr

KeyExampleWhat it does
reopen_statuses[In Progress]Moving to these after Done counts as FTPR fail.
fail_labels[ftpr-fail]Jira labels that force FTPR fail regardless of history.

metrics.jira.bugs

KeyExampleWhat it does
task_types[Bug]Issue types treated as bugs.
tags[bug]Jira labels (useful for JSM incidents).
title_keywords["[Bug]"]Title contains any of these strings.
title_prefixBUG |Alias for a single title prefix rule.

A ticket is a bug if any rule matches.

metrics.jira.custom_fields

KeyExampleWhat it does
ticket_size_fieldStory PointsDisplay name for size chart (resolved via /rest/api/3/field).
ticket_size_value_map0=XS, 1=SMap numeric/select values to labels.
ticket_size_order[XS, S, M, L]Chart sort order.
urgency_fieldPriorityBug priority charts. Empty = Jira native priority only.
urgency_value_map1=Low, 2=HighOptional aliases for custom dropdown values.
urgency_order[Low, Normal, High]Chart sort order.

When urgency_field is set, only that field is used per ticket. Empty values count as Unknown. Native priority is not mixed in.

metrics.jira.flow

KeyExampleWhat it does
work_statuses[In Progress, QA In Progress]Active work time for flow efficiency.
wait_statuses[To Do, Ready for test]Wait/queue time for flow efficiency.

metrics.jira.subtasks

KeyDefaultWhat it does
includefalseWhen false, sub-tasks are excluded from metrics (JQL parent is EMPTY).
issue_types[Sub-task, Subtask]Extra issue types to treat as subtasks when include: false.

metrics.clickup (when provider: clickup)

SectionKey highlightsWhat it does
routinguse_squad_field, squad_field, multi_squadShared-folder squad split via custom dropdown.
workflowsame as Jira plus cycle_start_fallbacknone, flow_work, first_history, created when cycle start missing.
ftprfail_tags, assume_pass_without_fail_tag, group_byTag-based FTPR. group_by: due_date buckets by due month.
bugstags, title_prefix, custom_item_typesBug detection rules.
custom_fieldsticket_size_field, urgency_fieldSame urgency rules as Jira (one source per workspace).
fetch_open_tasksdefault truefalse skips open tasks (faster, incomplete bug backlog).

See ClickUp configuration for routing keys and examples.

metrics.exclusions (global)

KeyDefaultWhat it does
issue_types[Epic, Spike]Jira types dropped from all squads. Set [] to include.
tags[]Exclude tickets with these labels/tags.
title_keywords[]Exclude when title contains keyword.
list_ids[]ClickUp lists skipped before routing.

metrics.qhs and metrics.targets

See sections above for formulas. metrics.targets sets good/warn bands on summary cards (keys in app/targets.py).