Portfolio environment analysis
You are given a task prompt, an environment_access.md with the base URL/endpoints/token,
and an answer template at payloads/answer_template.json (prompts reference it as
input/payloads/answer_template.json). Query the shared environment, apply the operating
rules below, and emit only the JSON the template requires — no prose.
Read references/data-model.md first: it is the field-authority map, category
conventions, enum vocabularies, and distractor catalog that the rules below depend on.
The one principle that runs through every task
The environment is seeded with decoy fields and adversarial signals. Winning means
using authoritative fields and ignoring the decoys, consistently:
- Completion/closure →
status, never mirror_status.
- Portfolio category →
work_type, never legacy_category; labels/title are
noise that do not override the type.
- SLA deadline →
due_at, not recomputed from sla_policy.
- Release truth → authoritative
status / blocker / dependency records, not mirrors.
- Primary work excludes duplicates (
status='Duplicate' OR duplicate_of set) and
cancelled (status='Cancelled'); report them separately where asked, never count
them as primary.
If two authoritative fields genuinely conflict in a way that changes the answer, that is a
data conflict — surface it through whatever the template provides (e.g. an
INVESTIGATE_DATA_QUALITY / DATA_CONFLICT path) rather than guessing.
General workflow
- Read the environment access notes → base URL, endpoint list, token. Substitute the
real base URL for
<TASK_ENV_BASE_URL>.
- Read the answer_template fully. It is the contract: exact keys, enums,
const
values, ordering notes in descriptions, rounding precision, and self-attestation
flags. Build your output to match it exactly (respect additionalProperties:false).
- Pin the scope from the prompt: teams, product area(s), quarter / as-of date /
window, release id,
scope_id. Scope match uses authoritative team and
product_area (both must be in scope), plus the relevant time window.
- Pull the data (prefer
POST /api/query for filtering/aggregation; the token is
required there). Get the candidate work items, plus mix_targets / sla_policy /
milestones / blockers / dependencies as the family needs.
- Partition primary vs excluded (duplicates, cancelled, out-of-window, decoys).
- Classify / compute per the family playbook below, using authoritative fields only.
- Apply ordering & rounding exactly as the template states.
- Validate against the template and the checklist, then output JSON only.
Determinism defaults (unless a template says otherwise): sort id lists lexicographically;
list teams/product areas alphabetically; category rows in the fixed order
NewFeature, TechDebt, Reliability, Security; percentages as percentage points to 1
decimal; rates (breach/readiness) to 3 decimals. Counts are item counts, not
story points.
Family A — Portfolio-mix review / readout
Goal: the count-based category mix of in-scope closed portfolio work vs a target mix,
plus gaps and a rebalance recommendation.
- Population: primary items where
team ∈ scope.teams AND product_area ∈ scope.product_areas AND the item is completed within the quarter — i.e.
status ∈ {Closed, Done, Deployed, Verified} with closed_at inside the quarter
window (2025-Q4 = 2025-10-01 .. 2025-12-31). Exclude duplicates, cancelled, and
anything closed outside the quarter.
- Classify each included item into exactly one category via the
work_type map
(see data-model). category_counts = item counts per category; total_included =
their sum.
- Actual mix:
actual_pct(c) = 100 * count(c) / total_included, 1 dp.
- Target mix: fetch the
mix_targets row for the task's exact scope_id; each
*_pct fraction ×100 → target_pct, 1 dp.
- Gaps:
gap_pct = actual_pct - target_pct, 1 dp, one row per category in fixed
order.
- Under-invested / largest deficit: categories with negative gap; order most-negative
first; the single most-negative is the largest deficit / primary rebalance target.
- Recommendation:
- Any negative gap →
REBALANCE_CAPACITY; primary = largest negative gap, secondary =
next (rationale e.g. LARGEST_NEGATIVE_GAP). For a single owner_team, pick
deterministically the in-scope team best positioned to close that deficit (derive
from the data — e.g. the team with the most in-scope closed volume — and apply a
stable tiebreak); confirm the template's allowed enum.
- No negative gaps →
MAINTAIN_CURRENT_MIX / nulls / NO_NEGATIVE_GAPS.
- Irreconcilable data conflict → the data-quality path if the template offers one.
- Exclusions / attestation: list excluded duplicate ids and cancelled ids as the
template splits them; set any "ignored mirror_status and legacy_category" attestation
flag to
true (and actually ignore those fields). Order excluded/included id lists as
instructed (commonly closed_at asc, then id asc).
Family B — SLA aging / breach audit
Goal: the primary reliability+security SLA population, which items are overdue, aging
distribution, hotspots, duplicate clusters, missing owners, and the breach rate.
Inputs: scope.teams (2), target categories (Reliability, Security), as_of date,
recent_closed_window_days N.
- In-scope = primary items with
team ∈ scope.teams AND portfolio category (via
work_type) ∈ scope categories.
- Included primary population = in-scope items that are still active
(
status ∉ COMPLETE) or recently closed (closed_at within (as_of − N, as_of]).
Exclude items closed before that window, and exclude duplicates/cancelled (duplicates
go to duplicate_clusters, not the population).
- Overdue = included primary items still unresolved with
due_at < as_of
(authoritative due_at). Recently-closed items stay in the denominator but are not
overdue. (If a template's field descriptions imply closed-late items count as breached,
reconcile to that wording — decide once and apply consistently.)
- Aging buckets by
days_overdue = as_of − due_at for overdue items, into
0-3 / 4-7 / 8-14 / 15-30 / 31+ (inclusive ranges as the template lists them).
- Breakdowns: overdue counts by team (alphabetical) and/or by
severity (S1..S4) as
the template requires. Hotspot = the (team, owner) pair with the most overdue;
owner null → UNASSIGNED.
- Missing owners = included primary ids with null/empty
owner, sorted.
- Duplicate clusters = in-scope duplicates grouped by
duplicate_of → {primary_id, duplicate_ids sorted}, clusters sorted by primary_id.
- Escalation queue (when asked) = overdue primary ids in follow-up priority: by
severity (S1 first) → most overdue (due_at asc) → id. Confirm the template's stated
priority definition.
breach_rate = |overdue primary| / |included primary|, rounded to 3 dp
(guard against divide-by-zero → template-appropriate zero).
Family C — Release-readiness assessment
Goal: ship decision, per-milestone completion, gating items, blocker-cause counts,
critical dependency chains, readiness score — for one release id.
- Release work items = items with
release_id = <release> (each also has a
milestone_id). Drop duplicates/cancelled from primary.
- Per milestone (all milestones with that
release_id, sorted by milestone_id
asc): primary_total = primary items with that milestone_id; complete_primary =
those with status ∈ COMPLETE; completion_pct = 100 * complete/total, 1 dp.
- Gating work item ids = non-complete primary release items (
status ∉ COMPLETE),
sorted ascending, unique.
- Blocker cause counts = blockers for this release that are unresolved
(
resolved_at IS NULL) and high-impact (severity ∈ {Critical, High}), grouped by
exact cause string.
- Critical dependency chains = ordered
blocked_id → depends_on_id → ... paths that
start at a blocked release work item and end at a non-complete dependency, following
the release-gating relation (blocks-release-readiness). Emit each path as an ordered
id list; sort chains lexicographically by the full path.
readiness_score = completed primary ÷ primary denominator across the release,
rounded to 3 dp (the aggregate of the milestone completion).
ship_decision (SHIP / SHIP_WITH_WATCH / NO_SHIP): decide from readiness +
gating + unresolved high-impact blockers. Defensible rule (confirm against the prompt's
thresholds): any unresolved high-impact blocker or critical unmet dependency → tends to
NO_SHIP; full readiness (score = 1.0) with no gating/blockers → SHIP; partial
readiness with manageable risk → SHIP_WITH_WATCH. Apply one explicit rule
consistently.
- Do not use
mirror_status as release truth.
Validation checklist (before returning)
- Output is a single JSON object, no prose, matching the template's keys/enums/
consts
exactly; no extra keys (additionalProperties:false).
- No decoy field influenced the answer:
mirror_status and legacy_category ignored;
category came from work_type; SLA deadline from due_at.
- Duplicates and cancelled items excluded from primary and reported where required;
clusters grouped by
duplicate_of.
- Scope filter used authoritative
team + product_area + the correct time window;
out-of-window items excluded.
- Ordering applied (ids lexicographic, teams/areas alphabetical, category rows in fixed
order, chains/clusters sorted as specified).
- Rounding correct: percentage points to 1 dp; rates to 3 dp. Counts are item counts.
- Percentages/gaps are internally consistent (actual − target = gap; counts sum to
total_included; completion = complete ÷ total).
- Any self-attestation flag (e.g. ignored-mirror/legacy) set truthfully.
1---2name: portfolio-env-analysis3description: Answer analytics questions against the shared read-only "portfolio" HTTP environment (work items, mix targets, SLA policy, releases, milestones, blockers, dependencies) and return a single strict-JSON answer matching a provided answer_template.json. Use for the three recurring task families: (1) quarterly portfolio-mix reviews/readouts (category mix vs a mix_targets row), (2) SLA aging/breach audits for reliability & security work, and (3) release-readiness assessments. Triggers whenever a task references <TASK_ENV_BASE_URL> / environment_access.md plus /api/work-items and asks for category mix, SLA/overdue/breach, or ship-readiness, with a payloads/ answer_template.json to conform to.4---56# Portfolio environment analysis78You are given a task prompt, an `environment_access.md` with the base URL/endpoints/token,9and an answer template at `payloads/answer_template.json` (prompts reference it as10`input/payloads/answer_template.json`). Query the shared environment, apply the operating11rules below, and emit **only** the JSON the template requires — no prose.1213Read `references/data-model.md` first: it is the field-authority map, category14conventions, enum vocabularies, and distractor catalog that the rules below depend on.1516## The one principle that runs through every task1718The environment is seeded with **decoy fields and adversarial signals**. Winning means19using authoritative fields and ignoring the decoys, consistently:2021- Completion/closure → **`status`**, never `mirror_status`.22- Portfolio category → **`work_type`**, never `legacy_category`; `labels`/`title` are23 noise that do not override the type.24- SLA deadline → **`due_at`**, not recomputed from `sla_policy`.25- Release truth → authoritative `status` / blocker / dependency records, not mirrors.26- Primary work excludes **duplicates** (`status='Duplicate'` OR `duplicate_of` set) and27 **cancelled** (`status='Cancelled'`); report them separately where asked, never count28 them as primary.2930If two authoritative fields genuinely conflict in a way that changes the answer, that is a31*data conflict* — surface it through whatever the template provides (e.g. an32`INVESTIGATE_DATA_QUALITY` / `DATA_CONFLICT` path) rather than guessing.3334## General workflow35361. **Read the environment access notes** → base URL, endpoint list, token. Substitute the37 real base URL for `<TASK_ENV_BASE_URL>`.382. **Read the answer_template fully.** It is the contract: exact keys, enums, `const`39 values, ordering notes in `description`s, rounding precision, and self-attestation40 flags. Build your output to match it exactly (respect `additionalProperties:false`).413. **Pin the scope** from the prompt: teams, product area(s), quarter / as-of date /42 window, release id, `scope_id`. Scope match uses authoritative `team` **and**43 `product_area` (both must be in scope), plus the relevant time window.444. **Pull the data** (prefer `POST /api/query` for filtering/aggregation; the token is45 required there). Get the candidate work items, plus mix_targets / sla_policy /46 milestones / blockers / dependencies as the family needs.475. **Partition primary vs excluded** (duplicates, cancelled, out-of-window, decoys).486. **Classify / compute** per the family playbook below, using authoritative fields only.497. **Apply ordering & rounding exactly** as the template states.508. **Validate** against the template and the checklist, then output JSON only.5152Determinism defaults (unless a template says otherwise): sort id lists lexicographically;53list teams/product areas alphabetically; category rows in the fixed order54`NewFeature, TechDebt, Reliability, Security`; percentages as percentage points to **155decimal**; rates (breach/readiness) to **3 decimals**. Counts are **item counts, not56story points**.5758## Family A — Portfolio-mix review / readout5960Goal: the count-based category mix of in-scope **closed** portfolio work vs a target mix,61plus gaps and a rebalance recommendation.62631. **Population**: primary items where `team ∈ scope.teams` AND `product_area ∈64 scope.product_areas` AND the item is completed within the quarter — i.e.65 `status ∈ {Closed, Done, Deployed, Verified}` with `closed_at` inside the quarter66 window (2025-Q4 = `2025-10-01 .. 2025-12-31`). Exclude duplicates, cancelled, and67 anything closed outside the quarter.682. **Classify** each included item into exactly one category via the `work_type` map69 (see data-model). `category_counts` = item counts per category; `total_included` =70 their sum.713. **Actual mix**: `actual_pct(c) = 100 * count(c) / total_included`, 1 dp.724. **Target mix**: fetch the `mix_targets` row for the task's exact `scope_id`; each73 `*_pct` fraction ×100 → `target_pct`, 1 dp.745. **Gaps**: `gap_pct = actual_pct - target_pct`, 1 dp, one row per category in fixed75 order.766. **Under-invested / largest deficit**: categories with negative gap; order most-negative77 first; the single most-negative is the largest deficit / primary rebalance target.787. **Recommendation**:79 - Any negative gap → `REBALANCE_CAPACITY`; primary = largest negative gap, secondary =80 next (rationale e.g. `LARGEST_NEGATIVE_GAP`). For a single `owner_team`, pick81 deterministically the in-scope team best positioned to close that deficit (derive82 from the data — e.g. the team with the most in-scope closed volume — and apply a83 stable tiebreak); confirm the template's allowed enum.84 - No negative gaps → `MAINTAIN_CURRENT_MIX` / nulls / `NO_NEGATIVE_GAPS`.85 - Irreconcilable data conflict → the data-quality path if the template offers one.868. **Exclusions / attestation**: list excluded duplicate ids and cancelled ids as the87 template splits them; set any "ignored mirror_status and legacy_category" attestation88 flag to `true` (and actually ignore those fields). Order excluded/included id lists as89 instructed (commonly `closed_at` asc, then id asc).9091## Family B — SLA aging / breach audit9293Goal: the primary reliability+security SLA population, which items are overdue, aging94distribution, hotspots, duplicate clusters, missing owners, and the breach rate.9596Inputs: `scope.teams` (2), target `categories` (Reliability, Security), `as_of` date,97`recent_closed_window_days` N.98991. **In-scope** = primary items with `team ∈ scope.teams` AND portfolio category (via100 `work_type`) ∈ scope categories.1012. **Included primary population** = in-scope items that are still **active**102 (`status ∉ COMPLETE`) **or** recently closed (`closed_at` within `(as_of − N, as_of]`).103 Exclude items closed before that window, and exclude duplicates/cancelled (duplicates104 go to `duplicate_clusters`, not the population).1053. **Overdue** = included primary items still unresolved with `due_at < as_of`106 (authoritative `due_at`). Recently-closed items stay in the denominator but are not107 overdue. (If a template's field descriptions imply closed-late items count as breached,108 reconcile to that wording — decide once and apply consistently.)1094. **Aging buckets** by `days_overdue = as_of − due_at` for overdue items, into110 `0-3 / 4-7 / 8-14 / 15-30 / 31+` (inclusive ranges as the template lists them).1115. **Breakdowns**: overdue counts by team (alphabetical) and/or by `severity` (S1..S4) as112 the template requires. **Hotspot** = the `(team, owner)` pair with the most overdue;113 `owner` null → `UNASSIGNED`.1146. **Missing owners** = included primary ids with null/empty `owner`, sorted.1157. **Duplicate clusters** = in-scope duplicates grouped by `duplicate_of` → `{primary_id,116 duplicate_ids sorted}`, clusters sorted by `primary_id`.1178. **Escalation queue** (when asked) = overdue primary ids in follow-up priority: by118 `severity` (S1 first) → most overdue (`due_at` asc) → id. Confirm the template's stated119 priority definition.1209. **`breach_rate` = |overdue primary| / |included primary|**, rounded to **3 dp**121 (guard against divide-by-zero → template-appropriate zero).122123## Family C — Release-readiness assessment124125Goal: ship decision, per-milestone completion, gating items, blocker-cause counts,126critical dependency chains, readiness score — for one release id.1271281. **Release work items** = items with `release_id = <release>` (each also has a129 `milestone_id`). Drop duplicates/cancelled from primary.1302. **Per milestone** (all milestones with that `release_id`, sorted by `milestone_id`131 asc): `primary_total` = primary items with that `milestone_id`; `complete_primary` =132 those with `status ∈ COMPLETE`; `completion_pct = 100 * complete/total`, 1 dp.1333. **Gating work item ids** = non-complete primary release items (`status ∉ COMPLETE`),134 sorted ascending, unique.1354. **Blocker cause counts** = blockers for this release that are **unresolved**136 (`resolved_at IS NULL`) and **high-impact** (`severity ∈ {Critical, High}`), grouped by137 **exact** `cause` string.1385. **Critical dependency chains** = ordered `blocked_id → depends_on_id → ...` paths that139 start at a blocked release work item and end at a non-complete dependency, following140 the release-gating relation (`blocks-release-readiness`). Emit each path as an ordered141 id list; sort chains lexicographically by the full path.1426. **`readiness_score`** = completed primary ÷ primary denominator across the release,143 rounded to **3 dp** (the aggregate of the milestone completion).1447. **`ship_decision`** (`SHIP` / `SHIP_WITH_WATCH` / `NO_SHIP`): decide from readiness +145 gating + unresolved high-impact blockers. Defensible rule (confirm against the prompt's146 thresholds): any unresolved high-impact blocker or critical unmet dependency → tends to147 `NO_SHIP`; full readiness (score = 1.0) with no gating/blockers → `SHIP`; partial148 readiness with manageable risk → `SHIP_WITH_WATCH`. Apply one explicit rule149 consistently.1508. Do **not** use `mirror_status` as release truth.151152## Validation checklist (before returning)153154- Output is a single JSON object, no prose, matching the template's keys/enums/`const`s155 exactly; no extra keys (`additionalProperties:false`).156- No decoy field influenced the answer: `mirror_status` and `legacy_category` ignored;157 category came from `work_type`; SLA deadline from `due_at`.158- Duplicates and cancelled items excluded from primary and reported where required;159 clusters grouped by `duplicate_of`.160- Scope filter used authoritative `team` + `product_area` + the correct time window;161 out-of-window items excluded.162- Ordering applied (ids lexicographic, teams/areas alphabetical, category rows in fixed163 order, chains/clusters sorted as specified).164- Rounding correct: percentage points to 1 dp; rates to 3 dp. Counts are item counts.165- Percentages/gaps are internally consistent (actual − target = gap; counts sum to166 total_included; completion = complete ÷ total).167- Any self-attestation flag (e.g. ignored-mirror/legacy) set truthfully.