progress: only track KPIs that ever carried a target
Tested against the live Strike ledger (9 decks): its decks mint ad-hoc KPI names every quarter, so ~70 one-off unscored mentions flooded the watch list, trajectory table, and dropped-KPIs gap. A KPI now only counts as trackable/ vanished if it was held to a target at least once; the rest collapse to a one-line count. Scoring-derived flags (no_profitability_visibility, no_quantitative_kpis, kpi_dropped) no longer duplicate their dedicated gaps as recurring-flag requests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9b9c7e58c1
commit
f13d044a70
+32
-11
@@ -172,6 +172,10 @@ def _kpi_trends(records: list[dict]) -> dict:
|
||||
latest_period = records[-1].get("period") if records else None
|
||||
for s in out.values():
|
||||
credits = [p["credit"] for p in s["series"] if p["credit"] is not None]
|
||||
# Accountable = the KPI was actually held to a target at least once.
|
||||
# One-off unscored mentions (ad-hoc deck metrics) are extraction noise,
|
||||
# not a trackable KPI — they'd otherwise flood the review.
|
||||
s["accountable"] = bool(credits)
|
||||
if s["last_period"] != latest_period:
|
||||
s["status"] = "not-reported" # vanished from the latest deck
|
||||
elif not credits:
|
||||
@@ -266,13 +270,16 @@ def _gaps(company: dict, records: list[dict], categories: dict,
|
||||
"Keep KPI names identical period to period (or record aliases in "
|
||||
"Configure Companies so renamed KPIs still chain).")
|
||||
|
||||
dropped = [s["name"] for s in kpis.values() if s["status"] == "not-reported"]
|
||||
dropped = sorted(s["name"] for s in kpis.values()
|
||||
if s["status"] == "not-reported" and s["accountable"])
|
||||
if dropped:
|
||||
shown = ", ".join(dropped[:12]) + \
|
||||
(f", … and {len(dropped) - 12} more" if len(dropped) > 12 else "")
|
||||
gap("dropped_kpis", 3,
|
||||
f"Previously reported KPIs vanished ({len(dropped)})",
|
||||
f"No longer reported as of {latest.get('period')}: "
|
||||
f"{', '.join(sorted(dropped))}. Silently dropped KPIs are a classic "
|
||||
"way bad news leaves a deck.",
|
||||
f"Previously targeted KPIs vanished ({len(dropped)})",
|
||||
f"KPIs that were held to a target in an earlier deck are no longer "
|
||||
f"reported as of {latest.get('period')}: {shown}. Silently dropped "
|
||||
"KPIs are a classic way bad news leaves a deck.",
|
||||
"Restore these KPIs — or retire them explicitly with one line on why.")
|
||||
|
||||
thin = [(cid, c) for cid, c in categories.items()
|
||||
@@ -297,10 +304,13 @@ def _gaps(company: dict, records: list[dict], categories: dict,
|
||||
|
||||
# Recurring flags only demand action while still open in the latest deck —
|
||||
# a flag that recurred historically but is clear now shows under "resolved".
|
||||
# Scoring-derived codes already have a dedicated gap above; repeating them
|
||||
# here would duplicate the request.
|
||||
covered = {"no_profitability_visibility", "no_quantitative_kpis", "kpi_dropped"}
|
||||
latest_codes = {f.get("code") for f in
|
||||
(latest.get("penalties") or {}).get("flags") or []}
|
||||
for f in flags.get("recurring") or []:
|
||||
if f["code"] in latest_codes:
|
||||
if f["code"] in latest_codes and f["code"] not in covered:
|
||||
gap(f"recurring_{f['code']}", min(3, f["severity"]),
|
||||
f"Recurring flag: {f['code']}",
|
||||
f"Raised in {len(f['periods'])} decks ({', '.join(str(p) for p in f['periods'])}) "
|
||||
@@ -404,8 +414,10 @@ def render_progress_md(analysis: dict) -> str:
|
||||
kpis = a.get("kpis") or {}
|
||||
up = [(cid, c) for cid, c in cats.items() if c.get("direction") == "improving"]
|
||||
down = [(cid, c) for cid, c in cats.items() if c.get("direction") == "declining"]
|
||||
kpi_good = [s for s in kpis.values() if s["status"] in ("on-track", "recovered")]
|
||||
kpi_bad = [s for s in kpis.values()
|
||||
tracked = [s for s in kpis.values() if s["accountable"]]
|
||||
untracked = len(kpis) - len(tracked)
|
||||
kpi_good = [s for s in tracked if s["status"] in ("on-track", "recovered")]
|
||||
kpi_bad = [s for s in tracked
|
||||
if s["status"] in ("slipped", "missing-repeatedly", "missed-latest",
|
||||
"not-reported")]
|
||||
lines.append("## What's moving")
|
||||
@@ -435,13 +447,13 @@ def render_progress_md(analysis: dict) -> str:
|
||||
lines.append("- Nothing declining.")
|
||||
lines.append("")
|
||||
|
||||
# --- KPI trajectory
|
||||
if kpis:
|
||||
# --- KPI trajectory (only KPIs that were ever held to a target)
|
||||
if tracked:
|
||||
lines.append("## KPI trajectory")
|
||||
lines.append("")
|
||||
lines.append("| KPI | Profit | Trend (oldest → latest) | Hits | Status |")
|
||||
lines.append("|---|---|---|---|---|")
|
||||
ordered = sorted(kpis.values(),
|
||||
ordered = sorted(tracked,
|
||||
key=lambda s: (not s["profitability"], s["name"].lower()))
|
||||
for s in ordered:
|
||||
marks = []
|
||||
@@ -453,6 +465,15 @@ def render_progress_md(analysis: dict) -> str:
|
||||
f"| {_STATUS_LABEL[s['status']]} |")
|
||||
lines.append("")
|
||||
lines.append("✓ target hit · ✗ missed · `·` no target that period")
|
||||
if untracked:
|
||||
lines.append(f"({untracked} more KPI(s) were mentioned in decks without "
|
||||
"ever carrying a target — not tracked here.)")
|
||||
lines.append("")
|
||||
elif untracked:
|
||||
lines.append("## KPI trajectory")
|
||||
lines.append("")
|
||||
lines.append(f"No KPI has ever carried a target — {untracked} KPI(s) were "
|
||||
"mentioned across the decks but none can be held to account.")
|
||||
lines.append("")
|
||||
|
||||
# --- flags
|
||||
|
||||
Reference in New Issue
Block a user