| name | engineering-portfolio-audits |
| description | Analyze engineering portfolio task environments and produce strict JSON answers for portfolio mix, SLA aging, and release-readiness reviews. Use when prompts mention work items, mix targets, SLA policies, releases, milestones, blockers, dependencies, stale mirror/export fields, duplicate or cancelled records, <TASK_ENV_BASE_URL>, environment_access.md, or answer_template.json. |
Engineering Portfolio Audits
Core Workflow
- Read the user prompt and the referenced
answer_template.json before querying data. Treat schema descriptions as requirements for sorting, rounding, field names, and enum choices.
- Read
environment_access.md for the base URL, allowed endpoints, and any query token. Use only the listed endpoints. Prefer REST endpoints; use /api/query only for targeted checks, passing the runtime token header from environment_access.md.
- Fetch the needed datasets once and keep their top-level wrappers in mind: endpoints return objects such as
work_items, mix_targets, sla_policy, releases, milestones, dependencies, and blockers.
- Use authoritative fields on the core records. Do not use
mirror_status as truth, and do not let legacy_category or labels such as stale-export override authoritative status, work_type, release_id, milestone_id, closed_at, or duplicate_of.
- Return exactly the JSON object requested by the template. Do not include prose outside the JSON.
Shared Record Rules
- Treat these statuses as complete:
Closed, Done, Deployed, Verified.
- Treat primary/canonical work as records where
status is not Duplicate, duplicate_of is empty, and status is not Cancelled.
- Exclude duplicate records from primary denominators when either
status == "Duplicate" or duplicate_of is populated. If duplicate clusters are requested, group duplicates by duplicate_of when present; records marked duplicate without a canonical id are exclusions/distractors, not primary work.
- Exclude cancelled records from primary work even when they have
closed_at or a stale mirror status that looks complete.
- Sort ID lists exactly as requested. If no task-specific order is given, sort lexicographically for plain ID sets and by
(closed_at, id) for closed-work lists.
Portfolio Category Resolver
Use work_type as the primary category signal. Labels, title terms, and legacy_category are fallbacks only when work_type is missing or unrecognized.
Recognized work_type mapping:
Feature, Enhancement -> NewFeature
Refactor, Chore, Dependency -> TechDebt
Reliability, Incident, Bug -> Reliability
Security, Compliance -> Security
Fallback signal order for unknown types:
Security: security, cve, auth, encryption, compliance
Reliability: reliability, incident, outage, latency, flaky, bug
TechDebt: refactor, cleanup, migration, dependency, chore
NewFeature: feature, enhancement, rollout, customer-request
Do not reclassify a recognized work_type because a label, title, or legacy category conflicts with it.
Closed Portfolio Mix
- Convert the requested quarter to an inclusive date range.
- Select primary work items with
closed_at inside the quarter and matching all scoped teams and product areas.
- Use item counts, not story points, for category counts and mix percentages.
- Pull the target mix from
mix_targets using the requested scope_id when provided. Target values are fractions; convert to percentage points.
- Compute
actual_pct = count / total * 100 and round to one decimal place. Compute gap_pct = actual_pct - target_pct after converting the target to percentage points, then round to one decimal place.
- Under-invested categories are categories with negative gaps, ordered from most negative to least negative.
- For rebalance actions, use the largest negative gap as the primary category. If a secondary category is required, choose the largest positive gap as the source category, using the template's category order as a tie-breaker. If an owner team is required, choose the scoped team with the lowest included count in the deficit category, using the prompt/template order as a tie-breaker.
- Report same-scope quarter distractors requested by the template, especially duplicates and cancelled records, but do not count them in the primary mix.
SLA Aging
- Resolve the SLA categories using the portfolio category resolver, usually
Reliability and Security.
- Select records matching the scoped teams and categories with
created_at <= as_of.
- Include primary work that is still open as of the date, plus primary work closed in the recent closed window. Use
as_of - window_days <= closed_at <= as_of for the inclusive recent-closed window.
- Build duplicate clusters from duplicate records that match the same team/category/as-of/window scope, then exclude them from all primary counts.
- Use the SLA policy as the due rule: allowed days come from
/api/sla-policy by severity. Do not calculate breaches from due_at if it conflicts with the severity policy.
- For active work, set
age_days = as_of - created_at. For recently closed work, set age_days = closed_at - created_at. Use date differences in whole days, not inclusive day counts.
- A primary item is overdue when
age_days > policy_days_for_severity.
- Aging buckets are normally
0-3, 4-7, 8-14, 15-30, and 31+, based on age_days.
- Missing-owner lists include primary included records whose
owner is null or empty.
- Breach rate is
overdue_primary_count / included_primary_count, rounded to the precision requested by the template.
- For overdue hotspots, count overdue primary records by team and owner, using
UNASSIGNED for missing owners. Break ties by team name, then owner name unless the prompt gives another rule.
- For escalation queues, sort overdue primary work by severity rank
S1 to S4, then numeric priority ascending, then days overdue descending, then id.
Release Readiness
- Fetch the release, its milestones, work items, blockers, and dependencies. Use
release_id and milestone_id as authoritative; ignore mirror fields.
- Primary release work is work with the matching
release_id, excluding duplicate and cancelled records.
- For each milestone in the release, compute
complete_primary, primary_total, and completion_pct = complete_primary / primary_total * 100, rounded as requested. Include every release milestone even when it has zero work, and sort by milestone_id if required.
readiness_score is completed primary release work divided by the primary release denominator, rounded as requested.
- Gating work item ids are primary release work items whose authoritative
status is not complete. Sort and de-duplicate them.
- Unresolved blockers have
resolved_at empty and status not Resolved. High-impact blockers are High or Critical. Count causes by exact cause text; do not drop a blocker just because its work item is otherwise complete.
- For dependency chains, build paths from a primary release work item through
dependencies.blocked_id -> depends_on_id. Include paths that end at a work item whose authoritative status is not complete; traverse further if the dependency has its own dependencies. Sort chains lexicographically by the full path.
- Use ship decisions consistently: choose
NO_SHIP when high-impact unresolved blockers, gating primary work, or non-complete readiness dependency chains remain; choose SHIP_WITH_WATCH when primary work is complete but lower-impact unresolved risks remain; choose SHIP only when primary work is complete and no unresolved readiness risks remain.
Output Checks
- Match the template exactly: no extra keys, no missing required keys, and enum values exactly as written.
- Preserve requested category row order, team order, and object shape.
- Round only final reported values to the requested precision.
- Recompute denominators after exclusions; never include duplicate or cancelled work in primary totals.
- When a value is ambiguous, prefer the authoritative field hierarchy in this skill and make the output deterministic through stable sorting.