Flow metrics
Skill eugenelim/agent-ready-repo/packs/atlassian/.apm/skills/flow-metrics
The complete AI operating model for software teams — from first idea to production. Three peer-supervised loops (discovery → build → release) over a catalogue of curated packs: skills, subagents, and hooks, each installed in one line. It's npm for your coding agent. Any agent, any stack — Claude Code, Codex, Cursor, Copilot, Gemini, Kiro.
npx -y skills add eugenelim/agent-ready-repo --skill flow-metricsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 14 stars14 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use this skill when the user asks for DORA / Flow Framework metrics over a Jira scope -- "what's our cycle time this quarter for PROJ", "give me throughput and WIP for the Foo team", "compare flow efficiency before/after the AI-pairing rollout via a cohort split", "rollup flow metrics across program 42". Computes cycle time, lead time, throughput, WIP, flow load, rework rate, flow efficiency, flow distribution, and defect ratio from Jira changelogs (optionally joined with Jira Align for program / portfolio scope). Read-only -- never transitions, comments, creates, updates, or deletes Jira data. Do NOT use for live-dashboard streaming, deployment-event metrics (Change Failure Rate / MTTR proper), or anything requiring a tracker that isn't Jira.
SKILL.md
15.8 KB, ~4.0k tokens by cl100k_base, as published. Nobody here has run it
Skill: flow-metrics
This skill is the one place to compute Flow Framework / DORA-style metrics over a Jira scope. It composes two upstream skills and emits a canonical JSON / CSV / JSONL block; it does not invent new tracker verbs or replicate them inline.
jiraskill (sibling in this pack) — every Jira read:check,whoami,get-issue,search,get-project, plus a tightly- allowlisted set ofraw GETpaths for the custom-field catalog, project-status enumeration, and per-issue changelog pagination.jira-alignskill (sibling in this pack) — used only for--program-id/--portfolio-idscope, and only for the four team / program / portfolio enumeration paths. Time-in-state numbers always come from Jira's changelog.
The pipeline (config validation, scope JQL, changelog walk, per-issue
derivation, aggregation, cohort split, per-team rollup, notes, meta,
output rendering, caching) lives in scripts/flow_metrics/. This SKILL.md
tells the agent how to invoke the CLI for common flows; for design
details, read the inline module docstrings.
Cross-skill invocation — name, not path
This skill names sibling skills (jira, jira-align) by their name:
field, never by path. Install locations vary by IDE and scope, and
skills can be renamed at install time. The agent's harness resolves the
name to whatever location the user picked. If you find yourself
writing a hardcoded skill path, stop — look up the skill by name
instead.
Install guidance for the named dependencies lives in manifest.json
under deps.skills — that's a where to get them hint, not a runtime
path.
Prerequisites
Before computing metrics, confirm:
- The
jiraskill is installed and authenticated. Invoke it:jira: check. Exit 0 → proceed. Exit 2 → tell the user to runcredential-setupskill themselves; do not attempt to read~/.agentbundle/credentials.envfrom this skill. - For program / portfolio scope, the
jira-alignskill is installed and authenticated. If--program-idor--portfolio-idis in play andjira-align: checkfails, exit 3 and surface upstream stderr verbatim. - The Jira
team_field.idyou've configured (defaultcustomfield_10001in the shipped state config) exists in this instance's field catalog. If it doesn't, the skill exits 2 at startup naming the missing field.
Invocation
The skill ships one CLI. Two equivalent forms (both call the same
flow_metrics.main):
# Installed package — exposes a `flow-metrics` shim on PATH:
flow-metrics --project PROJ
# Or any environment where the package is on PYTHONPATH:
python -m flow_metrics --project PROJ
The spec's examples use the bare flow-metrics form. From a working
copy of this pack, add the package to PYTHONPATH first:
export PYTHONPATH="$(pwd)/scripts:$PYTHONPATH"
python -m flow_metrics --help
Every example below uses the bare form; substitute python -m flow_metrics if you're invoking from a clone.
CLI flags
The full flag surface:
--project KEY— Jira project key. Mutually exclusive with--program-id/--portfolio-id.--team NAME— Optional sub-scope within a project. Resolution rule depends onteam_field.kind(single_valueorarray). Only valid with--project.--program-id ID— Jira Align program ID. Triggers a Jira Align join for team mapping.--portfolio-id ID— Jira Align portfolio ID. Triggers a rollup across constituent programs / teams.--from ISO,--to ISO— Window bounds,YYYY-MM-DD. Both inclusive of the named day. Default:--to = today (UTC),--from = today − 90 days.--jql "<expr>"— Extra JQL ANDed into the scope query. Always wrapped as(<scope>) AND (<--jql expr>)— your expression is parenthesised verbatim.--align-filter "<expr>"— Extra OData ANDed into Jira Align queries with the same parenthesisation rule.--cohort-jql "<expr>"— Issues matching this JQL are markedcohort: truein the output. Aggregate mode emits acohort_breakdownblock; per-issue mode tags each row.--metrics LIST— Comma list. Default: all ten. Names:cycle_time, lead_time, throughput, wip, flow_load, rework_rate, flow_time, flow_efficiency, flow_distribution, defect_ratio. Unrequested metrics are omitted fromaggregates(not emitted asnull);meta.metrics_requestedrecords the resolved list.--state-config FILE— JSON file mapping raw statuses to canonical states. Defaults to the shippedreferences/states.default.json.--issuetype-config FILE— JSON file mapping issuetypes to Flow Distribution buckets. Defaults toreferences/issuetypes.default.json.--team-field-override ID— Overrideteam_field.idfrom the state config for this run.--align-join-field NAME— Override the Jira ↔ Jira Align join field. Defaults to thealign_join_fieldentry in the state config; if neither is set and Jira Align scope is requested, exit 2.--align-teams-path PATH— Override the Jira Align endpoint used to enumerate teams in a program. Must match one of the four allowlistedjira-alignraw GETpatterns.--include-subtasks— Include subtasks in throughput, cycle time, lead time, flow efficiency, rework rate. Default: false. Flow Distribution is always insensitive to this flag.--format json|csv— Output format. Default:json.--output FILE— Write to file instead of stdout. Required for--per-issue. Path is rejected if it lands under a system root.--per-issue— Emit one JSONL row per issue with all derived fields, instead of aggregates. Requires--output.--no-cache— Bypass the on-disk cache at.context/flow-metrics/cache/<cache-key>.jsonl.--verbose— Debug logging (state-transition walks, cache hits, upstream skill invocations).--yes— Overwrite--output FILEwithout prompting.
Exactly one of --project, --program-id, --portfolio-id must be
provided. --team is only valid with --project.
Common flows
Each example is a literal command line the agent can run.
Project-scope, default 90-day window
flow-metrics --project PROJ
JSON to stdout. The shipped default state config maps the common Jira workflow ("To Do" / "In Progress" / "Done" / "Won't Do") out of the box.
Project-scope with a specific window and JQL filter
flow-metrics \
--project PROJ \
--from 2026-02-01 --to 2026-04-30 \
--jql 'labels = ai-assisted AND component = checkout'
Jira Align program scope (joins via Jira Align)
flow-metrics \
--program-id 42 \
--align-join-field "Program ID" \
--from 2026-02-01 --to 2026-04-30
--align-join-field is required for Align scope unless the state
config provides it.
Cohort split (A/B comparison)
flow-metrics \
--project PROJ \
--cohort-jql 'labels = ai-assisted' \
--format json
Output gains a cohort_breakdown block with cohort and control
sides. Cohort-jql matching zero issues produces an empty cohort with
throughput: 0 and null percentiles — exit 0.
Filter to a subset of metrics
flow-metrics \
--project PROJ \
--metrics throughput,cycle_time,defect_ratio
Only the requested metrics appear in aggregates. meta.metrics_requested
records the resolved list. flow_distribution and defect_ratio are
separate keys — requesting one does not auto-include the other.
Bypass the on-disk cache
flow-metrics --project PROJ --no-cache
Use when the underlying Jira data has changed and you suspect cache
staleness. Cache lives at
.context/flow-metrics/cache/<cache-key>.jsonl.
Per-issue dump (downstream consumer input)
flow-metrics \
--project PROJ \
--per-issue \
--output .context/flow-metrics/per-issue.jsonl
JSONL on disk, one row per in-scope issue. Downstream consumers
(notably ai-adoption-report) MUST filter on
delivered_in_window: true before computing delivery-based metrics.
Don't
- Don't bypass the upstream-skill allowlist. This skill invokes
only the allowlisted verbs and
raw GETpaths. Any other invocation is a regression. If a verb is missing, extend thejiraorjira-alignskill — don't shim around it here. - Don't read
credentials.envfrom this skill. Credentials live in thejira/jira-alignskills and are isolated from this one. Authentication failures surface as upstream exit 3; the fix is to run the upstream skill'ssetup_credentials.sh, not to read its config file from here. - Don't issue write verbs. This skill is read-only. No
create-issue,update-issue,delete-issue,transition,comment,attach— and noraw POST/PUT/PATCH/DELETEto any upstream skill. A contract test wraps the upstream skills and fails on any out-of-allowlist call. - Don't add
numpyor any other pip dependency. v1 is stdlib only — percentiles usestatistics.quantiles(..., method="exclusive")at indices 49 / 74 / 89 for p50 / p75 / p90. The schema validator used by the contract test is the same stdlib-only posture; do not addjsonschemato satisfy it. - Don't infer the
align_join_field. Instances vary; silently pickingcustomfield_10001is a wrong-answer risk. If neither--align-join-fieldnor the state config sets it and Align scope is requested, exit 2 with a clear message. - Don't normalise JQL semantically in v1.
normalize_jqlonly collapses whitespace; two semantically equivalent JQL expressions with different clause order produce different cache files. That's the documented v1 trade. - Don't paraphrase the metric definitions. They are pinned and tested. If a metric "feels wrong", read the module docstrings before changing anything.
Security rules
This skill operates under a read-only contract with credential isolation:
- Read-only contract: the upstream-skill allowlist names every
verb and
raw GETpath this skill is permitted to invoke. Any other upstream invocation, including theraw POST/PUT/PATCH/DELETEescape hatches, is forbidden and enforced by a contract test that wraps the upstream skills. - Credential isolation: this skill never reads
credentials.envor any other secret file directly. Credentials belong to thejira/jira-alignskills; this skill invokes them by name and lets them load their own credentials. Ifjira: checkfails, surface the error and tell the user to run the upstream skill's setup — do not attempt to authenticate on its behalf. - No write verbs: this skill emits no
POST/PUT/PATCH/DELETEHTTP requests, and invokes no write-class verbs (transition, comment, create, update, delete, attach) on any upstream skill. The output is metrics; it never mutates Jira state. - Path safety:
--output,--state-config,--issuetype-configare rejected if they resolve under a privileged system root (POSIX:/etc,/sys,/proc,/dev,/boot; Windows: the system drive'sWindows,Program Files, andProgram Files (x86)directories), or if they contain a null byte. Exit 2.
Edge cases
The key edge cases to know about:
- Cancelled issues. An issue transitioning into a
terminal_non_delivery_statescanonical state (default:cancelled) in-window with no first-ever delivery in-window is cancelled-in-window. Excluded from throughput, cycle time, lead time, flow efficiency, and Flow Distribution; counted innotes. A cancel-then-reopen-still-active-at---toissue is also in WIP — both signals are reported simultaneously. - Empty cohort.
--cohort-jqlmatching zero issues produces an empty cohort sub-object withthroughput: 0and percentile fieldsnull. The skill exits 0. - Permission undercounting. Jira silently omits issues the caller
lacks browse permission on. For project scope, the skill compares
the JQL count against
jira: get-project <KEY>and emits anotesentry recording the delta. Field-level permission undercount on theteam_fieldis also detected and reported as a synthetic(no team)row inper_team. The skill does not retry as a different user or escalate.meta.callerrecords the calling account so downstream consumers can spot cross-account discrepancies. - Changelog pagination (Cloud regression). Cloud Jira's
/search/jqlendpoint returns at most ~100 inline changelog entries per issue. The skill detects "more pages exist" viaisLast,nextPageToken, orhistories.length < total, then drains viajira: raw GET issue/<KEY>/changelog. Long-lived issues silently lose cycle-time math without this, so the pagination contract is required, not optional. - Unmapped raw status. Any raw status not listed under any
canonical_statesentry causes exit 2 at startup with the offending name. The shipped default config maps "Won't Do" / "Cancelled" / "Duplicate" tocancelleddeliberately so first-run users on a normal Jira workflow get accurate throughput out of the box. - Issue with no commitment_state transition (closed directly from backlog). Delivered-in-window = true; cycle-eligible = false. Contributes to throughput and lead time. Excluded from cycle time.
--per-issuewithout--output. Exit 2 — JSONL must go to a file.
Output contract
The canonical wire format is pinned by
references/output.schema.json (JSON Schema draft 2020-12). The shape:
meta— caller, scope, window, sources, metrics_requested, schema_version, generated_at, state_config_sha, issuetype_config_sha, per_team_double_counted, and optionallycohort_jql(omitted when--cohort-jqlwas not provided).aggregates— one key per requested metric. Unrequested metrics are absent, not null.additionalProperties: falsein the schema pins this.cohort_breakdown— optional. Emitted only when--cohort-jqlis set AND--per-issueis not set. Carriescohortandcontrolsub-objects with the same metric shape asaggregates.per_team— optional array of per-team rows. Emitted when scope is--program-id/--portfolio-id, or when scope is--projectand the resolved issue set spans more than one distinct team value.notes— array of descriptive strings, lex-sorted.
Output is canonicalised at serialisation: codepoint-sorted object keys
(except flow_distribution which uses a fixed bucket order), floats
rounded to 4 decimal places, per_team sorted by team name codepoint.
The schema does not re-validate canonicalisation rules — those are
enforced by the renderer's contract tests.
Further reading
The module docstrings in scripts/flow_metrics/ cover:
- metric definitions and core population predicates (
predicates.py,aggregate.py), - the upstream-skill allowlist and verbs (
upstream.py), - state-config and issuetype-config schemas (
config.py), - canonicalisation rules and output rendering (
output.py), - cache-key derivation (
cache.py), - edge-case handling (
per_issue.py,notes.py).
What ships with it: 24 files
217.8 KB alongside SKILL.md, 18 of them executable
evals/
- eval_queries.json1.5 KB
references/
- issuetypes.default.json209 B
- output.schema.json7.0 KB
- states.default.json1.0 KB
scripts/
- flow_metrics/aggregate.pyruns9.1 KB
- flow_metrics/align.pyruns12.8 KB
- flow_metrics/cache.pyruns10.3 KB
- flow_metrics/changelog.pyruns12.2 KB
- flow_metrics/clock.pyruns268 B
- flow_metrics/cohort.pyruns7.8 KB
- flow_metrics/config.pyruns19.1 KB
- flow_metrics/__init__.pyruns28.6 KB
- flow_metrics/jql.pyruns1.2 KB
- flow_metrics/__main__.pyruns927 B
- flow_metrics/meta.pyruns8.8 KB
- flow_metrics/notes.pyruns7.7 KB
- flow_metrics/output.pyruns25.7 KB
- flow_metrics/per_issue.pyruns14.1 KB
- flow_metrics/per_team.pyruns12.6 KB
- flow_metrics/predicates.pyruns3.7 KB
- flow_metrics/timeline.pyruns9.9 KB
- flow_metrics/upstream.pyruns18.1 KB
- manifest.json4.5 KB
- requirements.txt643 B